ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/0000755000015301777760000000000012321006415017753 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/0000755000015301777760000000000012321006415021571 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/unit-converter/0000755000015301777760000000000012321006415024555 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/unit-converter/unit-converter.pro0000644000015301777760000000060112321005637030265 0ustar pbusernogroup00000000000000TEMPLATE = subdirs filetypes = qml png svg js jpg qmlproject desktop OTHER_FILES = "" for(filetype, filetypes) { OTHER_FILES += *.$$filetype } desktop_files.path = /usr/share/applications desktop_files.files = unit-converter.desktop other_files.path = /usr/lib/ubuntu-ui-toolkit/examples/unit-converter other_files.files = $$OTHER_FILES INSTALLS += other_files desktop_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/unit-converter/unit-converter.qmlproject0000644000015301777760000000123412321005637031650 0ustar pbusernogroup00000000000000/* File generated by Qt Creator (with Ubuntu Plugin), version 2.7.0 */ import QmlProject 1.1 Project { mainFile: "unit-converter.qml" /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." } JavaScriptFiles { directory: "." } ImageFiles { directory: "." } Files { filter: "*.desktop" } Files { directory: "html" filter: "*" } Files { directory: "debian" filter: "*" } /* List of plugin directories passed to QML runtime */ importPaths: [ "." ,"/usr/bin","/usr/lib/*/qt5/qml" ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/unit-converter/unit-converter.desktop0000644000015301777760000000034012321005637031136 0ustar pbusernogroup00000000000000[Desktop Entry] Name=converter Comment=My project description Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/unit-converter/unit-converter.qml Icon=qmlscene Terminal=false Type=Application X-Ubuntu-Touch=true ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/unit-converter/conversion.js0000644000015301777760000000300412321005637027302 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library // the function converts the value entered in the input to the other units function convert(input, converter, index) { if (input && input.text.length <= 0) return; var baseValue = parseFloat(input.text) / parseFloat(converter.model[index].rate); if (baseValue <= 0.0) return; for (var i = 0; i < converter.count; i++) { if (converter.itemAt(i)) { var inputItem = converter.itemAt(i).children[1] if (inputItem !== input) { inputItem.text = parseFloat(converter.model[i].rate) * baseValue; } } } } // the function clears every input field data function clear(converter, except) { for (var i = 0; i < converter.count; i++) { if (!except || (except && except !== converter.itemAt(i).children[1])) converter.itemAt(i).children[1].text = "0.0"; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/unit-converter/icon_clear@20.png0000644000015301777760000000237212321005637027634 0ustar pbusernogroup00000000000000PNG  IHDR((mtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp 3lIDATxMKAEDADy Zgx3B$hzfaqyfuv^PH)mni-#0:Y/%STyS*!H'w{Xn".rቻ}j.te\>f>"=&7Yx(xhXA߄!úAJRpU+ZɥeXU;kxg6 yX@RpLpr PUۧl quKd"S2-Rf"P+*ր"Ӛp4 ې 2 . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import "conversion.js" as Converter /*! \brief Example unit converter application. The application demonstrates the usage of - i18n - units - Label - Tabs - Tab - Page - ToolbarActions - Action - TextField and - Button components The application converts length and weight units between several metrics. Related units are grouped in the same page (Tab) and conversion happens when pressing Enter/Return after entering a number in one of the input fields (i.e. accepting the entered text), or by pressing the "Convert" button. The navigation between converter pages is provided by the Tabs component. */ MainView { id: root // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the .desktop filename applicationName: "unit-converter" /* This property enables the application to change orientation when the device is rotated. The default is false. */ automaticOrientation: true width: units.gu(100) height: units.gu(75) property real margins: units.gu(2) property real labelWidth: units.gu(12) // Length conversion model; the unit is Mile property var lengthModel: [ {"unit": "Inch", "rate": 63360.0}, {"unit": "Meter", "rate": 1609.344}, {"unit": "Miles", "rate": 1.0}, {"unit": "Feets", "rate": 5280.0}, {"unit": "Yards", "rate": 1760.0}, {"unit": "Kilometers", "rate": 1.609344}, ] // Weight conversion model; the base unit is Pound property var weightModel: [ {"unit": "Pounds", "rate": 1.0}, {"unit": "Kilograms", "rate": 0.45359237}, {"unit": "Ounces", "rate": 16}, {"unit": "Stones", "rate": 0.0714285714}, {"unit": "US Tons", "rate": 0.0005}, {"unit": "UK Tons", "rate": 0.000446428571}, ] // converter page template Component { id: pageContent Page { // expose Repeater's model for reusability, so we can set it from // outside, when we build the tabs property alias model: converter.model // remove the input panel when pressed outside of any text input MouseArea { anchors.fill: parent onPressed: Qt.inputMethod.hide(); } Flickable { id: flickable anchors { fill: parent margins: root.margins } flickableDirection: Flickable.VerticalFlick contentWidth: pageLayout.width contentHeight: pageLayout.height Column { id: pageLayout width: flickable.width height: childrenRect.height spacing: units.gu(1.2) // show as many lines as many units we have in the model // it is assumed that the model has "unit" and "rate" roles Repeater { id: converter Row { spacing: units.gu(1) Label { text: i18n.tr(modelData.unit) fontSize: "large" width: root.labelWidth height: input.height verticalAlignment: Text.AlignVCenter } // input field performing conversion TextField { id: input //errorHighlight: false validator: DoubleValidator {notation: DoubleValidator.StandardNotation} width: pageLayout.width - root.labelWidth - spacing text: "0.0" font.pixelSize: FontUtils.sizeToPixels("large") height: units.gu(4) // on-the-fly conversion onTextChanged: if (activeFocus) Converter.convert(input, converter, index) onAccepted: Qt.inputMethod.hide() } } } } } tools: ToolbarActions { Action { objectName: "action" iconSource: Qt.resolvedUrl("toolbarIcon.png") text: i18n.tr("Clear") onTriggered: Converter.clear(converter) } } } } Tabs { id: tabs // First tab begins here Tab { objectName: "Tab1" title: i18n.tr("Lengths") // Tab content begins here page: Loader { sourceComponent: pageContent onStatusChanged: { if (status === Loader.Ready && item) { item.parent = parent; item.model = lengthModel; } } } } // Second tab begins here Tab { objectName: "Tab2" title: i18n.tr("Weights") page: Loader { sourceComponent: pageContent onStatusChanged: { if (status === Loader.Ready && item) { item.parent = parent; item.model = weightModel; } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/locale/0000755000015301777760000000000012321006415023030 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/locale/locale.pro0000644000015301777760000000056112321005637025020 0ustar pbusernogroup00000000000000TEMPLATE = subdirs filetypes = qml png svg js jpg qmlproject desktop OTHER_FILES = "" for(filetype, filetypes) { OTHER_FILES += *.$$filetype } desktop_files.path = /usr/share/applications desktop_files.files = locale.desktop other_files.path = /usr/lib/ubuntu-ui-toolkit/examples/locale other_files.files = $$OTHER_FILES INSTALLS += other_files desktop_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/locale/locale.qmlproject0000644000015301777760000000124112321005637026374 0ustar pbusernogroup00000000000000/* File generated by Qt Creator (with Ubuntu Plugin), version 2.7.0 */ import QmlProject 1.1 Project { mainFile: "locale.qml" /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." } JavaScriptFiles { directory: "." } ImageFiles { directory: "." } Files { filter: "*.desktop" } Files { directory: "html" filter: "*" } Files { directory: "debian" filter: "*" } /* List of plugin directories passed to QML runtime */ importPaths: [ "." ,"/usr/bin","/usr/lib/i386-linux-gnu/qt5/qml" ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/locale/locale.qml0000644000015301777760000001036312321005637025012 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem /*! \brief An application to test locales on the device Demonstrates following: - ListItem - MainView - Label Uses: - Date() - Qt.locale */ MainView { // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the .desktop filename applicationName: "locale" /* This property enables the application to change orientation when the device is rotated. The default is false. */ id: root width: units.gu(100) height: units.gu(75) automaticOrientation: true property string locale: view.currentItem.locale Page { id: page Item { id: chooser anchors { top: parent.top left: parent.left right: parent.right } height: parent.height/2 ListView { highlightFollowsCurrentItem: true id: view clip: true focus: true anchors.fill: parent model: [ "hu_HU", "he-IL", "en_US", "en_GB", "fi_FI", "de_DE", "ar_SA", "hi_IN", "zh_CN", "th_TH", "fr_FR", "nb_NO", "sv_SE" ] delegate: ListItem.Standard { property string locale: modelData text: Qt.locale(modelData).name + " ("+ Qt.locale(modelData).nativeCountryName + "/" + Qt.locale(modelData).nativeLanguageName + ")" onClicked: view.currentIndex = index } highlight: Rectangle { height: units.gu(2) width: view.width color: Theme.palette.selected.background } } } Rectangle { anchors { top: chooser.bottom topMargin: units.gu(0.5) leftMargin: units.gu(0.5) bottom: parent.bottom } color: Theme.palette.normal.base width: parent.width Column { anchors.fill: parent spacing: units.gu(0.5) Label { fontSize: "large" property var date: new Date() text: "Date: " + date.toLocaleDateString(Qt.locale(root.locale)) } Label { fontSize: "large" property var date: new Date() text: "Time: " + date.toLocaleTimeString(Qt.locale(root.locale)) } Label { fontSize: "large" property var dow: Qt.locale(root.locale).firstDayOfWeek text: "First day of week: " + Qt.locale(root.locale).standaloneDayName(dow) } Label { fontSize: "large" property var num: 10023823 text: "Number: " + num.toLocaleString(Qt.locale(root.locale)) } Label { fontSize: "large" property var num: 10023823 text: "Currency: " + num.toLocaleCurrencyString(Qt.locale(root.locale)) } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/locale/locale.desktop0000644000015301777760000000031512321005637025666 0ustar pbusernogroup00000000000000[Desktop Entry] Name=Locale Comment=My project description Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/locale/locale.qml Icon=qmlscene Terminal=false Type=Application X-Ubuntu-Touch=true ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/0000755000015301777760000000000012321006415026646 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Popover.qml0000644000015301777760000000570612321005637031030 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 Template { objectName: "popoversTemplate" tools: ToolbarItems { ToolbarButton { id: actionsButton text: "Actions" iconSource: "call_icon.png" onTriggered: PopupUtils.open(actionSelectionPopover, actionsButton) visible: true } locked: true opened: true } TemplateSection { className: "Popover" documentation: "qml-ubuntu-components-popups0-%1.html".arg(className.toLowerCase()) TemplateRow { title: i18n.tr("Flickable") Button { id: popoverWithFlickableButton text: i18n.tr("Open") width: units.gu(16) onClicked: PopupUtils.open(popoverWithFlickable, popoverWithFlickableButton) } } } Item { Component { id: popoverWithFlickable Popover { Flickable { width: parent.width height: units.gu(35) contentWidth: image.sourceSize.width contentHeight: image.sourceSize.height Image { id: image source: Qt.resolvedUrl("demo_image.jpg") } } } } Component { id: actionSelectionPopover ActionSelectionPopover { actions: ActionList { Action { text: i18n.tr("Action #1") onTriggered: print(text) } Action { text: i18n.tr("Action #2") onTriggered: print(text) } Action { text: i18n.tr("Action #3") onTriggered: print(text) } Action { text: i18n.tr("Action #4") onTriggered: print(text) } Action { text: i18n.tr("Action #5") onTriggered: print(text) } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/WebLink.qml0000644000015301777760000000163412321005637030725 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Label { id: webLink property string label: url property url url textFormat: Text.RichText text: "%2".arg(webLink.url).arg(webLink.label) onLinkActivated: Qt.openUrlExternally(link) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/TemplateSection.qml0000644000015301777760000000321312321005637032465 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Column { id: templateSection spacing: units.gu(3) width: parent.width property string className property string title: className property string documentation: "qml-ubuntu-components0-%1.html".arg(className.toLowerCase()) Item { anchors.left: parent.left anchors.right: parent.right height: childrenRect.height Label { id: label text: templateSection.title fontSize: "large" anchors.left: parent.left } WebLink { id: docLink anchors.verticalCenter: label.verticalCenter anchors.right: parent.right property string prefix: "/usr/share/ubuntu-ui-toolkit/doc/html/" label: title ? "API Documentation" : "%1 API Documentation".arg(className) url: prefix + documentation visible: documentation != "" fontSize: "small" opacity: 0.3 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/map_icon.png0000644000015301777760000006464212321005637031162 0ustar pbusernogroup00000000000000PNG  IHDR2>sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATxg,y;ƛqE RLbDbɕvny%Ֆ\`sպAr.KUE$$R$!D.@$09=3=Tt3" Jbu,*s]r!BUڹRu{h ><'HA䚖902H:!{=^(ra Xfn؂)yR1=(^)RR#EqL^\Hu1,;Mt4Ύh}U&҉ci¶:?UuY]=5οA{,*hoB4AK)4tv02M๝e d~+M~(pQZFSr v~X1L iTjT8硔bvvvj=֗mm`RO5;뎸ɦZOUH,s*Vi6'ٟH# |AۦPiL4}9(ExDKh0 S1- h\au*BRSi,R, ~5Ea9ZKiP,7pr_?izxI;V ߏxUj%oDu70MXN(W:mk#<0.QIAcX|_K>\|o1i4f~/6@2Cs{w àPn\}~MG)@7,'WrX4Qzntn D p:u֗N=l@mfô  D?Dmrc6̐L2UJj#UʥڝU)0(tۛA"a S*+.*Fg& }:[+8HRvRIY=tUk:qFS,5(7)WҘ O_&kWNvXC(iy-֞&^'b!G!$DdKƌcx{kJE,;7ok'{_2[)8iX3r%:Lvۑj%Cٔ e0F'K|P{WZrl6kk]>#@,-Bs5TIH<>Ll+* * RhԈifI{8 <AQ`~4ҊSqD~i왨2i]@eI H^BN<^7.=vT5"ɕF{}:ezK^|]M%,8Z{'O k{h'?Jdb1Sĕxzݠ^2yeūRp&78~x#Y%rοBFGiXN.wG~ Db狃Fv S&.*RR(Pww;hm-y.ΫoR~AtaxmC>!Mv"vQ7‘cD>O>IzjE+F]yr4 9e{')JysbLC:4Ov]_̮]ɶ T 4V ~ :5)bQ^;fR~(mʈ7փk:V^kY+Tz:|mm-Z&p;:ļpO`DJc..bvcVhyxuhu…إbv8h!WV.]"!P.?o=N˿C\o^&x؎CQ²Tx"y]+v ː,4l:w*gonO^N\矞>ǭ,p7yػ:nmű4N?{m4ȕ!F-9a4a/V'hV#ۺuGqS'_``.. F1ƁY,!yT?Kϋ9q|Ȟ<)贆ra fcZ={V{Jyn^H0?_JKTAR4N[m+tJ)UX~MkMZQ(7fP1|-n NNkP;qS /M䅠<2M4huY,Rnnyߕò-L<6sU#`rClwLfL;&5r>Q.73]`}=dT_Yj&b PG8dy 2(H3;)Oqm8 mhӑ}%E1tu{:'9?s%8-{⭭֣+aȕ R۶mY̚{DtmT Y<(`x[TKm 9^xBОiyRHDa,q=7ݘY|R\e9u,uN7摇#3yU>#dŝX߸ ϓ+vMuv ӲPjLzŗ#Z۫47.vḧݣ:J=giiaOОCa% yhD;ᧁapG.ǂe# .u:[Ba . r`@)o"`\ 5Ddʚ,~$c| |o|p Zj[ e b^w(z| tT-݁6J}q07u#Է~MWhoBKhn"v(/"_DRX'kHkq̳.BҴ~:*M.~">8Kb,Sr"~yrQC6'Q\/@}DeRt/˕)k lFO6Oje-YK5顰.(vE)aJ!] <~˞ 3Q,xM>|o=(E=ק @?1Aq~XMEXr&к|!Bv:i:fG?>CV8aO}vrN-C3@"INHn( prEGV0\YqLmĦklM3ό>?9{5ZiXq~ʲKE.Ly>yX 699 ݯApk.ariC;Afk}}st:(>vmZS @NcYX8a})yc u[lo-!^L .RS\it( p-ċ{CL :'y;Z[S+aȋ@닭 # p9)H47~t9(|\bn\.fНu V' #d&O#{'T rc]iVcI&4GָtQawk?~r7@^أr_%N63)kzk)X.8f< {6(-@q$wPq﵉bc|8ܸ8RiJ>y0'OmK=A@2¥0s ZʹWin.Y1[zwvʽuY}EX4V}9R_t4f'J>4>(A0|#}LbU=jDXDaHaDAH("B8&BbF`0(Ɓ2;6\;G1|glDVԕs w vMhROq_,טZ^GŊZ'8$yFPFbG?d?7~&?8# T*$ DNp.d{E!iK}DRw1$Ky%] iPKݯϵ1?W7gi4 %1.gĽq,]x?yK4À\sxe'܏&>Z)Ra9Ћ0ted]_2nWu_&심A> 9Y60Z7AG{>z>^q=/Z=<ߧ\v\r81G50OqţEoS.;qL>ӐO >JC WIe(&Hvd@ʁ6:&m1a4}#3:OwNŃ9}=˩gCq}p;7 聂 (x"AؤРPy#L:4n"_,1qcRJLD5> ]ƃo/1!d9ɭˠ_korl]$65zDŽZ+X!Z>%\vDLMOz/ pů|eP;%l 3\ut]s=|s=|/\vsU<%_Y2<||<#klw[> Ng^ok$žUJ^ş_~Xoz$JJuF O3xa5ZʀPjDNG:D]> g!pG%r;9^fG B<ϧxA@A@x.:n 3W>*0^ R ,@+D$k>[ַޠToPIV%W $so:ah8*zڠ4t,ڠ"f9`BC~N#m6[DZsS"_MB\^}1 Rb -8 Wpӟ&9c\mY)Nmr)|'C`hEQDt[t[ Ljs(V戢0M?x>!i4јSt]k|cX/7\VW0s/R,װ%aցsWeC#E\O&d}g^R:PsVZ"P;Ew}Pۿ1oVcA!QGqim1nj(}e,|ߧL1(Am@QK}3Od9<3^̗|orۭ #5|Bek~N1YҜ=,+Z,efH:* u¥瓭jdWuʊl11?xk.Ep. h^~Á's#e !@iّH0RcF T+jH)8c~R#ng smκBzZsg}VOba «d/12rF΅)R8I2LP:"<5s]X30\ !}7b IDATf Z"BA\xsA& m30 !ٰ۠ybӧ6oq9gyrs FCbs!|;ʂ4a⛝+75%YnQu#L~p!Ifs}F?fbiKɗ_xDWvLcwc0g3-xaUC ˡM8\0,;8\ufe &tj{''T>OfrH >tpo] ݷk7u5ZcB2>2.GkpD1O՘P[B=C : yˢT(019-]sHJz@in]?O]50DZ]RR[X0q7~>ȧNa@JA*cTK+f]_T8\rMs~{,w<('ϱe55-J^'Ր>[VYZthIP J\&b(n,"t_A= 'P*0MB,,-.AhS,N_) ðwqH Cht뗰8:ƑZBpmz-)IT(IZP5" ôs54` #GjECԆw$ױ,vXG曉UˢR.)imcg2qD^~j:`{0@&WN.K `صQ5Udk RNg(q?[E/}98%]]k.CB HC)F" )n/{1\:X(:9 C]Iz:BwcefRJ|KF(C6(I %O X_B*aY@Xr^{iZJ5ŝ]0ۖ| ^\qJ jm!?X9cIR OOSr`{*i?R`bGvHS99Y[VW󖡘*Z2q̵~k?/:C:\èZ"c(^!m"-+1I,N_FRʈ&lo\FAPILEQBln^baHfUǴwp2_3O! 9JEgWFS ZR e…h|]0lDcu՚by9C eA]0NSfMmoKJVwdPMnbg!JR$:hY;DpZFg47X>K"u@^@ DяڼL]kuR>+#2_ }Fd(4[.ngr uW %XGncZ[KVrgO Ё08<7GAOqjr)%a޾cR.(HE_Qu Bb}!CJM^r(ɮaWcB!nAiڝ ʥeXqeS\&u&"z=v7 #"ǘp7nv޻aי1V-\ntFj=$g2cwXdoh8mǏ#LgPF2/[+=H#%Zsv9 kg^9:*a/V1͝32Nkʇ*8o4c ρ7O-&W4Uıu=:$BO#;0@Vt}b&i6K 8Z#8P,2_pysMz']h}ic芈x"m!R&\ħ`It=)x2 5ZH KVal,3R? )>BEdVu pZ[#yl,X ׍?JkjMflY5Q Xe$ 5L ,J}=fzv,̖VtPxVaD(Z c"Gvf&t:Әο()+4huy* K!J>uKҼ:o_1W6oH"Ev@rލ}wr{ !ҩo'۶C;Yl*{ /a_aY']L&0.FL^/Z3laK S8+r8gDPlK}> t '!j0U@S;)R暁^o^z%#Ā?lz~UXi=ž9[0W"'/y7-N4u,YZ~q}]i&%ebc!{*YBsO>K̅y@ lLA:{1=cD+Θ:c} ֲI&pc;'?CT@JI*:wWlPP٪5ڂJvUJʳokֽעlveb+3BH ^8 9}:zk%e,)D}qwx8Lt$kј3]`N.".;sV*/WOhNW|f668^g6Ghk&zm L{p˵ن M :${>~8KTgƂVEb=sگIn+ f02HN: ;D81i  )_ۙ&Ƣ6z۰3 âZ+2/xxwz_7|̓wTy6K>ݵ#T(PFc_~C~lN!5HQZޣj8}4O^ƾ}fCda 2gD^!u?'DJic!Mo .'/-0men356.nt p cqisqa޽,--Aw^n^^fvm) KU(lb>A2A:cq}aFN(Ԣ/2@ՇE*cd \D-yrJ-mz~h򣑍Aj0*%w?<ٌ5N>z7X_^Q,G: 0 }'_bMw"do{M7Zs;^xaWXk]&YrtNd+ 5r%2+eyiBAv}}* )yeǠs&̖ S]Nu^=ݢQq8XD >҂xǚv`VIi?d2MzcPw_w֊a{=XR˴Z-n8j~׻XyMvO 9}'t68)e$g-=|GC?ЄJ2Pg4O00ҐsZ~.0(3S/a؂svGUs8//v*8A*l\O2@NmP v&ЕY Vq~ t3.J)vsRw)%wsssr9lƴm.s|a tTJt]Mv}}ߐNjހ}H)Dm؎E/8) 0 ֞B,y.pc?Zsaͥ-S.|Y<[![5,|0$z.a F33{rDG|2>njnTB z(`h'ssse\qA=:[Wج/Yto%Ţb%P91#u4f G5DD%G!$dLC[̩|.9*j2)o_fyos}Ҫϡ]9DQ< ?-%Mbn ×U';*8I>E҄a!JF< J,B[t[brN+X<}݉4jRz=ɬ{_ =,~F ~v+ARmEt:+*u,v'1;dő 0 αvC 2 HY?wL߰y]t},"Y$j${aNJPFm9T*Bt ˲p5V+ev;],Jl[HD4z =yN!>yHV:AcPLʶdd&V Ð-!RRvOae]}w{.@AI$R>%a+Bd;';.ڢdYHRXb93;W}TUCV=07QUYUY{Υ6՚ϋ3kWnU qb'RCKV RRk(W0.%u)RauZŚƷߋOhC4h4ꦴyMh.FSp Cgyȓ."BNEgqz:Koѣ4n~*Q LX"jBoscStC o]8//~n Ҙ8{4{[G Un\nO/-Y ]f[Oqr>q#7t$cs ߍB R{uF  y0B"D@. $h MeP~ qPwc]$QX])4 %LkXZ''e LCq^~gJ㘂;<) 3}2OҠZk!u澂s=w>p-et>ZmF/1Zrooo%S672;w*9C[4bp:]\Nu0-d({#Hݝ~ TGnG--;BdG[.:Ųa؎B%2-36]aƘ=GZ IDAT4'+tt2 j TgĿSjylT3&M÷7R> ,:|RjG Z$~Щ]& LM|ۯqD"4=R9lPBiP* tRªA0SC`(u@DEY6n"Fm!:±1q\x"F"*I+Ie$.K8!( ei鳉A74c}y%"<ϑ؝N?R->izNӋVɡiilKG7+|^b?}/I#pY]2_I6^>2Y ~eIPU,P,OB#ڊkCW1]g-;e~"OvY)g"dW qlqmܸ38qRBD 7É؎B찭Z68"W$r (ohk' NDFgOVM*Qة|\ /|m%[?~s4-Gm__6RJ67tc;^^o+_?CfW7X >UyϠi:B)o+ fI6 Tn{HkzN19)Y8 yWOбaIȣ2܎)'cڤ]<ɌK2&ܸC̵mdZ"Ӂ%QVkTuO!O;d6]5ye5`ykS=a r&@wmB!}~ icND"G%$+R9d5RJ^z%^z%<7o작Vۭf(f*A)S`i'A j":ϸ;RD:N"dXqr0,3s!Mt%>ф'wl]nyX zE\* *|4 ;&`!oro fR>PO!s.;dzX 4T*M._?Ǐ t']V+_e{6b}:gcc .Ovi: Y_+S!ؙ#lRM.Ic_*M am`JHONƎ١!\z-#MwGU$Hoz_c/V씫4G/o؀}L[ŚOgb]G( pʯ>R"n6f RࡼrXKX|3/q)*HdV>_@YŴbmnyq]/;\ڠݪi&n{4Z[*ՉvcIūyj֙~ve&NLQ7OIB8OpM]ue $A֏@A )j\*,}=ԷD!ptwcx lr&/[;oOᡙVXC=ժ{-b4ΒL.@:٬K:/!_YqxFϿ('r%tkѬw$L_~ׯs1ܹC!aqJ>@Ʃi&!CľM/Wk&~Ц^!Oan4Mq>R[ 4MczM^G?ǏbW+ߧݬHMv#EH͋;)n.r_YB7)Si=*;43 zKI$ G9xY&fܥqzp橳[a1ddxϼ`w. BVn]ƛgZ]eg9p3JSոvlA5?f}#,'NpX<iBS?a>BI1Q)x6@lR),E @uRUC7m|cc#dYbXᔓJY?t ˶>"ټ$Is ҙ ZiiUVL^GEVGCOx^F]DA,F hΕ+Wx7 U>OopQvkl\M#ÍgF@[A7h6$jtߟRi+^!rXZd~e.: } Q/c9qˆJvMM %$qg*'0 qt6ѓyܘB>mY0bh>.k 5Cɨ5mOMAun2*:M0LwyWr9X[[<+޹LY#& (t# zh"ƻ!p՝lU].]Z%0޸C&8AlEœEA4)}"Kԭa7Ji k!]isO!SȠ驘qnt/ԓwkxݐhTC螆3"1C9FĨ?w~7_>a`e- |Zyd.\`߾}j52 .]0 ga~nl\W_GP|4*2E i5CTUx ~9^}U}Yyٺ d@,f#|\е)lQ.ovqLʕ Jo#X,fV߃(h6&籾|Oк<4Möw Z[u2$`9eR:EiwaY>$Ny|[F=@:MUId dfOY^^&ꫯrQt]P(裏8*~%v61}%IBt?>eu|W 9&Fk\R"` iL2a^~vVen"MM>DZm4u*;$DrPS+M 2Rx~ 8nIX .y!gϞR`=9H  chB) fxAu+s:Wm]4tOr4n̰yeDpzHDhu*x&LIDD"8c{2;$qk *Bס+!L?PlwW? F/&v!OSN^{3g<3Ġގ%;J{Я=}aòZ٦1d˳lӧgI&m}qN&SF'@2.uD 4M|8뺎eYضeYL$΅z@ `J92D;GD퉭aϫ iG&%.[}6:N(]_qZ ըQ-G MxAy%ܼ-p`|KT}>R{5AЄM9:*_1׫in9!).St#Qe,| =!'IKTUh?chp_͝@ߦ٪!44.T*ŕ+Wo <#dY뷹5Jl-< {I"n1JڃH9K'i6 {Vk~W !H; hf"Sx&P Q4_A@6GB\|UΝ;˗T*izB~*֧ blaa{4g/-0 Eҹy G_9I<ٽq+qg{G(v.[,]yn6^T B)4L XušΒnթ֣?aMǜFl]`{tx䥗r=wJk海Zw?cxv)XoZh,P8;2(B~a2Uj-ڲJ g΀},9DhajXE?mǩUi6dokd{{P7lz<}(bv{aJM#{Hȵމ4M=<BXp'ω3sB s#,_l N< Nu|I*aq>~MDQ0À/Aݝ,cԓ ŵ= c?>Ma:c.L8*CL&0e_7ߣ=|C?hu3)GVe0E |<$麎r}oLav)dS^4gs B- 0L%,4t$=xgW=eǕQcl̎eefkHaյu.HT%]Sxj~:Ziz:zyW7$33aF 2e0?3K}c269qzLaHIDl7I~R`1G,f#Txt$ǡStgs n/0=X< H;8~6zRrI2}r,lO][ GZ`kmS %埰:<ڊ~boMJ7Dѧf+{R2 !X8tôfqe# >d>i.Ai4zL *iqXZ*zy~syHFB2\n,c'et d`SV{)-;w0-> BC47[eE2Nx? R~QVZr~!AXJiCe i<Ͱڤܼhh^`Q?̳|],PdFΑ1~;lFA"20 Idh1&Pu"cdae{h'2lJL]7ɤgl"ޫSZ޻1W8@2S@J)4ɠq0{F@N|i794 MhT[l޿9 $;fJ1evtm|zmz}о$ylEo]ߣ*~cƮƲ]y vye"u~0u:0;" a:%jA,ǥNK`[O#Dr^@Jfa\dT&Gv,>ЌȾ :}v1HH{?Y=-d`oB~ #%ܼXh;O0/{MvvVG4)(7XvaBj}K{S2NШ~H3618c b4 <ʭKsSdhThԋ=O18a\[=zk\ CzyWߩ=d)yY.yjIԈ ~ĉP Z3yӄ@Kcvj0P)mD 1>Lgds ju4jl-O% x) `(l\EH ]HIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Sliders.qml0000644000015301777760000000412212321005637030772 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "slidersTemplate" TemplateSection { className: "Slider" spacing: units.gu(5) TemplateFlow { title: i18n.tr("Standard") Slider { id: defaultSlider objectName: "slider_standard" width: parent.width } Label { text: i18n.tr("Actual value: %1").arg(defaultSlider.value) font.weight: Font.Light } } TemplateFlow { title: i18n.tr("Live Update") Slider { id: liveSlider objectName: "slider_live" width: parent.width live: true } Label { text: i18n.tr("Actual value: %1").arg(liveSlider.value) font.weight: Font.Light } } TemplateFlow { title: i18n.tr("Range") Slider { id: rangeSlider objectName: "slider_range" width: parent.width minimumValue: -1.0 maximumValue: 1.0 function formatValue(v) { return Number(v.toFixed(2)).toLocaleString(Qt.locale()) } } Label { text: i18n.tr("Actual value: %1").arg(rangeSlider.value) font.weight: Font.Light } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Sheet.qml0000644000015301777760000000644412321005637030446 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 Template { objectName: "sheetsTemplate" Label { anchors.left: parent.left anchors.right: parent.right text: i18n.tr("The visual style of the Sheet is early work and thus clunky looking.") font.italic: true wrapMode: Text.WordWrap font.weight: Font.Light } TemplateSection { title: "Default sheet" className: "DefaultSheet" documentation: "qml-ubuntu-components-popups0-%1.html".arg(className.toLowerCase()) TemplateRow { title: i18n.tr("Standard") Button { text: i18n.tr("Open") width: units.gu(16) onClicked: PopupUtils.open(defaultSheet, null) } } Component { id: defaultSheet DefaultSheet { id: sheet title: i18n.tr("Title") Label { anchors.fill: parent wrapMode: Text.WordWrap text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + "Integer et ante at erat malesuada accumsan in eget mauris. " + "Nunc ultrices tristique laoreet. In non tristique lorem. " + "Donec in libero ut libero pretium lacinia. Proin dictum faucibus viverra. " } } } } TemplateSection { title: "Composer sheet" className: "ComposerSheet" documentation: "qml-ubuntu-components-popups0-%1.html".arg(className.toLowerCase()) TemplateRow { title: i18n.tr("Standard") Button { text: i18n.tr("Open") width: units.gu(16) onClicked: PopupUtils.open(composerSheet, null) } } Component { id: composerSheet ComposerSheet { id: sheet title: i18n.tr("Title") Label { anchors.fill: parent wrapMode: Text.WordWrap text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + "Integer et ante at erat malesuada accumsan in eget mauris. " + "Nunc ultrices tristique laoreet. In non tristique lorem. " + "Donec in libero ut libero pretium lacinia. Proin dictum faucibus viverra. " } onCancelClicked: PopupUtils.close(sheet) onConfirmClicked: PopupUtils.close(sheet) } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml0000644000015301777760000000400412321005637032000 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "progressBarsTemplate" TemplateSection { title: i18n.tr("Progress Bar") className: "ProgressBar" TemplateRow { title: i18n.tr("Standard") ProgressBar { id: progress objectName: "progressbar_standard" width: parent.width SequentialAnimation on value { loops: Animation.Infinite NumberAnimation { from: progress.minimumValue to: progress.maximumValue duration: 2000 } PauseAnimation {duration: 1000} } } } TemplateRow { title: i18n.tr("Infinite") ProgressBar { objectName: "progressbar_indeterminate" width: parent.width indeterminate: true } } } TemplateSection { title: i18n.tr("Activity Indicator") className: "ActivityIndicator" TemplateRow { title: i18n.tr("Standard") ActivityIndicator { objectName: "activityindicator_standard" anchors.leftMargin: units.gu(10) running: true } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/demo_image.jpg0000644000015301777760000030701512321005637031451 0ustar pbusernogroup00000000000000JFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC   C @ !1A"Qaq2#BRb$3 &4Cr 3!1AQ"aq2B#R ?T]مfdjT]}PټO?4{:\m|i CC[\]-|nkR*ʫ0TH(<.plSu~msNiM)\[P(BTd]D AI=yI8<G"*YEŷHTVޥ6<+L0DHF$o ˺,ߦ 5,3TJ5h&+6 4 ZҒHܧ~ms5sw'5Z5YY lNgF:qZك,2Wz_Uequ3:VEJ4 `#X#O udE|t=yr܆XѯcmsTԥdƚTd R:v)$~'NSG>]{uu/N)- 6AlbZAb1ꤿ2A)7z.-ez-bAzVڂI.TkVzOEK:vr[ln550~r[Ο=]J3Lբln ywe۶౎x8psFA:>,r,(Vΰ"P)DUGܯ GޏԚo䤊7"ˮrK:ZC301YUQֿ<)ieᩩvm<NXvta&u%:BT UM#Mo+z68/O]<:c:wm^ڛjY!J!`2`(DSrF-YU4MU  o3I3iĮ˯z+;fig=~^۵G+ gD;;pilKTNuj˲fR|r)(bA@F'(ioG>s^l.W5ie*%&P L$J'.V@/![BO 8}$21ݨTD6sG|EiQӽ+}W4i\WB0ԵH @(oq3ym}+E[\K7.-z$] A Ҋ{f\MگݖWيvhlOKXڌ1wߟ5$+'P|L$;J5 R j5YHNG"SYSV9E<9+O_w`nj)e,B}$R|OL(a mIrqZtr$UHُW%B *GFyWfi|#HǗ{I6:]r7V@rJ+r[l<0gĕN]s(GV.5j*S#;qLұ[ <lVs+] jC #7籹1F4Ab8Xba6 @a*5GƆPT > \gX1d&6I3nƛ؃s\$ꋝ Y ЂFpjzސYA*tr#smC]Tu,GoٓʔӺj+|Qƨ-4cEZ72~1=ynur XoqR9y27޿ %wL~$`䜿mp}~pֵb\>57f׬2G*bJ_t֋#91J7C'٩4x'H~ϕ =oՎ$WLυ:$jӿ?}KayC֯عV-rv;|ӡZV\+2X^~':&H|<[[;jP BU%V-i|FÄ>ޓiWUa۾)ZVW7q QI3nCRTlJ'z%C)i$`\ *qFǨ^N4Ъ^)/l[s@'sw9f8`JRiUҨ6b.T-J+v\[ȤP+dzIvw:C$n{|ˉ3-v{eJVIr2ʲ4nH2`NP$.d9F:>drQ|]L?KW{zT[ E!A#̹g^X9)3fJ?UX]&"T I vN=Zb!'hNQyNwBMWfNmTRr7IR;u:V:4kTZtRire$ ;|ˌcr|Q7̖(c|/\kSN"Lx)XFr5gO;![FgVE4EHH WS6 1*`Ǡj^vs\QiQsgRֵ\ފU-UٕQT#J@;82qﳟ,T2NzQdF :/+%D,w1+.;_NCZo]uM1BK)uy!B@&q+U9YӴQ? %nҭUVVN%Tv nRm5:?Ϧj_:2gkzSp*Q`NUT1,L9?id^:'ǖލ_C8t]IЙ|-_*RVAZi%i+*1\~Wgɏ:ٰFiɃcyaayyyG(k[_ 0]2Hװ};'rx3 ;g\snwf7;u9&0NT:DOWhd%/[tV[vy)ue5HR}Gaq㌾:~Tuq=ȳ'lX4)biƕurQ S7bIz64UHdynI])#Q*^(zzI; N jlmO-8>/Fi@C, ?\5E 6q:aхtdy]hl#mƜxlϟ,] 5SR lvm ͜$V6*CsqF|ʚ*;mƬiRch )%X3̚j2T,4{_iro<3Mih̞|q)ʔd`i$޸>mdrX:)//KAMT2MlUu+}1oM$'+v?uBz`Dd{ik W̚O3T'XI,|U:77'IR%+]ݡ&("  b܍R|ÈlL08G,AG ;A'$ .#/L.t1BFдjSd4i.Ron ) OLHqߣ>{iV e P;WM\"Ǩ& }G; TښIm\22ٛ$PJ3b4N۫Bio Q0cqOGd#R2S,I}q[xnMiHe-pzH9Lz‹ʐˬ=@_&|ᦚ/~QZt E 備8_S̓%adI.NQK;U3xv yIO;c hG[\tka=cJ +jUxܱܒ8SISm$;GeW. sFSOmݪc|0?%[=Q.Ⱥ5z|)hn3LQh Ke /AI*#ɸ3vY卽;4^BlhbRX|v:k~MJ6ܻ;^KҾwI+ۭ:1MEBU]'ӆ{ÛMEkoI${`Vwo89[њPsi{[t JfNqZ O?g-ej]4r:eOQv%*pIHcw>_gg:.j[/-khT e1O,{2Td޼weo{J[u򛒉Z ߕ?ßÏ*=UL=ouA[6.)>zbv.o ~WRCxl2T?Ӣٮq)kSY)P(mʐ7g$9tct.ی>K*IqFԫB iq21~/uZEK)嵿2[f "*N|x1{;:R{H>#f6Lz_sZ$Au 'mǣvEU>K6yutz\(Uw he!>4OF9˓Jtw,oI ֥:ZjcM;c"{`;.랢 A֔jV" s9t*v|QJIAz?L :O1k^3w:0ȳkR1/P^CPyD҈6rq^4Sżcz]zWi%{e#da̙ߜG6NI][?z)ZMZ4;jQx ɋiOߣ"tR5\΍CV\MTK.4 WoxG̔V ٻ<|f-oQuFoJ*xMe|=*&O H 57~x5cZc޺Y[uWWtVgwm^ڛ@"M6 F?zM,v,Z-J裠҈UIV#0Ri~AmY+[C1$x#G˜:/ї"rt;vqNʝ&[oQKSur ǿ3yRrK@J,.ɲ6y% ] obx8a"!cgkUhקE*:Iě|Z;۪֭ՠYUNḑ ǸFG:r<(% I;}1֧VQհ哔tX,ATqm{5Kr˱ O0/:Vj- F6Y X-q}0WPN|K7/*3V2#x?f %*ː P`B6+݋= K9'_ȧv )X?\Ipi0vduciա7 Sr@-ßnqT> Aa@>p\v%G_aFTo0vgȵ)ۑ596fwOqqtsԬfT0tƈF>_"Y_@1fD?n0j2~u| ՔIq= S+Lꃰ)S1dJ*hԂ:04b`#ñʄdj{~ne&+tH-qabߡjO)+*S1xҜk ) O$[RZw⣓V2x(aKI552 ?r0IG4 `XH~¦F >4oͩ,P@`aR}*76Z-ǯI9'|T'|񴻰4ƝL+v0?BZamH+ DNrNHڢ!ZAfrjVm1Τ6`HFU&9E*eMcuJ1u?7_8|ԣJ1k7^OH'8<핆<`a4R  rHpY2-Ќx?jMuF퀖Mh mT|vzцs*4-6{c4跖xih֭"71{9R<ͯ*` xCHA)s> :lU7E^3-T+QFGߞ# SI rkiu\ζTzip)"ǗHvҦ"7nswoeS&i1H#s>\|:|uŝ>[SEFH3\ +ZfxG3>^o٨Fޥ#UU\YB'ʳ$F3G4 xc QZ~'I~'kPmjIP*;H QH F wU$Iü첞[ӤU!P?cQT,ܕ{#ف4SNOYR7;c8v(+󮛦6 hZuS Dy0G}<~g%B臣jJT ؍^cY>}}7p? 3uKNҪPMݻlU 4wc临y2g\'2slD\ i*tqsTssl ]ֶ5nrQB*9?#P?1~Կ6_t/u-CAMG$: "AϴlTw|ω 2ȳWi\Զ>54؝D#J$IN4T_ԛì,&q;RiTҪi`Ycm| 9tv1(~?~$UtŮ[`ӠPPDǘĒOs;|@iU9k$AGHf>uAvXљI[褣gWhjRqP(mb6MtN);*?zs6ee^)\@Կcڡ.joL~$?QJ5;Ďgygd$~4~<l>:RW"vBЇ`ЮYbA$STb4k~v֓uZlj\2]m I;&q| JWTfBb<E'0>kJG?,'^>˕Ϙ PA^0Jp۷ffբ26ũjیbZjP "YtqbOR$qxR02Ǖ.M))BTgi -H`-vnxbmӶ4ęi;Z?%*kH=Fvۏ Otexx7խcm@mSE}J@Iq0Ŗ'uK/N]DHsհ'BIKS$ 'mVus V*R 7R3R!Cv'-!Қנ $ٖJ@~qy |t_EI40o3ammQp>^'&"q|S56g:#a˯ydm7<]Ay-r䂭iؕJc' v}t`|.Mbda@v@8ByRz:Ӽkqp멑ĝLvq^LV̞z< mRA+y$qiKnz&(ZJOĦeAL0F+$@8SI6hkqgwL2ʯSB*Q O$&K&N:~,˥z5Tq]<6 uA$5'"DDznr24ޚ pWA^p?yYmJW<|qRiڢT6׉VUj7  ckR\ދq^6vAZH=f874K?nKGhW,n֩soRbCI8!UT#@$p=R\ZqKMQԕ-9l4զ@YmPv~_dI3@xp[.,PPRJmJ+A7ozcW*š i5|MjO8G-W\ͺs<ޣ% g:aF{oRK%>MLElQJRԃJLs]b87 Jz:[?QԴjuS=-|2KRve.:%3xl%P*+0mԑ@N]77)6gH%dVokҴ[[er)}!:X(ƔJJ_Sީ3[&-OEFTebQĩpN鿃:ΜytmSJԱ^ gB}Lռ$HfՋ主ο.*|EzK1ϦUz"ZiӪU*Ux.[Wҗ`gů5Quo7"o 1y&'p#ӎ?Etd[!>\ .Xu 8+ cqW;=m MMk'LRVm$y@gC\Zu ߧ򋚙+vDCB?߆?-_T~mfN֝:RbzqߖU/}~Uֿ`,!&vW0y,^~-Pw%cqƴ:=JօHR$~n<m ա {|`e+V 'LJ+۶&I >4 ?}rwf\FԗPXP qEN g%WV|l#.Q5=Fyaֿ@j&"`zL'~ $ юRE㏟ZNjr C~ܐV[O8zdz"`TYt.xW:L?ˆ(}0QnuГ)j$KT\H{hdշam $_4`jF-TNκhF0XB$Oo|5:V2uJT a++P;H]K]=`5(~eƟ} 0nGYM Iff&5v,QObafDș<\gZ Gњ6@%Wm{kgq$8ѫrDԥvtAngqZ`RNҊkeV./ƠA' 5q?iNa1406D<^~Nӿ}I{y5k|EMrM?ml 2,.^XTIpa!v>Ĝs~Yv|C:o02ڄ=Gf>">"nLI`x7xSgtܧ4s^U,YG3~X91;wVF@]K٢ҡ54Hml>xx&S#j[S ⅹjP6< o}Qo!oТpA[jd0D񍸢;GH2RiJj?8) m-x4G 6w~,\6Wjk5@AX,dIϊ"SOo֟o`tص%,!>t$\u1xSkjtA}p@uEҹ_r 7lq S+i=s7:iҴ2m E4Uĝr mر'Me=$Ow.DKg{!D^*"MKOH擱mЙJN5ПOEsY0Kz5XԤ;wXT-$A^Ζ$'8L?զQs|멫5Jw4;Q^p4 |O(q+%­~ 2R 5Ibw&vi>.G,Kz[ KT Nc+2|]#B;QcT,lZ <%C8V\Ə*]B7}o131rKm q,f&Nc~u);ƔVw6ԍWFRL($L{%)GgJ UK"91KtS-4$f~[ZۊՉ"O Y>I2N;aђ#4U3S:AHOtE&'TqR/:` @$qeBJ[b2ǐ03W)*n*9cebrRl )3xƄD3֥QТf}1 ]WTU\*¨ }SBVIIPU$q; k #Q~ {qJVg4EAzȔwrZ꣱PLHͪC @ O”Q1(UU j*vSiU)7&ieolhT،x教tb]8dfJPmsc\Jع)rq0AR 8e%EZ5ʍD N9۶Z'% P,vߜY˔& =39[tٱE%  1>C|UZFK*3 05amܓ'1u~XBXUy pm&>))7itY=ss](kH#'i 5 Î9y5izӄ[-^NwjrJ}JnC>A36ʰW4aŝj2ֿz+&X4ڿG#nh>*ZEi~$S;T2 0=(k_o<}3:ҭDm/MbHbo,si=vɟ(%hҹ4Ҫ@#C%eJ;%KJZ#ydK~m} V %m?F5&evζ} PF5΂yc:0FYxSs/7qMA`@#c|O' g^Hc[?oԸmEZ=5cMuHMq26a8&xY|wŭzQzw[g9M |PM'rZDHv˚Y_O> ta[o;$w q<Ǚ.݌⾪/daZ([@U`N|sF\cK=\:.Z] "$2q};@>%}wqV5( ^06Q3lte|k zU4ꬺå~5ҬZx 6@uf:sW8I^VUjV]!Iv,=O{6䊒j:KjЂBxU >6/d{3EҔm,LaOر~s}ΛJjJU֦g6e5p~A$#>I>|^!׽3ҭmu[.9 T3|iR:i#2d忂/g4Jyy9t}K;Q4T!6 kCucÎQmɹMRLL|t!fl]?t7Iҷ VL `7ٟ$;fYul.5jb`%b(kaQ_an#WT&} T&3tXO5 c~d~tW]S\ȉWȏ9V~w`p_r"H@ oa T^'-hѩj;J "RD^0nIHJm+ѪR"pK2 T@%b~2ļ7R -zn5j{xavtcMw&g+Uo@9I7B%hlMm :2fw Z%$,b@'M僋c]Jf< ;ayۊLĐ[qًɏ*/b;'G++^S$I<>}\PKM@!RY~xSߠZ[Iq޻aH<؛ЉPPO.Ш㒴. 8 Ϻ1BFmR{DYF7ZMQHD{IՎ 95/f q&? u'OXs}T 1'f"g1pf baT萩,@^-k^7\LsHҪ@TQ;T8 j];v d.l2Bi'o|@bRGDǧ8)dԩ%JvES+ƒWE:@*>XGjk >]zdmJx=QsOfJZ43>~bK%p`$K}$FI{5dTRqDlg"X?$N#+2ĔmlJA7_ASճ `SAB@f+؂QfV$8ۿ| 
y[mf{ dukjObccD}aԨ?|%`A+$=73ml(ŻﳦtP[uw{'2EE† D/taF|3J2K]՟.J7CuW.zƥZItR+1QOC%3$k*n(>Tz[.5*H$yǩbrצy)XfUK"ʒʭjMM1ZbC#D0$$3d<2 <4˘ԩV *G$Fѿ֎FE~èdƵ[;AV?݀H|0f7COs|1)̵ HD$HٍBR'j4E;!['7>ȥI7H4gM^0N|f ,wǿgFfW_=?5jV٭el fc rۑ9q)5fȹ;qz9k̯/+ R>S(P mcҫ 9>ï߈:+PMV 8Ig^<=|;F뤪g7mhR.VA ,{,Z zmP:AvVF`{R}ԕU͍\!^[ZI(clu>t~t>$ur42=P$ɝ:{s_lon3gYwPOobX[S Ӑv=BMC?3zD_ O N6l)8e_]ENjiAbNÒ@#nI#U3o`hZ QdL tđb*J:^KܸUQ)\Pj)xHRֵ!)WpxW $sWNa\fV׶Wv~5JtjejYiQaF\mîB7Wju>@cM^=|Jң_#I9'k.E5J0hb^!yc}ZW P$Ș#evt[HӉi=4[=LG]kS4VA}A! N 4i?={Ѕ vW휬xj>z  Sn01M -$GA71}U@`A[ @(]ȃ%0M;t D`Ds!xZZT[Rsv*KyLs1냔z^.i3mе N;q2dv]SI'hC#3roJh@NV; zj)j~\vrZIE˴bFm8^@QGU4Ȓʵ6<܂{S*iInַ4dvHD*62Y}/UV^ŧU4c̘2z(r\V2Oq=&ѢX'Y'Ż:+mVjJ,"BG9p\miV[}?y Jxά`<A#N)̍8-E.L*YTTUP-͢hŪi *BKNI)Iǡkρ}k7Jd8MN:ЄR@$s{&V:gF\fAG)C+!:C8D [x{c:F<]ϟll, u㼨5adbațFvwE̷1[Ugc@3dG.:X}3 gTW-U]pɡh^CZ0Qu)k.MHZ־z,X(K!B OQ켓rI{ٚM.߿"JORrT*QӦW(Ku0yHfܭt*q\y4~u_wyV^&uN>riDG%? ijVj jwKգ5LfA buY̰. AwwauBJ73D 7>)WF}?ww}@iUp w{q+]#z:X9SUV+ ;w}M JoYwWrkj-XSbGA:xDp1J QĞ=K\gKqV ʽDZ x2 \[<̤u3j*%Bss;c%{3mK翈= ٍk-DvQCLwzfu&3EwgpW.$ir'cǦXjV[V ,qǎvWIZ ~R\iTfl4V`.jd0ؐ=);i)½L;YvB wj(.IPA!L7BvZW7ӢU*и<Դ"63`e?aSè'q#p;ؖI"Jε+Z5)CFؙͻy[k=U #Ib*uSzv#g$@<c6lR(FTʪ$ۼ\cf(G{MZX[a)Uvه8:_{1hEz(0 vl$p}0.h8–Taxʬȭ zK*}+TW]WӨh'zmq@Qqzk΀oL`v9`1nUU RٶpMli @IR UB@3}`Jо⚨b ƨ$1ig!In1lRQzUIcL&G'7Vr1Є6EW 5xoYlkg:Pi88h; K*vBI<3[^)[* &N$r{cD% a"[2-lbN/"Yo#L鰹Cً?qGMrx[lPlF̯:vKM&>[#SeJN e}j1퀄5d]t6 H٢#|؜X]lʦwtqѱMXzf ظqO*#{6ijUjga3R4KaP[R=xG4e%,i+kBT3FC*O;}0|\q5h-+0'$rqJ*lI;U 80?b7ֶt*]\ZtQeaBseC)(/} )ln0.[`HN0GcɺC3~F?Ц[e6ܭj(t#{|e_K'',C,K$B?/R = "$qkiDQD$YժHO@sM9G'2+ԢS|-LڥůR@b[dx4TAG 7NWȇvoOF*9sjZ5WqNT5)6KiSOEJ/o0|;[6 cNꐩZJɦTpUvZuFX:1`M>UՈ̊:sڟmg֤SdWjBAu,1>͞9)fEk UUM ;}Ó[7|鼲׭nS< yA)&ݫ1tUO7q;O1&Rj|m5c9eW)\ѹhDUe @6BGGI\V~ZήR ȀFFߩ)%F 7'4P %)E@!VHƸri?Ό: +NfPj  1iŒ=6[g;οs卥&Z5*bP S'[2u6?WfL>|IʳjOpMm>aƙǎ~3ɑEtw0ƿGFe O.KjtVW PT _"}3Nl宬_3RjU(e"8QQ3zF=E]L_\?_VgkV/P;$"L'mayenN+ힳK37][EEkRfStRI!*_8,ZKyIZ?0ycWjE:cTHEբOc[DDGng1ν }6YLx٥S*I} mɟ${}.ut+Y_fZ2 DNyWA#OdwXfֵRt"ՙ4&u +,O? s.4ELҝR** ppxiݜV]BC;-<Q4.UҘ,Rw;JYҺ1)'n⛧f$kU=kE- [$s~KT?1tFS< a٪xtþԵTXw|w.yo^q:uSg#uv1(NNx%u~OAjlL,kFhLA:ב4'يG,2J00Oedi4|2rHV oo3 V'OҐK ՛aKHbhEֆ\GbcJ:]dnszB2EcJACLv19vsTo*RH}\j R.5#C+H'Ƭ9@5 c#鍑̚rrxc0%K'm+"NR_P( @،E={%9+ JWuLC0q<L& 4 r?/^%._7+/ O0juOu:f*I$j T>q#I،Tz"}_gwS'F6,%z[eM޺(;75\%j :a$q#RrqPPyE_R`(Pc+=c0yӋj.322n]=m2ڵD)ǣ<-G'$$ei#(1ZfKr]beǖLֹ֛#LF;ۍ\:d4gMtSe6y](FF^i!vQsgϚiSZzu.,6Z*5B@ULuH-'/_ZWo>Vji:EJj)RU~f/HZq33KKlގRVJz:SS$LPS 7Em>Z-ye=zZM4 Hۏ>r{2gGXԴw!jPj7>+RԥY%H'_O9|~l ZYuVY{̾Se{P[R6]?T1eX'O(F\-\~ӟߧ̷OIi;~cCIN7dBec+ȳ,ًD)N88'B2IS~w/ez(ѹEj˭PvPeGVtt)\=JCƑ+1ˁc#Zf9zAv oY%5_U _]KgYYu{{gYMDR *I^ ? xK_p8+W-mnT H@~7Nj͂qqzLO賺s27 M]֫QA`$Oxl5xOa )57U[zVjtNK:7;r=arnQ}3{l_^ vʰti" 7 )hs9W,#fYufiVJ*]Ju)> T]'td*`gF?ɉsIz<*̲K74RC̸ʆ`V"--QZ]fw<`m+k,^¦M :^>W(ś rIZt>Z)W†ZSӝGmYjb['{$:vW\ZVViv¡ 5+|oL"v^y7 qNj=_:K8\Z[]T9kMlOE%:H\{MRkcӦ:4BVI,SHL25ǣLRi&Z^O QL@Ɗk2.,ëZ$fpRB5P|BҡbdzH_-5Ӯ>N <(w[E(SJ׈ۈ+܎'|HSVd`՞9͏\tX߈]-uC1߹ry#M.|R_TWEtMdl!Mt7U5O`Os%p+HLSr %wo7V7Se32˞>8Af?CrHYb71wLhS }drz bnjSC$8:@RcE`;=ppmq ar;N*,nVF.2]5B)mlKs>1dܬ"g#Bg^*=:F2`|9dihR&)0ۓ$s8v[ĕF<$|Νu{Ziw 0ST \K(xã'iuq&wӍ1rSpRs' ~<_q:tCTԱ4WϮzO*GKnJۀ9cr3cM_gGι:_܇`ɜTzQ:ſ|/I:}T~qsr+Dq^GԲ=5ab j5Gb5 Oഎ|)2>\jhP%VFp'8~Z˩7MZGGiI8? RQT$,-ANSy1)r|9%*oUgvw7kת[Q-$9?rډtQ~kd\M}w9';m\BV1ےd~`s)) _E6$6=Mq@թBj`ͫN?ʛ?cqWWFU^]%#ypvH7>9?jBI{ʔ^V HI\ c5~΍Q`>b\7^Ԭi G?{]v(Gl*L.Q4 N*Q)9܌*Svb)>nj22, zoHxF6bsB5M~O%)"W W ^( ϴWNݙ%O=ZAar@A$qR؟#L f/He`8O=~7S='*OwZ.Rp"8F-wgʚ?j |N>cwOηU_fޕZUPH e;b?\fqlˑ_vG}Ns`$HeuQ_VEo o($,WT%:6{oV*>1e#|K_:GW}f*07x-I*v?7rQ%9G'|W?NS~jT,VA@1?ڒ]c:_RgRC)ʲVE7օ!Ղ6T%]#2dA6:d%̭a=+pVM4fRO',^ro-{ IvTB*`I 46D&w%7gDdt 5njJWI[&.}GTuvpxooD CiV"BvZH49Y( ؞UkNkWI4[q;w0;Ygu_/ԮrZ-zShP q3<m?uMQ35g/iN u ::K EJ&q񤒴4ݺ9.̗3BQY`x=瘟~1ǙsA%&qޚUu/fmru-16gkM^QEvm31w {`rE8l59&uCEņuwM*:7"xۿq<5./w|l{$]aom_^T Ƕs2`{ax&^6wUoQyj&jL&b?,G1_Ǻ8rΈ=K]ytmLT5A$2,@=q8UJ͒Y0Wu J?xIqFNeUsI]VA>zo7 w6=:4UH2 L>.΍$vl/k CAH}uL<#M4ݨ[eJQ,dGƖPJ_Xu al݆ZF7LIMR i6ӯ3.˲o[[դ*arbT'Wq̆7ϓ'<TaW:pEY@*@X Mc4z),۩P*G|6Rm&FK+!iP7 D8tʧ7֒PV$o?_κ[*jZ``Al'ɛR6( D- A*[GGō9K%_6.VB1ޙ油 ۺ/a11 Q`hUj ^dI lO+ E+D}@2O~7mB'ֆg8l(F1I3UV@Ivcn1+{йKBҚ>)L"^\[k.<6Zbɪg]$Dnn:71$}Ⱥaq1Uj2vcKi"8ZrЗ`JeB?Vn`)`ptpZl.̭^W rK7zc޴_~7M[da_OJRSnumhtd$'/KZu-hQ4mYP?3' WГQLo^޳ҪaQ=#O"*95t+oE`iB1Y[c+Zz!ЫE/L/^Sp*S, z$yuRKv|[1NZtƃD4H?\T1:J55Azoǚ-̙!4!-^QR dN2懶ue;Ga۾ɚ#1sI$iZ uR l)U5jieHܑɀ}s.΄rG{M5Cx•؍a(_b(Kj9cFhuNfO'\f;T %EfMQRdU vO㥣v۴t^סQh={M*4imkPy ((&vi||'43A\uh,55/IZ+G3`<*iG^OGzG5![ZXp<2wQ T*Ol9=Bwi5m[m;ۅj +<|Üi.*ozk:ΐvoK\ܖWϊ=<C~;^,,ӥoM?T&PӹiռD1IqŞ6_ϥԵi@Ol?vg?$%]'cGAŋtOT5Sp&V=Oe@Tj,`7'9i-APStU2?)$|5SI*u0!d{"vȾBt% l'(M4KލD@3$ls՗U䆅ETv'vTn>'ֿ3J:zPK9"NC*ѫƃrUt'¾>z{#i,{OסnUc,{p3;j-!F$fܪG ybFOr'(rTL (QF Vs.LT~~zOG[\ѱI&iN9W ^tFwY g^.ˊt:-C8ө,$3ʂ[ NN?7j^s׻V6z!̘ێI{P 3=$bc*^_̱W*'LqJ. jL?}eT-W riU+/VyKjWn*$Am8䩳cQkmܾ7jJ]  jvΎePheO%k SUIz㷉KG=ZJө3"ԪH,F~d[nm5Ɲe4n^ ;ǩ|PV~d,)j޻Ğ7{VdRrV[w9m* 4c2Tkۮe*6>gkRh,oQ=YR7%Uf6o(P*yA+\4k)RԀ$~q.Gv +^ck7iԨ 5&9Lz~c1ˍJX$z{pڿ,4jڊ/`e "?8y#ZlkZ>T-kH)2 m4I]z7qtC^yOP47n8Rj/Nv=6vP]ybO6ޖfwWR^`GQ>=ܗqÌt~3Jfe;m?\l"h}++ҋfT n d2즺Ӭ59VӍЙ=ܫ-ZզQ@}A&]$B#c2Z&֒ԧZRf`Ω)۝bzldi\Yڕ5 N;QZvmd`DO EP, Ϝto㗰zKGi;*)5k Qqn;kCC 5:5HwRj.lUBWS`+RLroSb BjU oe}|"K嗅W@MGkVۊAu_$h֓W6ZZbHX rFݱ@\ 1QW;Ѡ#xcLjo-tPQnZ,w8I@ZNߦ/+\EM%ޥJJ4rH n2+u0_5iicܞ?,7 #*CQ;ib o {'HV&4HVR6ی>1M]QU f֖N SXwz +Z;G䖅)^C#_4 k'Vѥ%hm?7S)QA>i=FT+OQ\)jM#] j )Uzs0Ui10LD`=㣬EoNK(M@TL=-іR|O @~cyh( =߰6F7E%UM oXSEt =fZ,yoMc}pVWǫ7扖QJ6TT:U*D Aի*UqETdU v-DsUvtEU๡ `)gor0y+Tz3uCP^RNk-QjDZd J,gVڊgV?WYCtKծڵJqTl`i1r>O>FPI~wE)7{ViR=4E$:tZuףLY7X-JaٍTZtJEedAbIc`#m"(zN@񇶚m= YzdR`[R$})wN\xfYY\7>h[Ml|nLz54 bN1QvU(Ui( >>HZ^9]f) lNRgy[;ecLP4z4:qV+\V@1XۺdȔSȞQZVc2bDaLLj=v6^$Q9ռNn CQFX.A}_KZ`M6\jTXb&@ s]|pI/rSY :BDKMUi+*LNyᨹ 80pQK:K {b)Zx8.LՐ-Isq3"nj¡E -~T8'TLJWӤk'lEKkŇ4:JH'y'h`wC!P5"3mM/B='UҜ1tWVv ?^ WZU(]鈙mL~.-鲔HgTn#V)718 CmT{k&'Yy'l\etEmHBs9bB)-QmF3K#ajlt[*S%"N4PW-V×APD h MZHT`A߉$luJjwͤIUv""xJ_cv\ )qCրOĢԝ(eu]!H\$QQs[RYtɻ~\_ an[3TWovjت:t:5vǹ88CiiҷTPpL8Y-=;MHw 'W%5KnFjzfbHGrhaɻY;Gh{GӪiUjpiV#p<c^6S^nuB`BZKUZY[a#lM^5 @y,O`H?#"EGkucR~*e%VH2@}Lw*+C]KM'j:3WMѱk(mLy IN8:il6h- T, 6vZN>(_*3(/%Dk-Z h;q6oQ䩖֢we䓳oЕ j.`TFNܞ? sPsnDl ɼkԢe*hj$p7v8lU0` LG=pi5yb.,ҋ |aղI]IԵzT/(_[fRCrKncvуˊ)N0kjՉMzGvN:td߾7cMv-( Q]J89*v);WoG&Dw4ªm=Lg EhJDJBiݧi'6폔5g]t[;c.[zT0p F|iٝG<U]3ugP64:jAr!#F?I*NL/?}^QzjVc &I{qĒ2M6z~ }%5  m<]8?~?oKdcdU,YYX}T'K$~RЫdmK?MWE>'8ɺKnk^r*#CR%V3:.>x9MB=8i.|OYcK'eſi=EZlav*S6< >ݏqj^kҴJVPX#g8B2pdJ/3D-5S>)"yc(L>;MhT Qu!4ثd8⌯)49*Vz3xSM +dAQiՕ_21Rޢ*Ig!$O`E:Zc}s'C0I(:N1iٮ1n5IЩ= a6Jk_rP]TR`&?Ƭ2wei۫dZħ 46# „c;z=vM+y5&hS䎎ޢ7aΣ ev] v qsM^U1\Ϊ5:  }(u!+[ZS 7Nm^Fm]Ra;6]^`ZB}gX."AnF L[2pE=MQ'cމ:JI-$tJ'be1~QhuoBW JAں'/%楻.O-LFE!:ՠ\3:8cNT8auqs(}GZlzƆf}}`Y;MGk[CywFȩ4}TQ>ST4YM(73e>Uu"Li+@F.i{41[YxsRvo &ZT*1t0!<6&+} \daU mb~ƸA8A[PUP}'s ->lNR]Pm;\[I[Ȟ¬jW 3IE\<"{`RP]:NH 큭%c:5 'c-a>[z X&Iօ,e-jRX0?2hp҅zuUΡdc_a*eɐ5/{p@>_-;_Ym[e6ٕT+v:TGiLnO\qrxٱeOk.U'b}㤭:tԭJGt)!7Ի j;`T]+ΨfTUM G̘ŗ ѡ6G泬)ְQ5"['sG00Joy%%E݋9;}1ʒK.*K%ɂq['?}ԧD_1m y)Wgmʦ3.B~ rbMDңq^T)LH |7'Z&h:@IP>~ 4&ǬfUC,A }ԗYy7Nf.hT|Vt_ǾC;[.ҮTV>J`pc%*0괉dREULOͪW7e ұs0 J2KX6jި%Ӡ w0Iulب,f $BxEsi7*MXTM[ _ɓ$ ̩TfJ5"(;;D㣅B2\dKsQk5o=~odx\Wf0^UF'tZYQ*v Gi *.,S,/[KZՒRWy98yV#4xy>,u',*9Qd-ގ_ni4u,IcP,@0ToM Zӗtp aP@3x&x׳rw*Ri\caxcJ7R=`O+tIiдni\: 3mpn)4fRDWW5S9u]]U{ZtK]RkCǮN3r<8ә^ZՋL>qe9:zeeX֧Qφ@ 1mErnkׯLQ#l;[F:de)+EXiN5ii/bB r`7'4a3(ު3s|T۠Vjt@#'_"2Ϭ*ٲR B#A;m{wǪ[ d\uxֵ*A*R|F[#QW4jX3`1 jR,$12BޫBIƂ DF3N5m|G`@<϶7cO{t7L0좍0-Ɯx-u0kji?5]YUg_] Jr=qpUgK;mu!lT*)izY"IY08cqVCR:T "0`(TJ bF* 9Ӭ.+:{v94 7v@<~XE(G+5 ڰ?Q[FOvF HxO5}0B R=v]Qz$iFko cc* ԭt> RKVNG1cbh`I >qZUFӿدtD~YIޜ#i |'U*bruc )労\0.6WLq`mt Iwq0ZTͭIXX(4-fBBǾG'zkvBNqez.7Ho Yk!5}N=;ZD=2=pWJ 3S06?"C%6% , L10#MUv}#еLR _E'IlSj`SXG9tY5@*Sug>'ӡ+*ѦN|Smp~Υ{Қn^AcH^GNPnlc1r5ʳ j;F$qRZd8<[DĂbpض݌WU(?=Ͼ.p}BUWUf@Y;ooC{?=W-jomcF|73nʪӺ̟Xd+VB< ,RlaaMj5ivq=km0T5Sum@1N3KZs-LKrUdǙ dcoC{C%;}T98EW7t^]gP@(YnOЮ4R'Pw?-LCEoADup(o&~mGªU09'N m+[nIPF+$*˳*t#sS׿mY"ErRԂ4lt4;vӗM&mދ]ZVxۑmX2&~<ʭ. gMV0'C9^th]tw(f ;0&#QsV6Z&4j~9 *%O)4OmHxW(ia6<+ eOckɔTJ-Z݊e~O8VI.FQEaSXt|4mU5@,4#vi1Y*(!c0I>@k ?㎶F!k:vRyqVr-\m$cacOrVnt>[V5UYnxN"|$dV*(I O{d;nlt헇I.n\0 #a^ԈouYI$Do\1bOH6T5gs E)Zȇ\8!v~ vɩit2uQQS=\_'TZB HӖ-Av\搭Zl) LN:Z;EoVLhFI}ڥE jN.w*٢!@NLM!0z)k]톤RqLg)x:b$º*X)Bv $müc=$Z+y{MZ/JcpR Nبx.ķ`W'=? +- }&rWb-j]XiappBRi@ J2Ucdޘ'V.;{iT$Aۜɦ}U?2y)#aɕh1kb^E+L,I)'*t}&ÓQC+jmG}W$}:b @ ;qD`hdrn*5 c>G S:?QQ i I;Zm ݌G iP27aYckE&?%HOY"m\U)iRԕ9zw"2=?Ar}"-vxP2ThVF" ؒ8j!'O_=)t܈^@'11ӣokzk[4ތ7 cx{5rd&mNfE43 `r =kRݧBDoxOUD^慦GĞ0/OL'8촺S]-Z&0 ^ˇp } 9e]q\tM]+% 6N wD9}P{cTeڱ1O;s;ڗVn^ďqcn&-ױ3/KelRޝX0AըLvz MO]t?vn5VUaZdL/'Ӻ$0){.os m BV$;Ͼwj^o/l֍ !\V7 4|!D/0l4z)PRUB6IgRNKa^QZ Zk:ml*L 2OI(E={SvVmT MHO1W\}ʀV )\i6i&Q&}gKL8]Y+V34$mʄW!Ӣ:HP$L lRvmJ%4rU ?,]Cԑa+M ǯ;e|/_ Ahڸ=yX׮KwQ oz{GժH$ ՆJhd+=Zc4'+^®iFbľni'G2Q+<z9ᱍ6.sԋTH F<`PidzlBqHn( ŷ8$~ŭ$$`kcX6tBXPX(A1<|1ʓm|Ѕ$Q`YA,J ۑ)=4hƪ F {[j/ŜW`;|\.8{N岳.c ŪŖK(1'GH eiZAb j{G8N.Kt^ڒOBI$3ۺRL ^(\wNIc)Hȶj!Rf}9gRJJ)2*гOJ4rX57HE4 Jm.\DTr{?ix+V=ÍXqU)S","`J7TQ\I3'{<\ع,j6Dl1'TIIk+gkr%pblB֚55_\&J:vejh[Ùo O)YwS~U] >++ʚƫ P;o/ȅVeqomNTw8(63UTpdpF9) P‚s91}\M6!N^=Bԋ AX7#Kh|-eP{4J e'}0A|aV[$&thiќod;pf'6\N'z)CFޭ Zt 99ƛvD7+k+qBDשim6jXwK*usMiQ5t WUUB\b`?LO-$e>hM\L{|1W*ou[+ K[A]c<*Ď RDr{v&c8 ,ҥ%] (Iҿއ6ڭbJG&=}gױU/4lh^-*UQ `pRW٭iaܵҩZTqT 'oO1Ɨ&*QE_ k/BӸV*J 8+R,'Q.DRu@Y%v3 Hx˺nMAJw'LʍݖWѯZV Jʫ;:{Z+#(G&9-#cIۢ7v]շ&HIȂfHQ A뇷3%oIٙy^@>csNZݎnNp@fѥN=Ǯ8i JPc%jIĘSbθOIҏH FOLժBɓ QtXc1P.O+S Uj ԚT<0 | zEMmR -m( o]i; gl4 D8ld^ Mj̍ܜ-Zn~q`O{Tj^`_n~c *[b 9Kض{[O$0;_8;9Tt5 I }X u ?6UJ@% bD5͏TR2ŵb][Sjj&#~?O~ʭ"cej\~iaEKpm;,թhl-.!)JE60壍~›P_7eoCuEBJ)p3ՂֶUpk_ʨvu؅"x?s:x!vZh!9`jۆKN6[z!WTv,OS~lE\*5oy~KfxǓ.n7!OtF?C!'*D\jVxm\rBJGOLfoӫN G?cU#Lhβ K™ {Fhl <+voBI`w=f}0)+Im(;uS*"/u13v\q,*ѿZij;_Ci)vIsک׸ZW HL=bO *rFbxi;![FOCUa#QDTBwǸThr,Ιꋦ[kvF,8#o^~xӫ4Kwe}KG,ai 1JM[gX._S19}%Ke|#W7w2%jK&R^ 2b'-_ݩ7D(0p5 }iѹEI٪TP<qw&#ǫ)1_g~-f5*"=UZ(TKbp'-ti?7ӡFv'3uk;k85\6V32<)?D}7Fwٚx%)lUE@BS*"9RxJ/Lb*Wf1R>d ; u+eNWVu«5ڳj\$I^}"1Td'1IsQZf4àV+v8ӱ q fL&NṻI-z],UT\j0PƜxS{%4ktҥ<5Pn#,sl؝*#*qcPvm*R :[aeJbcZ.RRjo dG8R#|Wm MR ycK{-%Z`7SfJ?LT:[b .w9|6i* *-6|(PeQbԘRd+lcWCHH[h jO.ǧo|-4bW6)U5Ih8- )SUE0 O$QC3?C;$"e)e{` zJ{~_kjNĆ-<lfq_S[v, )=1Wm^ŨZ[no\ST%bWfEC MH_,?*^N򼒫( ?߮ 822zVIINBFCl~;L ݖ$}EJ;dקr7^=xU}S O`WS٢ejP4"}O|.S/mubi@|R@pٻY5:H$m=ia05{AEuJ+6|VMmSg¶W$틔]5uCPXӺ[obҧdidvi !1#s;8ѲR+[Z(]ٿ)o~QoCRkOH-0>VBod<݉SߴTֶ&eh.iSY=6N9Sro]WYՊoT< `Hm6YyfaO1T"˥P#}@f^<]B\USktgl*h8I=vjZZ]/V$}S7="wL׏Kk}TJuuh;m8͑/cV"ڥY{ϗ@c'@a .#­suj;~&Gw>Ti^H6Z³j,G{a ]JbMp̎WbO7mޤtIjB40 U <$9f4lYͳ+1@;I7(*$ړ%?`):Brd?Lejdkh%[@ҝ8`:?6m/&ZU('*n莊ohijS gepTYږik#205@46*J9C迧lh֯Qb> ߢq1צ渨 2A,km;@U B4Gw =9f+ɾ-jfҙ0s-)EnAS  No⛫gW(iIA׶޸&mr+I-Lyl*mnШMܷnot֪h TpM/FkE;ҊtU~&RadyHJRd 3 ʪV)y}A"M47R:#-Z-龂qsM2+ޥ J6H qݭr4 :&"}p%T!B㧩_ cN*6wNTjxZtDe!O;vld.kG@|]mX9]@HCK7#h~XwEJ-;eS`b67 &|kpijmtƒqbKм#%B-b2p6-~? L,O*16D{=8OmGF#qTdSQL[3m鋊dk:izoRU_TF.4t7P[Im*66ēTؑ+uRo'OQ$XU+ST}Y~bL8GTʌeOREz}QT gcZ'W.O ;F=>c%? Gq30$jXfiPˊ❊>^NYH;킋H;RU`c*3 `$a|t}lDLqi[JW\TX$Meyt.PKNQ}Zt/a>P?|ROˋWDږ[onomplOH ȟI%vYcjfy|am?fy):qD?Ce*"2C79/c#z'nOkU=4߷01A:DʗLUPR"4&pz=;pM$~l[9qrAWFӱr* e%!Nwoe{ ~\[ZI4vGX`g` Lin qMgΌCiVnZ.^jgs&gɤv"n$A|o$W%y/~5cE="%@$:0:"vtl(Z`1Ǯ=2OT6Hg,,jQ~iT]2c. iUH@n$#q\tkROHdJ/BQ!]fLNߤFUQF:Bͦo8#`H_t[]56ꪟs `8'+lj$-ٚu)9rL‰1s-A"%j-+pĀż9 .K,Ȟ*N)>޿Nz/} -CIzzLv R@^UgƥRfWrp0'!ɞx~8u'} v9MV&+ecA*Q_y;(m[ңa{|X˰/EwXSP1^D4/oDnr6sƕS-6ZPi `{my+wzRF}ǾؿG㾄dZ҄7)SE:$&b m";LUt`,$2oC}I, Lvv8"h@܁T%]ճz@KUֆ+aHT)XPA)0&],jjmOlؗдP^#}1|Iwɉ6Tem={/دUb`y1o#_t$=KJLi߶b.pKjzl29 URo@GW& $*ȁcn㝇 IOp VUR< GOԙJEweI6S#iaۈ +&WU s-sTj chظEU.t<.$zb6GR%yMSA9jPIY̮{b꽆%}4>xփV6T֨JI"t\##-F*bLLۤ3'j-H ;qdcwuΠvӿ%&YYC(D3AQn%f6eۍaR l#cLU,PAcb>1?1t2躄;A,ȺQhf)Rܻ oM~^Doϖ)-q" n?o9Ƕ.zR*V)>S7;sVaŵ@\V|cȮ;46ݵ}j5͹AqS{4tem؋kԔ)=>HFySgf_rJ^;c+O W@n l-*MV$(o IΟG%|EӦ(T6v04 -JpMia@Z9҉|jS yqz$]L֦aJ֭;)VTOߏ|GM[(qux*ի.gY=q"m_ɣv ]_O;J2ѩTUG(ga⛥av꛲dvc ob?ERpԔA 4HgUuD544lXSIjzy|yqK§UC fX t{<ʫҮIpǧmG%a.?QutOmVb' )I?Ӧ݀4٩oIγ_c'y~]Vei1yUw?, PRSNv~w,28Zvha|eбF qҴ[^⡑%*@s_'#Kǿi}mH0#9LE:ka]>u3I "xd&œU;b. s}#iFB2&8ᱚb9'K;1 9@aRVhQ@o|RpR TW;%$.sN+"i'ùc5C}Ke5ERpB\2(FXN筙ҌTQ}&IճDh 0'uGq>b#n s" rF(Q4Uw0|ߨ>uCSFOÜIW:QVW/H0HJ1'C{k"=P'a|sa]n:3[.giREsKwRA>]"? Ņ"j\5C8>|wٲUԩ tFmR'Y~bmh'n0.g?7jb72H7# TI(+ZlI lHĎgit8\r0;C-Y*\Ӫ3=c؞L7T ZrLDmk' Ar @gcwYsP̆P T#n.]ih@w m;c^)sʯm2WZgũH לuKoj7qw{~ݪ9`ǣZ1?P3i}gf_õy^AzT2J$3鎌$3՚Pr}^.b@5`sIItiXpbg|m-4KgkcF2עi ֭j^ĿhF񍑝gTSrIQ3(.H;c:*.RrWRe7,,]%sh\QekJiUJyJ qRj:'h2kE&pčqR{ݲ2zhԴj*fؙ`>}%VIo..sdh;S`r7%)l |*:B_ Qn\Km:uEv8F#)uRAڥ㺶g"iPJl#c8L5F1CՕ*4DUc0'SBB#~X(3kc],]&b7 Pҧػe’@i=1Jvc%|7U&e6z22&{ nmBIl:W)yMe"ێ0Q^oN֫4P?T!)iUQ@ui6K~ g ܃ ]!)]+mb87tM p;ǰWPW{JM@ Rt11|~8i|I` v?LRu~9=&>0]AE<;\/w-MGnOb5.+{fg}L_`mvTӦwkoއ*Y[@@yUX*;tY+1.>qٚbӦ-mQ} vBI <إ6=i-b+= ca\,XZsp$6v[K*J8 Be&+Qʪtkh*\L$oM-n^]" qMOCU\]Hg&A{ᐓ/Hln(bwl:xZGA+{cm57Tmz|p_ʅmC+r \I$̬u'~ѿDO]" p)bN2ɇ~*.`IGnR~ƹTuOm @FG}T3ڤ!{ 9=6tā^gEo컃QHc銛l$,*Rz Qlvcƌ]gce+6nvՉndڪJae5* Is?|a+frk]*-hH'N?IE. hK1gTf~Ay5t9t=cWpeQ'}7dsJsjk#)f QF0d\mmNӬY @#g8&5L9$L6Ӝe6mi^b793䭌rIw (,*xlg[{Nj6B4N$4F .؀'#鈜oD*zt $Q#|:T~M5;9Ą9'6^$ju.Ь&}>C^(IJ bﳢ9i+?[&`;&8g~OW=Ef}29rjyOkwy]_ja* I^wż9Oes=RZX/(o|zOId%MyZD9 wl]ܳ3# MZ}T-QDG(dHUozg*AѮ/eI9C igu^YP7 ET =;w9Z /.~[-v1?-f]&V@ӷ]!A9omaXlzWj-e4 b|ŀoʪ}XtR9[O?0K-c6^*)`gIeFA/дrsoN m{JZgy'xZrZ4,WQR6~["kC*i+dz ڠ{~ :0xph4BJ&?\~ inK#yEThÏl|hM>\~}]*;A3l3\>v'Xԛ#ײ4,ښK&>KpM;4x0c{Soܒي֪) 5bj8p0V$AO$*"UԶ%wmֆ8| +#C%P 0D#/A]1-;MiX3}9(d(ۥU-و 87`T`J?hXyx0r`[UkzTӦ_~9Z$ψs2}W(b5ߓn~"U]Kc$q:g1O'a,)LgPHONݢ'xb3]Sj}هȀ{/tZ@rp#?sy/HqKL S78JI-5C<\E&Rz9t4p)4oW,]*"cpPEq}eeI'Jh^:ſlt@f]&I?-Οؓn5˅Sax\9'<}['M S`(֋i4WNU[/ @WSS除dSw< 3"bsTR7k$ރ_f+9& olo`Om}~Uvę8vVIjaX]\(jS3YDy*pT=:4h!PsQ?f&l:iv>ÿ~qȭbہ\-?P|܀'H\㌓&t9)]? l>I e9`^NWv\ƒ%˾XTn UEFRAxlgpWdOBKg|O١jY5@;ɖaM69Ky92>٢ySɎ_^GMmi#تub2s )t,B|{3pToJG.Ę X۶Ӎc̜Wܼ2ǹQTѷ˜z {8nMki$ ,3-+kmz䖕,:R0vl.m7~َWZV a׷4ў{j|̫:\: e`H҂ؓE{#}'iB;1s3~ַ)>x@GcqrtGhU)IYIjKOlzjaHkbL@l"R4U!Խb~PaXV Ǻ],!: =03/vZt2D"bf6)4(i.ɺoVZv) 2i[+֡ %}_&;m֙rPpWBكo vQz}0)uzXmIjmwiťZz/\(wclC /IM Wo: L(BvBުceNU;Lv3;bT5/T!|'}ށN-W`Sװ77=J!dlSm(okZVzoELn7&vv8O`4@A7;l-X # о mD+Gd( T: ߾ ?E;m @;ZFE @)a`䘲;jXm3OjYtF'lskH ~Cm'Ԛ6{7kk؊X.;[-ղL?'TcnC*Ԡ7CR2_Mǿ=_&E6 P6÷ˌ>;76 BG)rj1y8>$Pé"$ pVa%frG8.O0NJO%Aq{bܶHQ`Z1̉߁툟{↋¡DpMk3JSfY, xelTʭCϘ96T>y&?|`d F&9߲N l)61mڱaU `fhq 7\EF ;!ȐG8Fc7[l]Q@Q RTSV%UfYƺ,*G~^qM42儯~[QjN[Z)r$DvUg\tI">\AsƘq$Ve.9wؕ7Fft:E̪%I{2c"0M'㖑/2Tje&O#mt!0u.U&*S0#?> ?6 /V*u-#ӷaruY}JAK?>p4ܓMt4]bF d4c98N1VНA_r{_\jfy&:[2=9~bil\+-ӕ@')jIwlZamoOם%]V)v݄mf.-*9u:ѤSod?D{zA͒&PbQRmޗnMJd==$ $q-.!eJNI#? %2Q L Ʌ 3hO#R aK!qz'LfY\0|Tl#QiD;Lҧ\'yYTUXo+ENU%JRiN^( (^t:跍2Yi"vG/.)1KR { DVBbbn%{Q0A?% dqP=%kX@ܒ'(G?oYu0vM{HJayT(<>NRrv]5AmLG%QO؛ٻF/*\T457g>{{`B(zI@1'Rj =j`SrdH4$$%q }ʆ\j2$v'7Hdb<ߗӿSUV*x0YkvƐ!U"I-I6 (֙xv vTh0 WV\{C^Y)ܟ{mVYF3;mp$H$ڔӎp*5Zz F)'ɾص)4޻t 'GpdGdobeGej`}qjLM2b1 ũQ#}Dlɐ4m_' JkN7~&p P\B$>2I1*Y$m.@q\Wv8RcH1o@m{3y nxzCoi <O)N!AI0ZR~ɒ>i0~R=|LCI[eF?t֏u3 6>d7}&ER v5Tُ<iyd|. W0Jv3X #}8F.9U@/ w#~>rv'k&9<댓MCl)ҷ$A11#xRR7'o45d)*)se.oP2r+l}ɪL2d_=*3aDn6IW$ld9^Z"6}a8i-ȝ\{ γ;o!)|5N͛"zI5ɑ{.Așs9+5)*0 _e E@7 [VҋM{'PbL<1?88+'+K/izRð#~LɛGFeuh(D'J.vr24KQ$؀$c\fѵ ( }f9VCТK,56'*N)P:j 0h=OTem<13ŕS`ͬôLSVU9jJ#G|*7+Z(ڧc Yj-3 2w䗣f)[#[4) 6ݱܣ]3YM=(&#T`Z"p22A^eG)J O 66JomEf L[{l󊄻ǧ#zq=|ʕH:IpZ-l7 I"W F)F4N)#>JM=2QcL++#1|Dj0ɥ{w!(`w{b_s+wqa$֡$3  `h< XRcվO4 ;=Rtk@%gizDHj'>`oV cR#|SefVbI [Ճ$ϛ)d]_~Ol u:=Wَ !}~Cl\ 7VIn9N-J5|T➍jUj"ĉ`]2(+| AaVq,WCRi@q'%aB*leRy@>%;EZs+jLXQ MR#Q8rM!ÒL2#쨦r(Kqa$A wČ߰mW]IwcM?_R[Kebji}bi,A>۵ҷblQЈ#p1 4( O8'j!^ܲGy.2%{K Ao-|V*IF)O*BD*j")3SE^9sS  ~͢)[K8Y٭͘j 6{EҚ8R"JSLrGmiSR ԩhwͦ{:aԍvp(i%ZvvƼYtdD%'O:O8Ԝn5+z`e#*؅|)?pc(Ls5VY'W2tA-4 aFkKVbjFը?Q_l ZExG0 79ߖn*ʭƦe"3$հU \ftE.s8]k GJӫDGI(me &ARrgS1В2E [phPB' KR-ON1 |A\hZ#(evcu#kd+VTQk$qiri--VdtU2Fn5'V|dM];ujxgnJmY<[V'ӌtdaț?Գ5!]Df8Ltc4},`2 m;hY hcjΪޘ nUm\[pWŹCLZ+P8*0t9 B`1/a5oQ|qM!w#lK Rh h!gh3tz Mʰ|K" A[a qL#]c- HO~`qoeOiuDAv|Z&X'DjjwKj3LVvNTݸI -" w ~)I6>|HKU@O LR$}wҫRv^=Xa^.D5oL/8Q jE0q}Q*71iJMM mE5"wK#:{@>bۥCZVmfR@l_ tJ1sv-PjUf}Ra87} }6ƌ k<O2QE:~ \Zu%%+^NddcݔFjЀLG Rb=hA>!GUkU'Ƨgǒd*%BX$ߌ9$aedUpAI=,\:vT l'ySQI\^U%dB +?lem;o.+tiRH1 kCv0ֲk-V3n vn<I(UUT?|rJTtyS*8$mST3uoLG6z5 5DӸ ;OcV Tf^ުTo YVWLJS- XH gNG M7eG#+缩|R`}Y&$mײ )z*:GH\l$) UWTX #}|G)4{,Lt LL.f/n˵%VEI!| QJ:/ V6%0gyg#8ĩ:DjR;'>я,jk#RP~ݯQm=li4*"( N$3$}lhKB S'cDDTP<vFlqp6?Lc/HӍGUEzt|:4zAu^S*n6j]?EVD{hd"X+Mh~U %Y =Liİef"{JDpTP} *A{vuH g[3UV L'69LT 26}SJFʡd$LqتVɮEjAyy`&A%<09]vi^xqJV\$*i 12=#kj 9Vu) jtp7lSz>.0@SwfU  KAnGqwƅbm$?vHlsƾ OFc" ]ڢmRIșb7+j~`@ˊN0JɈ6 q]<\e~8gmML#?qM PmRCJe┛rN4-J%Q $Sti [+j>);o+)G[O ߰_% ޅN]K-[n`o$`HBW8ĴmvG& | q..XYeVFv2V5mRqm:[r~|G&JJ Xݰj 7\-FGDnFpJHѨBY]87ъv ʎg$b ea"ʕ qNE} RJ>ʈ>N$=MF+RzF0IaJzgBbI"iH vX'Rl.n]qRuXq"`,UvY9NKV[ZӦ$11ZDˉE;]˂TkP¦LzFя˿}2BV^7629uմx'ږ)jΒXDjɟ6C%i=3¨wl4ؙ{*lʕc0bXɈ'ZB\Z} :5$1P)v R+C#eUl\,'H;|[Hbtek5 DL<$Jʗ$΢ dl< s'ݚ}>顡hǒ#o·ߣT7mSriauFxUHFoߌ xC3i[c}AmZIUO9&"}} s{L ;27QjZ EZAx8ziOJ튊3Sgn7o$Pn>? ߶#I UgxjT'O Oգ )! "Wl BtP<ß.3(i8fZGl )1qΐ8 3H09F~?)Qd3X 0OEF;JRl JA]1}l|o/)7_QI@DyL[W\*FD1`J5$(dk v ?eТp1AAXEYUF|@m%%W#Bh۟L&kS].0l+[+c>.0k`2 8~ 7F^O;A s dIqK7lD1BXPOlDK{>usoukFAGniD(1inn:A)ޘ†y.{2Q'V'nq5FFJ`{h.ٽ;Rڄ1Y?/$b}:{8/|'Mm:jɝR3l8@[ wH|G"I_0d)vg.ʮ*v|I}%bL 1voc,J#t[V}JVUP02n5צY1RM=%WP ?vdZ_EE|$4kjD<9#?}, ϡ&\I% j=I|XԤ݌m'ljĩR7:lܵB:N]eocQwF @8+eNڗUp$06;cmm7|OAm;ΥAv7 0#op6ڻ[jd'RoLe;4(*t'J o-[BBDJOc)[}(XN cѣTZ#s VMz.ڿ;y>-: UlJZWWry=5jAlvBڊTZ*EUH#P0yۏ7ZAV m$X.Ý&NjYZ֫, {zct9(Wzq{hV-˼${c/pc\_KhY'׷9ғƝbd9aX>T"v1m2bOVtGZi5jxy9ˍ/OF)Z]1?}'tL_3:r`;A?oBJ)\w |Trv -#& WZB~[a] -i ȟb(qtH"UVI?#c[dzU[]6a$jxqԄUo9Sk+]^*ij ؉y|GhK:nJĐsי\z}Oy=:U[jT﷤@%F[Jl~&d껦*0ߘAʸQ,ЄpWL#aP99wٻQwP  )hm& 7$l'AƑ7ɲKہ-3bL%UQfm[̶JsՁuvBUB|K{}p.+t͚3E WJA95QRG $"./duvA>$1+3F+'@t4kv1ֵpٸQ8/NTnb c?`ʞ!"c^}p)P`AoL$w $b Lr70} ӷѹ؂ׁOz.2ޅVՔo= )Ķd(B73IG;b0hp@]%L1%8y⃋0K 1`bNp6*/Zlv#V vȢЇ$lI-*BGExDA n1 &C#n;%DhjKH CnG%aFP#)};Fnx%+ƣRèԔ,W o)lm4۽SX*~L+$kNf!hH>*'|Y*zYEj(>hɝkC]_o٪ɩ@;y7"4cS >-g N\b5L!^XfX^ڝjl4?~Sk"ۑ_-RGRd}@w"Ms :씪"HA;>6ԨۭdkHᬈؒ#px$cMr3dcmD OYq1GjU*tI-$F5ŭ1stI)F*4u1M*ΈnWCUœ~%)Aa߷:fwHeiMAjL?f͑= |~w4\mRV1&}vp{cFNWlVFiQOQMTF7p%itpf~s؜9,3 +lUC`~~VMJh鞓ޗLktn&")sV#lUVڣr yZ~ !޿ͥ |BE%QP̝>X\ ZeV(;߾'".YR6 >؜vD.Z$N䍷;bPJ?(!1$#TRLۓSVO~JƊa!Šyb+&s[}.\B(O48 qnAܤqY*;}pشՓb$ s*^($SAFښNH0Gmk$N3#WE&*mԸp|؝! @ 3b_)6 =8?ZiU`{MjjU투*]6&QժOӡ 56&@Q~D}:Wo^jVjbex .H&& 3`eXZgR¬NN ՟#io-;V-"A罖ÂH~\|v E0|)57ZGW3ũYm J̒$[_]#!8&ވ dWlb#q^6Ԣ+^[#c }HۏĽRV)Ӟ1Iʄ*SccNNf UzjMrHGM#+ 'ocuZ@j*1"3Viձ/?4idx,ttg.XMvsv=4kYmZBcĸ5}NO{Le7 _M6d450DZל1M5lԸ]m.¡ՠ9'/fJ+a`mf eשP2>*K9-i%iP0;KRIRm,61~C3{5"4l"~9LuhԲSM$z) qra+^%8Nuv=1齄[ ȪFmy#OoD΅0F߶1eov.I&rB@Yyv0y PȫDq.I\Sy#MxG(ЩI^C>;#4%T)mcTkqIU[\Y<8wF\JU-~2A#5Us%I81ĒMzVÑQȮYD7ybi-Ɩ_]On4[S Mv4F{Q}*juI#i04(k2e$ڤgOig!JP= *)2M޳FЃ=>SxB41|IVSfmG@=4c٠u Q+#H&@XIDqwap`Y&s3.T;CͭM=Ex[eR'P枴Oq8l&V9﫛zW%GA`L9&%)vTUf%0ן渺tiT YA~"JJ@Q:V47q}h\-SL #Z*_UXmjJ"aWͬY'̰I_f/emJԪ&B&R}42j9"~?[i3!`'{>T ?-7c$lgɏ ]ִ$㛟m=4/S+e`oL~0(dy:[WWBeF1I7C29$diGSU$>ucPA\UORWJ4 mһOieҵUCN:k&]LRk:މu5(x 6D$a-$&F L.v: [5Io;mv[2CzRwl0'tpGvm+th=٣ YM&d[]1f^f#}m_۫S L;>.N˕-r`qbbG#NgJkNi DlF˶$3*O ITס=v)&Oq?.>[{EL ;HӜZcTk/`%̊ Q{{/cqMHJ#d =n"[f4o6 :Xj19荷ؐsDH3a[IBS+(;&0XCI`KaFN]uU]PZD] }_cpvc5,iH f 'oOn&5Ƈk'(Y&GG.*?XT=L>\>jVS @ 1 F}]n1辂TpI4=}7ױST9Q늜CrMӧV0\Hi?Aop-qD0@,US)%Ĵ3q K#uh6]ǰ>qȎ0HN`n+X-$c8N)JI|UR;=+qh zRED遊il6zravtș8jŴ%jZӐùO~M&B.suNhX<\n*M~еѪ0aL=έ^UiFTJN߯l\`+KKbZ6zklI|mŋ0rN3*ismRn̬azHoŝrM]^Z/5 sL:.jF!G26JrkCV7e`"ҕ dd_#e3>Q&6`Rn:X EF) DAef `.*^ :6; Oa*ULm!lhbKjQ&x@Cj!ܝޞN;+VѸqtI@kL @y>}NL75bVX$F-_E5nցu;lSx|V(#-=2qz(S YTvI\[Ǵ4d.* w;ؿ 6m=!&w1#xP;>bgw1TN/^jRkCz*ɒvQvm&Ч*M{[RRfWOlF蜥[7Tc3Q[@tn;l(cS]iԤWæ bCGh`eOLn]xa;]/7U-*eDx/4>XԁRcRXfǫgSP*p7<qpca]51;װbeHEa<߱qdڇ-&$7bI\o )ߊUDyHǞ0:XCQsK`Yʐ 'NݮCs7vWEi>RWq{Ul?'ήh\-٭ZPH.FƌQ5+Zi5DI<{8ߢUE;AzMc?CTYC@㤚lЇR`N14ћ.+TA?^gI(,ʥYH%BH8)ފorBiPŞ9<Õ5L(ܬQ>;5JTcOddm֍f[IOV+&tM+3A2E5c|*Mz48Z:CHdb$,^XtM@ XGT3rGR֕6[K,\2gApd.oye)E:!=~x|iXcغP$q'1{THF.p jJG&)d'o fѶ3qm*]׳JKb:f@j m@D1 G,l  gl~%%TeDO cZF&bU'|$RVU>o6on"C˴095`VQ3;}:r)(tR6&#a"8'Nb(*;$Qֽ (gwB&2/IРY .YJةxք@#)V16Ě ǴqR1ԖX?!\S[Jqa~|=;7|8! %@`=nqJĈs /kbNd:g;bM 4,ϙ7lBfmbQQ{5J86}XA!u:i!^ 1c 1KF }6'}i&Iن!t*a 7BI-i߶%vKVkr;bg2űYQXhP ~Q[[Ivp HG F1fJv9J NKGMTb dG7)?"3ルir5Z*A$,@} .ɪh@ l<\.Pjʌ7lIzIn} ;m ޺&9Uv$`MM䝧}).tUZY,Ds1:M9HIԎ'6U,rj J`}F| t?0f*wpAi yuE2bHʉ<\Uи*:C\Φx>ݱz`Ũ)c;q?9FZFYk3hHH 6IY1pk75_Oኲ ϶ o4UIrԚ62ټ>GI+JBie{zLmai;!ku<*1 '֒1u%kBkѨ*46#YM7L-S F?4B[{$Vޛ;m1qBKb^+k%u1v=#hãarU==QjJD$;̟O26#=EAR 'yۿTξwQ1 5I>鋔Rexim;MPI5il>*J$ N6c+ J՝Ӗ(СYi"Yti$,l:v\Sa|}W)>{-_a2ǰI R2ഈ?=j#lY!Q9ݒ Hj,GӜYqu֠ RU@"Gy^IVѥ@H"OQQA]:1 Nڿ0K Ϧ)}Zi uP؉ØG |B]lMIRA cضK0m#~~~5-QkvєÏMErVN `9 pR 3[-Qn(C ;GŨ5h|MCOGIJũi33ZXJ>SwBfe 7iĠ!" Ҽf>{l! jڑBYn!hX(PDI  *Jʴ&@H1b"4 ŶS"lWxJ6&i`g1 R~ &c\@TSgƙy1mMB 'y kT"UmrT$ޑ%UZj*㩎OqemoO oދԛ9 "F=WB\?{)O?{'*YUjU,t~Z1yq-W^Tu+)KѝK~k\-Euh2ɘc ױdvI/> bX2jD{d'ZtK%VJ(P 4iaAm)ɿ%鬡 ԪEjjHU&ñ )v?.\)%JWi߾;E["bm鍔ZJb[%֥c$~80ȦaP^]MG80 }TU `Vk+O,dgWR3 G\cVLNLzs6A7 w]6!Z QܟHGV Ï<c:U؟/o JFL4IDUf} P2W}]ސps۝}y-Z쯼m7''V"R.-z}!_TPfd;j& uح2IdA09ZCZ{ `(".΢zK`JL8R ;[v8PLH(ZA`ҽ,5 TQ DHb]-; `e IVGBm|=F4hʁ@'X;}0iH.Fcawluؒ_c1#ZD,S]_RjI +JFq$69L4ZEpWHԻj{»C1}W̊C7'8ѮOM.>QP+f ƄSNcG0b#R3N)+,UZ8#Il`iG~LtF<1eeB`4`EV*tKr UAгfh0ñWLє(F3IQdsoZl>Э9V1aѺ"4zE-Q$Cճ Iռb:T1vbfD#l@TjrJ4@ w$ b`q` ;q!/^THۉX4**. /pato\K/d@dJ  %o,:D=}hO@C4<`Mg%@I"~BbnxVAb'Ö#bݱHp ah>bgRAئ݉D1xzUIKIQ#ӌX)6 VPH{z$06;lS.K23L[vyv[j rh)R_"{IƵBTpu$piK'mhu>Qw\)6xtCUG;@a3\᫐2#Y,f0OoMd\n9DE'bDN0P^N<Ѻ{\S5;#ygR}mRqq^5RRx8c4KFW'WKmI킋j[аۚZҬFFcDmŵ#EZnLqhMU=kd(Kq;04cOAW_8Tatջ8SH9S !>h$զN RX<J4L@}LfpmYN6Yн lpbM,ZAOI,1htrRe؂~!it:x>ՅV$1PH`DDv8Mz`LiզwӶ) RZ8|Y~i]i jL1ø@P %A1NcDf88RK)Ol(LЦJGL@A RV =P H0k1 I]!@ؑ7431FHth$EF4,@@1閕3 $mDLm#41؏T^o˫~~.0wI 6dcNIٍB;`K .Yf}x8Jҳ LS!#}Y2%dOm8ߣF j4Rc~z`{ Ԉch@*~|mZE\SB5-~hl=J+zY,:{w1'>=hd>нYZ~` |}F˛fVh4UXZRtΠ7` \xJɅNbiSnʛQ9#@l PNZ#9JY$ZؾvO}0ԭBfEWWiUaD|A;A܃m$:'o3EZBν"XqIWc|ZF`a I 0tv7t>e50ҁv2$עbeRS .I$"xW[&MnX˫ڗl(c*zDzHB펨t; (v,I ďӷ*0d[Mu*0A{JzpX܁8(cJ )VrF m&&U ŦDD1H 툛w C{5GHDmq z4Jjv|xmP$x8>u37Se1&b ib6\Ui@Th:D|K( UR9 ҖmxL#u `J,=7i5 -'1,Vc( ImKhhRH1A8-tG'DL+KuTm@W'cDeA Ʈ7lL|%m"`p==ݨ)ߐqqTdHdI86_dF lD$XO>1R)]+i׾)z*N&1id˖!TE>ag,7<ǟ)l4HR $|d!(3;|R@OeYjm*`ߎ Em*\wjWyvcV8$v-HdiZb :RDʤSvc M~x͟mlxȺ4bwٶMT']6脄 ׳vNOV'V0+w~Y 3Leq>4oKS$I"{%z.di$(5p>bT+i{;ŨA`5&&RJԤ$ scfoj1T$Pw08{J8;%$o}|),tu@Rv1H1 }%&ރ/4"dj/4O% *jd$z{ d*{5olv@ Pf=\;$.LZER4=}f8f6ӤvOymխFEX.A|9eVbz4z9’5c1mE a*4%n:W&[8je7O($,)mwd룬jY IRMtTU7Fލ+j8p䫤L#r ww{$gph>VUv3$ 4ʕhdOR+$ DX:;3Ԧ6TVcǪ%@@1{]XI,[:5.o,RTIPfV ɉ0biƗCJZuP p,̍>1Ǻ dRI$vK%3ʰP ˜=t HVM'K>]$U{{u$2Ɓ[z֒C3i h}YFցNj DBD+#i닥eVٶ.C+=1ehCb)Iз+\SjTmǫi%v)Naؑm<Pq7i-MWyr)D>&n[Yev"sJTIEE>V`dHxB{ͷ0OC_z[ Hǂ.1m voPTAIf =q'㲢u(#(e *`mzbM!% 7⚵c"ԑ_"KH=?B9Rl5b銤"J!~fh*fUf@1`c [+&{Tnj*}a'nARjj:>='d҂WdW}>K_dΛ_o$>|/a!KV8[e+ @bǬҿ_Y-Xw35h\26IX˿^GsŽG*MʮΖWyTN5<<E1]y#e~ tLe6wх4 UРI'yMijmJd`A'rH(TKiV{HY&SfiDP&c -츦iBƥդkA`8x"{Rw؀䣁Q"8nh?GFv" za9+ 4DÑ0 {}qmcѶjMUcs` 8:A}Õ$4agwjP/MY 'sqUrVmOBGnFϬhֱH 8 cs'n0VAe 1,'a눮OTfXÃ$}%H-!R?0`/mm`7I "TӰ؈|E0h'I-j_ MM1rg#bй8>a'+A`XCRHqm|JQͧ״b%]MQTg RzA$t)QQ SYՔ1H$ w6Ӷ*2Ð#ʭdRn0JTBsgY϶c*JG)H$*|RO^Sď4Sz@'@`ʼnAmA(=mV @:c8솅 y$yܫE"vKSt)X*r074Bö/{"V*Bv0j R*PyV=t-( ػ(IN*)Q%HW<}󊯒(VJI=ؖ#I'A  *]Đv~XĪ0Jz֐aI x\zYhq_C8zkHl{-_S] tb«:ID}#_?&P2]L7xE$*b6#w*y޸P/v T?)>4RWAQZuQoSvuA*r y߰׾8ˌ{ bgp]┩Epһ|1RNKB[ M+ i'|`ٍt5Td5eSLǑ+,V}jVZLLLz0F~j4^ޟWQz>4/IQ,o`4Jz38)ݏN68c4tq%4I=njeԖ>[<d m+罿}L!oDeMZ;iٜҍRQ#Pw$ɍ>Df_muZ că|^)ZAUDH}Г aYy]ջҩoN@ZJFӾaWE{T&3و1;m$[jK}JzD$o߿lEF)J&VKXN@\eլv^ p'09*AIjth-*F$?i0I;RT RyBGmť{a9*+Mh( f \lkNwl74ZfN;~n%OPڈ =q/PO'v6ձP \FS0--Pi@e b'UfP1#hA(l—1ݧ~=o|3*W F`To$-MDg<#oWgj{Gs‚Uy D_cc=Ċ% W4qliwpd6Ź4 4$\7M>X܍\GvSvMTCi?|\]iAT1A o߱J@Ԣ> DI# I]l\;`Re#'CTF L)85+*2OkJUT)-J3Ϩ>Cn̳46D鷾v݄!sq27銔rZ ᩕ0Ju2+,qOnG `"?|8#T,Lǹ"x8dT)2Ruy$G? 'MYY˒RV%i]T:B; .+fijp z}cpIa  I!ߟL nJT ܱ$b h [&u@18(Qg'C"~x X#%٥eALv,#on>}~zXv\Z_ 9P T_0o_KV[k&ФhI#HѪeS?_\ktjdcbz)**q?-(:Pڛ*M4]40Dwėe)qz.B0=g:cy#r-G䆎շi_d3R<eV`X)h)%*)'r$G'$5jB@{LpkU agR]>VR#wdqw$(Qg۾.n˒* 튯Gd9ɟ H1 ,(E.:R )" Vg} jmAhK{ amGʄ ~a,\cL'vL5U %lN}k,R]Avՠ$+i㏯*HvEz ,EI; b} 4]P zDiE%@jol%fEqPj@R<7I vJ 2 SI @QsSѺM0 wDC:mMXL l"]v>|KB "~Xl >]4NN<ABt?\]P gئAI>[$}-Am}bݖ\(r-|ŀӀ;|Ivj`Iqe&hyfT)@U?beDF&^aV\_Gۖ|`Udtn$:-.5 N]nS@E!&Km٘!'VDF$80`Ngq܅*Uw- K iz%QW >+Xm/.#VӀV!NvY$=$uE $vE3 )Ԇ6_X۰vw5.Hh8Xq3 PUX*cz Dǻk˪wee}dhQN5D! ğߏ7$6WGRYI,#HPV :(LZR""yqi8'y;FC1-{s'.,mdںW!˨cq3Ub^4݃V \ɍ`2ve֭B WiՎC{`%A@wEfUO'JZawV^#ƔLu9k, p$N,9| Ҫ0f=p62$L Mge.QL0,D.^EJ؜)8aYL/#=m2VZ9t? hT$?>ÙD MtWH]TdQ-\  o#r[;jΘԨ/-UjtHFdy|`b-P&L cŝ_Ҡ* B@$Ǘ[5E.ɒg4*ЮE#U@dUU޿?L>d|][kkRε EkрK+I b;h Uu \RF QNc}'t3 ngq#*Ti>(~륶ִP hһ.vܙjdz]l4Z`T.Pi$"!P 2tsRF U!D 0 1t)| HBh$F(H$wŖ(bHE nȕ[Tq5r?(Wip)R_OcZ~^*'o|Q>oW"e&)>'2m߾-HɈ;N.tՖPj34ʭ xL@У|IėF<|SdPRHv;Z.QޅJZ{=Q{#UF <>$]16a0ԟe@Gqŷ#Kߎw=Q X_b1UgAe$ mhT w_a\L^ Lny*Mƒ%!=9KlÍBl}3S؂VN`AbE@;r 6IGɜD]NA$''mSPցeT#VYӣ2Uw~{ai;=JduzYC"LafiE[Lu<( cC"zu u;\b{"ҀHpG$+{JzH威BgP@+mtHjFZCleDn}7'c^9RbA+>{e@]E6N|f2x+)6* ӿ85A8@FYZ)MB2N٘g*ĒШɷD q`?|UCxPP23|>9bˌnIue; LRʛ3-TQ1;|&y1b[,3$&HN2յz&oCj`Gq|'hNJz/k H#| .A Ϥ~>0r;{UhUdrGxx|jCR]{kʶŦژybGćtܾoӽ7M ƙH+=ܟ5C=Z|FJ;E!,s(/ a[i{(}PA^^Cܞ'hLJ?&MNnV<Ƹbr|Zdtb iaV ,|h.OKuKf)QPTB7@H?uD ꋯ+<7w605l`ߑ/OCWjMTi;c1R+$-z |ũ=(/QJ;LvZ7ztKTPd)O`F+=1mBU3i4BR40=/MZK֪IOIL Lwn-HnTDGsF-+V3V%MUm‹odCRf$L@F5RUcͳIl6n3U0Zu5EX&|݇w'eAU<6 {o=.OעK!oL YUGܗSO{G]T A?}aM;tah7-*L}SKi31m^ˠ$bj;8zM wE⣬sM]2P,{HFNA 88 JeT{8!&m`#oBȈ<\^JYL)}W 3$7YtH>c]8 vqjAF;>8*BLF"c8˪عӦH-#qLޅ5#@;6zUDn}{ mXD7nyź Sh qA]l  -?bOQMCmz`i#i8* MXPQUF-F `$D{}qi* Y#-%n;V,;Hч&48Ǯ!%! cbTbx툒K01* Vd#x\oh\yQ!I Pdȿm* ,ƨlwd+gQ9'aS|hyM a_@h lp &RT'~NNnnHTQ'M>-Ux1kOFlC_Z^SjȊ̠T%Σݻ`SGVg]Mܟ>˟HGs; ;I~ZAhߑOrr},i5ltbd{%=7JK*¢+L`mSu(R:TuAM۾<zĽ9cN kAT;ys]#z9VSP@啽iͥ Z%]GqƸɺpTBTen :,+Ć4b`$Ssopa^Xq1Nm$8n/2Xy>81ғQ3TԀNc\B..@d:/mW6'yP N ,~7TH.w #o~_Yjb判'}a'F,;i[ծTU%dBx1nc@R[S jX>|'bN@Y$j*3fռH? TYQޣ X2=1kiZXRuΣ1'i`lV)hH ,uJWV -NIDATxڤXIO:t2vCH! BB\י0Yj:,$c.WW/&H薾q."ʲ̡ߎAt:wa,Ǡ%I2HB<#Ad"dzVŻ]>Ӝ; 3@cAˀe`lü;orfprp]9waf4}Ӵ\+;H#k}L"L8Ƃ~ي|K57fAxf vʊuSSS29DfQ??9ZZ$@r?lx'dkkˍkڱg QdSd@?Hh,6'yw ߂A[ZZ VrnjlT̊U]MQQs`½=fEs'r༁YB_6XP榛A_زuȑ jV3̀.//I1o 6h! 0k LY 4ic^̖Ea]cMӉewnG Q ykp=&n!qr#b 5dM&S;~&33Y[k뛞o6]/Ԙd%A޶t٦V RYj:=|!߼ Q܌U׾!h: JSlMLP*> R߅eɌEb6#YYe=ǵ } Z4#c;/溘tȔG+~$1N>ҵ/C TBNOOU_\rYA2LfKJDmsXxqtK&p&ѢՉP;]2[('/KJ'𸟚 q'b\e2wp `, SQv 0eK<נ =Aʣq9F_4tCgJJg8} q$2U{^P `ۭi;H\&x4s@1yEpKI w/[]]lXxx㣯zؤ'WM 4gmll]=9oQ-O#ptsg? \2+UXYYaeyUVY]5MRAv1@)$IKhBRbSy7HRF0F) IiT["%U4MjԲzAUddd!# 0<V~,#2LHYB$t:8EV9IevjV9:VBh4h6chZ`N 4 :yj0°J&sUl4hg:ZAkipxxf||m<zNi^[wų{v1w?K ,//J B$,˨V 2Fj 204HZe``T*5 w QՐYj2ͨTjh\+4E)R< !1ƄwVv1m? ͕6RBN'GL R5ФNJRi.d/$$.H J*mAцvRVbyy1&lDJѰn`qqNBur(t VfI xRT1F[ 2($^6Ff 10X#I!EP}:JJT*]xgCJzD +&F4f964WYm,Lfqitm&yF$,P* qʜ$ I*H I"DB$@ LIS B#Eq-_h-C."DGa) h: }6-";hmHTOyRhJٰK۸xHC5MSFFlSVɜ^Df)#EkuT*Hh4dYF%l6i7h9xphZ-hggY_b~afs%fh! zuk'x e/{{Yݣv?vZGy47nd|6l$k׭e||Z-?24-VWؿ?{ΰdf h,..nuP )0"V^YTSPjUjaR$YH*8-' WИ!BC$W5Ɔ*Z`eQm[ +a[NT Hb^NFFÅ>g0mtG6vB́۝cvMw@PP82 <6R2::ؚ cڵje,,,ppv?s)273@}HaQרm^RCb#tti,NJ:Z:[`&tV{ b *N@C, A{ZX61}G˄&q6F'h to!& eݛwJH<)bIWśjB\t:MdM:yۂ2>Z= 011#fp`Q֭[ZFf6K NkL];y;e].S)Wzou/SObr<{w۷~昝fuA;$C22<##C RשT*iol.btqM1c`{OBb+kA@Ħx)TBVN1EMFkYa~I E@S>8#ܿ.ǯAB$AAX%4F% "t .2"G0>Zv|z~x;g~?Tiw?r7s?΋<,ַ7#ocff5###a͚51f1*̆Ch[d'7!tIK1 8&C eX57: R\JɮBiQ,Q&^I E];~8`@ ֏Hlx4L(0ҸZ[p}-d1sT<MJl@QXA< J9gtlhnMcX~'t;nF5y3۷8#֚UJs7V ?} >O~|+_a޽LI''ʑGɚ5k+ExV(WsPʆ"m,6LBF`DzvBI9)+!]`|ѵ^)^9K"d>j9VhQfxڸ;ѡcQ4mBIh S(-ZAclcB?,V8U@#=`׾7  mO9&1Zt'c Fda_%n]b \i5XYYaz333Ԫ6mG93<AWs_ukPJRA W 2 PtSFdVVuj6(ps]zElcxDKą)N#t,-]ml8bϤK }ʆ`@Գ10hƀi5AoY⍍q`AC <ϋ0Eb< Yr %vdX^]e]4v ?@}m<)KVĿɟ|x/z<>;z?S1f˶rlPH[ KH7/E0.>Ƙy'ƺ l'V EqB%UyOe\Zv2 Q^#zrimajBgk'tN%SxCL).W+@mr.Z ](hBexH"rPB)͔Q&KFdHbaa;dpp79~Il{0o?E/R*>1ضgy-'ͭ$ׁNk8묳h4WXZZ*y @(h*ےİ+m YImTx/#=q)W( nN<9sHxʘN `^B %Ng:KITV </ U{R1{b[-a y@ Ϧ&𞷇3 LYX $0m  ER~`\YJ AcR];vxW"~켋7}2?7q~ ԧ>iowpIG\ۿæN篲n$N_ aP3wmMP3q};ȕSj60i~ IZA)v"l*YX9NE9@bdO}/,p bgЮ)<1͔6Z(C8Oӳi):x1t#TB\cV HPCTʬPcK. vu; #FjL UN)*CKX2$kX#8\aD}6"=Vk( ףVY%($"-|Br@ YR\a6(x'y+^O]{1Z%ff&_4o;͛f뮻yɏ+&,K9xp$]`!2vӢ-@5)ֽ[K㕰 1QrIW.$K+ax%r)eѥ40==)'P{ޤ~} '0-"|" qg th.ހ9TT8c#<#*j{0 TjWq0F ,gh5;,eݺu )FifMlFR ]9W3 j;a";~ /|-"v=4~v'k֬=y]z-] >Gk~SN:YZ!*y,z"ZOBtMy"LKQTEX7" ply!L F&9O>_XYi088RRaey9Ҕ2*ifEetT$I,y&WSXzH%乥sPVi,R+xnv+VXFk8͜F5(Y(2EHc4JjY#CkEY%jAP񹢏 "iR yL$I@sHQFw:6BF4]_g3b1{\rkyk^-~`?Y]Vʻ~}yeW2h${TW_1jv7,\ruJU4J,n(l( ?ٔPw$c~OfX;ǙX3%*& ,7Ya#y#&`fvqܢXjfݺu?;=E2@^jQ3:<xh.xpNxǨ2fsܱǒ4?zֹ菼 ϢD&h%F a}08qcNYZŐ!($$Z+@-#HHAHk;]Ƣv?tSiL$i277f188͛I JG}A _d%TȲ,%f|+/4ӆ$84יWLn禛wo|:Jke̡xv0K H+mS GVmShD LtCK[mVIꄑ"E*viT3y6̶L:ԇ$VW"Vh[r7fl-y)|փ@ t(0A&L~Fֱ4[laǎ?;>꯽\r%Toi4WJu*h tYY!rqd0[06:g(&YYmrQO~Q/u=4 IDATi/Fk>91Վz?p \oC15V;&19êkK\N KqJޅP (`@k)fᩴiHۨ\EtR*$ׇ~ : No q8X^yER_'n`BR8Ô,ҙ6ձa#A: MI  D-h 6zrJ'3LTG$)ybٴiC/r  O<z ]9=W]ebtܴEjaӦٳ{'{,w7ۙ++Mӷp]8/cќw|/Hbh"pM'dol% 4ߔe%s@9 rpW:zR %&x RE).P'JX/"U 0`,_`SkCH:Jbe'.T[ eBSAVs#MSeQZJRD+C"$.*(`Pd425.LDdֿ \&E EڬmQD"]'/d\%`.//߹nݑT)fݻv0g҄Vn\I4CݚE ,~7Qpx,,y3,L a|@?,x卓efs—Qt4R1`!,Ń#fG}T OG5*YZ$(i+E62%v *D-7(9#0Rbi)8}RHB6뱴_ ; c\QCZ݌Co܅OOZxY[.i0u7;LзۮҒDQ'<;袻,-.#`5_ӱg$'M+a;,ÃU^sϿek0kL30<4*o2_jcx?(,ydCQx聵} ]bѺ]r!&0PTɺ҅,ڊB&SRF ?s4{uӂJ& %X~pSr$i dw^a=&OBJiʈc HQ|_PX wM4*-/z­},8i#V5+ h4 qH.`Ϟ)FG,x-1F&Dk\^D^CtI;7o{Fa+l]V/m#ԅ‘jJ>^,l>e̍.՞bbA=}KL)lQO|c."KD)*}4zB D4M8iA"6=kuwX "3dH6@ek>3336<۰q_mKK+^-Dt4{s">KC#LEWGBzF6J'E>bnP< i%s#TEPֶ%;Fн# I4,dJuAi(LiDLbarve1`~J3O`9 qPoiDܾؠj۬V0 u)=*7c'YB"[DoONB}@AܸW߯,-H)’}ʎ@-;j0:f; cz%Jɡv!<,-,<ʑ+mhqL4I_7JXmRZHFyn42\C9 ^G;~ZRJ %"P*܌9ɔ@rҭͬ>6m[)FhT=֢|J#u(2Xc+2#{PO'Ѡ,ǯr($*`PyCS0T)͆#EJҴm>OYPn€D'݉1>V B(gOBݲ<$ Q&bTgE:5=V>x:)0~݉>YӲob]Ҙ~2}Ƚ2*]S4] ]wk(ѳRTc=O&yni:DtYK-KuOP~x-@hA Fru#t6>HY@^[߲alTAn#ʴ{mʇ*R;C)=t6E% Kb)lbRjveU&yL1 ,xy!rIӥ,.)Z27J@;cP҇A%K pY5:'Mz&Ѧwed̀d.eI0h:~]G?_CjQ1ZB?#+*`0ۻSd׹8+16ZL7}=Xp~r[b-鞰~u:=JJ葮Y]z0~*Bcé:wEJ)<҇g4+ЅT9 V=~}~^GAj3Pָӛ0 !CKOgⰱ+[2ݝ r䑤"R2!dMez2҂6U󭄔+BMs8e, 6q-V/bCa^.bFI=-zɐgIs[az(4QSgD94TM U 8.::-eQeu9_K"{B^FET:ЄLQD -3JJ;r[jş=2CXH13uuN)Lg.W,9|sT7z#KEJz.,mU&.JmԅsW\Na\-CƸSL'Ud:_;@nC?(87@(:ljKdġ@{vG`$Ҷ_f8H@'7K(!Za"omPR>ȳэ"=H3Ѣ`4xY-aƲ+js7^L1픔ӱmRɲe)e E12|`%PpMm~ؠ?+yQ,dtތyJ13I]NaJa :>ƱmG(nr):G5Fvd=prɎqGiKכt|õ_$Od[vGmB>hH$i D b׮.91yp>h/1 ߡ]GKM'k1WELx7(+t @DST@1=6MS4y Z+&$^ݩiFrQۇȄiE:T#:|KOQ|X@H\3hso" 󬻑1!ai6tuX12N]Ԩ$RË$0(ST!u)0Pݴ_A#RIɒy,&:.!]SJ_CѲ)I9z1 \5xk]Ju_*Q1e.Vt !#G:woxD1mhE\L C㎻aG$?ĵn2«yB8"#BWe٣FDWCp<mm nS63ӐqKHqԊ@;(jc+4RH^ j򨠫"2pԺ0h%EK!a2{UP P#} o$r{\0%EdbΚO :{D g Ybb2% tzs?Th{:*`Z9d_?ɸ 6?Ÿ1?TDw0hr ~F> ZYb)jM)!P%lž٢@(\u5"BRI=D??\t“R]NEuvY"U1J@v,ۆ72g.~Se ,S/0eh[ 3a\2Bg D ?0b,tM÷}O(PYpGE qOlBF-(Ht.7JɋۥYs݄Sd\<)!Z*qYHǸa?=p.g1gtđ*ؽQTz>oQ ˣT9byOҨ&KBEsVÛI 2DðBvq9tH|>+WŎz0sXE[L_E]YkrjS(.x^)܁LJ(a`?vX#"e xkp F>vV4T2;M'0RZ͈bx֚NCZ-r4&ŨWFJwFfC)#2 983KR)o_;PÑDžP>Dѣ7{7~=;%Ja؇bPB^LHQ15%>:5Mhm@2#~%]x~_̗?~>spJ=X^C* Ldߐ`B[9]/#+,kh3AS%: #$#1)/w^:~CJ< z~_:wۿzco_z]BQDLM? s{Ḣ ۿ!X7 '-VY6# 2T-Nm<e9MdI_襀r!n6P{]a>J˘AC>Ct&b+FYw}P):;XQ:v"عiLh4o  4n4?\&YFlM^g˖-dY#<ij }gv[͈su8!]gxp3~֬YC,..Zr'n<å}Hԕ'aCd/~ա9nFG",2\R,J!R[ Ubrr[n oy[ؽ{wx-[p9o۷s90113<<@Rabb{bOGecX~=_|1۷o硇V1==(j|__uK/eӦMya_*]wq饗rynԧ>֭[ p2DBv6,CxޫQhW^y%\}p ݻ`͚5lڴ/~s=LNN25o~|[͛׾<ȍ7׾5.Bַrm|`ffO>SN9W2TawqgfffxG?K!9}[w\Rp/۷o^IGL=#% :*g׳뮻89%gLZJa\G?~fggV\q,//2=="ge,--044Pǩ)y&''i4|;#䬳xٴG_x\}͗OJ`4o'I,ˬ U*+p" iT/Ľ\ IDAT6vӦM!ɲ,;#x{믿K/38'x|3Ny3Mjo|odjjN8xkj0wέaÆ ?%g,cΝ}ٜr)|s_:_~9#C;Uz]wUW]ž}Ȳ׿5a~~`p̰fmۆkO|TU~a&''Y\\ ,..sNN;4*mƝw=k׮ 4> ÃE})y?6|)_7/9::U;yc?سtq&݃D"o)$ʏp'miԩ%p&syB<77=~z(Ї8G?1>q|A&={{WD¾ {nmƩ͛QJ1::ʚ5kZsP>O|fɾ}{y'9cgqq$I{v7̓O>{^8㌒G7~WE/bttA."| gr RA|,//Or=!~頀GgvqM79ABy||gܽ~;b}4ҳ}}Pԛ~n%^fS9Z0tRV3'MI^ﱂ HRDŀ .fVE^xQd1Qij$Bq;o0ACh@Sj"d鴵⪲)쉣9irX]MlFW X2 } NɻTZC!Œ8L8 Iء[(ϔR)J׭݊VRφz :K9鞥F9IDB4@5}kfᏕ AsQ(t vng[W~8<Į^ޏׁoiDŽMR>Br,,Mx>?h[ϤI d;֖׈ߏR[ #_K7f gsH!:K6ݘowj.ø ay͚uGI*]{]pU܀ KDR]RX)jthA+qeY!^Ogl3K21>5;k?dZMSMj=GT%vz_?M-դ3ypq낶kEhV5!&d93@9 ˩H&d6qbO>REjL!T!,BO>IQ|e%%O&Bd͖`m-Rj"+ k":9{T7Ѭeu|4Wj̘EDJ!=r0T lڋs٩]^ b()(]q3/xZx9]cbr1оRSw(? C(eB19!1By?/!H^'9Dw CgG~aKq^P$fi*MDu7RjbNz"ڠ4a0zzȥks@|ʹNfƘ śg4)Ggf59D|b+Olߍ9\+hr"mka<ē3tieYNcݖ1=(ٜnAHP7؃8u,X(E1m]X@j)ץDر~L=Qm0hXLwy1߆azSE4ʷAiS4ZMLekM!]S1鲡ZIYڹV$9D'O[nhP'- ^\\M,Ä:L]bxoUUEl`МFSZ2L4`gZk_lP41XؽB>MR,hFZJRx"-`;m{0V cPȻS. H߆JƬ!_iJZ2a]E>ЬV2MߤA0iD#X6{00ljiY_g&.A3WͨVi]!0 Zk>яrAl2F7tW\qkkk֤$_1Qd7JooYZZke4M,t3!:^AB?-<2&k?amA-?HX4 lEa#|]妏eݺ&6AjeUޖ彨QaҵvOO|=1%9{Βm!R~(Snl3X;jT8 o'!ud'ǜ3=WWWkxsDٯn_s0O4)wf~~5Q׆y1nۈI:tl۶m#PYFֈ9AN04h5{?F@2u6f9 ꟶHjfs;q gsY@sqxeYokByETj2cV2':111 h4j^8ĝN >{2 Zt?7|39כ .u:g뮻3^w^p077w͡CH3ǭ?(/9 ͜FLnv*ʲl'qYG0r +',nt)7z`k(T4iTѿ?cJJ RR䌏6|(f1fgI#S: ̉L隌A5gúd?y:^V/'!ScE;RϏ۷\@G_x=Cxt:qwqYg׼n?q#?#ݻk-wy';wxu]3G?{^77[ /~vίp'n啯|%guÇOe1O?~WU;vl0?/a&@Pmg?i !L]!UN 0Mh\63K[Yǃ2.t-FthW/?'P윦8xȱctۣ~r GLQA'ʩp]=/~~k}?|n&9sxGB\Fk矏sO}S,--?k~vٳg 1??{\qMZXXO ֺf~~|n_5nJox1E/x_W9PcrcORJj1yHgZci~JߴJaST+)#~cO&Fyiir@A[4ҨXqa^$7hH5JSxQɛjUUqYgquqWsWrrg7+cǎq!g5gرcǎq?|VVVx衇x衇X__gyyG2S%rҢ`"KKK;v,9FJ~7b~aaOǓ6`]x351_tX^H H fi@C8BJG41ߒPh3s\ek9S:E@kյb o .}/gc>&#dԉnkgi4߽mD⃘Oۆ 5LJi \ve\s5  lllP5=^}Ǎ7 >(x3Vc8G۷k-nw'hhnyΎkݼ o0Ⱦ}g׎r5z...RDz&Qhc15NԲŠa-aAR~I1E$tmRq)&ҟX7N[7M^彘8hrJ&=K'X΃,lm70,尙H!B˨fEJᐪ2F,n™g׾5nF~aF^xaRkĔ6`CN9Z+ꚩEozF^nVw׽ <qSFam_BXCH3+ jSc-J`Gw,NW\)$<'mC 6(:^rM\{.Ni:܆{h}4 (:T Bg9 ضxVLt[SYzrİsl9稆#*=J{e߾}l߾j8O<2;wdǎڵ;w277714/FZt ȱ{|_R`0O:??m|ONBf.˒}C\|Ŝs9^4k ̋== ]1qMY^ e%FٸNZVB?lNX}OE"X]LH|`Uߤ4>L=u $yyutXmndܜ^zÊ.j]4x F=yO#= SkkFeYsΠ,[lie?'?IUU<9auuuPn0p֕ߦbڛr-(6^K^Vd ' Km戋;Ws6{lO/A"fLm |(N = "rl<V׷b~_a7LAV1&!"~FQ~<#Mg-BZs\~~o:UlllpWp sm6e/c~~!k_UU æzֳŻ.={4u]WW۷NÁg?g< _B֬4+% Q nQt C=#A`zMcdw2H:TT qUuQ¡'-6yT ׺$J6*MڠOw6/-}*I)*[o6nʽ3gٚ/`eeebgGqqq~;w?ر~?Q(}qp}qI z /x󬮮6qcc[n>u]}v^swu]ݻg?#GpsWReN϶mX[[`N6|G8J ߇Փ` )I'4JNyяcTF9LvS^V9/E8=u9YRI6+Y#9Y41u?OcE`.AiGS>Z934|7N(OԹ`?/WcY<̉ny:ĸK éuvgIUUMjpRM::۶mE/zQsjk,fCGAxPRΥ![~E>T/]#Чi5+ F3ո3.A) E]45U[Ң{Syo<LǘE&x䑨ͣi6zǺa]OZ*S7>ƙ-'qSрnK\>JOf)X__@1}yf0L666/#Pkq)CAn{(1D27FWVg4XePcDK=^s[CM/jR; IDATjz}b$ pֈyg5DŽql6y*٪S]N%4Ŝ PSs2=[7{kAc)θyT ҝZ,i/dDҋs׏|0/DsX4mr|Z)FTgloHHE*Qc+v):7Ss:7D9p?uHapj}O!xbqaܶlIi pqJ=Vy֦"5947"_ {.sΡUxGFPIxDgNTny9zRNj# ϙbI;m3RJjIۧO ='g<<Ứ_0B貅v2yDI9*vDJZEe?_N%Ș~M'%%OmHB2%4Ѡ9CYjzcr=_}X)àÊ+]\y  yx7-&V/T>љOaL{Ѹ'|]h1k?ýM[|X5Ix"j1; H ƸvB01%1ڦQ!h+ϔ\5u]7nzK5OlDs _aU's|o>.>LtS,KR3)is3'ŰO:a):7NN3qRۈp7˷;U//[~ѧߍSG`D!1{ECK,t1a#V819> NLӞtSYF{\K̔=mlm=~MEUҍS9ˣ1KJY6_J$"xv4𼫵U7`|(Ίf[S(,J/~T}1|gQ`5Ra<;;PSu?H5֔ {+Zzp^HQW6^ aӺYHG6}zPTMzZ`4fijOAnmˣb 2-mhlgi|j u覠kLráMY>ϐ/6!s*5mFh˟zmmYWgDe8$UHnPSeQR ӌl;͇ڵ2o`qmrUm59ؑw6KY~ Ɂ0:?{N^I9Rףf乁n~ (ʲ&rthV~*1?2pn(JTCt&4(rLad2{(]ZfW5iZ ' F8!)ibJh8zx<&ȥf觺\N{.m3|jYRN0K4B[d MzW>/3!!>fE=9f~Qo[; :OrvS K!6Q!х'9p@9l0xyRGAm W"T Rak֞H(L{h9<L#I^ t mzJFsX;:˟mD;0u)O[uG][:.Z*‹.8S AMȀֹ$Ht~䊛m]|po[o(ONy)8sY۶> ʏPI%Ύ˜Z S6=@)*p815fOA\ɥMgG83CQJy;Յz5%ߴpsCho\iߒla 5@M/i.UTmb~k(g-RD(!rESE#YuP~c!*(NDX R[!XrJU,^9FrBH[>;iOgڤۆYYXmV_t86( mzը,s^cʁ6BN%-fMy{m3!ɖ_qT2Pȡ׶?BtMWZ2ApoߦV@ܹϜ6/ӱHrm}Y$*>S6 AZJٺu+'WTΏOD,8 8k%@3)ۗwwFl/Kv>HVn::ӓtnW۩6x]<=]"B^T\Ӻ+o>t)hBe3k9#y4˳䑻jlk*fnnm۶%I1ͣGW=}|B2!WT,TGG7O#sm"mnsqW`~SȒ;{͡8]n"T (>o:_YMukH\)O7q[:Y^Ķ!OyBG&_ۨmWHɝ1 I_?q-B*͌[NCj6YO8$4T\:TJvHiV o3PS̅fG@tFƼNh*k^qcٹ07,C;n9WQA iVptlLŋ0nMƵi͓i"Ckiv-?8>,46«t4ſ<~/y{GB'/周v I5"يѨϑOЁC8>tPj~EƦ"Qkv= b)~#w^CQz7-[ر<2;v,3X^58~hHDDBTk ocn2Ccl,__;amhصk^j?r]ѝCQz45^"QΚĉt5K4x$Yi'_XHm9r<{pHb1}Mrљ7f.CNM{iTCc6m6R2+{mرC|~>诮PȌ|N(Pc|צ'tdc{s;5̩s8c09Co**a*+|K\.;kE\sՀ!FqRL }QÖ-[(|ོ~3)vqW|䯨?Jzȋ:l TA) y)&qì1YXXh(?S׌RGB8XXɖ8N ׳ ЏЃ*l'֛ o|UVVVXZZ|0j?F"-le~_V\hc8o-d>-%vԶFPRb8 Ј"h\XtZYCp: jCaG(pH\I"˄ԟY!Sո1P(>{ۙ_׾Gn`ZRvon<};8 쁁˞^Z@ rNv{u1!2b 6BAm۶'ITLxD ~\d9,^aQPqb{LaINZӼPv /BKD6@ouNS)%m@/һӞ"CCUü*ԒnG! ԁ Po1Fas*"%Х)Х(BbBΣ֐#|Zc֊JiV |4Q.~1K0 !=* p:u Zu[ay:~Cfiy+PMZ>6pz]R eF`A:+p rGK )D G4V>mƧFio!j2=0r~0o‰&e2Iׄ8xLCo5:uQX_`QXegk⮯.c0XGRCh 3a}og/W9?O%v=FF%@9EDW3^ZbF`0¨uMQ}qHR2HP)/H ?0hSs/˒￟*rr:]8 z8y֢kԾQeV>+:t?usN.\r% kV8*s5ukWj"Fv@! !K#P  [JBRWu0* j\4QF#֡F.PH(SՈ |gkC4M6D'2hߏ ه`9/E㔄u Uwtֳ@կ>3oxh‚%,УA~3}KnxRZ.;!5MxVՐ B_$}][C|!.ÙȣM#ab:u*zifrbSRkA?z7)S#Z.c=Ƌ_b:Rh6UPn>4=Q:R19?_y'xsmzOu zָS2cǮ!0:QSjJZ![z\Ws߭/G3s [#Cc|XӤ/. q] "}T_NpR9ʪԶ$iz=/|Nq~wy\s5\wu\zEU,mJnc1dQc^ IDAT瓟e>{3o|#_{sss!v?wqDŽ:|̈́PHbX ~j)|)< SR~-gw EY]Np/H-PZt8gJr 7 oy)Zy) SVvpCUψIϤlFg:|G7:5>nE&l"WO䒋.F)G'cq;v,{n8LimN5;wdI"8سc 9$eTOsə2XV!(,6QYSz+t!رOiJ( % /``CC*@M~ ߈v8cPX7ԢI1!n!J0 i@I)X'YbyN;p)% Eiu e CG8`\ϮS:25.9z]W(;[)Y߱NwwwV|{onyH'c[mFlmc 89h|'oFi`ԟB~^6#FW4&F{CGI j>wo嘴VO;NC 9C9At zƧ?B:2`*hSdn^4Q }&vaBdT"%ܗdatutaGf=̺: U4(+(D*.ͱ4vs'8X3b4ZLf)J 5x<jCe` *_c3}ǰXs/s.5E@oBJS7O;aqB"K($N(tGEɎ @>jIA[梳O2:wybc< DJv|-F5~2d@LcDj\x9v ]^SXr_38y _|f'v8 U5z*Q;L.eHτCHy:PA,0p?:c>Y:Un8m5nR s<أ9r(kNsZ) x(呣hwޗ܂.:AM!,-}F`۶mݻhDU[, ,jbZylmkR)|ޟ*w./ nSh#@QY"ԃ *ГMCBuA)p>劑$+ǚc"V cu8DmY;w۶`C>5Vڛ kUsPYbT,G*ha Q2srcNY_khܧ]N][ŏ|GYt }G,ʥ\a+hE=Hl]Zλ.9y_4ʡ+;e8cNDjՈ@.%A_fBi4K'8_?N!u]O)Y42n\-2 }c\ WN JڀbItDgtb#7ݓu` ~ :tQ=5 . t D~,KttʎFi-+BPfz8.;ロ+.;=?+ wS{ְWE8mƸyB}ǿϝK [b?E&>CNШ]7pۡ7'q w}QN\yN/%oNܦY[f'sz6=f>|tx·|5q0$h|I=͚)w_|w̽-&:D/]DeGoQxpnu'ߢ~s<WoYqύ#t KQ:eמ{kB:6ߪisl>ao68H.+O{ mM*4[`.`g?}ފh6ONyT~B?U\ x 6ADPjϼqni$s;f|ew7ھ>_!7 co(#D5/GӶ>SVa3̛aէ?ꛯp>>yMm?ymv_iFQƹQTđ9ƻ+E40scEI&#[v* opuP\/s{0(t9߰t.H+![W6#ͷ[Gf *kڏ]"@;N #lokK[f$)4a"enarװHN0.-.{?^뭽ۜ4cT$6x9-nǮv#RT$ouWvo \n} [C4*)qF {ofWU ޵ϩ!!B hUQΨtSo_"~iJ tZ@B @I%TթL{~aϩO-43VU b 18(rNn6]~s4A+Bߦ;nhpw`(9@x(w;+c!0uX QT>,=HJ?iќ#0Wh,ch\#RWA@7(Ƚ-'}Ӧf ր>sG߫-5Y+mw9,v?v?z D0mXϻcݏݏ':0Fޜ jfc#%5&piʸc;~g+a4M3v[ݏ? A8Θ ?IFq_Oݖf M/sYH8䵶Lz=jE-=fэΛgiI:xj"Z_|4i8ތ?~?knc.dIc㞳??~cWn:^ ^E a `aط/)[h^ǡ*<̅ZX,K0zeLcQO7sm[o5x\419`|5iG¹I!P;HJZZv K87/]h407΢lbnn3sh4h5l6jj7jvzT&$#,*_J\v7П LϿ\"=g\.P(\.T*X,V\.\)KUT**(+=+űȸ_ug ku͟| e_y㦛n:awOMMa||hLObjj SSS7h6zQ!d ||ЃJsRIO ( vwCAnXC gub@D0CVQ!+qqq"l6t DA""7,"DQ_8nZMP*N_ZZ ,@__ \,my_矽|+cKC>Ƚ(^ІtXWwb#`h͟ ZOCጏvz=~t?X]uVl1czzE̕%P(T"ϣZ\P,Q*WQ*P{(Bz%M@O7R|y=$HIY)b>tv4@iC}[-P +@Ez4a,;` !NaףYArzԷ:,fFfa jV0Dԑ`F2n71;;N'3k;V*\ӈc-hZN;SJVq * %TjU -YKb! a߻r nLK([ P8C({ݳ;?sظIDBqÊ"P>09',64$D،RgRd|*f J;CР󁑳Bv:dZ` `JjCr#x %WJ!"(F'.Zt qCJ]$֎\>jjֹrb P,UPahbKeTਥU 4MDQ ;GsvNa>"ʕ+q=(榛n5qU8蠃d-[J`E Svlsk^s,^C{#b ?ׯ'۱}L} Rà2j*j**VGRA\>p9)6hXAP֞1+H0cƥ>4U 3vHTyLMMWGy۶mrSZb`pk_3 %D$fG1 G%郠&C!8M%#{0509ϱO2ޟ,'4Y*/vnf\;R>o1rm4'kEh#ƙ&J!@vpk&ԲS:6m_~CY}CCC)Q ) *+ VȆu/|Mh֬* Pkov6Qܺ7 q":+0>tݲ'FlǍ[8vO M% >Xv]dB3ű0 dREڴ"!8smDU@dX1Ny(&#c6g13;1LMߏU/?~IXr%v෿5?c#hZ'>>˄^+V.{c#チ|;ơG}4VP,\8&۱AaF L@Ph7ʺIDdF$D Pmj@`vv+dJ* UPCHέK4%-/!(fH4cQ&nJ"-!A$%KDJS񖷾"o69ts,ZN'UT!!(R",`ch)wn=s kcaw-:З Xü^h|N!HuN' gLű;;9<>~56?#%#|;l-?k;os #@>S}+_v( 4MmV""㶰}D];ҡeYWYRNh8-P!eb{ê7JF\(V0 f#"u6?l~Rp6J\NY&qB)%˨&`K1XjƢEl,A+s-JoK@l !P HHH)rXHYc"^>[A^P ?:zyx݉c?)" ^]ﺸ\)pYk8uWo|?pVK>K`lDJK[gfM[+L)mpl|#̡ui/M\'f^ )څ)?ZcbXI~xS_s7MÎ?qTLNNB1  C>t+,4R.u) 5ܪpAy\$tb UQhrBi]@g&0:CRiP$Z1br3Y8uIa?J&mNC !*@@׫Hgݗ-[Zv+64:h F!9YhW>HXNq`[쬽$H^O Fw VBXh *DNlc||u#<BJĊS}@ cزe :\w܉x٧[n>{>1?. >cp;Π~#>wa=/~Rz]k:e!r)6&a-tMS@65{Ԓ$$RyBެf56I/:)V].CA@x~x+nbllb`F. RY[ v|>(j܃Ni+b` v\\$1 hwDQ e 6+o3c+E4Zw]8Зc18P '|{=_|7mڄO_){e|ϡWF>bq8TJ!fu pc=&mUQvz!C 5E, anv?@p;4:m %Ƭn#@B```#Xx! T*D9$i5Zcj| att'J2^X`nnr9,X01ԪUSC,ʥ< Iqԫ+;QGH[ P!IOp$bao{ڎ95q PmHgF&9 XǞ P ^CVz(56MR]׈C!>Hx/.^V>8]f޾g=>}Hgy .zυfFrt K^NG!L6A_tKNiJp 70YT 3`IodLg9?`Ps;w>9w]x;`l|j-αa*xj͛@!T oBS "lzz#j%<,Y? JFFG6O aO`x!\9Cc oݎfgpA^Z08؏Q@P  k谆Q[ȕP FX*T.N{0xpj*IUF U]hEƥS 1Zb>,Z06uLND 9Tj p+!D:`4": :.aprp;~Bf$Q.cp7+4ǾfÙgPaR I'tr*!Et΁6~Ҿ7z("tG|NR:WfrG RAN{~_s .lRI `jb}C>ȣ՘84Jac+Wsd0L!ɐQSӨ92P؉b>DDZfcZ;Q,h̢R,ݘCF@ ۶nΝ;KT(P%:(PXOg#%!T :C!dl&ѮXl,2dj(17; I,j!ma1C(\fȃ% X;j0a&CV`V{XmGrJ<]=^56:}g?)馛NK^4'֬Y&\; D-pʄA=ڂO,?Aҹ‘d9Uȧ$! {~\bѢ%h4\1UC2 *"C6ra 4>5BZB'҂y[skOObpp33uJ4fP.5;\uPȗ1ۘ@?:0=;PkZ-]0==KMo~,@sFiBAt DHq Ʌ8 Dd4 LAIx91.Ba}Vcfj9QD__DNK\N)fS(J(#FwN/ + LGh ?0GXdFvlEP>g)*;'_yau=;G>r> "&&w˰}!D!;ྦྷb2t=,Hgd*辏32AM[.5wǣ͛7<#_DX|Yt+nj :{Qa K ?1c+Ў$/6<3]R2VCDKH-[=щ(8CP6 H fъBJ"F90nk*j!`@!g Rzp 2!(Ja%!kvscaN$d8f APa^ǣNxކo3%4=mᕯz }šLQl$ڸ k[/AX˵W-19u5$^JqӲeGe ǚ~B]`E 8vTdb]hsK~nѲ@๯ (R&`jyd HuL=FH"i~! C2#BCNA+ ,4EP ٙ%S($KiIuObjj+A_jՙE%!aöϣX)C* ؤ|"Hˠwpkҩ>E <կ< վ"e??6뮻WqFϾ3MM-~>~_0rҐqTZ邿"\'Ezד#xJ2BӔ96ۜ6C@2Ayl~x0++edS-*s*C)!8R|R:9LP9HeVl.q@%b+PRB 2,NJI 0H)%Ca蘑%9<1TU,] q P0 mt2$ P^EڪSR/ Rit,@wt?q{p`hryZ-$#J14҈ 'dHbi 6Tws&%Xól-Xmy-R:^VYa2d~ ~d_Ai"beʯ '&ARQ7@!4e* svt $ 94gg裿FP}&Z|nLf'syG>0` ),݁-[4,Y/!^t![8ejBq(#Ҕ6YP$Z9SR%؃שԏ29K$ D&$KXg]>$,U'4O A=$SeO&<0𩾧X m:cg&StrkK#vbiCq D|+ML"3#<C*p ),7o DĮLD@ yI"I |V oݎO9֮]{c={~]ig, [R Iɒ+( /EH`ݲ5iGůbDЬ@G@*a 0JQ2Q=B2J!v/R J57A@R#&u5>{{zF)N"Jys [a7(w Q6&.^%hAfX"SQ҈dS} PRjffĜ}r[Ax< Q̔vJ+H+3h9~S*Jy(1 rS 2 iGPNbJbIC>) H7^|eGk%$6-FK`eNJdGdZMA^W f-;14pǣu[7OG!unCAI0Wј&5sy.:0%ӭDyu|Q[>M̍u>X%5DRKR>♜ːFȭc=cg[ޭ )%BavO]JJIaŽm[PETJ.y ͂C-[V RL>fBfP'԰NRV;d91"B//F]nբi%&wPDW2.PB0q:K{Hլ̡=A鵖f.w(h_%角ġViMӍ( b. $` !,(K Zd<w&9Q*QuvvrNr ;wN&_R غuj~T*:~*l lY IDAT|٤{/և `8e"eRA~~ܑ$eǬ/xL+K6R7A=J40@LhYQz-3GZPGJ[~9A&L ȉЖBS^@BY*牫DZ8?SE2HmrZkvph4(h4D;'z!7 GoTO`b^ecR^&U4PB r z R.S3Uϓ n#c!&SZQKWB<œu n-K)<%kmDE[_"?;TRʞ`R҉Yybض &刴Ci纒O@1]gҔf'uC %cjjʭ S_%"j5 ü]-OqLq:X-4&(>99FqжE CﷰmlUp%K7̳άwmݟD`i."ݮC2EZ%HZqA#*RNq)8F/8b,R *x 0LDd`6L4ǩZILΗn)2UI }ٚ1}b8Q;Ʒ[ QJbg/\&s,Sp% =ZB'-"<Ǽ>1 Ħ%&|Ŧf{[f["QIs=XQH2I/aAx~ Ed"tz*^@td J6(e*ua*B& 6)w F ])e4f`5'oIk?<Ӧ)'*1:PTҪJj5Agiև&7#tҜl}ٞ dܔrAR6N eq͆zICt@|Bs?3괵"ᔑZ&=Eߟ cn=[?@/I2-/"l_s HOo749<uqC?U>7E,[Ke1Ku"I1!)ӭA&I֬$̛-Q]Hij]) 9Ƙqc3VO o>fiqzhd#|6v㳐? 9-l2A2=tLy֭K& $@zKQdI ]Z$.8 eF:uv')M3I\e 8 +kєD.FtŔeq9AH: b$*U،m L.auT,Env-433zIo+*;5_{eVJuё;i|KI{;0!nP[I/|{ȋ t^\;\{"++Ŀ֔Dk=gy/Q2%hiv6x <ܓHOo$ݟ4Ì,2(34.і^m{t"籩\؆ʋ'ļ{ђ F#Sl~,xb^%Ի(9. M[jK.RH4-qifDbi .Js|N(!>%LPwst_3"%Nn4EQ£?ʒJ(GKSZUr $(CALEIW1}LmaAnYh?;va$&d)=exm|@XuXbض2b`3dTA7`:&%e"QJFJEe<klYI߇&5s$>3 %'T&=+rsb2=ϳhq:w,@$hE@Q@=1"&i֋pz$-Q֭rQ%ҨXRY%2✲/i^T)s itÙrN3Sy|_\G+nY+2VltףIHXw0N('}$+F&:PoY2TL/g=*N#MR1vܨD r Mix>;GI킀ڃ"J= [#hc8Q㪅iBIo(, ce( 7;;ƽpfA QSZ]snh < S3`UtN(Ecf^:`.;5!Qh7>P!t>E fU2if??M@Oj0 ӲnXJqmGۯ a mzZ$;ڔ1e [ ̢k\B!W[D=W{f-l:RL ph v^=\N+N Okҍ)IGu%WS,ߏ8n2 uXA\pa`݅S̙ \!Bm͛T|1 ozYg?oW}}`meX7֮ŷRAOk7LrfVހR(#|aAEv ??v/^A]Z_s#`R9F2Xw1ͺgrr{T"xb!cǎftQc2jgF+Ջ}mk_b`ZL0 ]J!OZ8gaʕn&~w߱S=x˘{o+$𳞋 0q!Hj'4fT0LȰPj(PTp7bŊ8155>{=q6mŋc˖-x',_~8}Q M~ӛބ7b󘚚BZEWsRZOꪫp#ė߹Ct2>я3Ȉ;8p/R\}]}.R<p 7bӦM;?pCEMp=`x衇ܵ|__??0448/jp '.WUwX/^SN9zUG~CYg,]p5׸8餓O^x!׾{<@\jn </Nù瞋i\wuN1wA= MX7I]0Eϝs9`foΝ;111t:袋8rJ\s5Xn8lذ7x#~[V .ryx[ނ=/5k[oE>ZC=4I` Ygl۶ w133[b||7o7ߌ>X#ڵkT*8묳0::O>333c=g/^z'|2,X 6{1C9q;w0;;[n^{-~k_z)=ΰߝb?شiFFF0>>ql߾Ø`<22 lV«_j|ƜKwg/OSwyu} FAmFP S 6Κ+Wtltݺuw}v*?87n .CCC{qq__7P*p-sŕW^ ?uX>;04?),{/~17`ӦM[QVQqUWaXzu8zؾ};Z>7 Н}bbVC^{\s =\ʕ+166Z}8z~Xhqg/ZP,Q(P(1t0;;F ?0`_tE˿K~nft yqeo#@.!⤱.i1e-NCOti%W{DZ;]v.B^<n .p 8 kA^ y}sgq?1ܲzXwz8#tR|O~N; Z )tⓟ$:0ğٟSOfggS^c``7n?|\}Xt)q,_333J;vދ=\p.\wu(J)ܹs'}YJ%t:mSVAJgs},Zfp[oΝ;˖-CZug#U011C)qexpw40B>/&9̐rkP yf֮]w}NGU/<fƊ+wqo݄M6K.?il޼LOOc||V“O>~^{-wkW^~xꩧO;?utt6l#3%R42/ oߊ͛7C… QTߏ}J)_>@k_֭[q~>`=_}8: +|I\yxf^^#<38<,X Vd`o|'^~+bb)%6u}v,[ ###8h(W+8#qWcx6Tz &.cП͋&*t?P\:7_H~z>pI'cvjZCAH݅2' Wx]zWc3cڵ_s9>(122SV]pVX v]k߳"uvocl b|̌(!񬇿~;{R{~7 >Ϡ\.ht˗X,"c׽j\}V… Zf5"BƎ;RJ׾Z cOVR\`nnN?gr+נ=7+X{]3ӓh̵~Z<̓B3zP9tT A$ C >gY{s4}Q.ÚM0zx~wdXv LoCQ1F2SRe'''E; ~G/| htuafl߾}qgfffR.|X7>}^hbHŎ6WI[)I8. QibUH&KRQM"64YTir+y ͳ 5<L~gbչbN3[Vhf=B⋑xۘ<;|?#""6 ~{' #HJQoJBdнBh6!!{ s:˵5ANds=Zw#s &#yl^8I_9XAj F۴6hUB!rLǟЙ|$u(2@n#(F P/X U̴u e4q_{{ ^l[]Lb+EPPFPhB2 AiJ*KIowoj}^^Kv|n} ڛ^P+ d^P%|lΡPA|JŶGiC'D `Vs ZPUX̡(m4 C#;߰b?B%sD ,$n^ܧL$\3r1O(r$x^ؾy-9tOB)H֑ Y@dF%ukb!ngy~ H?QvvͲ\{ IDATn&le2?˧;#9@"dB }5ހo_ 9'AHl":H@%݈ @B+ 8@*T%wPNzn/[g5o­7ΟCfzBBw^ZrWLV/Kc-2߸̹ڗU\+"  #LjJkA|ӭxs֎[B[䠶 bQceA ZTR}c?s9EX)ewo$;6SeL#MkrChH^hV2jntw A>t}4TSZk (ϙZnWzB5R30Tx̂n-7M=hD87=QiyHqz&`FYLMBÉ~71hqD[MYqߎ8r̕^T\FZSẏAW5bEZSOy0# ?F4k$kF4 *MC%f YA#F9hGk #HE)+[^Ke0?4Ijָ8V'NoR vUp) )\md[:&Oh;RQ/5@B8lz?p2w9ħ9pYJit)g1o"W׾ PN`:+U=W,܋@[}2iO|¢_>h5il1y2pi~,HFt Hc ,,,!Ppс|h 78DTߨ l_[ӷ8 }>cȲ^8#AW:M9,4E1wރzh'\UR(4sX7v?@dg Jf8G 0(U&>@B.^ဌ3b?MuCFІύ(Ns J# G^{ث#C"meެXj8NT]lOiR㰟Èz0YkZk}k 0eO‘#SG|>]/V JzI0~ETE5BY=vD4ټ-imzn=;y򴙫LJf\'k)ZwR@)|fUHU=!gbb Ǚd||i<_5@* m)o9iimB4 $M;V|AН.?}pA2?:(`9VX#0ON"CP=oyz5 :izdJ IvJ}oO-pozȄ+,6qTQJS5u"wcpA RShT>zUM:c=D4m9ej/ilrr^׸)bH?T?fNMMY\\X[he|9-^RVē+hD F*;]d)KUh!pw܆m0I95VqEᴞtkCG>Btc0=b&E\S֢.9U!: hޑFGF3a`5Ԗ.;G9pSSSeaa}ݻև#_{?)Zqzr)nVv[Vmqm?8)LcccO|.7JE)`em]etQ'E@U,Q\Y";e:TV[[)DaHkŵR%մAI]^k{UeA! r!uu cka+2f y1h7@JSO=_ϻn;fl55.;Nbn֚Xuӳ,7lqqNi뮻+ c!y%VVV8NAP)U z)^|EY2݆=6 RP‚q!H ٹ#0O;E.5ᐲ,ɲ^W?xQkߵZU =ǵhZub,>ӖFXmB&K 9϶XYYV7ZYanщMF0@~mƍٰar [mg)k.֭[Z,kQʲdƍLLLcytY~=RJyx}Q&ֱat`޴ۡYkxƍ,//o>8^׸BR7Mn&&&&x͕uWt~Fka72 1Y">bd:Cw4+K}<ȡC_ 6 СC(o,I/K~xgCa3'>#/lN3=^ԓb jpMQUV$Зqy5=%^3<ï|;G>–-[x{ߋ@9*?^;u] \\\drj3ά{6m<=>J)~g?|3~팏S֭ٺukɈZ<~Rٳcǎq}Hӥ<VXʊ̟Ado_斸/Yq/ī c _=sˎ;X\\d||G}/ 8g͵N'hݷogy&SSS͕mТhV$j|oA \Z}8RO"M\Bxߍ:-Fo jvk_ڻn=Z^4tꩧr.袺0<~8{/r B{9~~>㌍q뭷|O|/__e0~w|ӟfll 9.2nffffBp|}cʝwɎ;kٸq#Rww :wW\^1Hi!v_2o  a%q Zû.b nJRvkxF 8=o ˂n494P8W4>0&oܸ??sչ9.2066ƕW^YrRLMMqwvԧ>E[o?#=//2z\|l۶~O7~7xW[G38 .<֯_[:~ 4gevv={† 83ٿ?^zIY~%|q)P+}'-`$v*6Rڂ׾<l޼ .%x[m7<Ȟ={xs9`P?k8p^z)rX!]/§Y!71}<)Ez}GDS@!֭xwy'~;۷ou{7o<qr}Wz4}BSbBZB*If-(T>Z7U #B^vnnQ$btÆ \~|_]z( :]YYon`vvQKM0etJ{FolpRrq.2>7|3{ǩb] !:9=KKK<3<㫺={i=\f־T9!)Ŭ?n@JՋhR0v"̦Mx׻^N; ϻ033CQ5P#ci1.te 3xq\j=F :Q&m~02slj3=s)b>:77==K='D4nUyY/Np qݻ;!_W8ؼyg^7 :<[mcp8N,:kܨ(R'/"::~O~ʯʪ~Ce|_eݻ6'ѣG>L9dr: ?GH.>E͇hT%gqs{9SR^ǝwɆ 8qa3B:y U=5m6MVo(CgV0==6U75Z?Eظ02{»!4PH(($"]t\pЇxG馛p1vr|nޡt RїN;ڇxÆ u#-Tcv[z: /\űz{lٲGg:[03k`: k~XB2]-PQt҄ԩ[,Q^硇'൯}-+++Ňi؜a#*s@?#O~zCh0*r4 58GTguyOOY??_z~~K/Rr7O|+-[077<bn+++ w''ٽ{7[na0/< />Hn׿uk"߅wStf11 0P#+iR*?=RZ%xWq` )SiD䉥aEQ3w}7v"sfff8|07pZV ╯|%5r#amܙ8e1D7?LmJa*#Zu~ RrTH\WT͞hfdR81&EOo|ဤܹ.fgg9s8j\mk/}K,,,066Ƶ^T!n6lИ999]OjN;4sMoìp%я~m۶qFgyy]v{UpqYU3=cһ(L+ BX@a(ER*K r9?>eA4ccob|5RvSe]w׿[ټy3_|1G׿lذ>3Y\\.cjj5!{i?%t6_Jcm*AYJ)PGrX{EVlu/)$׼kfMP{{(arY."F7F.˒믿(X\\͞={fd*r-n0pر@ rg ʸʋX^:?p#ZV@M) Vn8y f9CA zc\x+X\gX:=i8.Bt:ޅ!x-sF_O &}Һ"Unu۔)L+7,@ڝvB3G6_4 fJGFVhhmJ1𳀘Se1Fֺ@;Y}رp DΘlm|8kNptxG~GɏA9eM@ c ݦ%Q"|3W~+KȱvR5{Uʄ{_Ʋԃ!D:$-STFt᷽&fQ-bfjdž pbRо!DRyy(ML㏋T6eDk,.(,سMmrrQAqSH ҮPmEl݄pB{Sa!Hi2#}NbR`C5K)GfP8s;(T¿TGJqAmRtMFkCU@J]O3x#M&gNUڜbp[*W~N1|cJ`s¨7ғ,HSzMC=Rjҥmef T/ c yu*QSS.XYbKCm ӶSi@ f'`Cv{ /?}OP8 Z  EaK*JS6S45js+jC4U+mR#"m55ץv\##o"f\=Tù"^J[VƓ՜"bX8aD80bJi3!#' a>7E2NWj6 o@E0y|;ڝ'^Y=2!p¡~6 `XH'u2JJliPNeȫ\tD|P~y|;~Xt#Rw6\QP,lxxt9<8j Q (o0RՙDž܈{&p|SaGmbjt 1%<7MOxZTPN`Mh ldm1p 5džyJ#_ L r,bD[Wu%Y#CQ=ƙ@\Tfi<5p&JC9չ+ޔqkt0:2L^ul0Z5X-?^;bF0вZ~󇞩Ӏv Z'?([]OFtmBH_FHMrtLyni\H(M~.yH19UhmͿLL9q߮[(,Zߡ<=uJM4-n6p?}Wj8?DuiS16"eȔtSc-Z6"Ę),NCCb.6Ue*u#Kv޸ʼnӵc*MĤsۊٔ("8))%Re8:'UzXPru:ޏ8"uMo+]!=6^_\+ [hkRR{Kw*N7V})sU#aޱFJ(Ѧffl\VԅB5]tܩhڧIk&ҟ9?sݶ;hQ K "҈DivTe4$JD! N?YW IDAT(-R) 9DD& H۳[%nKk[oe"ڢQ}?Km_No~@?Qdi3cصcFu<}}k˔}"Ck;r 7.wiB)mf7GW:(U]Era%źa5H&mkl~qkAVB{+1BօmicRn5:mqzFqV5Mf/MS w:z8f~Sxh"쓶S4=`4Ӆf.ȏ ضFdv8%YE87[M>sUY s J(*21b_Zc*/m>mM@ŋKLuѮxSL2!$5gᚇu2=ʲE;vlHa 19}S|=Evr$!=ԫ-΍cJz[zixK:aAvJ6L%Np囖,TOFSFZ}8k)ߎֿga-%+.{M#Cv&@ JT(lSUU3HPaZ oJͫې6>X[C|4m7mmOZ߄M榒.q>W$hyJЪ4ZH$ݖb5=ބL9if6B*#}.fQ29᧙;;3U,gkm&5Rm|8Y( b*`''Kqk' =ض5&7q-8m5?SB|eySRD3g:aŅk>إT\=U^Ʀ\?m@d]Ӭ"|eVL&EU<ڄ7lþ#p"Fɐ6ʼT﷒ vnzPg%(94a=20x4|R64UuM[8ৡ;ŋ~^J*GNӥR=4Σțd%%Y\XOZHDݿRJ`1tq3:Yވ u]]@N Ie5Ĩ:HLc"6m21gH T#NzVf[xͭ& d:f!ϻBQ#FPې=PqM9g0s|c }qu8Ne04AJ0Q%Vu, tKXǖl!}rUƊzsdYFoDt2֯_MYa-[6딭LLLZQ <.06<>B:7kFwycs-ȽwR6m~3O=韀1-I27fo}7H !=mt&li봭Mhkױcǘoy3iTi>И˹KgZyX `|(D\ .q,%sss(c5U$*#B%&ƦXZX3v~=$/< eR8)ii4*8*ve JUdWjnW+A!de`hQG W9jqWrm4Rf`;l<+o} Kw|~.=zrX#dYAobn'/|c\y39:]߶mdbɹ .Qiҵ,ƒI l A6a5nOsڝÄ |g*duF#.kT4H[/Dl9$%E$Jw0?Oe;v8TG[') _?"s96ݸKq::cRk.RuCE9b t0SmC~[]\j#!^M:Uk-Gi:V@`-]?X`ye:ﺋ_5W?E]s8'T 4B\Zu2~[S|| 7㦽piLdG>-ɗV(kU:J,S㯳)- "-1wu-}tpӛlv֏'DQNvl%-ZX%BJY7b2bĻ"p-Nw7cW`ݐ~0׽᛿E'.?*Ȉ}68(M[H---Q4өl6ȓ`Hpzo*Uj# !݅4):!OOJ[o艉 ejjnۀGIek WJνGpi@ CZ$tNF&5]@ F9G?DzT N [*u>SwRT aRkE AttdS ʺN2 BOg~[|S|w733Bj[/n)$.Kٻ} f̰8glĖm{^cJ#ضͻ6#,\ !Eൎ`”0v؜xc(~JWb"j-޸P"8ֲ0##Š&Ȕ R\ӥkP8?UxJS 9:U=Soc3EeްO)oaN/O87kB1()5L"DɌ<3e\.ҧ2*V>e)tPRC lI:Fet&2aɔ@ Zw9XZCF1]Y=]IzA"{>%e&֟Ǧ79r"-0c˼sτ W;X#p w_ޣ阘)˙֭zqݼt-ըO٥a<\&[Ù#D_P] S:UT# JoM Cg;2BE=Y7JS7AjP +FS5m%Jx4i⎿>@g5NK:]E)rQڋ_]AU 2.3D&W{NV#i#NjNw33I:Bf rLi/tSFi )J5Y+koD<9uNy7#`=b6~3dC(%2p7@(gx8tQ+ ?<йbjr_wʯ^w۶ћŭi.PCRb\9,-Vmeɇ9jX%yY5&HelVR^o:Ч+>1U9R;F-!ȳ\R5Lp0YQHol%Q;lҬT%|}ؾ}+ve {ԕ TYR"QRyg̲CTJTM=YV%tLԳmP+A8QAN7I:Y:&:S-*~VbKJUʇA  L=oTDJW2B>WW0VVae5F^Jgr\NJ;7p?Ks}~gY~~i:6o䓰V)baG&"A u5 ?>cX+}_X"2? ϡRq6mƍ)KK9,jCCJ?"Z19r_|DXΝ;Xcee] Y*P"!e0<AL&Og!LyO tYؼag[qAKUWD)uf#eLO IQM!JxTLW0j(U4h.2\O8: *Wtn:Q"Ǹ>U>n!pH!ݬqgy+g8TPQF@#t0˺Mw>[Ǟ=ƫŠO-|e?uF>[ )88)CcF#;᰺U,edVˤԝÙnk\=:'_?ѣGYYYild<Ӹ+ذaRś駟f9/@RJ.7n/Ρ3 F(E5B Xlu1֐8~t'/:Q !*2^pr0ICGfDCst zu1J*0SEU],Bf#?Gl7ҵPX6Wlqߔ(E+13XJ #`蠻=\}B&=#+/++ <{_W:'.@`:- ܯ!€Q(%vxLJU3ԀHh]k[3~A#2H`a4++ƕߚ-K*4"{Ys\5sDvWΏAKUgeظa=|0G}gڂ$J gBa%raoz;He`,[_q9;.~ᅬӮ<FFXk+L!j},JO#P!vir='_g 9>pGjƻ *0Г<\ʙ\`LMW?s~p;x9w);]-+E:4PdOGRVrtԅ(f! [DO/@i WVصkzՕ\{5{=6McL,KWv\wuɯ.DIB~HP:G˦,8F*S+-;9 w(dFEP))%Z!J:y4g#3q<ȡgd<Yfg+a}S"&o{ȷYzqJ}C< xP?,;ݬ:GS7v\DzYΙ ѭSRq>laa={fff~,\ 7of۶m:tRm.sssϦٺu+F &ZXX`֭LNNT QZd Y'Q}@ ? UA+L)2VU/x︐1?%QYQ VɊ4(TN۲!a>f('D5P3^r9J)y1ëjj-L"[g1NURc=c )=lFÊ-Y^:rH?΋k_Pڒ++jsJ-8K)XU@g$BGjҖ AekF=`XOf u㜲iw^=V)ȝ]e84%H"gfWLG{Y}S (>W>λRcjr %o l1$#ʓDs!ޞ ĉ7k%?~?!$[2~=x^"D1l?oݧk "5;p6S6t0p66oT9u%V:z=jm3LIUJ5~iNWk(1} *^-5Gj|1 m&NX6XS*kKM S߷X_K}[#.Ñ֢mBu6 cc*#_/|8v4Ն[};R|oz};}ɚ;s:o'}^ۿMqK};iFo};R|Nn'}N߷GO}{ o'7 )ny:]};v"߷`oAOs"߷~u:[V !Fok }߼E5r2QUHADH]2öTV\VP!ۆ 杖r'ʢ6,==70\jH9%~dkRyC )ێ!m-Et&X0H㣮u%Vڍ(r7§oDJQ3Onj7fV9W~[߷2 -Wɠ uX{.y>OXFG<}t J:#X5D ̆[UwYhUia/dYư(j0 Xt)bu -h |2-0BQMYhF v 0"HsNyh$PGG)pΘ>U}{y4Ծo\|ߞ<};/߷/<|v28}$]䦁 g N|Nnj7Z}ߌI#V[9~O<GkD|"߷W}߶mͫꟵ|!T|7IrP>Qeb˓2K-t 7\:qR"KЙ*pڏfwV`lg}P}dll<_h?GOþ>6׹'gnuq-j(W+gOipݶv`S0vD{ /fqc @_P/{ogYU݋>[U]3 4C〠 C@1mxѨA4" i#OŨD#F^`7C35 M5w:~s-!`_?~ùZ]*E[n( w|5urvKm@z4\q9>I|Y`)!uxauqtI>od~n( `DCoQ zN3~Ʌ.%:cFUg4£cpmJظb0Nn铏"()&D À%K}~x&0Qy }{,\NVm8JtD(dczn&ԃލ)o@7sC冿Aa Qxx.}F,?ҟ,1cćt N+>_⟁d\a|+fߣcGo BB@ C0=Y OAxEI{N^>9^N@3BN7< eܩodb~zC{⛯Y mʓõKE8yoC1i.?db$ p8g}F\M8y_x8?翌K=n=h<.ׯ?&Gj5j5TU,,,hZVVVm7Ȋ[ZR鞵2VXtԺkrB̜aXbX+T*Qʥ.J%J%twwT.PDwg68x>?5ZUY-F__8wߋAcԹA1??$I0?Jyժ LNNb2zy4 wJuTk n vck"3fA!PO^v"A Y.\MàJA30uCq n QCAK+KkVHS"\f3NڎuTF(vD wtA(t7Dww7:u7fvVߣjmӐ"=55Qb~~Zݧ0 Qubxx{,9W{[ͫ080z{{r* -ÒZ.twP.PY`||'F1=iAZ4:*J)%R"zS &4 :Ba6L{OER%F۝)uqNdgOB9Г ؄a&'b$ZOҼ+L%$RjBJ1I1D"NH%I4I1Xg3B> zBsщ=}(&/*D=XdaP@gW N@8N177'099 LOObjzs:'^W|婧oa4?ɿ~zqCo*,_1+aIUFF022ݻwcrrs+*A#֧! b!DџΒo'](hrb R4C,rz&J2Kf|%{!y"Ry9~sz( m|fv'H&y;4_즌sWA6b}}vsPzMK3& GH6d"N6jPRI@@!@ BJ%uJCgY{+W`Ū5(K:AGGRH:rۋQ޵fgFE'K?AIW¿:h_KJ =~޽{={1>ss ,"O:9BWWե (N\* @%Ƈt2@ZS$gPlXjz.G-v[!0!:%!(RhkQn6,Q/q(<%f -{=}#0dRB1Dkh@& XEq"I4ӫA ҥXz!",T}#xx;#Xoshܺ 'xj0}a;pww`td/$ATBOOJGgg',D__)bC jr2VT7 B)q$K4ob{PdSLAfЛվ@zn7hXR 5z X6 c%ٟ'6lR2a1rRJ0ɼJy7 =|Jz=x,SW!ʂ%1n"ⅇ5.ݍ-܍AV駟._D@d|77~oz%!|:[W@ww7Ţ>9-I'ݩ %=R 5~EZ<]rsc !8S"eo@8ObmOe&Y8.l"ϰ@Rυ1c wADD,“O>{&Fwaltr9n/3 ?p o !I$ok_^^6n܈#:+V@XD$il&%Sav!bp`Usꙕ6CLr ? I=T}#VZN>2ycNTH P/U'Hz|yl҄kmxlDY()0a% ˘vd:9N?2w\4Hf=f V+akARJabr ccc(Dxщ'<K[ߋ yYxGFwu 9O00XmWkǫ^u֮]r'⤊jԸfP7{Ct@P@\W鄦͛N9pKq7Qg҄ ov1?B(!mRȖ0Y&S\EτL㐷9m~dK}_\g,}O4$DHsrP]zF5"?T^y>6̓y6)/OnW$Mb06>#qa_ӌmo}z7 K?~JO?cٙyPD c]g+Gf^Zcbo@ 59 CdNoΓ؍n˅g/ʋ]HgZKfވyf8yɛZHaf+8@% W`mmvm{C .xn={:055$֖ϐސeR.%\.u4 !j0?$#Cn!Df|P@!ʌ@"]|ޤ@ e7gj,uH(3TvP Kl0%5 IDATPtwx)XBbI \08S S()@( ݽL._1Qڻ)IBek8)kZTt{K|YPǣ=7lŠFAW ^擟x^w8_4.}8E/B:B, uKPXY/qԞ✏yu 56aj?r oD>&O (sP$ eKRfeP C:XY|DHLĐJԃ$LA;tkYC1! g(u9~ Ũ $nBD$zYOV !L9 >Czd]`HB?(8ƛ7o} N*صkq埣h38~{?|=kɉiĩt xyaFT@ L׆0tt y>K< F\mX`o0~cXoppJxPz~] (ـ`΀$ ( ^'|Å{*FlȤcj~$=odʾyEF=J"EA qtX)AR)?8q15`^ @Hpֈ2ץ`R{`fz⸣Ow>_/FwOq٧{x'qch &&d "0BđI 2IKs8/.j&Y-$~ (ڡk`d(s; "8ѡ9-*zz,S=_ Hob@ ϔNZ(H* @Ln%#e@O !CHb aƐKRJST5, 'f:Ddzb` L@ aB{Di#I`"ubRarrj "X jy: H=]*0APaC.LNNcӦÎĎ'Bؾ};^ҍol4O*ow^7 c|ScL$( HeC CH5?TNfWZh+἗5f| "c{aP5C4~rΝ; jͽV tk!M5?Ia`BX^~DIˆD*DCI  Hu @3"AHGH^)% e԰>i)$n iIp )k3 RաRW-Ovx4@b~X|9J.w( D!4%ȢF:L1ZHb]ǟXr%@T–{zof4r ⎻#pk,>zXrLNOkrEzXdciЅJW{kD~'xŬ"W[2[~B-y`y 9t19ZN> ,9e4D@C0t˘D&Q,v"D :z r/ׇ)ɤ2F@T(@)ʥ.N܋4 ,P5P 095J)K^|2;4R5EC; D눫PIա^a2D]V&4&dZB,wlK'P2c`X,Bd3AXǯ ( I=SM!&աrbPB":FBP¦ Q kZָs߀BA l{z;C16>->&_L>`QE솄lSr])4+dI[6h,D{![OhF$tD2! Ccw_bLLLA\cU:JK+133^p v؁5k֠VkZ[ڿ3Xf%&puًeˆPoTӉq`hh &&pbjj x&'14g2j211N49 ,-[)tRG'(0??~Lc!ٽ07? (t3+PU z^@P@ubVF5@ Ih9bJŐI )硒 X*kZ FT[ZqGbnf **_P@'ފ J% B49<9= OLYo{7⤆V/;c!lڴm5||_.\.0119fm, ί--eh7g&e9frlNm8-59Y6ľ چh.W(u'J1zzzCKQO߿̌>AqRDze'1 D'R~4+1z DO  !c,_z+VAwnoo$IbJñb*Tk5ӱI`N! ™IdH ȩD B8AExOA@MbFA|*-$;:%B ?H;`,0+l[Ԭ A@P$PT5+P̐2Z5f 2` #0DQ4 䍀..43/G-)R33SÊU+Ӄzz\CX B1 h::5B)tvì}slX4\SK ]h/D{Gb D_WSKNo=uQ([;q"M f.)Z\~彙N)A0ra )yLY{iZM`uR_gq&JSFKi4H!S@I $IzRTߩCq te; 'ǔ6M9n@ M k@R+u53% Bg@#_mbA &! *4.ZRM@+xtCT*\!aR#wCT,ه!CUڄk'%:eL'aػwtnf8N=4q!#a~aPC 'PFh) H\E,4/93BcSזcPa }yI.ʲJ&n-R'zM_ ?`tt|@V&0I8z0G;[ܣDXSY=غ]v9a I0ijRsl_>9Kfs JIŲlAslBH2i P ϝB(%AԿ4m[nX  Qdc @XHR:eewg(n &`d^M! PSttFH5 9Hi:67;-P)Kr9k׵MפitKn,4Éܖl[IWmY U`[Ml00 NM H{PG/ʆ!yo(k?P:fF3Ei-Uh[290,s,'庖a,N$Boo/(i2غu+Dө<{&,&;mS_iEB2ML|D(훟̭CHr=#CG7YH.dP snt;ѷͅv1cNT>ɡjw'T֍TSY[Ih]4Z2/u5Ä'--ڪ6ba9!(YΡ Z 5תr9ỵJykOp^ANk'mJ>Ru0 kx~g%yu$"s!:Fk_f I {S-ڳ*FTB^GTB_pT.133;DQ1Z Z] bzEr],RHYƱrgMI-$M43 {`dM"]T335df՘ay!IZm]PARm"[vdttH<2Ri2|II^GԖVƞ?T<sODިT*^oD1va+055%(JNvrd~m,\۰nBdVP˒CnUɪ*!'R(ڍ_?ȈS XC܆`Uq2P]ql2H,Y NE{Y=Bփ5F(ئ9/AmP^WAf'@ݘmP}aXJ*gC{\%r4Њp0Lx, ANWEųJN4F\oa(<5 ˼j oIҤQz"u396CNPGEWVҕ2MEpбS}tB3lTa>hU>"͚r!Zhė)((Rm~d@.Dk+2$hyLn:욾;͊Xֻ5τa>C9eN%FzqTU$Ir(}Lh]`oK׷SOLۋ})%,s-nO2kn([A=O$58jCN*:l֘7^Yx(ESxD^.jϘe_є;ahYcBƉS·(N B𶙽ke5"Zk7?8I(0k4ztV{/&4Zkߌf,s!g(|ũGȸDgq0[a)'>:.DCbFH)'X@66͙0ydsԨ~6'6HJsHAXI< S05^7=X!5 gBPP `K"m&:<<34O0aX01mZ4Un(]Q V'|)Β>/tC9؏MxEvaSx)tJklVWN :#lg)yrdZu5j MsVPV&P:9&r%ZdPKYRNS߳Di[eOs̮~Y lEfOǦS[d6i˂/qL5H@y_cF`!sEPgbcf/)A0`)j( tTVf7UĠdM4Uf0,dS񬩿EYuO)-^]qҏCR&$r-Sָw?xWZdX%;VN(ϗ[ܶL Y2) ސ4CmNӣq$툷ڶٜf,[\"|#R巵+ۑ6T(v1R4 j =gQ0bvԊЃE5X?D2!=U +̈́B+ IDATGj4`nnY6_ДkϤpE« Óbl2^nҢ{ CYA ,&Sڑ:ͣu"mpk8@/K3!dԹsu't^@"XmbAXv?g_$C: εK (k1@p0t$ AN!CSҟBm]MS^?)f ̡N)0fI7pJ2G-v%48t}6D?τ*6aE,o_&/ȌO3K*M  ,]8~geYh(tv et\3۝%ra}_hJSS^5% B1bi"MSۗ=NY!,ƞg"AnaE7?%4$)r )jrE1+^Ӭ rtZɜ!^&YCu+r漴|mNE$zn&ے!,E{s2 I'F$Vy{o ᷶'-4M4D[ x'X6,`R֟%n+.,<~2^Y^(f23">1M͋|]x fR B+x#3Cna5SC4k yS S]16ೇ2-D"bR^{w VqM=;bCL ~dRZ0[фYhFcU>$&&,YNHB҄1Smcn#y3C(htQxH=A?gQMuI%rj06 ! awDhj&RsLr >H!9db㍅+T16Vt%{VNJ4KS!HlJN{˽\Ed``dZFeΆ*pAr!qh !9Cm'Q=2Cq/LTІgs f8es51KcLd^dVڐRez +|~@_1nOdJl4!OFNNC:*2;2m w=OYbs譛Q9$ <*:k 2R^'^x3["HVό1 :zs jd+f!<{F'3yr3\0JÿVx8rRnJz`T,H4ݺl2ge ^Jʕ ^?f[(7}DS"i*-8+)Ȥ0 3 F[5|t -)BN {JM"69Xk܆C+>W[=;ӌ NzUpd,8'8T,;2ZhUh@Fj:b l]&2("_;Pw~fYYf+6w‹o+e 96-)J%}Vjsp;^G`L;i%I\ UB/LY+JF ѐq+ؠ -ߐDZ"ڱcR8_pm")&M c663M+iw(:N./k @ $o4%r-D(ٍeCm@) Qz5kL*,lAr_$cCE+7~X0Qд|%YNC hJ UNCwý@1rtw^G.WnZ[=%Ee|,{3./j]і8aH†^8m?a!Ӆ#EDQ6aXDF'%c1x9v|67dn ],֥֪ۉj_Kyqj8+;g~nZ' 1orEC-r0.Ech)!@fJD(ˈݐ抛,Ҥ46*3#da #[Amp@S!lus6a wG ky~xDgr3[@k׮}[y^XD.Y "LMMa޽~Cfngj]=¶BGD-h]( ,sPTޛ/^g>`f`LNNbjjeusU J?ߖQ֭W_I~gy&vEX.|_ny9眃'xwu>{s)zFT<Gq>~qUW{-[{ ذa.\{׼Ih`Ν?3<Xb?||k_s=XDž^YwyOSx " | _֭[|s `||_җgϞ}b~3P֚2FD =leXr8Sf/ǝwމguV^M6qI'__g?;8<>[npᇣ\.N3T* 6oތxކq\tEсkׂzj ? ,8g?{ fggo===H`ڵ/} 8ՅO?8{/]j6l p}a˖-8묳jժ/xqu/K|/K4 Y&6mڄz;w1>>{VVZ~ V.wr)X~=6mڄ(|rq/͛qyKi>FqKi aeiQ~+*1*4;^Gy$[nFtMX~=n݊: }{1<N;Y_7ko~s݋uC8 'RĈx+_{wݍz+B|}x׻ޅqu|_ǿ" CJ% ===q7k^:?ƍ1::nQaWؽ{7>㵯}-6l؀j]V^ Q.Q*1* 077p뭷b``?yl۶ wO4|Iw=/=e^kCC=ְE0 }<ظqPΎ:(<|%\?1*ر{.8tA8q '`||wy':::w^LMM3e˖a˖-q 7ϑЬϣ8#h4p 7?=Pcdd$wuJ_x8 4Y.877NڥNoŗer!x188r]voGWW8 vmK޲>55qDQFZRRzMsn^%Kۿu]G} ؼy3`Ŋn/AKbVDdVϡ 3I4@ROmFlQ25yNZn x;pM7 .Gqo|#C[qn O<˝ЇcVOƮ]~袋pW_">Oaݻ̘>?ONNbbbk׮ڵkqwb``Gy$8vܾ};/gq&&&pOC,Y۶ms1>>u'? ~\xعs'>Ckz'Q(җ˗/ʕ+j*VX۷k_=7׊/A P( fΝ;[P LNNbxx8ÜWabbW^yg0~ O2&X+։ zȞku>էG?. oS|ɘ,R~FS(@/|O׷Tzvk}ͺ,>_O;/tf[C;1NLdBT鑈uEmuC 7s2)Bѵp@A9oNk}SRϺ-zr\+]lj}n snwXkiQF_kgaܭ}M+گSSKZV{-5n#H–j7ni+#/:V5z$mC6m?! r(H1`48FI @:b8c bN+ if4$ $^B8v77h_f;kk~! a&4r./9C- "~{7T`46>^/nٰ|ݦrm&_~;d6n 3z{{>޷vU}cε˾O0kbK>6CI%mAkB#h>/JiJ*S)QJPPRl %s|Zs>9ko*q7(YBp* =2*!&yjt*>r7: 8hE&O X{#D[D*,z~hxxJ/|nw"i6 v*:b~TXKņ6A4'*6_k]XfyeAG@Q-O9Qu\ޮ*K^%,U. VE`/^?(=:~hX2C[{g9JG9:둇RSNm0j,CA;Q9%3/!NqttQ]:bd0A iP;X׏"⢼ '4 ͺO]/U:Xp+,P6?r^fC.y< U2rjyW׋~t*_<0tӘQ=o i? B Iςs)<.!+wmrpBy,l߹)(%BXהRKg(꜐UuTp(~ CRhRe6D]責*+U$k)EҡX5閩zR'tafl|@d}:H̟ۯ.n}Oқh$|s#!-WsG!9(D8zgunIpUUbM?ϑq,`ix0.JwUr5&Ja6h&&d{c*S=~AE7?|l?ǵy&?B'S5M|ejDNy@$=:WG9m,=.N׸O'NKȩvt9o9 ^=_)V5kw]4Ba^T2Dgp/fEMsᩧl63X2\9}ի=~aF%F'ϓ題2/O<7i:)zd] X2XpWAh<;ƘD,A2Li8%>%cݵTqXJzY&S$M`/²s]ass>,oZTUd#l64OWfbhZȇi]vӧ|Qu;78l J |G%Oφ\NJ;95vx>J} VO;$Eѧ! K`28%1֌k^UZE- cǎg?q|;c糗NyNgJ:.Eʐ8l*NC{hիIu1- ' 3jQ/5?P3z :-^gr%8*ԱAbޗtͫu>JƮJ~_Gݴ [F{p@gRۊݔmOO<N8MӠ Yi8ri$VÙ]ס<!F/>NfNtp/>IϬky2%d;VctCuYXՠt&tDt ΐFuUR앃B֥s>2'I9{%|>B<bd ro.\?a|ӟO?o9lxgB^'N˹r (k],90?+WӧOɓXVx饗|nZ=+L&8yd%w].u IDAT fʴCٔ64Bk5NrM:j4|Ӎ̑BۗzLlBכ%#ݪZXm\n =+%#QƳ >uH \׊A(=re׾7 qM7+_ A3aXMcǎ}/×|MӀp]wᥗ^ٳgʑ#G`ss3ψ| _39}?f֗ԧ>/~x` _kx'!>}wLX| 8{,//`VrȈ#{B: D0(Xb$Ay XLsj:(Q$"4ԑ _v:r |jr&OS&>e|@>['$%Y{\WvccO<>_.]n x'3*"=ooo7|3s=̙3򗿜ӲIUgRГ$ #DO_5='Od1MqԩS[qiuk=xi=ٳgq tÍ׽.Teڶ{dߥdX>5?d o2R&&P:עs B5|= ;BaJp"Bes=3g`:?sz\/hi@UUh&.ַ /Y}6!,KrzsΡi8۬k-%wy'Ν;~.\Çs"Z4Mn r / kFIdѮ]C)Yt} LL%Kz} JYf%Nw HM/.KjޠFeC3eO/?ߌ7fS3PpWZ6 EKm|ŋÓO>g~&+\t ?/⡇§>)\pa>Hwesa:-w W:)QJ𰄼K(_ ciH\G{^Ҡz4D/):vOsQgS a٦ת |9/ \xu'x"{u}yw!\zLҶ-\𹳯_1r5j^(r~@`cя~w§?i<8zh? k?ıc/9wUU 09VA-=^^)(8pRh9lIi4 nOGTGT? k>@uzLNE>!٨|W3x?l4#<ƅ?'Nuڹmkk =1I:Lpbs烦{2Z*sBފn '˿Q;Au]|+8s ;(5@qf(!m2 E3#J#C=/{S >H6sm66rȔRn6Wdip)e,$טeu]}\-`()lzQ?) ޓws|[B]xߜй!kpwOd/˅d:rz+N:b[n/BN8;\ 2&FRiaoo*ڶ#Ūp!| _6w`gggTPL>h/=/fI!*y1PצstUseкfȦi-W @l̲,v {-:ZUl>V+iʔcZG~7 tHl&7GŻ.vm7O~_:u Gţ>~87Ϟ= wvvvж-nyg?o|Nh/^׏0WU|u]k-Ξ=#G;nX,pw}Fګ\(ӧuo 3ƠkKC^zHϕz4C25$9hK)p{NzȤ]LNi-x-Z%@9VCw@Y|\6,\s X2u{4yϽYx>n\xu>{7x#VU|H>?s?7^kjk,u]ߏM, x\.q|&vev{ƭ72He0ggj5J t4\L!1/g;Ppn$\7 (f1ց=z\&5R|ZHhX&zbѴ.OM{ f~soFsqmij&k۶8|0?+W.>`\b:oߎ3鳺n zۀy˜jObWo1??d溭V+ass?3?Aӵh &2TAds#FrR@ @U d(ҳj/@iIö:H uDg(,j_SJ o4zyhd#Xd1g!HFqڠ\TA£3e\`K. Fi9ꔼϓ[,hfD(DǺ9]@N?awwwQ5AtS2" t賵64%B;D$45k*pPOރ>["zFE)N`Mr˫aԁ9fil3F4ri SJ~u]#8_4BBr1dO= 4̱e$QtxRK97bEH*Dڱ.#QPm%Ηf4 娻DdJɡ 눬jJjA G21ql6cA ^"4 iBx*6~ +Hgv?ij\iAN{RkR{%՗=^yX痨RDFT=/rhM_ZAGIt4#QiF,'8f4J 6gm?;PZU{#/Arm܀BK8;Er#pQ{tM;F9!Sk-Z Bn)MCTu$8q,H`\# 0HRP8ppiO2%6$,eI)GsJ#g-lPUFxB]' #Y &|!z4<$Z{%k?1}#!yWv4SFIY/ juNԄ:-G5O; ϑFFPFK}ﻔΖR\EOAːSNYLfO DžpWCL/sÑF"2e9X 3&zLYs\,z&m䑤}qDmWH( ("@%uu?EíI;Bk(x0j_JԪO)s=.Dߙ.k)^%u)r+[Ag:3԰ qx"xBzfC#,%q7yxuZi%UualZ)AIFVgt3Z^. GI:i.i8khY7U S4\vUHbI0(9=#:LrÇ𝧟KQ$eaf B`M /q_Y1h!8 8-TumZRNyFL PːUXelZst6Xm$& x9b6hG(4K^F(%uw鎴FJ3H FѮkSZ!ؒF:>- ;oAaЅ:Y;P(qSiZKJ쒨v !n}$U ` h YZIFe)4Hcȍm|~ TF FK]L7(%ҳK]-s{.}:PZ>I5c됳lJ^J%j)umrJ#VX? 9Qr#TX[)\\JE<hiu[LidDhS!t $stB%vkm0>tmnXKʈNQ }h(q₥4qFk*`5CZ9@&`:'z5pǘ*)oFسhf>, ]KFR>B bمx5ynN@KK :fçQײ'7):s&EjUڗ#k/ ۮsp%GPBrV%] t4Te:M@D c-a:9Z$iRtkeaSI4Nva Md&=2*ygfPs>T0)HJlRήc)/XZSzz=Z#\wnt/)vfKLu>ՙd$_*lZ0>c%QtOsZm&ZCj'_`X̕X*Jr !h@})d`HM^cϑ z#='Б8t8x˛qC񨳄DY% 1㔪xAl|wY@.!-9okԘg <7mow! t>|n`k[̪ `N&kZEl2:q=<7@zA?N0L +l סt]l6-ry1;PL_qq\wuxpQ\ Y7Z,D,4.QV΅AN!8`DjDpiF~L :prStd.ƺᓢ#*A#%kNGLv2QiDnnLtնJI8TX`6Ԥ?~/9iP*sMء? N= w8<,|P̗[Ma3(mmA^P{=H/ &)Y['gԩ/pN]tn4OAn h8Up# B2V{ip5)Şր 05.A=.a*_A^i*D@d.P+G,6"> D>| (|%ì%F!^*}:t@:[[]=66fpƠ{jf|wqPYG}}gkx kt{мŌߊ_~M`>cX`Z 8 ʤUdхXO4zzX皌:x`B.r5{ʠTYT`ZaP7zr)K7'VAGG=Dz@Cel^)MUpߣQl; oʢ;;;XctJhI ;Q*IDATuuC+Q uMӥVUR C N%m^go$1 Cf;v6 j-K#Id>bkܿ2b :t2 Km1+stfT5Mu'c{3"] DzGv)2L&py#Eݤn?7Hͪ4K6B@6GII+(e5>4E k'\4\t8ylw}<ҤIbo#ejfk}c i8X!V_8TO1@Ba,5C.F0GT).>?7*#4wY ƋC3NuNW~cЉх-2)"LmWϞh^x;x|Ѐ8ڏR0kf>0sn@JV;Nu;cr.A X..,;-PV La q 5A pʦjM"R1qi3F!h]IۊgW0䆠DpFpc0^׍ECaWbsTpt:r&#jl#R?,)?h¤RɉcQ9[=~%ÍQFł)ɶOw!V|IPFt}_tulPL㈲t(!j[ {NzXkT ]Ybtuӹ3OhO,en`9 Aմl9"T7C,K] m,G `~S.9{qKR| Tͭ9MzmG=g\Ae 7ѰS2&OfI),qSd d 0J^YZvb0(61 ĒroQQHu3k[V OoɰK|)77p-E@V`ψ,,cRR?lX`(ϰ"ҚQ>BlpҒĨ@A*hHF!*#b*5蒦) \yLm[Ee´l($6 1mC&C9u5\S!DPqƚ%*&Oh֡ȶH7u~0NZ||L:?0a45 HbaA!;Hm"Wh"Q2K<:kJ" g4-_Ui4 POIy !Ri\Q0imbȃ-X,{IN* TH6T` vX3R?qޣJeb,#X53CqvQ7_k5~c:Ɔ/y"YL "!#H9:"*>b0cHQ&qRtaD5a1*gkQFh@(5LFwZ;"?>Ghc,ل_BWBӼk>aj+P #c2 h1%跪*4]}Ӝ ?R"Srؠ}ҋ#nkml#bAn]lll 7mڶm0{ӧOo0o3+qT 9pJDDiPvzcSke `LYbMZRjG@3ԂMN[*?֢9uLN>f2vpQ-CHgJjK6& Y瑐obsmBrh?rԏZT`ؐrzO΁qA\ҳH!km*gr+)LHÐ*}i p2{w\|d$  i$q(jձ=/X%Pe2m!9z'hFd\cf|A}bjR;t^d,N`ʻYCMb{t.d/.*81W*z_ .G!,`RI{clzZ_ld"%#873"ֶ-ꉅu5!̭Vz qDB\'zV`}~y T aPKIe%F|mt&p/E CQ/rD5 42{P& 9 Hjy~z&0|,PF &s}vHJ9>=t +tQe3__`CTrqޟ|臔Taw a݌jtt|E*}.AfD*@G&#\[1!Byg)apGcԲߓx-.5uAҳ\uC"[u`c!샃ol^K]ޅ=&*:"T5&ԋJZ_@ѳ657{lU崄5|PM,i4<Hr# GlB\l! Hl[w=4)[&T@hQgz*nT5I;@@()|kbiFlt1E0@?~EѹI@[S!$)mvX*섴/p "٬:t]R+eF@޵?չrZ @U4%`=Zנ89,o^`-j~@6'ZӅH wF/? ;;;ؚ4-&s?f6͹U;ӭ1'GZCQY,1NV49y7PLc1ϵ 1yeLS$1nڅ6IiƈP}2"+dlXQ116yg#WJrz+k0+ E鄘ZOR}A6rlMi欂=Ye|ܾGdah/u \f p[@?|FZ*MX&)R5OqۀBx?BKf&FuDVmD<66x{ߍO7϶uC<o>n ?=T3\s5pX7Ξnćo~ॗ_D?W?'2SYsGyDؽd:\ZrK֠25<~5PM? 9i>-8~86 9po^ $L?NK{"7`<@3ńxV0LvNgfM#G)<`K|#~#O>N|oon^T't?}Bۺ@-ܧ6K"zw.^??לć?a*ͬn -*Mly?Zo!ǫGZVIFJs9?fҸ?<#k:ϫyj4yOv;ljϸf=hڌ^ocؐQ oZ;(=ϥZ6e`pҲ&Rl*g[ =RėlW~?ϱcСCtu??fAC<Lx\ U(*tY (6u&õSZ`Be1G%8E5ϝ|VlHeQD 2*s2 L(UT|bhW6+RF$"lKu1S@ <:j4y)7?\ϓ+y~~{gx~y^~繺C'IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Toggles.qml0000644000015301777760000000436612321005637031003 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "togglesTemplate" TemplateSection { title: "Checkbox" className: "CheckBox" TemplateRow { title: i18n.tr("Unchecked") CheckBox { objectName: "checkbox_unchecked" } } TemplateRow { title: i18n.tr("Checked") CheckBox { objectName: "checkbox_checked" checked: true } } TemplateRow { title: i18n.tr("Disabled") CheckBox { objectName: "checkbox_disabled_unchecked" enabled: false } CheckBox { objectName: "checkbox_disabled_checked" enabled: false checked: true } } } TemplateSection { title: "Switch" className: "Switch" TemplateRow { title: i18n.tr("Unchecked") Switch { objectName: "switch_unchecked" } } TemplateRow { title: i18n.tr("Checked") Switch { objectName: "switch_checked" checked: true } } TemplateRow { title: i18n.tr("Disabled") Switch { objectName: "switch_disabled_unchecked" enabled: false } Switch { objectName: "switch_disabled_checked" enabled: false checked: true } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/gallery0000755000015301777760000000017112321005637030237 0ustar pbusernogroup00000000000000#!/bin/bash SCRIPT_DIRECTORY=`dirname $0` /usr/lib/*/qt5/bin/qmlscene $@ $SCRIPT_DIRECTORY/ubuntu-ui-toolkit-gallery.qml ././@LongLink0000000000000000000000000000016200000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qmlprojectubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-galle0000644000015301777760000000126412321005637033303 0ustar pbusernogroup00000000000000/* File generated by Qt Creator (with Ubuntu Plugin), version 2.7.0 */ import QmlProject 1.1 Project { mainFile: "ubuntu-ui-toolkit-gallery.qml" /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." } JavaScriptFiles { directory: "." } ImageFiles { directory: "." } Files { filter: "*.desktop" } Files { directory: "html" filter: "*" } Files { directory: "debian" filter: "*" } /* List of plugin directories passed to QML runtime */ importPaths: [ "." ,"/usr/bin","/usr/lib/i386-linux-gnu/qt5/qml" ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/call@30.png0000644000015301777760000000342112321005637030537 0ustar pbusernogroup00000000000000PNG  IHDRZZ8AsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATxkU]}ԈʓZB$b)TvY م052B-JWKI] `e+4eRfv9^R#[33̜w}g~_ϳ=y9ɓdO /FW Q]! +Dat]j}_ޒTS޵կOsD̳q @v6,1ShSG,%dɪvvTmpoϨڱQu}@s\bDھ2yr)0/Jx)vDNڑ["%CG (3!FSЩW]smMI5h虢CA 2T Qӵ ";U0v*pjFǀE˽#S F`~K折qEˁ[J& 5nOJDNv/"k<5i_ĸ A00,V#5uZVf?=i 5f],8JM1kS45e4 ;i1יR3F';|A#1U;u}a{dH`S񾐮J!'ܯxA'`LCՎǫ>/81g* S\D2Z՞Gǩ÷hϿ_?-϶E30.N!b5Z^|$*A`=C GEqR"hU[72U,"7ZށGaZ[qb70^lj@",hzL^ &CᰊEC#"fy{R\( !PǫFT C1?}](j3񶄵ۘr;2Q ɇa&1+xL֡j=4"8 ,^1f|wQlܔcنyCW$Z3 ߃wȲ4j;2߰⽎za06"d5ra: Qxgt!/ƖRՕJDV*U0BFW /.SKjIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Pickers.qml0000644000015301777760000001552112321005637030772 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Template { objectName: "pickersTemplate" id: root TemplateSection { className: "Picker" documentation: "qml-ubuntu-components-pickers0-picker.html" TemplateRow { title: i18n.tr("Linear") Picker { circular: false model: ["Line1", "Line2", "Line3", "Line4", "Line5", "Line6", "Line7", "Line8", "Line9", "Line10"] delegate: PickerDelegate { Label { text: modelData anchors.fill: parent verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } } onSelectedIndexChanged: print("index=" + selectedIndex) } } TemplateRow { title: i18n.tr("Circular") Picker { delegate: PickerDelegate { Label { text: modelData anchors.fill: parent verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } } onSelectedIndexChanged: print("index=" + selectedIndex) Component.onCompleted: { var stack = []; for (var i = 0; i < 100; i++) { stack.push("Line " + i); } model = stack; selectedIndex = 3; } } } TemplateRow { title: i18n.tr("Infinite") Picker { id: picker model: ListModel {} circular: false delegate: PickerDelegate { Label { text: modelData anchors.fill: parent verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } Component.onCompleted: { if (index === (picker.model.count - 1)) picker.expandModel() } } function expandModel() { for (var i = 0; i < 50; i++) { picker.model.append({"blob": "Line " + picker.model.count}); } } Component.onCompleted: { for (var i = 0; i < 100; i++) model.append({"blob" : "Line " + i}) } } } } TemplateSection { className: "Dialer" documentation: "qml-ubuntu-components-pickers0-dialer.html" TemplateRow { title: i18n.tr("Clock") Dialer { size: units.gu(20) handSpace: units.gu(4) minimumValue: 0 maximumValue: 60 DialerHand { id: hour hand.toCenterItem: true value: new Date().getHours() * 5 } DialerHand { id: minute value: new Date().getMinutes() } DialerHand { id: second value: new Date().getSeconds() } centerContent: [ Label { id: hourLabel anchors.centerIn: parent } ] onHandUpdated: { hourLabel.text = Math.round(hour.value / 5) + ":" + Math.round(minute.value) + ":" + Math.round(second.value); } } } TemplateRow { title: i18n.tr("Overlay") Dialer { size: units.gu(20) handSpace: units.gu(4) DialerHand { id: selector hand.visible: false value: 311 Rectangle { anchors.centerIn: parent width: height height: units.gu(3) radius: width / 2 color: Theme.palette.normal.background antialiasing: true Label { text: Math.round(selector.value) anchors.centerIn: parent } } } centerContent: [ Label { id: handText anchors.centerIn: parent } ] onHandUpdated: handText.text = Math.round(hand.value); } } } TemplateSection { className: "DatePicker" documentation: "qml-ubuntu-components-pickers0-datepicker.html" TemplateRow { title: "Date" DatePicker { // make sure we have the whole component in screen width: Math.min(root.width - units.gu(16), units.gu(40)) onDateChanged: print("picked date="+Qt.formatDate(date, "yyyy/MMMM/dd")) } } TemplateRow { title: "Month" DatePicker { mode: "Years|Months" // make sure we have the whole component in screen width: Math.min(root.width - units.gu(16), units.gu(40)) onDateChanged: print("picked month="+Qt.formatDate(date, "yyyy/MMMM")) } } TemplateRow { title: "Time" DatePicker { mode: "Hours|Minutes|Seconds" date: new Date() // make sure we have the whole component in screen width: Math.min(root.width - units.gu(16), units.gu(40)) onDateChanged: print("picked time="+Qt.formatTime(date, "hh:mm:ss")) } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Navigation.qml0000644000015301777760000000362512321005637031473 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "navigationTemplate" Label { anchors.left: parent.left anchors.right: parent.right text: "In Ubuntu we use three predominant navigation structures:" + "
- flat
- contextual
- deep" wrapMode: Text.WordWrap textFormat: Text.RichText font.weight: Font.Light } TemplateSectionNavigation { title: "Tabs (flat)" className: "Tabs" description: "Use them to switch between views of equal importance." designUrl: "http://design.ubuntu.com/apps/building-blocks/tabs" screenshot: "nav_tabs.png" } TemplateSectionNavigation { title: "Expansion (contextual)" documentation: "" description: "Use this to show more content" designUrl: "http://design.ubuntu.com/apps/building-blocks/expansion" screenshot: "nav_expansion.png" } TemplateSectionNavigation { title: "Page stack (deep)" className: "PageStack" description: "Use this to move from a main page to a secondary page." designUrl: "http://design.ubuntu.com/apps/building-blocks/page-stack" screenshot: "nav_pagestack.png" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/call_icon@8.png0000644000015301777760000000267112321005637031502 0ustar pbusernogroup00000000000000PNG  IHDR;mGtEXtSoftwareAdobe ImageReadyqe<fiTXtXML:com.adobe.xmp =IDATxbLLJa n@l@7w6//`G1ZADXdP$C899͐EYYYH2D_EE$CDDE># 8:ؿ M!"W`nnEIɩI2x?˗/@6;BB+4߂8g#LMgE3oP܉$C@P%!xxxѣ{891 惼\+FFF IN~~@@ NG@  aff~*b!P幹:qq IIpdgPPPv4h(CIHHtlظI$ˋ@ **(.A6HJJ'1!GX :]E,rBϟ?#Ο #gϞsվ |!Hqp b&PL"}phIENDB`././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.desktopubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-galle0000644000015301777760000000066312321005637033305 0ustar pbusernogroup00000000000000[Desktop Entry] Name=Ubuntu UI Toolkit Gallery Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml Terminal=false Type=Application X-Ubuntu-Touch=true X-Ubuntu-Gettext-Domain=ubuntu-ui-toolkit-gallery # Added Icon and Path as a workaround for http://pad.lv/1227359. # TODO remove them once that bug is fixed. --elopio - 2013-09-18 Icon=Not important Path=Not important ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/TemplateSectionNavigation.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/TemplateSectionNavigati0000644000015301777760000000351512321005637033365 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Column { id: templateSection spacing: units.gu(3) width: parent.width property string className property string title: className property string documentation: "qml-ubuntu-components0-%1.html".arg(className.toLowerCase()) property string description property url designUrl property string screenshot Label { id: label text: templateSection.title fontSize: "large" anchors.left: parent.left } WebLink { id: docLink property string prefix: "/usr/share/ubuntu-ui-toolkit/doc/html/" label: title ? "API Documentation" : "%1 API Documentation".arg(className) url: prefix + documentation visible: documentation != "" fontSize: "small" opacity: 0.3 anchors.left: parent.left } WebLink { label: "Design guidelines" url: templateSection.designUrl fontSize: "small" opacity: 0.3 anchors.left: parent.left } Image { fillMode: Image.PreserveAspectFit source: templateSection.screenshot anchors.left: parent.left anchors.right: parent.right } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Animations.qml0000644000015301777760000001433112321005637031472 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "animationsTemplate" TemplateSection { title: i18n.tr("NumberAnimation") className: "UbuntuNumberAnimation" TemplateRow { title: i18n.tr("Standard") Item { width: units.gu(14) height: units.gu(14) AnimationCircle { radius: units.gu(6) anchors.centerIn: parent SequentialAnimation on radius { loops: Animation.Infinite PauseAnimation { duration: 1000 } UbuntuNumberAnimation { from: units.gu(6) to: units.gu(12) } UbuntuNumberAnimation { from: units.gu(12) to: units.gu(6) } } } } } } TemplateSection { title: i18n.tr("Standard Durations") className: "UbuntuAnimation" TemplateRow { title: i18n.tr("Snap") Repeater { id: repeaterSnap model: 6 AnimationCircle { radius: units.gu(2) SequentialAnimation on color { PauseAnimation { duration: index * UbuntuAnimation.SnapDuration } SequentialAnimation { loops: Animation.Infinite ColorAnimation { from: "#dd4814" to: "#ddcc14" duration: UbuntuAnimation.SnapDuration } PauseAnimation { duration: repeaterSnap.count * UbuntuAnimation.SnapDuration } ColorAnimation { from: "#ddcc14" to: "#dd4814" duration: UbuntuAnimation.SnapDuration } PauseAnimation { duration: repeaterSnap.count * UbuntuAnimation.SnapDuration } } } } } } TemplateRow { title: i18n.tr("Fast") Repeater { id: repeaterFast model: 2 AnimationCircle { radius: units.gu(11) SequentialAnimation on color { PauseAnimation { duration: index * UbuntuAnimation.FastDuration } SequentialAnimation { loops: Animation.Infinite ColorAnimation { from: "#dd4814" to: "#ddcc14" duration: UbuntuAnimation.SnapDuration } PauseAnimation { duration: repeaterFast.count * UbuntuAnimation.FastDuration } ColorAnimation { from: "#ddcc14" to: "#dd4814" duration: UbuntuAnimation.SnapDuration } PauseAnimation { duration: repeaterFast.count * UbuntuAnimation.FastDuration } } } } } } TemplateRow { title: i18n.tr("Slow") AnimationCircle { radius: units.gu(12) SequentialAnimation on x { loops: Animation.Infinite PauseAnimation { duration: 1000 } UbuntuNumberAnimation { from: 0 to: units.gu(12) duration: UbuntuAnimation.SlowDuration } PauseAnimation { duration: 300 } PropertyAction { value: 0 } } } } TemplateRow { title: i18n.tr("Sleepy") Item { width: units.gu(10) height: units.gu(42) AnimationCircle { radius: units.gu(22) SequentialAnimation on y { loops: Animation.Infinite PauseAnimation { duration: 1000 } UbuntuNumberAnimation { from: 0 to: units.gu(20) duration: UbuntuAnimation.SleepyDuration } PauseAnimation { duration: 300 } PropertyAction { value: 0 } } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/po/0000755000015301777760000000000012321006415027264 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/po/po.pro0000644000015301777760000000114412321005637030431 0ustar pbusernogroup00000000000000TEMPLATE = subdirs MO_FILES = $$system(ls *.po) install_mo_commands = for(po_file, MO_FILES) { mo_file = $$replace(po_file,.po,.mo) system(msgfmt $$po_file -o $$mo_file) mo_name = $$replace(mo_file,.mo,) mo_targetpath = $(INSTALL_ROOT)/usr/share/locale/$${mo_name}/LC_MESSAGES mo_target = $${mo_targetpath}/ubuntu-ui-toolkit-gallery.mo !isEmpty(install_mo_commands): install_mo_commands += && install_mo_commands += test -d $$mo_targetpath || mkdir -p $$mo_targetpath install_mo_commands += && cp $$mo_file $$mo_target } install.commands = $$install_mo_commands QMAKE_EXTRA_TARGETS += install ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/po/nl.po0000644000015301777760000001054512321005637030247 0ustar pbusernogroup00000000000000msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Tim Peeters \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "Activity Indicator" msgstr "Activiteitsindicator" msgid "Basic" msgstr "Basis" msgid "Button" msgstr "Knop" msgid "Buttons" msgstr "Knoppen" msgid "Call" msgstr "Bellen" msgid "Captions and Dividers" msgstr "Bijschriften en verdelers" msgid "Check Box" msgstr "Selectievakje" msgid "Checked" msgstr "Aangevinkt" msgid "Colors" msgstr "Kleuren" msgid "Content" msgstr "Inhoud" msgid "Controls" msgstr "Controls" msgid "Custom icon" msgstr "Aangepast icoon" msgid "Date Picker" msgstr "Datum kiezer" msgid "Default" msgstr "Standaard" msgid "Disabled" msgstr "Uitgeschakeld" msgid "Expanded" msgstr "Uitgebreid" msgid "External page" msgstr "Externe pagina" msgid "First page" msgstr "Eerste pagina" msgid "Grid View" msgstr "Rasterweergave" msgid "Grouped List" msgstr "Gegroepeerde lijst" msgid "Icon" msgstr "Icoon" msgid "Idle" msgstr "Inactief" msgid "It also works well with icons and progression." msgstr "Het werkt ook goed met icoontjes en voortgang." msgid "Item" msgstr "Item" msgid "Known" msgstr "Bekend" msgid "Label" msgstr "Label" msgid "Large button clicked" msgstr "Grote knop geklikt" msgid "List Items" msgstr "Lijstitems" msgid "Live" msgstr "Live" msgid "Mixed" msgstr "Gemengd" msgid "Multiple lines" msgstr "Meerdere regels" msgid "Multiple values" msgstr "Meerdere waardes" msgid "My custom page" msgstr "Mijn aangepaste pagina" msgid "On Screen Keyboard" msgstr "On-screen toetsenbord" msgid "Overlaid" msgstr "Bedekt" msgid "Page one" msgstr "Pagina een" msgid "Page Stack" msgstr "Page Stack" msgid "Page two (external)" msgstr "Pagina twee (extern)" msgid "Password" msgstr "Wachtwoord" msgid "password echo on editing" msgstr "wachtwoord weergeven tijdens bewerken" msgid "password with echo" msgstr "wachtwoord met weergave" msgid "Popovers" msgstr "Popovers" msgid "Progress Bar" msgstr "Voortgangsbalk" msgid "Progression" msgstr "Voortgang" msgid "Red rectangle" msgstr "Rode rechthoek" msgid "Root page" msgstr "Root pagina" msgid "Root page (again)" msgstr "Root pagina (opnieuw)" msgid "sample text" msgstr "voorbeeldtekst" msgid "Scalability" msgstr "Schaalbaarheid" msgid "Scrollbar" msgstr "Scrollbar" msgid "Secondary label" msgstr "Secundaire label" msgid "Selected" msgstr "Geselecteerd" msgid "Sheets & Dialogues" msgstr "Sheets en dialogen" msgid "Show" msgstr "Weergeven" msgid "simple text field" msgstr "eenvoudig tekstveld" msgid "Single control" msgstr "Enkele control" msgid "Single value" msgstr "Enkele waarde" msgid "Slider" msgstr "Schuif" msgid "Split" msgstr "Splitsing" msgid "Standard" msgstr "Standaard" msgid "Subtitled" msgstr "Ondertiteld" msgid "Switch" msgstr "Schakelaar" msgid "Tab" msgstr "Tab" msgid "Tabs" msgstr "Tabbladen" msgid "Tabs (Non Segmented)" msgstr "Tabbladen (niet gesegmenteerd)" msgid "Tabs (Segmented)" msgstr "Tabbladen (gesegmenteerd)" msgid "Text Input" msgstr "Tekst invoer" msgid "" "This is a multi-line subText.\n" "Up to 5 lines are supported." msgstr "" "Dit is een subText van meerdere regels.\n" "Maximaal 5 regels worden ondersteund." msgid "This is an external page." msgstr "Dit is een externe pagina." msgid "This is the first tab." msgstr "Dit is de eerste tab." msgid "This is the second tab." msgstr "Dit is de tweede tab." msgid "Time Picker" msgstr "Tijd kiezer" msgid "Toolbars" msgstr "Werkbalken" msgid "Types of list items" msgstr "Types lijst items" msgid "type to show clear button" msgstr "typen om de wis-knop weer te geven" msgid "Unchecked" msgstr "Uitgevinkt" msgid "Unknown" msgstr "Onbekend" msgid "Value" msgstr "Waarde" msgid "Value selector" msgstr "Waarde keuzeschakelaar" msgid "Value selectors" msgstr "Waarde keuzeschakelaars" msgid "Parsley" msgstr "Peterselie" msgid "fruit" msgstr "fruit" msgid "Orange" msgstr "Sinaasappel" msgid "Apple" msgstr "Appel" msgid "Tomato" msgstr "Tomaat" msgid "veg" msgstr "Groente" msgid "Carrot" msgstr "Wortel" msgid "Potato" msgstr "Aardappel" msgid "Hide" msgstr "Verbergen" #, fuzzy msgid "'value' is %1" msgstr "waarde is %1" #, fuzzy #~ msgid "Value slector" #~ msgstr "Waarde keuzeschakelaars" ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/po/componentshowcase.potubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/po/componentshowcase.po0000644000015301777760000000541512321005637033375 0ustar pbusernogroup00000000000000msgid "Activity Indicator" msgstr "" msgid "Basic" msgstr "" msgid "Button" msgstr "" msgid "Buttons" msgstr "" msgid "Call" msgstr "" msgid "Captions and Dividers" msgstr "" msgid "Check Box" msgstr "" msgid "Checked" msgstr "" msgid "Colors" msgstr "" msgid "Content" msgstr "" msgid "Controls" msgstr "" msgid "Custom icon" msgstr "" msgid "Date Picker" msgstr "" msgid "Default" msgstr "" msgid "Disabled" msgstr "" msgid "Expanded" msgstr "" msgid "External page" msgstr "" msgid "First page" msgstr "" msgid "Grid View" msgstr "" msgid "Grouped List" msgstr "" msgid "Icon" msgstr "" msgid "Idle" msgstr "" msgid "It also works well with icons and progression." msgstr "" msgid "Item" msgstr "" msgid "Known" msgstr "" msgid "Label" msgstr "" msgid "Large button clicked" msgstr "" msgid "List Items" msgstr "" msgid "Live" msgstr "" msgid "Mixed" msgstr "" msgid "Multiple lines" msgstr "" msgid "Multiple values" msgstr "" msgid "My custom page" msgstr "" msgid "On Screen Keyboard" msgstr "" msgid "Overlaid" msgstr "" msgid "Page one" msgstr "" msgid "Page Stack" msgstr "" msgid "Page two (external)" msgstr "" msgid "Password" msgstr "" msgid "password echo on editing" msgstr "" msgid "password with echo" msgstr "" msgid "Popovers" msgstr "" msgid "Progress Bar" msgstr "" msgid "Progression" msgstr "" msgid "Red rectangle" msgstr "" msgid "Root page" msgstr "" msgid "Root page (again)" msgstr "" msgid "sample text" msgstr "" msgid "Scalability" msgstr "" msgid "Scrollbar" msgstr "" msgid "Secondary label" msgstr "" msgid "Selected" msgstr "" msgid "Sheets & Dialogues" msgstr "" msgid "Show" msgstr "" msgid "simple text field" msgstr "" msgid "Single control" msgstr "" msgid "Single value" msgstr "" msgid "Slider" msgstr "" msgid "Split" msgstr "" msgid "Standard" msgstr "" msgid "Subtitled" msgstr "" msgid "Switch" msgstr "" msgid "Tab" msgstr "" msgid "Tabs" msgstr "" msgid "Tabs (Non Segmented)" msgstr "" msgid "Tabs (Segmented)" msgstr "" msgid "Text Input" msgstr "" msgid "This is a multi-line subText.\nUp to 5 lines are supported." msgstr "" msgid "This is an external page." msgstr "" msgid "This is the first tab." msgstr "" msgid "This is the second tab." msgstr "" msgid "Time Picker" msgstr "" msgid "Toolbars" msgstr "" msgid "Types of list items" msgstr "" msgid "type to show clear button" msgstr "" msgid "Unchecked" msgstr "" msgid "Unknown" msgstr "" msgid "Value" msgstr "" msgid "Value selector" msgstr "" msgid "Value selectors" msgstr "" msgid "Parsley" msgstr "" msgid "fruit" msgstr "" msgid "Orange" msgstr "" msgid "Apple" msgstr "" msgid "Tomato" msgstr "" msgid "veg" msgstr "" msgid "Carrot" msgstr "" msgid "Potato" msgstr "" msgid "Hide" msgstr "" msgid "'value' is %1" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/po/hu.po0000644000015301777760000001045412321005637030251 0ustar pbusernogroup00000000000000msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Tim Peeters \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Activity Indicator" msgstr "Akitvitás Jelző" msgid "Basic" msgstr "Alapvető" msgid "Button" msgstr "Gomb" msgid "Buttons" msgstr "Gombok" msgid "Call" msgstr "Hívás" msgid "Captions and Dividers" msgstr "Feliratok és Választóvonalak" msgid "Check Box" msgstr "Jelölő négyzet" msgid "Checked" msgstr "Kipipálva" msgid "Colors" msgstr "Színek" msgid "Content" msgstr "Tartalom" msgid "Controls" msgstr "Vezérlő" msgid "Custom icon" msgstr "Egyedi ikon" msgid "Date Picker" msgstr "Dátum Választó" msgid "Default" msgstr "Alapértelmezett" msgid "Disabled" msgstr "Letiltva" msgid "Expanded" msgstr "Kiterjesztett" msgid "External page" msgstr "Külső oldal" msgid "First page" msgstr "Első oldal" msgid "Grid View" msgstr "Rács Nézet" msgid "Grouped List" msgstr "Csoportosított Lista" msgid "Icon" msgstr "Ikon" msgid "Idle" msgstr "Üresjárat" msgid "It also works well with icons and progression." msgstr "Jól működik Ikonokkal és Progresszióval" msgid "Item" msgstr "Elem" msgid "Known" msgstr "Ismert" msgid "Label" msgstr "Cimke" msgid "Large button clicked" msgstr "Nagy gombra klikkelve" msgid "List Items" msgstr "Lista Elem" msgid "Live" msgstr "Élő" msgid "Mixed" msgstr "Vegyes" msgid "Multiple lines" msgstr "Több sor" msgid "Multiple values" msgstr "Több érték" msgid "My custom page" msgstr "Egyéni oldalam" msgid "On Screen Keyboard" msgstr "Billentyűzet" msgid "Overlaid" msgstr "Lefedett" msgid "Page one" msgstr "Első oldal" msgid "Page Stack" msgstr "Oldal Halom" msgid "Page two (external)" msgstr "Második oldal (külső)" msgid "Password" msgstr "Jelszó" msgid "password echo on editing" msgstr "Jelszó kiírása szerkesztéskor" msgid "password with echo" msgstr "Jelszó kiírása" msgid "Popovers" msgstr "Előugrók" msgid "Progress Bar" msgstr "Folyamat jelző" msgid "Progression" msgstr "Előrehaladás" msgid "Red rectangle" msgstr "Piros téglalap" msgid "Root page" msgstr "Kezdő oldal" msgid "Root page (again)" msgstr "Kezdő oldal (ismét)" msgid "sample text" msgstr "minta szöveg" msgid "Scalability" msgstr "Skálázhatóság" msgid "Scrollbar" msgstr "Gördülő sáv" msgid "Secondary label" msgstr "Másodlagos címke" msgid "Selected" msgstr "Kiválasztott" msgid "Sheets & Dialogues" msgstr "Táblázatok és Dialógusok" msgid "Show" msgstr "Megmutat" msgid "simple text field" msgstr "egyszerű szöveges mező" msgid "Single control" msgstr "Egyedüli vezérlő" msgid "Single value" msgstr "Egyedüli érték" msgid "Slider" msgstr "Csúszó" msgid "Split" msgstr "Választó" msgid "Standard" msgstr "Szabványos" msgid "Subtitled" msgstr "Feliratozott" msgid "Switch" msgstr "Kapcsoló" msgid "Tab" msgstr "Fül" msgid "Tabs" msgstr "Fülek" msgid "Tabs (Non Segmented)" msgstr "Fülek (Nem osztott)" msgid "Tabs (Segmented)" msgstr "Fülek (Osztott)" msgid "Text Input" msgstr "Szöveg Bevitel" msgid "" "This is a multi-line subText.\n" "Up to 5 lines are supported." msgstr "" "Ez egy több-soros subText.\n" "Legfeljebb 5 sor engedélyezett." msgid "This is an external page." msgstr "Ez egy külső oldal." msgid "This is the first tab." msgstr "Ez az első fül" msgid "This is the second tab." msgstr "Ez a második fül" msgid "Time Picker" msgstr "Időpont kiválasztó" msgid "Toolbars" msgstr "Eszközök" msgid "Types of list items" msgstr "Lista elemek típusai" msgid "type to show clear button" msgstr "gépeljen a törlő gomb megjelenítéséhez" msgid "Unchecked" msgstr "Bejelöletlen" msgid "Unknown" msgstr "Ismeretlen" msgid "Value" msgstr "Érték" msgid "Value selector" msgstr "Értékválasztó" msgid "Value selectors" msgstr "Értékválasztók" msgid "Parsley" msgstr "Petrezselyem" msgid "fruit" msgstr "gyümölcs" msgid "Orange" msgstr "Narancs" msgid "Apple" msgstr "Alma" msgid "Tomato" msgstr "Paradicsom" msgid "veg" msgstr "zöldség" msgid "Carrot" msgstr "Répa" msgid "Potato" msgstr "Pityóka" msgid "Hide" msgstr "Elrejt" #, fuzzy msgid "'value' is %1" msgstr "az érték %1" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Buttons.qml0000644000015301777760000000416412321005637031031 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "buttonsTemplate" TemplateSection { className: "Button" TemplateRow { title: i18n.tr("Standard") Button { objectName: "button_text" text: i18n.tr("Call") } } TemplateRow { title: i18n.tr("Color") Button { objectName: "button_color" text: i18n.tr("Call") color: UbuntuColors.warmGrey } } TemplateRow { title: i18n.tr("Icon") Button { objectName: "button_iconsource" iconSource: "call.png" } } TemplateRow { title: i18n.tr("Icon+Text") Button { objectName: "button_iconsource_right_text" width: units.gu(10) text: i18n.tr("Call") iconSource: "call.png" iconPosition: "right" } Button { objectName: "button_iconsource_left_text" width: units.gu(10) text: i18n.tr("Call") iconSource: "call.png" } } TemplateRow { title: i18n.tr("Disabled") Button { objectName: "button_text_disabled" text: i18n.tr("Call") enabled: false } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/nav_pagestack@8.png0000644000015301777760000050001612321005637032361 0ustar pbusernogroup00000000000000PNG  IHDR"bKGD pHYs  tIME9$% IDATxԽi]Wu%iӦ$8F@N`~׹GΝB _?Mco  `ʿGzK`>OYس,77\Uy2j-Ewݻ96Hy]ٟ/Zrz1QP pJ OjHAJ PJ!s,Cv A k0^w?_w#{}l=Ozw |}^u eiE IxM2glRӻ<Ϳ˿}0M&y.0\re1o-*SB5)0Ƃ0ZTVcs%T IC Zk7qѠ!IcjΌ1*d{;pi:lP^U L ^Eyprl>~;pù_ƃ=`Md rU^vccfgg~.hoהGrV{oeGȏG(!<8P'Xs|`C޿y%>o!M*!0F#2C7?O_{-['AJ%K+ ./f-P rz wM}M1\(g!l~^HYcnn333}oMqT\V:h.v;"`W!\t?͇= # 0_!70kKC3e g`ݶ@%A7á;k1o*.k[~C) IaxLcaрT.Q̢"hC+.^4==>ޚj5jI"nZ HB$jȲ; Xa'?o}[w>? jfK{wمZ믻|#}/}v}33sR4җ {go ҕ+W>hZm;bgk lbғ- N:rQRSA^Dޤ*r"HRÃpZxXÃQ]y] a 61KPpA0BB0h MTZ ŤEjCAl4̱^5M4 ReȲ e<|*TU4M<$EGa2 ^nԫE('ﳳg<ロ׿w[w;g=^T[gO?8zJ cxl_ݷvj) 3H@JoI>M1(",{( Iq-E6~<{$ԃFT-*3)+e18epseF0 XEX ( hY?`~7}D R@07$>HmI%0X<9&Lṳ̌TJVc3Zi*$\I0n֨M-X,c+҄w] sH)166^`g8+.Z׽w\ b-w}Rn7ps֭[o|JĎ93'9äXh C SQi!yC ˻z[2{^2/ ȳE6?7'Εq崜8$"iraVSC4^z#C0t8EK9>sK5Yо& ڄ};KeQDKV *d䤴`%QP `sV;"@`q&#0̅&a$N@s%K-'YrtfjI!brI^jRmXbPTxV$Ru.3eZ1JFyJ)giZc:̜?q~'@ ^ ;wr9Z|mcϙ`}aDn[|eU?:\w[߄} Ⱥho:t\ Ksa,4 `ԸfB5x1@UU眵󸬀l0~Ƌő:2 G*vƣp]"0Tޛ&E0 abXfE @덙$9B̑[%rҨMHk ]?DBFsbbv 6^(j{Y?IDՓ4MƔ1%j!H@ J8N(euiJ AFpa? j7&On'6ʇV{y.n*zo4`? f}iFDjd6Ćz3#!h,"2HQz42[!Le>ӵp#$(i:<# A ϧ3 w06 BPS Sj-ϥL*+D@ft^nH%~Ž6uFA4@Rj})8`ՠJ))2R+F0ժSZ~`-O>wgkw ڒJ$BuXw\%iQZR EN|穛s3Ǒ,6T߀b9L"ħKlGy|2! ]fnN[~|;яje+?pq0H-ؖ3@i"P`Ec`;pZ;-X-6D"ȕ5QQ>9>xj R=F " /wx6!u JH%r[|o] *uqP4 )$ 2 R!X-:2Ov[t5QO؜B kj K@1l%ILjV$s&*_> "L^^ RjZIAPF!U )4>@s3 _]_Uwo]I_~ J}dߡE{eޗz[GKi=ͯzў-(3N|$\^{D9zyR;юj It]TUdYgd1K$ ڝ (0R!SsPB`*&n333;8u߳Dֽ,H Z51# @%*y̳b'Ѩn \h̝:9ӜyF#x\ 0\*0}㻟i9@)*{O|irlrx9ehXkܤ&2J Q B[ 5,]4Mo߹`vI]=\N([D.)-+w{) aRx(.4Kq Q9oU #qU̪с_© ވkF~a`ŪhMbX|9Zcch6V!jŋ2 PJQ5$ZH :kB X4= /^ij X /7ֿ? na0M j{ ˕doܧryY1EYaY2ҴY8vY}d^ef~.QTmwpQ`GAj}{) 搊RJ8y8Sv`ص}&63k֘ư<@&k':GO@ #XR*2KlN\b"1(gB:~HP2@F I ՙ$Iʨ&E Ok 5 jka/Y Wۿ#]b+؄8.E9>s=S0>MS0P 3cT" *ʀ Zl"S> Q2JZ+nQ4P^[-(:SPTgp~XK|@f9)C!^d&%*PX ~n6c9825}#Ml ̝tNoLۨ*+%V8]3hXk+`B F,^ngeXvxW!$XpD9n/׿Z瞻xi0hdaZP#aogoen0`KHE"FCS>0"(\ f s( vwr9]w]J N eRfTV#@'3DښOI@ fI9^s#"ItڧKM71erSr`U"d:*W<FN8 Ma@NȥeJ)pKX+)bDA rIz'Nņ][+&s0yB >g~o~ӀPi[ 2xMhI3`8ݠڲ4xvk\ t+E¸KQ !^ DDa \iys C&n"R'.RJ0FY0YgpuO I@I=RwN=*g}h6k}݅:K/sZ5%ETV,k_zp_C Ǟ_&9,PeTXb]jıtZ PPZ-乺7 7@,PrLsYd'`⢆Jj4Bt pV/ XE<~yU A1KRy22A.EL~JaX `RP&qf$,ERrXD @&J6`)LfNp@%.sIg-k3,fslx/I"DKY",RPΙ@$Tg$M*QΨRf}itR.y/c#WC{c/zō27ˡrB%ێH8hFv{ .C*ޅ5SpVo˻W;7;⳽ڛЮc@@z')H)Ajx=`ACGd⌚;a l"xXgȆd{SZdF:D/\B@cXljR(p pS,WF^\d^UZ 193C{99r՝ǔI I)baBuT(x mKyϑg~,hp*N"c IDATIV)GEFKgTyYc< NXXf!a q=nKdU!-5VZ@[@#@W2Bp*A A^ ::<cZk(EeUViMi#i#q26^mK'(QWʀ,V-!/-3gn133䬳ΆAށy7E~Y/6uY5*#+7&-LyfKŖ3  0 Q` dצJϙk YPE¥Su%" sr',ٿ hgθi?.,.@+8TF6?4|%Hٗ\ѝmwaFDP P*WFɨ%%R5ssTˬB J)8'2chB(a%,C1@@lkCk m-*n\ @߰  $^bҼn=?~}s69g 1hI.bnqP!.KldUѲdUzVT9-mNapoqs?rnx:Nk4M^ Y?ne ;pR(w|!λ(Q__uze3PƜf.@S}{j@rE-&oMNNCA)lU1 řȞ3jRBcZc˃ug6*n1 8kUV;gH EG* wkt)l践t+QH8 Cbp(ftt]Zў:b0t}GXgϗzӀbdjJ B\ז$H*MRVjj-K`s& <6FR 0Z{~1#ҺxIqF;(:~:  U7, N9r~X`:d Vˤ$Gp|I@  64irep0xg]dH0kc%[pAii4Dz )=nt 202p bm2oe_ J<~O L)Z 0J(1Vfِ,<Ȟxõ9Z_z7]KM@&w $\[k-ĠO/EO}>ދ>՟EE1T%ڧF0WF"Yp|;o#xϬېp&ԃfH"lcA@() Aɱla5 ZkUԂu2(-%(Y P`!t̸32Oj,s(~ּvc{p)xe 0er kXL^7.A^ Cj@"2 J8sUQ!=&([x?@^z$}Sdž\T *3PEA-vzA%*BILCJЁDU$ȳ6g(u kGXRIJi Cd Z cɳ,(2՗mn(|p2k*jKJ|r""yhm}kf|(;k0y9g_ib݀O6|J$Қw3 $J WOAm|zwRClфn{I]-y}a(Oќyi2xs-HFaN&_װQf%{.3bcEM"py\Zv+BD=מ,<6;yR&IU$() @Fc3V*jZUgȰ3frw)bpcZ*F7$[e5.Q%2H`iіWPc`Kf0FaL#>ȼYɹ +4VyphB'J KVQ2!o%!A ]EDŒeAo<7hK ߏ&Ɉ` j/E9‘/ދlZ؜N\{udu_3?AH$I1^,rHWk56&"jU&URr^NpwKK]GR&1!87>{FXa%`<adr5@ZdRt'Vbzm4̈́A I رzÙx`msr1 L&8l t1"96YT~%fKX"u<8 _ :X۶4+eZoBg?V4^/t KIQ9o~cg=uXr dw m[(Ú=@'N8jXDѸH@x&ȝ;w8TSg=4<.Nw B{ Ļ'<3w~s@|M: OE6/t̡ONNN2,_ >zS>@_>Y(Y GNxO?_O8x2 ;,PQT]A -=$VZEaE)g>2f<Ϗ|`Jy](K4N]p8Uw7dX^c VZ=t:hZزe >Ak4Mq7nG _BZ-<8r."<eWnkk֬ƍ1;;Ç㬳B8tO=1Moz.]9@VC'> ́1;SZԩS† 0;;ZhV\5k`rrO=*݋n /___F^/1Zp\ׯ_i`ٲeQq!|EJªUm6.M7݄%+|7pCq\p ,^f\s 9|xW/~1~w~R8qj|+l2,]7p7WXl^Wþ!%#+^${Zk.]2p9(l@LVȸq嗣g>ꫯ|Fe8s033ZVc z<ꪫ066&&& ĥ^ظq#6oތ[nUW]ǏX3'FAիW?M6ᩧ~l߾{/ك4Mq1,fff/~?8:>ࡇRE[&ر> /_ 6`rr{.y€/XhsNٳ6mž={?Ūyk%\Ǐc޽M6կ~5}Q8qb^g-]{*-Ek-n˻ϊ={˖yӾg:Nj &9CugMͮ',zٳ<n6}ݸ{j0;;[h^G=#lZ73Cz:5p++3 ,@p a(2= F13Ú>oz-`Ώ0Uޞs7v21J.#71_jbFJݘU IDATyoqe%܎dPdh~!+\8vލCHׯNJ+%b x x*Zk$I2onX1vq 4}q`{|'Tl1'(*O$W Lh05W`塠9} C@YPO &2Pbᆗ,J ևE%KR.0\py&''|Ї}v:u [n=܃v]jpcݻw _8j;J2bj*Z{1|sCX=(Hj0x' .0g {k=Rj ×pD* I|mbOa5pNI$%*#wŊ53]rmmۣýnu,Sew ۿ+Zky#G@7 ̛o@=k)J4)2,TkqKu[eVx'b'>k׮'DT#<4MQp}1bm 㓟$كz O>$~;v>'|ۿ,..\.c{{x衇Evލ~AX^^F?Z@B]GZ/aƧv!}>φRi@($Nds/}"9+NT+#3hauIJwp6!VWWQTPVE͖>ܹs_u _VWWO㡇c {,c8s .]˗/C]we8t2Z>+_ 066o?o4cX__GZ=܃vJ_~sڵ 0&y$$w24kϝnJ ]ĵ~h<0~6ar3JXKw͈WR8zv?+gU6tRF\T*Hn5x*VVVckk f1=z.las{K###v|".ӟ?ZpmpqQZnL눢V <{{8{,}QLMMa{{;|ESP!&w};CV a.+|kpbI=I5N`b;cݕݗ JetP Rd Vvi1G JeA^6VVV0>>]KaW2FsTU\z_ױk.|=c_n6ϵ>&H3Q9)}T*̊q?)bu'V)~f2'I;?."➯߳BJE…Nz$ShC(7LO}uXRP'WUnϼA۱c.s3_w7/ K6KC\#I|)~$?w ?kD5PMn3@<!$w~s'|WO J5d)gyY~W_Fc1̍ajj˲KMPp10.e%C;vkkZr 9:!V!cavZ)%%Z-t] [t,=c AeT*٤ETBݶ׵z.֝&ͤy>Oss8S|D=)ao~q|k&7LtƎ)L;wM#p4[x່! RMF#2>>VeDOt F:>8m&&InkWsαiWe nd&ɦ$ܴ[pAFþ\m0nˈs'Ҡ{M?ul*NRһ3%r: _Zg7*TrPBgEUI!)˄CC ޼X[T64ZwtKv ܔi+x7(q rs؏ndvYzu#~?48k >ZR`n8m}j(mw0(7zy*gWBnmmGJQΒkL2WZһcn p*J:ݧ!V FTP,9˹,>7`.εHn.n0[-n~vʇqcU[u4C<&>[jsa\IOP` j 3˰8oɯ."Y(k}%@ĿynkyXX,DQA1VnZivc%X%MvXe;i'uX%RPBiکjus:|mnw]EC(Г97z1Vh#Mv(J#bqj-JQMIӴaf9_*Fjݿy7MӶ,i k4KQ;_+|jnT*3nw݌yB0h4MӴ;44t`kkyF4M;zjuZz]s JihfLjRZBVRЌ_$@1nq!7y஻OM\@췙r7>>O.ϭ |Oᬠ~JyV2sr8kO|8uTȢ>c7' {EkX%$yWx1Я؝~/]dk>_3pReȌN= [[d(L~gtE\סk(i˞zu#;i>:Ǚ#|vq>'-cx^>?$}GEmR׉9sA^7:9G\}>9<+S|3.ku @uꎳHq;޳9W2;;[r߭٢k{?rЪ2E{:M CCEEyF٧B=z$"gggggg^׋z8??'z8;;[s;?? ϟb1|3tgonG1>_ gx_h蜟ט199Yo[28avvv^&'']gЌggg/]?#]} 3ftɯK ҥKM}|l9qĐs Y׋"Ű!Ίk#v2 Ɣ^T0푑dҥKzrF-ԏ~%B'N iyɅheer_x !6M/]@=;`_ti&y~~l&vֿ.]&y&s<`Y΂!0\t<+Dj\polɓ'̂|:;;[u 1|fyy9GJEYqt7q* !,a皱woo9^\hhԄ(VS5Y?>_=r|.Mv81`+9p^?Pz>-(e58|s>w|O'=05>*8yo Pښ&-ezMv;CYI=i"97?ŏ;~'N! `ePZ^^~stt4j:Fl6$NLL.%l6kZ<{Tix1<(RNJXݢܱ31v{= N暦j/nAj АB85l@~$Nڰӌl:XX?44 r33U8)r͖1>>~1cٓ4W#0Ɛ$ *S4922JU!q>Z]~ꠟTPצ $d?=~ͪ |755uT1| :$DyՊS-ԻHSyZ S?O<܋E5ЯNgBȴ p eJ_¤# N[}KKq\$ù:u7I` }}Ӟt4ʈ>UPy~ gDqlf' ڻOg*s {I6i:A͒g'8 gġ|M(E]_G@Z + ,@VVr?;EAw2G~L?K_'GZNнn וI?ӏ]1$6hz.SRd(Yյ= 3!NMKVVVre\_]k^Kp67Dh^. r92?ahs>G׷n'>YFwRW.% !$=ג>fg}_xV<)$g3nNR9Ek9jbtQM[oȑ# 4ET )Kd]dc9Jy4 }ݖ@(J~:nܸcǎ7o"cI`ǎ`Fy333h4 Z&*FFF0::޽7o=܃V[naxxb(X__ʊA={/_|{<Μ9Fyu bΝ--ѣGd T8C%Um;Kw'vRGMo]`|m"s>c~l27xcW԰!e!dcLqs~YYmƂ3ǩDHQ((R)_cJtL;lzWbssibss (j4::۷o֭[HX[[Ԕ,..ѣ˗q5$Ie,//R`ݨjh6~6vލqbttػw/E8OP1߿7n@VÇڡC$ 0&''k. 6c-k`4 ]_ҍ\bA {ONNBf]?AoLp%+4FI@uwL ՙ7n6.EwN(RNQ?.8==A(A {5+T*ahhNׯlZa  VAݽ{7* E@ mX[[C6h_600+Wŋ>͠?M-6vڅt: `nnB;wҒ(ꫯЯ9Ko|͗vǕv4_kBA@LЭp'h666У I2vskWǤّS b{Aصk4E¡Cnh4>Vj;wNX,RQׯ_FG>}o/CJӧOcuuV&\.cmm 1a֭[ػw/!طo* 03rnAرcn ?nvi$I-:tfӊ !~eY*{nq; IDATZ- `ss(!z=8W6yǹ t|H-Q!Ki1e~ DVm;B099>>"]&`LMŅQR.߁cs7n}3;v@Bh6?a$Ib4I8 &&*w[JSsgJ:`Ν;wԫvCCCF݆0LЩ)$IVQݻi""LOORjV(DZd'NPRN6Oo>[} WtOjԇRCeHwb'wG;S=(n{HRAIX`j38r (ejdHW6Rnkqkպm{]Ӵx5J4:&$.`n-ՙpJSUl&g͋vb5bxv %S疯*g{ _~~%N~=O=V׵/d~MF?ܿ86C1w/P9 u,)7gz}hߟK>ߺDW?qeWa~JڏݢOz9 @o\>E 1wnI㻁{>S5fL=ۖfR'tkV Js=X烺h/h_qj}{?n ~)np{>vyy6@$DPA'O}SM۰szgq6< nYAV5祗.,1$L|(M4yʏ̚S+=۠jϑAru,)!d ) RJ+:$tT_x.5N@㒨Io 3(E1cf`$= VKդN c{.J):N cƏϴܺ=o q@e_r R)WK[*)'#R$Д[aBvcH@IH)A T+V!IO^JŢ*&fZJP`| VPԟ pae!0Ӂ2ot!:.*E%za$*^Z}<9Rﶤih0"œPgn.$U4{|)RPjy i*T)B P-L2ߵ TJ!@$f54_h b1u@MޅŤlm䤝TPUoL@`@9P("T?utsbQrnۃYC$dceim)'$ Wi܉~Y75IJPO}TKlu :Ra,iN(J@T¥NJ|Zݩ5@Y}iWA@Q=s<䚲46w7-P!+>J>+'^Td+f]RMaRuKORrP\PBV^*uSr'l"'nGo.biwDS ImX)Yk-Sp&IIp)!$wYDQ|o!N7zjib .ɹRrp PK$+pO*7HHpg @ Aw`X̺߯FPB:~ aTO(%RBii"7a4]ޑHv^36Aרg+.ڐcw[ wmzD肆 PQ )9/r ]1={ccc/ r9x5o 7߄*VnA4MKBކ\ f'U)׹^U(p&;A6 QB.R.@%  @sSzoJaܰ (ŃB!8@$Trd3>ipqRLz\N.s{2Ik& rY6nGxد\3ܩuP~acch6p&&&P.1=˫hxqq ɥ^o_|9|3AExwqlll`mm O@ӈOYh0djI HG&)$~lR+TΓL{R!bH8֐a n>+# -@H b,PP[ZΙ~Lu+p"h6YѦiCy3i98zJg>={w} @,U) TAe vVw1*s˗/^ZbnnHgϞm\|'NJ8tn߾FCaxxO<&VWW뮻lP^tn|whDZs|-#v0XJ!H_\ ?Lz{%8Fl2DCdʺ+Idu$'o0PJv'xOk$Iril4Zxe  Taj7Q\Jo(?\6 H %(bZX[i܆D0ֵO…dQT?|\9?ZUF$dt Be9WѺJdO^>}/"!ߏ~5v({Ym c8f8~8N<7o⭷B6Bȗ!Y6OUܪ'KgT=|N^„R)*!%BB+@X$v!6piT@pp&6!yx>Ma9R" $JTc$>gTKWj]*1VXZ'znv@ʅIvM$Bè<")@ e@ Kt`CeRjG* %%G155V̙3سg:}Q={O~LNNž}pH)o>{˿={`bbAĉHw_]^^ Q 5Ѯ (q|uh68qX[31:>®]Gyn=ujP(pa$Ia8qBjtNGDo> -!@ξ8S$$@0@cni*lO&p.2*! +2+s)3fӁ`w,dx\p9IF{ dߌN$V~>l)t$re@&۱!@Q$җ{_:w~o_}@-p@E ($E8PVJ]%MPYn ) ڭRMRB0W^_ _SZK]{avϹHNJڲW_MQ07 rw €R̞9 [b1`@[%pH0DA'8X@Z0eR07%PDty_D3ۡIa !@4N ;7]s@ D160u brܒPIB)A@Ԁ Ki0xp.G_l2,J'+$0`Y%e3PH=#U"aGrzh(2EWFgMرcrU8*D#A h6a r@M 2,[] %PRQnPѰU#YFSeT@M'dlKniinT;Hn-\O'T[ 澄4}b8I4,);EVꝥ97L#kpƙh z;vthaq^...]@3"DW1P'e|WIP.VK^‰Q E< 6ֱ L-޴G-RipƯ ѧ7ʊbzk),/nv*D)>ۇ3g;WQoz<(s7pEj3L/~ #6U߅n|EXO_gG΢^x뭷pa:u :\cǎ̙3xpu]ؽ{72:>6z)}6ʽp8u^yCYgxo8~8fǎcC<'6*71%\u !3pM/%Tj|<{U&0̊\MqVK@Z$ijjTC t!GKYa/YƘ4VW׺{ݼcpV&h4ñ'tc7޼#;Fmb,M8r(A!‡݇b )2z kkxw]A_~:^}U0n83Ϡ MS\z?8^|1==}{xgpko8x ς1:^|E ?xrr}goArtM(X(Y >ef1jWl${@mКUv * k<ޤHf8=Y*U*#z q;+4\Ab t:*LND46R,q C61s(~W)~SxTBa u;ǧ>)رo6}:tnP7 ;Fw>g?fffcss?</###xW055}s=|_Km]S ,WMF2_ڐe|lRȞ̞ 9n@y%x\+ %v䳌"RZm kEGU=2eWVV"169`%btt?E8M IDAT8c~;&3֭täFLAR$Q*U_(Xmnq ]7XX@mx𛿍 ~G mYV9~,Mo}}PV+-3nwW%4h6ڱBLJhhZc"@Yٔ!5iɪ~xrH: j\ 27I㦅37&K_$QwQ\z\85Iˊ(ԲY1Ua?;.ckqT*咪ϛzjX_D.lv$/Chƍ9Zƭq ho " 5'G/` Zf"E'nlٷODȘ#acLcWƁuCVX D!2#% 8UyYҬ<, w;N 33q݀ѧ|f|a~4,dKɞG.Rz){ӝI*)ϖ eA2pEMD~m:N=*w^CbBE'( mbsk#% Thci6q[oS?w7hQJKmoըdP)J/5"L0/Wկ~8hȈYp~,{inr \ wR2~4c3z hZOZWpPam 5ovk174݈յ.LɼC/aP5)U1s1cL^G18:,~ةTGq#`l|8FrH#RC*BDSNu;\l9 H.zm݈a: ̥d] 3S!&r mѣb=-n]mPV*l! đp`s/=k hu*Dg{qԡNLB%^yb8K\a>BP*^`d0E1>)4H[lІ#DY6*ŊA5)~օTӿDR .N:ۨNRJP_#,pKYp )S+Y 47h~ݶ-Ƥ6)osEQ[0pp0\}I]c-M Ã$@h{OG]|:^E1s}7FvBh0\DFbazRqkZZ+j].An>]]U͆2d&չR[X: 7@{r0}LnMIEiv-jIz"|҃h4Y%ro i.~3WߣTjDX]`F:CQ'Ks3P_+Fbޙ̴xqC_ v*C)ARPV *ߛϮH!,+++RO{z!b6ƕX |[TLGjj`k`l]cbH6!3&tmZO8Mr=f._ уJ(KY?_f{g^:W EZl1.JOUD pNʔ*cVj$ 8:ShI Y#eת pKJ"Vx$L6(4siC4e߾qLG?p aoj 8gNB5\.CN7E`r":$aGTwm\"C@rM#҃P )`)ꅓ|Wм[w&wE%Q%0rj1|Epe _! RJ(7`7W(v3dFDN)PHrigS`(HS{uM%gEsnEr:z2O96N@$q'/BrX)|$<'l1%*A4Lb^"RD&e \J[P(WEZH%9BrINfԤ[TJ@c"RANCBTeˆjr NHJr( ME+JԎzp[fd ?)Ni|f%""'Ջf3WXW&bbT4r r CДn=<ܿǢ yCS0-w$Ȁh|MtDZ"㋚)L9*,<Ֆ\gn*sC,؞/&%0JLJ8ZD AT)@@q^!eARH H!S.SHg݄KnM+`m5;J0i'Jb Y2&_0UϮC=K˶#;i}%=fIuYI5P6 ;8 ہ$,̙iodu}9^ݳ vA"!$,Je!۴bbRReټ.%˩8))ȦLP!CI3ٗަq{*M03ݯ߻ﻌeӬ tAgd8Pmjj0$1B[PʂkfeiVvD! \1񻇪#..+x] %ՠr텡U:}nDݧ6n m/6ho"3̓<ؐ&t1}xD y$LutT//k=` "m^yN>cZńG"kaݍ F)|+Ʌ2Gx7֪tQU4uUhM:Sٱ>R o~h!(B ~2eSkԺnoItVFUW@JGU$\Wh$]o,dR`e46(*t·/ #EpCe䲃5 6_7(SjݛQwRÏ&H0aNIr9%Sطl yJl``D3r6VlRr#.^_&y;g0fӰTsTNN'7,^%#Eho骖#+k*sC )[Fmi4yPW .E{,RܖL8wQjR=a 4) 0DUPPt}0 EFhY*gspדdny.81IZ<K-c ̓ɡ!E| V21bnݠ ? i>6QK y26V!58ڤ㡹oXE^R ԥw/1v x%2G ڙiHJd_ kqvR,KU@.\cIP13 kBhKiJ5d! F %:ۢ)#7sAP>=pcɂv.ٷFSC7x(Ũ[=K(v^8.4Za%ei C52-:2V2  }27&幩.°%Z1"5F.- Kgy~jbŔ9Nn*Mfde$wd55+˔Aj`]pXS׺`VL<×T f'Xp6hv*.u5Sk$ZBn+*C}<ݷ䛧h\~u\VMI6^dt:Ud`FNBum TqM /4fx){͍6&Lr;czr?ʟjx HjpGQeݓU_pPGP'2 +-綢 .p%\MV;59[(!_+{vC˞Ycc/acD;L&BNrӡS6aCV >F7_e{nRerh #-(Է-~{~a4SS_mee^4}xQ4ζgmy]cN,R[jBR/ PB/.նeMO7k޷M7Z#[ 7JO}zWmDnկ5y!축eK?:: ❗õݷW?$bsejeֆ^ʹs8z(vZd7J-+L/G5( òJB֯F+xҩWɔۏ3Tյ%~Ċ_yFt]W1*2$mzH9kn樓wEX06=S,_ʉ'?qf]e;}k|g}t/ӳtoefg3?S'yET9{Χb6T묯֚sαSSS9s|+}Zs9>ccct[kzF\|(p2JE^[W],W8{ kK,.`ꊫW9}<]#m?5Sy߶MAia(Gdk$b)&݈D6SՌ:ŋ6mkAj,rx&u[@&3AX27g&1^}n-;w7Szhe1y|t#cte_9ۯ;N0::ʍ7j*Dxŋ|Z׸uwΝ;qX[[w}<lmmq5{Y\\>>,_pyn_g_}DAKZ`̑Pe{s%xi6Qދ[yuoœZ ȂS"#mdzm7񯪅պŨg=d([mNZ YUaT,I.>;E@կȽT>p_{&>Tauq˧O#3\ލT5 v#1{{w Y[[[[(wauu,cqqM<,K.]SϜ9Å ࡇⳟ,_җRN>Y^^gߡ=Wػw/_Pur-dq4Kn\|,\l!s|pӧOGYwy7oFpvDhc?Hnm7t )DK\~_JfTt;@&Щd&Nh2ښE'wG:k"E45#].}9\11>íl W@oo~9W]Jۅ8ul,`DfPҵK,--gVVV[M/%N6F0t]ϡt%?yf%qV֐YB Ơ"ӖOW)F*suzc-o|ftt{'% ?LB D+%eoe4`r1q:$ASq8DML^yu#~;N;+ٌ 8e+*zyr>`ׁ#\z].'5ggǏ? ˍ[욜y[|p'' % /ps<<ܸqdvvǏs8q™={k- =Z|I:UU|N؀OÉo{r mP'T_ hh ue*sb۸"066ƛz?>Ǚclleh -DHkr7 SX̐b{RG4l#S{!y(ʫ&mwN-{mхelna."JkN10te$W_B97qⶓwg}~%%{v%ƻttٷwZot~qyfvOSU??իWSOp<СC(޽~5{A)šC299ɱcG ٳ9vߘK1 -Ѫ+o%2_}FXƩep"f? '⩧ڵkLNNƬ )#;@Yy 7 C{Cҋ{|qǠ-uTO+\jF MN`A ):v6OˍlUvLJd]Hz6g LJnXq,`k;nWZךMcL>Xi@(ktMXZ\㱻+?cmn||aT]cvǸTM_[ʒ:Ξa.OUFm*(,w~ )ə "nm "+!Om,ݕe'2%Hƛʸ/+@dn*<\3 IM Vv#|$JThEA_N-e|ᤱVBiQ(Ņ@Y0AM  AIP4^Oi OYxvh@3dv Pgn1n u]3kb4Ѯ(r0D*4OJ_|fß8HU1D ϝf<읙/y֖VP>uQI2V7VO=hmI,;T0F@$ΌDv;*Mf3.zVVid>k"v:oL\lm*zl42इ@g 䜘~9mGM0"xHϷ7ИڧJTfG~̡`]]vo⡲"e T[H3=grW8x,o6K>`c&/gp :#ێ[ped5S#gB" U=t)Q:oa`MF\hԟz {,d"Cz+GOLq؉2#Ef ҨƯm֨#XđoCi9/N BP4/.3l5;ҍ{vO}ءYGFOpj}XX[e6ɍ;L+87Qds2o*W7Jo\grSzb׆n!5ՠO%TA]V7+~ႄ e0Ӌ>OƋN߆kȓUuEfkZXH,VP=k@AZH6HDVR՛d!"oA n4n)|R:NdM{ ߟ>`HCG'_2wESWuW [Rr]z߃sl^{$GF~n<>v.]gukfj˛W1"`ܾgQ>l N'2H)ohQ) CQuz2 0Hm1Y+Ɵn*QMχvsJ&&%"X[\} mvLL'ei@VzZۗtvol\lo? u @)?AYc$mQn P TfdRf,,`lav8e]jr y o9o~[ǞC{?cbdK[LT[bNd[֡ ɔkfD[qPI8~ʓkAFʫ.IQ !*-_*bf $L!)ְUSxoE[ \$^. m*d)_jxԆڰɛKPX/\w_U;4Ik]ػ' Jn:~noqe>Ə=&v!e? y=\@qn 2wMp t9s(7Y'3%*sMVnwмx(\SN|NQ- pnGg2~*~iABD/^]"bBɼQk|P%nwpAąSD6iiPX>Gҭ)Δ;\f#ʮ]^vj=B=;X Pf~M.}89>0{3ws̑w2ӌf毳GJ)j#g7x\ CLC)FWm ib.TsMMmÓ"ZuI ںӦEWsG 7P0B˦z/Pcf/++rt,#9o\ůy5^{#bmm}b8qQ|꩸5]zfh mucѢ,Ql ;Pْq)oR^>MxFC-%Btȫ[05F(2\r-%VK _8@M +3@!)@P&i~Il(浽($1Ɏ*dRW8y]dClT%a5hAzqy*caO,:VJ"FDÒ(5S[0[Wy,`q:.[F[xr@wCgl}{98=ή^&so< SxUj*l]| Yh}Obj2 }kY?݋2]f# X  MZDz"ycK@ɉnlKpOmUD7%r&,'An`\l{*+4MȆjN,"¯W{}v,˪(FFz#y #wnh[ayi{`n nnatžz=U9@ 4Jshgi9Ն[˫N$q\ہL؎1PB"G9JKJX)?a[KƂH-AMfшl 4HS_@IAFad.RRFYhm!sѩbX3ûSP8hζ:m9PjJ}ςPYV2ۆ$焊[("/7Ku@J״AVb_(S@_dtu4NNU#LL t uy̑BSQec|+?,Q^ o,VOjfaJ{ԢLPXfYN/F/1 l @RG~G z6PW7hyU -Lt҉IB gWQ/[~WBv{aEQۛ$TA!BQZoB,6`mC!:cL 5  0w*u*Lڦ`!dWr{m;чr^v(i}2AP-@Ss&N_@ X#eQEϞh2GQS +K:tadUZ:¹igG̮n6?}b϶M֍dZUSwgg2,lNڋ@̸G?BVxY=gy6}RGҲ\diV(JMC?0o*e;8fB`33jzm('`}Kɔ:iBb@(  D #gC \| 1X"JX6N>8¸ϣ`'wV J ٥}Gr8WMfM-Ri.pXkZuqacLMlu}i%nz0$& S+#eXB]n..."+@JIodl4{W͵\vm,#hQck1<+1C8ޭQmZd(P )Ԇv;HoЪ죤iŴ_!')Oޚ,m l]:,FPk\+kLHJ t9{8_S{ʕv1:94̚L팩4|&#x8ZEC״sS7ϲ"݆.vA Bl0' q֭%(rP&l"lOFo\ѬTT*'@c kֳm˔ȝRJdɔ%SU F 5c:~]+wr@ݿ~D>cUf~ Ug!%s{B8_6e[ C[U3h?E\*%E|J(|@![{vakHSEE!hBb2ps0ZS 4.clllpzЧ*2B1+7266,uh6i&LC }ƂmE {NzF[܁Ѽi)F'  n|#ٞ6 U9 t:%*$ņC&3@Mq"LJ؆#oPH;㷣 QYڕw0lzN -BLjƭaddkֿ|5TFglqGw1b|(fSko2б{2Ǚ3s<4e3*h]* |oi CEecc(`ee%*R stt<F*Tdzմ< {g}}/r%:O<~?ڷ:unC=)_>ɓ'} `||)ʙ`ssG늍dbwDzn2-N~ԬiL0IUTGMEty"/2Mf_ۂ&UD[76PtN'AcRgR;b4uVWؿwΓGwzt0(.65J]c%ր8SEEpa~ 666b ^x~~bll?7?<*EQD^/ȅ xX^^fmmy&''x"N!g>opܹNy^uzkkk|ӟmɯ/~gyO)SSS< VWWaee>7or9yY[[k_=lllP%޽_~-^{5~o~Vw-U$}pèQ#]nB֟!T)˜ׯN5ÎϛdA(Z!D'ҋQv$;""AEu];]w}d:(:m=[f $>Ι3g8}4Yq)8|0 9s}c$/2\tu>빇oYZZҨV ձN!1RVv&Ј ?ۃwWEz"ɩc8#['"C8TT][2>9Z67)\[x[}[,'3?7?\[e{_>o9G!8,K^ufff;x"_җ8w'NppLYK/"SSSnmm++:u@JɅ ƍ e|;C/L!~JLdyw,6X=@6YcwsMz3 />ycNpϽ{~o?21Nv?'G1X^k'0??Ͻ'?IG͛:t˗/sqvލ֚[n3o} )% = &Y^^Fkͽ4x9z(sssw}lnnrfɷ~{^uxG|8p|Ifffxy嗹yf!PAb4f^5TƴJ eڠ-F Yyx_vb6\0صijwR4S{-V|X2k}W@Qo( W)l`UXvr/ n#?9r{\==p8}}YO|#sTCǎ_-EoU"ȏ IDATU_Ge0py?ɲ,Cs\(wy2z>|e<Z=EUU;ʀʲOpneV!: 5(2֖o"6ab냳Oqu<0>e>p<(|u:Z3ĥ1{xx&dss=Ф,j2 "TeY{}pL3RGR%.79Y 7pkkUr;W.1X_be&Yl`Jg u}NFЛ0=9Ch[X:Y6YY$1 =$SeL~R v nkLOOsQZhP>ǑlXlR12X (åviݤ!Q!NaloJnVny?>0T`Bm]B JftDaU AO**G?3u>G#%9S{pkccq}Iaoqi96OV𮒕8%m[ak8'+6T#8 s8T,':V-Zf ȑSu afg.E,}rT4nSm+a36h2e$zt02An'6lx4@WH2+ :,jjztrҭn.{"Yu5@4Fsߟˬn x_QJUɨٿw'pGs"-Pt'ظ],_ơO9zvwPR U{c)7LAƀ %? @/:$ڴEg0 R0"v-gjCuCEz~Xjbj/.ncETHg#!\PL~_r)Ë`b*AtigVXdLFuS}B?8ҥ{EݑuIYqӠ)2%ܺ3'EnӜ~%o\bk}V=+K\t;Gf8?6sk#\S}=HL%i 8)A&WRZ^lء3rKT3Vilڬ}PuhmIDLu4UCذ 5l?UI h?U'H+h `K=YeYfkeds5p1o-r'bpkF2Gr҇&hb;X^ueX[su=2 +k N2 їzzX„qWi2P]Xc"+C)N2pe\KmVUe5U&NJdzZy,β"ZWZAjT6].Z.q9N:#X-V1k?㙤|u6%N<qz$h:fk6.w* o-IDj"Xv>eR}&9҆5{y2No~Jk㹶bmMr,B`ȃBhbߝ^៽S`yxȆ`38 ֗WYШ`su;:,^0Ϗ=q&5G'T_ڏ5⴫]YD6RwQc|O1d>$ 0PAHkW6睸0SiUXEE5lHۂ`1afE+lRm N Cэ@qaSL-츃a㐥})\$X/ܬ*lͭږkSC|cHar2n0u'> o+,]a{79[VD5d:/֓eˆ*< Nb6'7d:FX'׫e SeZ@hoa˦0]TRgN(Bګgsd:nq }8͠Φg'I{ TvʕMt!=0JMtHیFZ)E&sjLTdl| nɉ4oqBfl #JpQ$3,/|?z]3z&C^dc)WY&b|j jN*^Y ܱճц,kz,sƳ(m ݥX:0dx|l cdm?hgoqq ]]՛h7}nDmJc1Lܦi3*GU,m5l&i= M:ò`@K=qZiTKv`12%?K~i6e FU*c}Og4rKDtzq7-b6J>:ΈֈuXUr[G6Tum1KMAyР!-X1U ֩vh锱tVctÔ\[NێJ'S/ y_[u #wPjxؘ<;;y.E]K6 2zESET1s΄CI}꣬s6P b%2-\g>QHE2H )$]WHl|df1Sݤ/-<'A׉& <% O=KƙU:Ö]S]NhD quSY`ÿ=pvٳq4~3Q!ѐN6;kD nvvOyhKq_\ J)u;#c~AWNR❵}ޅ4;8Q0U5`GhT&Z8*j_zIvB8`i¸8l.Umd&f"%ໆx Aptlx`LgK d]yމߗ9)+peA9!'-Qd2yKu]z,]ŏy\K*bgYOo(Ru0)# !%Ӯ7T+*˲\"7FצrX`0`Pd>`-BP*L%H], 0ڸ,I 0t([Le!y~iO85 5ӳV]xXsB|L w Xհ["ӂ[__f}k!,e8ތ~jokCKdP)IvmhUUat?Է:t[Z*ȤNtG0 uE..qβX}EzPا@e.i3 +k T y&)#SJehٚV !jd):nJT17A*=&at./v\4𡭰sXRׅPĶ ?5&ˉ{V,CkP*1]y*b+hS !4X1&h6X[a1޽Hx.8HM7o|!5IÇ64abhj'|F536`U=Ժ$ pvJ^v-RDA-:wVEX5%5n,rN#',.DY!VmCp $)$B d'=dPkM= lD U3ϲiMM$:5. 8A?f`%OJg5dxgJ")GFV[SURdn'oM}$:)6s='B3x/BaFbVՠUJ _r5_晃T3ɳ,6֖&&&9t+ <.FR!?BO:)YlMphCOpYkj):,qX.H4 2&XK|!mܲثԑy>LLC)P&< ӈkC 0DR,K/ WBb5ԞƑ(Uǜ*1U腅rDȀ+% ]\5d![{(y2i˼ 6u~W69CYUuQvt!^mƓkB {haM`vtbR9)rB (sH*'Je6aRPc6Z:eOJQ -F)\mPyt d!O _+{HWHٳ[}/Ty&JX71"bH'Qp'^Z#8 ,LLc%x2>_9Jsϙ~ͰX𡊧Fmr"3; kjZDkG m9o3s ?, 7h5p̰jdReP#*$ oĕ+W8wkkkfnDZqؖ)\Bk*H,N]PDwX; J)׻ߪ"nGm[:]*t6V!4msɱ[VkGi,b.;G~>M1Ă G31k~^Z9,زasΝ=16AEDIQ*٥D)+v$e<$~H9IU*NJKI%i(QHB1 A@14It}3ZyX{W)>4}sY7߿;znC7YkB7{gTn<KKu@ !l#6u%8j\YY_d~~ Ο?Lܽn~5=ޒS+M ‰y\4 +63݌$΃Ff ǟr>7Ԭ=r\![2r$ET*.530Uwƀ*Rg!rYS1 /`@9%khX$Wbeܸq N<ɓ'|r+AI#* -Dwgi2Qy Sb8 *<{X@~2jsHcnp\IY1j59i5#v<h ^C`OCfq.Fs"]nzEdC!:Owa5hͭCZ}MvqhcaJm͸R"Yc{{y ,PRPS;ymmfteѨ\Ckqh0f4$6\ tӪզ6z0m D,$*+jB(*4zX[.EYRӞ~؛A"(F$tJPRQJ{^ x4ʫ`;7O6)̎8j:KeU[઩ǦF#ゐM IÎtN5aM*B֩=o{"J-4l1*_^[:L8Vށ %CV1ZZM*u*Sf1clbV)1VpW[L){b6.:k{yvWv1xK8N3ekԧJovı)Dtk! h鴵+ݿg4bR~p񯑖W=m!TMzbVZRǓ᠄G8 ՞JCXt\\RȞOaN QrjP֘LxqA]i2V,IM=Bu" WiѦl'/yt-M7K,|r-d[kk^ZMv<>}SQQzz6exNu.ifuza3va) Zl2쟣o .lꮙw0[ɪ$Z)W?RZPoV)tdsJ EnDa}*5N͠LNG׀6j !TnT=V,<[x:k:t o'!jQ3z1I; G>h">wi_x đ6fY>xP`pD<㤉4Zzb^ iLP`%vZʹ#MLLS:W'mq-HQ0ٵnz81ge{CDGd*C28ش$mxvtPAV^gZSәl.RJtт!q^tD%~]\0gVhŨJKBO]PҶB!nƕL$.L!et0>4'뽶B|7OQڌ}kM/**SuKetsE%`L=t|U^rTlT+~]ųm c@T1>{[!ѧYkY;fUUzkӄb۴Ԭ+%^"IUr2 [䯁5S0Il=/fɒaEdM7Kb2著qYtmPh@PULW9ZԮTΗl " Q`a}B IDATYgWf mHzV !2Zmrz...:ᘝw+ b2@eͱ,Ѩ%6M`sm3r=Lj,ZKFX9݈)vvvUpv7ƓBaCV+6t,$*e?ՕqwWj ov5CBnv|/H$tKcY U&|[LF(OKV6EQ`Z j}K=:g$Y?G?r:^}w/_O>z ;;7z2rw=e nm\ƚ!ȹì_`5>w>?;=L?Th1-&X KKKEO48nm`eyy5p]wƒU(~x .]bffx +++ё39Ke\M{ v!NZ3nMbДDLx1Qט4Z?(kX^/.EBJ=6V 1Tl@ժ*BHo4TS! [tTfg<-ҠZ~Wxe8?}|?W>9G(ƌ>[~^>ȭ#--8 2{?/wlon`E"wyM?pa:2LpCV9w<5Ν;K/`caa|+[[lmm/p)^ٳg9s W\AQ۰vvv1қ EfҠlC6E<UJqX|чXJFOfe NX)4~fJK}"&1p}MCYVZ6U-؍3[PXe"SFUfF99Ykww'ȑ5n\3"O.^9Jpg22GIN5)˜8~P=tEW䞓|S`0?Os}s=|{w%666? /t:lll/}sqw=g}6ϟg{{s|+_( {k?#.\>1K_Z>Oη-Μ9Ñ#Gxp}cǎɠsn ;1'\Me0&BDIrTVB;%&K&e+7j B;LtDJ Eeɤڅ7^!X^[;LCﰶt={7~7nxgW8r(2]GNټ~Rf,,-y*W\;1!eY3gy衇xyy'R}|-VWWx"J)xטG!<9s,ym:׾5 '_:J)fffPJo~3~PǏyȹs8u{{{Z׊Oa 8ɑփ)fA&DAiH1ϢM0m܍a鸵1W J̯>y]lJ ۶`v.asc~CK;_>28Eo(K;dqn* *VAP`<עs\t~w]VWW\po p8d}}u>OW՘)_p!Vop-f<3ܺu/~,,,}5w#<*;;;<I`T& JV}/]Cqa5~DlluUlȖ4Tbc0Rqma VT*S 6̢}Wz=s#Gc{|;{GN/>6W1I4-iD% hŦ\25wR:I<Ř>KY*ZVBcGNzM YVJJ{y1"b;bf㥗^/yי[e*pwpX[[eUɩM >쳞 3->9)-gΜ|ӟ^,..2;;?hę3gv ~`aa|3,-yg{c x;F;vӧOٳlll0Y[[ˌcD$`jwbVudѵ!zNub./ _yHfLJs3+[0`,׃ ='Rh! Zlcڤ-:/z0h!Z.(r-(cRd*css;kqQ챸O^~CVڻ`dr -4KX.[;-b<-]>=wo޼hDƓPp˙3Dd2bnn&֚CE`vQ8qk-ǩ*RjqF1z:<{-U4̀jNPYk]ݩ^ xS?3Bڍ<;?% SRhG^ir \+`.&NHOLdbbg}. M XbMF1XS*,sua<o9dy搮@-7ſ{Ɵ՛q! EU2)c5Ɉ*ZNCp$fѨubV3EZFA3mSDS?Ϝ9SO="&jj@3pZȡ0hVZ:h s8H(EIVD+^Qs6NFn\@6l3VR&krHҰsDBg2(BY@Vn:.ǡfLPI56Ֆe5[J -e6!ʁTk3^s?ȑqh?qY'J-/p50;r2 ȾxeH㠚${Z[j?0ہlݡ8u%\5P/<ϙL&L$* N:*NR}Uu7:lZB3׌.)myzv9ΝT-^EwH[##cx!XaTsM񘎫Wқc{{km0t7sp#fUg xV'?y3~YZI{! HR)_*& %:OJ?: >]w:ݷp1p)cYvw+:(jtin*yjj[I] $lRb .:qe52z ꦆ5෤FƑle*gh>.y*KUL3-,iɥwaai.| .19|׸}*Lsn#^gix8;X66o2dIM"RbhQU{mlw:7dDn5%+L}ߚqIS)0Za qcUy!ΐɍ6!`mUkТ WM4a6 o 9 G =bxtƍӨD ]O(;pt&=*k歴:g@-reY_JC/;PPV&50X9r~SXc+}4; n^ϵ7zf$w=Ȼ%xx#m?ƉVE2(<`Ψ#MRE&/]zCiX橖2mر;fy},ۚUVRNAŠ?Q}u(V-<;njjz&q8L=mF<'ro_3`F]HsJ)-RJ]D 0iƪd8sxmo;>|)6o^KX>zX>{'1bv:W2YppX3v+wOy7w?>d}wlyElrۏ$pu:1؄z'mCAʖe@:BԭVUcUirA;]JPggZaJU`U4e!q"$0hː1E%loƾd&b2)PAZ مpVUrzhtTYS}OiSr9iɥw/VWX\Yg/BCwp}G{{EĽK9;?3pMQJa$- IQ0 8`Sl[mmRPcж He!n(-Vw,iڵ .)sjMܾrWw3,:+er'PYoߺڢ $V T:ʶ†QUd:7]ŻC )c&ɲ[q*#,#⹨ۓhȥp 6tsC\8w˳\p]-αv|bq0pW"۷g~˟D+F8cBԓBH,|&+:I#[&VHn=طv"RhmI-:p \ОeM:SUtzX+nJ _Q[4ďcT\N9)F *q^agsQ:g.7~?dd_K\{=;osKYZT~'"UUQUɖH_jo_vpBɴOP}ߢ*0?:R]$œ1*-XʐHH j PV骲qRGI2p‡>kZ]ochXu="ِlrxQM :4%HWe†`=jY˪ uf:t_JN YWtwم%8z\zrBov>ږa27G>ˬݱƵk>O[AN,oc9,XK[֥-v͝3c(>Ӹ0]&Atb_: _Bs7cXA A27@BKwE罷k eYu`&ԣ8K(4uxprY7!DD:wV*,ֺj"ЪZaHh--sG?S;/EOͰtNq\7#6nsQeLYh&>u?w?˗2.O&ğR"d fZ6zf5xG+xJF!щca>GFE8GC|. o0?k@ 2n9𝐫 $ʵa.y5dPW.]^'@B,})dߥc |˿˿{"_|\9v̔}7};埽[y3˳nsmw''~OE:jnA̿mU|$R"B0ҲOPi}rڌ5UMcP_ Au-`6UkXzz )i"1Ӻqܕr#8>=j͠Vq *\(i%Vx}UrRMӣR1z@ >cx#vcy`uv6ᄳ=Fzω;UlCe#Qӟ&yL_\uVj{r.f؇#*tio 1r{7M JU.:1@X|)JFRH2(H!D}!9,9^d^.vJ D_bU(,cCF1 !1uz&%-bmMW!jw`4ʿ沚uJ+$ꅪf8 I)Eᗟ\Io}P<2?F7`- +QcHЏؘy/63"UuM;+!x9ˢ!ްIbyc4mB"'rʬ4[oJ\;qE=fzRhNi r,Ø S ={)+dTꃴbnЧmtXKQTj&p%f`p eUSid5cjA{oIZ~H uffw IDATaLjs-k8m}2)㴅+j՘K Ly7RFr7E0k12¤CsE"걫%Bp0MB&X4a*kcLi?uƖ2l, # 9޼SCu&!a-̮ޤھ{ר _^g8"6"%K3yb<gMTLjŲv BkOgԟ U{<ɁI7lK;[>yg H<)U 1XʸBb * 5E1M)k?LisIa!a:r/WkDlmpuM'S>oGn qZl JQsʬΐNDT1Z{R9]+EQx&slQי.a'z=ǍC;V?H}^l]}p^=n[Xk9!8O?x95Lټ`fkvNV}~}}y-PBO0M_^hˆjAVm<… Kc:-fpss 3 cVVsy~sw233Ûo+$pzANjh9e;7'TRhm]UI΋p+/pń~Gibw[PU[L̈́:vwk:Ly{˯{Ag[ۥ$(^7[0{̀O~ɟ οs=͛7yWz=N:/ /1O~,o{/7n܈u_|'x"162~7x9tEQp/suZʯPk8E9kLB!la/ܱt='¿ _QJJ1AH$T*nñPL+ʗV]-VY^iuZ|Dfjt|M9wG[o0[f2qc@,CՑ"JQ,j ]b]e13ca~^ǹs8{, sO_*w}7͛7r OF)__!f~~'@L^z%>+pnܸ~y嗹{"t<3;o} !'N`cc#wy'̣>JY\rpȷm?#Μ9C|_gmmSNqܹ67R( V ZObE8 C![3'BR$8uըK.D]Zr-b0̷!(3"pW"3r.FJWNl \Kl^]n7ӝ!;6|oW.qi2XrV- %p_Aje`2qL&1 ֨pӧ_U>0׾~F'N%,--177믿իWecc_~u,8z(wuGȑ#Q%O )sVVVѣGCmZ!dNu~rkm#7ϿI'4!}wտM_#$xlOdNa:p`2>eʲ0.\ࡇ,//#<.ggymFhyЇ>įʯp)ΟDYvvvX^^!'s>񏳳7 )O?48Lbz<F#yz)|A^}Uz!SG1L:s=The? j#~*33ؼ/Ñ9=]Zp,y?wcmi=3a 'Cg~W=x=1 ʿ\lݾG?!7o},/2ΝC):G?gϞevvxt:f<|O277x;;֚E?@LSN:;;;/RH>;d2Ӭ 7n`8F_v1]RFQ#|MhI%_-MBzZD浠HI_z-X0jٱN;u75\$J㽄]ֺJxHřA,V䌢{%2~OoW'h+ٻR6Ҕ.*F[E܀=ܾGYIfS!HY_333TUSL& CAeESIk0D̩ f( UU133F#Ez$ߏ֚XXXp[]YYȑ51U)Ǐɓ X2Ȃ&#萻B )I=NXOg-W+KXY&IGFo&q-V:ϳAJ 3l6;.GmL.9 J pA/8s9ʩ9 Fޥvi%W9bWӫ,ܱ›&7w]kj 3sL[a–%no8c۷cde"hGmoY:mĨ{mooǮz1:ڠb4M/)(^*bЫٹHONU4-DKv9pn]9`=SxK*N!,Qu37!NJS"] Jj)VJ|w1?Њ'L+zss|䗟c^Mx_X(__5%F7e{}0U96x[c0[V-p(*㼰=s)):e)>,Ts!ݕΕklMʦÍ-̓m4o@)= ٵH [g6'ϥX(=nCS[4MzAz990lHOXm(*=)RT?H(VZ1s#jŏ EQ:4pcb{̭_3]|C,RJ]{TQ:HB^r76 bګPVsy3qm*PRÏ*t-Av:SXxh셬5uv}kq[GGm0n(B7FyZR2.56 >('{U7F8jT&<ҍ!Cg/ܪ3%AccqՈ'!Rӊ7;H0?y35ymx0M-s!mO Q2-s8+#Svn\a7qT7o1~&Xߝ"aQ :\g} -S@xiOET+=>ל6t-JL늱>J"#a4 EcCֱ^Q8<7 ShXtL 쎧lmlq:ni$I$2Rf1H:OIaQwEh(O$W:z N3yO@ z0Erk}͋tCР;֜[mbhZMޤPxI9l$<ֺ^Y{Ȥ,Ɍũ rz}Ar9er:=%|ywx19#)*+s ʰYN@g _ y4*|&bO}Ydj8~2'uw..CmO:ۮ JZkڧ"(Ss]R*M 2 (j,Ϡ;lֽ2 )f2z6Cd瀜N&&m UUBO% nKUL֯(,F ^y~ ^ ~fш$4dW nmTkego2p~VtKN7zS1ՎjXaq5\& eo>XkkKŽaAH?B$B)4K!^Mט:&)&S e)h9k״fn   %@ ȥk<+c@ Lb"mazJeLot^[y/_\#Η=*(cb7&CvֲUoX\=N9C)(cLlh,t믩%} )4DNR ]k 8}41.EXzA8qT]8)dKǴ^ۈ>cwJykCjE=Cl0|# ;onn 1LRY RV֪/b,-nNR8Ȫ 7$Pd,M;<<-͇;?=_:\θ9b)Yt p|oxP~}}g?'no-c8a7w A4"^iLxv#RgdDy\cpE N{+j驚Ǝq-Y̦%L`j6wK= uLl)i۠hʵȼXZdnȅ6"V.d QrR:_derp<#Ƿ^[s'{VeE+F 唝|/!^4uLHJi[?m+(䨕O1:WRDae|CA}5B mେL+jct4Mn!evzz#yQ_ (%kBӠvBS$s(A1| 2)e 7V^UsAe`N]ISmWY!V ^O$q yC>xmz{#&m챓)?y%EAsޚ1dyǡrg>'ٺu-Ji)q7-.D|'HaU"j-&u$X͇F&Zm.))?h啭mk#EkwN'u IHa|>XqhkWskrc62} ZnM+o4LT}FB^NqDGQIe- -dRPLw)V>fRYNUZvR \PZZтѥIH#Szx뷪$x*&7ݪEDеJ?Z!}fb2׷0c!$Fk}-# umʮUm@x~ qѓ* l5z{9gix^oN)ճƕB mP(pOVѮD^:gP`sO<9$8zcN*le:Gc * .u@$KӚ )4|P mzEY3kJ)Hj3K5(-+);<]`61lZk}RtAՄA2 Q`T'8oxk@ۄ0[e6<)Qy$t)E֑آQbUj*gqul##-Nx|2G5lU^e HAEV2bQ~XL@Loƹ*झ5k+LU'OLvjicP݈XZp6pl8gUt4(O_;} z .]?LP BOlC nm K䟮ەR6 (iMd6ҝs.YNe BDIJ*$]jȵrJQaWa+Ux\—jP\e,XJ)7JnZP\9|x!y_ƀ"J+;L*iNX_ ,(kܗMPH1v2%X~3BpF[!ǁh1$gU}ҺHdc# f1Q'i:mS#&2 IDAT1RF)sNLC*E׷3wEM/=kTtl|nTXDA chK!ȴFG aLM%㤞V RLDF09m)ZvlHCe [ƐGIvߜeY[TF=lzGT椋{hz'j?48<~ι[o$n"iQ}#eN1r|6BgLV|[# J%ºxr <䆕&n}R)*7pW>]B^(MQ{*RLOahE!O9^JDU-*}A.AVS|hf-y[XNդ'Jt*`=@%NR9 yT TۈͰ1~r5* {<(p3`h:Fa{. `\[7O8h (`".zwp{sNV*tp 2png V`9tq%L&< عs'lQ%4|>'OR۷RwVVV7ߌr2ܻJ Pd v套^$pС ሜs+!C6+{1ȏ|\2FiPhG@XD^G][<4;;gϵ0MηBwy7rQuBbH2QF~bXpƺmz^8KRy> Ւ2@n7!$aAit>:6uC X,Cxŗ::;e;`Z:O8.]ע\qM]N @$uw{.(R7D.C[[0`6~m߿L|O>$ v.L駟_ 6`jj OƎ;044ӧO?|]w__ȑ#ضmfggEn`"J^x(U03籼6QSo1uaYVX *ZȘ_xb?ݧj|˓uxä5]SJezlSuy") $pf0DU\N?l6coco_reVcqq7O~*[7-Ja50;0p}azz\v`aaFXDX?4qFEl޼s?|> ڰ_J|nrWgy8Ο?\.n7|3ocll,$/Z"ɠX,"azzJlKKKxGc?cxꩧ:BӸpNhjwyǎ=܃˗/?0>~lE,--Q-a ʄruzPJj<, jŦNThT ^j\ŒNԗPH1ߏW a=Q{1 /<^{ o(l_n)r ۮٳ੧PZ)B#@>[aqr,s˨VT*jh4>={`qq?rn<|CC#155 6`ƍ0MSSSۿ&mۆNj/??2~ĝwމyJ%,,,~' E_#1q d2| _]jCCC(8s v؁O~4 ۷o}vp.L_?K#` wEFЁG^SB%$.^zF,`HGTÍD,>zGxhqO|c0M8y$^{5,//\.^öm2L<Q.qػƶmۄ!`!{8N4A@a.$TzX1zCiZ ?N[x~'24d?8gYMTDiť9 j2FF-_s<+ܼz֡=qe+ػw/ &'`b Ν;ť+ڂ9P.CRؿ?zzz`vލ뮻F?8n&ؘܹt޽1ض;w!x'ى+W_m۰ge`׮]( rgg'zLNN… 8z(B//s#GR\.00::,d2¡C.vލ~x122GرcvލR^x[nŶm۰&;vO<M044[o333re;vZ$6),6s en2/1ܩpT~2æ%Ǵ͉mɖ(?ﷷuAe3j翻X:)Y/} ::pя&  p;jaV*f?En10"ZWe}W~M/'A 3|:๮[F_XDžkKƫ!-pϑ[n Jؾ}w*R((dEӰi@9$#t6&xM6kQ}}MAwK#8ՓRV3v <!xRѶuh?#tuk1!=S+f /=$-YSihFF09MbSyaՑj۶aY\FX_{+bq'ϣ ###b^tvv^vqmaݺugQKC}xi*-[*[ARWm+o46cTpY8`ڍ$P mh'bILIOr_X܈R6[FӨ< p=6p$J4lepMqTS.qPmTQkؘCGo7>/?\ }p9k(WKx8wa w :w':{zQclДƧH RETt)MΩFitjY-oFmM}V]澺be8A XQW>GDhQIBO! 3b^y`+D{;%ߛ!c7xPs\ Hp <.2z֯ 1{ alܲ [EoP+b}ط_d KaJ423j.YU.7İH6:1#fڣ3)2j^x#$.C|?Sd 5 _0` ! ,7=J) MWX +CqY2Yv/{= EznӨ*^Hc_Ivk ~㢅 פ4 #8$PF#ArLjTpaǀ ~lMA)huM[ XDrGu-4n"cm_iQ!ƍNLs2@D\A1FS^<=tؔ ?pď8\)=8ظq#6mڄOc5aez^hh(.@)NenDg ?##*B@&#VU"Dx4 $+gֈ/ HHɦZ\$|VbZzbU^M~1$u7,)D.cE4Wk8b ԒU- V4h,tMDhw U|d 4)ꐛvTei4 rPPn#3`pp'ZR1(EtBH^n2nK,KNYJ@,KyׄkM2ȸ8NT@Yd*F +"B-PI јNjX!N.bU"l}&R+KQ(>1x* ;@z} ) /'*n3 Ӱ7>(X:WT\Ԕ9Lj*$$qU#'=Qp#c32MO$=&:XЌ06ZGEU5(n*&Ɏ)aYVQ$68B.MD_< nYi *)M]MnW/\R' 2dY^rBq=#$gÐ c~uNqMPdp2 ~PZ0QGȒ( 4=DɁAC>'THtQU9#XloQI:4bmgU@BLpH'\uDj #YbLz>ta#w+#Y!Js&>nP B ύZ"0[Nø;QLi&U!%XC[LNs116KH{Lx~4$|S/*2"*1PA5Q -E@#IXȵAv<\.>Jjqbt4y*IMQR>U21Z^&3P7`k`}R eF%x4Fן0LPIAO2Qp0}J4p)D{,´Z(=ef:lT0ȧO<>w)b-i]#5\bFBVq~0|vdS&kjBիʦr\бglIS S1)9*JԍHˌ Sġ `CDVh[gϞB!3;;9>>>wx[ڴqo|^5 Noۭ#S.L\KRc[Ο>{m۶ڨfggVl!YTl@gg7v^)NLL,w#=88!oooJRcddd}R BRǏsy˥RQ,={_{~~~\.P*xqjet>={/JWWW&֕u9wӆM67wҁ]{]*^園 {{{:n7ť\6ctwu]\.fLnٌjoﰝFcq>c_f{s=;FW4#(g LheT+ex.9Ȣ;Fs7gkSvk8>e-†F1iꃧx1 tW1FRk}իeIjTIO$e43%1i%m*#J|4'Mnza %ƍsi$b6@&ei_?s Sp41FTuz[5? <\! IDATnʓhYfڽ6*2CA3:;֦E#`;ga|ՌFC)D.Fɤ(TY&KN^`TdMrPb-9NMG ;[dP#YlQ! LQ䩃=6C0$v Z9DD4ڲV4xDZq ![pٶ>m'1T>a/' Z5֫`;?|qm-чIHt&MEdP \B8@'y!fL`!\K~JWVCVql+py얟49(aJ- 0.][-4E,Lk|}$a7p} 7Aׄ NOYpZ.CQ >LZxt"DU 4ke$ ~xI KB>V$"*sשqZ|-OR=/݈vSTmB}Σ@H,l>w42E㍄Kֽ ixm;غe._Rk@ XyE@뢰,VШTHXDW\] bQvt:..iV^1Uwul[x{~;_ ebeA:[8 i-9LjՁv~dM 76 RE5TR2`;0?? c6dx+?\G-5S^+NuX%*\汜;8MaT"np$5.dՄLTHc&kx@i"`Q.(@88IVb  :hPb@SϿMjl2 {WRNk3/Q+WQ#`+k~WYQ^"^SkXbuZyVU 9֌W H]5K" Z mV*%lټp݅GWFr˥S"xip(# yAM`٩B{f.# x]?x̏WΓ/%5) Ivjc^2-Ÿzc)0#kD늙T7N.Z%i~?|F. <"&`Q$&SS30uU";=燿ϢZ}YZx?ލA\dQzm5%tX"BZ$&&0"^OҐyge={}{uۮoW'addرC*P |Pdxy?|k@iJI kXm[䩱kZc!k![>WS\f|%꤭^TB0jbyd3!0rSKi1j"H`^PJt"L/6Q9WݸիW;ѫ:5d I /a4A>[wQJ1?[n{ט?rcOO`dd' $D80-F:t;;4!Oǚ%D{Їױu m 91K_Mj׫yZIV邭]}Y[&DI[UZ{ݫ VK EsV?Xѫ iR)0 L`bYz__8Vx~P  'm SϽ󓳏Sݹ<݋rmEt&P6"(9Ma"U (HV_Ǒ7 s!QMߴK{WK₋iF SHFDZOtZ4Jr`rb"*"0!6%bVY,:*U3Q>xЗ}Gʯ&$5 !?q1}]0Gchzh! _ c1q,9) Gzۏ^VhЪ v8ds5 )I<ͮ.ֹ4bfʼZJn%' dLJ++T _;n˥"Gada2457!tCNٽ.FqP/.\<'߁ШNN85e'!i}6+_ *+-t5HjY,4w8(Zk`msWp O7)K$]}:҃R'@&_aP0A}jE `R7ҸxzUC$^B D>v=Ck^)_شo .^a!e'ԮDemܤ ng%:2PZa@OܲTƕ)\48jޏ0fjՒ)^H.VazzEu^.ez[O&iژ[yӌ7^fM5JCԑq.:]!Օk4V^z90Cv:!{__pĉ{//ԩ&g"xd7Gx9G=sG?3Ͼ0\h-cG5  mB.i DM^3陓9MRڥhɪØ)l/e6&kjJu!p"_S{ua ZgzB"xUOAcTAa LB|yy"bttcǧs3~\YBOw'~ڱ!VW<}2LHEi10 ؆`.2 <}觷]3rǟ:_߳wYhq&O͜*,Kz1!~ȹLp-V ]N0%8r&5BzP7B,-励3/F%4 ZՆuՍ\8陳篼@=Qǭv ucttů}k0|Hckuk8r~Hiy`% hc?g0s` Nu }ܕY,,\J>òfVH_-PEC2U5RXo&Gta0AC@jܩƗi͵ߔj8<цC @D *gAH ŤPp$`zaVag`ƼwuO^Yގ!\>uFGG-R vZ&//4],*jX.QWB41k&(fAAafɋSC#@s=4OC{xn)Zαgcx<#L_IB=[`%rj*hGYa9p!m۵@EShe2 ttݲЁok^% 0˃5O/\yA{!u7W~4pvR @XKS4Z M2ckg GWЛotx yݟ*kX90BR1p|Y38&eGu5[WJeV^ccr E )4MC&glRtQjMco#q2=IGh0AtSU5cPH&RBLy 8!ie YvzҥggzF 8nۮ÷{)(]N`:::044ue?٭ /%<`a.U`0XbIChqLab)K 1q-x #j-NidokCq<'^H*4 j\br,89pԭ];w-?PV (7 k 8#Tՙ y񦸲2 ADI`M1`{Bʢ2'$qT-#BhAF4i4MXflZmD\^H4=Bvӆ V.}qqj%f5 NQ(d`͗_G g|A殠JfZCmyŢ*I3޴x71`$]v`llvM7uqΉ^x4@6pq<(4Ą4 bYxix`C\"%84Lӂiu,^mP\T*+$G$ u_e h&tK]g۳{h@jJ cF._7ZZb |ߟ=N%l7|s7[É6 hލiu֩^4XO,2nZ844oKZz_D>2SL Ku ]T{MӴ}'|rQ"^ ~/Zƍ[nݺP( +BOȅdjY,4MeYT w҅gΝ uf u*Ts0zP: ``:恉Y("Bc]3i `΅Pp#3:s/ 4Yi5Ajys ۶hذZ|0U<'0 dsjũKϟ?ND5-X:zhvtt4GG4>vםkcBp0zi-,˔0AmV T#fڰ"aPb^$%u: ou~7[ߺ`YFӁ2 xqMס{B\u@64M3700׷~mRz_F W/: 5фfD4E`04]pS aµaƸK)}oxk@ M'g5c ׈{!S} / `L 2='hza̮ܺ0(6&ႚ9JR^859qRTOm"VZ`5A[>:Ynunnnޛ5 [^^nUc^la }@c%aۺGU5wbTK%-aJhʍ- 8|p[nehhַ&fffb'c{0(_GuϲiCƣ^:BLY(R6 $c2cFNQedtj!iܥyc5y]v:::2iLX~}~``;3L}:;; )yرcӫ0NbɅ*J[i(E)3[;p@p`G___'!,MNN^p iU4kZa)woe jYNZʨat׮].sN8}˲tP 2Lֲ,uR؀RRԘXW\i[κrJ֭[g gppR[.juuueŢՕICw+ fBo4uX\\\T*RTp SJB8!ܢ*U[W V*}ɓ'# N3Txj|t@ZTD*1.Y+9;k校r  WW)Ob2Ţ366V۵kWN>U+_嶖U i-O5<ͻUt֒-c6117aīydᑯZHૄh1l+ZW{-؆X~'Waï{E"h IDAT8R~LZlXbf`X㱫]k=kosUl2B ks!#$yZUUATܳ}}Pjj>.baa 4 o,B;W* r`86<p//?Ksxol%ͅo3@p' !(0,zJ?u# AA eYt]ᮑv3 [$@J`Eؤs2P*`N:0B903p!:o[O~N?xOp(teEY#XXPh4J| $ 4)<TBTjN"4M뺁A4-.hFЂCz0d4R#*R-D̅($x0E9bQOqxh)UG}t€t0A9|7jC_q<2,\pZokO\Ƽ!-GeBMtT. 1u8ufIhDp:q}~tᄑ[oƗ5 К VS^L{*`bb"%^ 8OO[8MLa'\ל>=/TWYH6- mG$^x} LFT43z5G@~z7~yws@NYG>>:a>“QgzRivbqyj`U ,W͉3?|`+nX~oO0/l|a yS:Q(ձs{geI c!B&KWfgƧΟ;E.j&+vmֿO]rw2&YǦC: "G$gbKer0;B]$1J;A1pl/}᳿} MCCC7o|}Vۈ~evK.\<~ųlLE)Bk;Gw_䶭NțcGĮ&h, ǵjmvqxniqiny KKŕz޽ ^'OU}{;GwݻoÆu{vW.WWfsʵmF0hj׽L& ۶]rRٹ?O"3A= 94:vwp$F-9,s9wrxRYqkkv#rK5(@;Aߣz2S S%;*!7?O¦Oo4o;oc @ʀ6h_mOė;::\.M*5W^ Z.;>ǯ<>77G9x@*KNnّr[nje q0t+j |^3: q@t7ΡƸK:2 4,,xyp3 v0b3}X5جڞm۶hYXZaÆQ]Ӭe?y-pN i M||>>ï`S.(>=ҐD]7&Gmup5x#ՠ!TOOi(<@g@iv󂏁OTDVCR~RQ]՝{K:uV’@` $ć$ɃxE61L0f0`l[0cI!JBgUguuuwu'|νVYUx>ۿ?~)=A4La8^X- h hN!ISt~j2PYh#RI^is$ɠTF+pY~RR Vƒf RC%@=;s6Ϳz.t+y睸ӻ! #>z>[{MVM]RBT'ǹ1d+NkDHSML,w&9/*ex?s)voT'BRԸ}t,D nUs*X+cM jT+ xrGdh"*JKB-j^WR"Dc`dxt '٨hwv9@1 ,M- /Xl /~/_ J)6mڒ^&0c(xf!&5p=woq'^+ ׾033ߎ6֬[g Nڤ" b1+9I™dL~J(B :OT @%x9K`R!1+x2e9Q|7.duK0ZP۲ު0 (ihԭjk^ .`nzfn`5Av .c#fƹR nw۳󝑑U/;{,f000;}lCrӫ|[/b%y 6x7qSFrټ쳟+9}vo~1:6O}ꓸ" ?r=xFGxgR 'J0< jøZ^-VvMIydqx>KLڐp8ue9- tLpS55{,L *K5rY%bX j5\h=%8<Z5 OlOaDM)-Bš,,p4e×>3_xlLxv/_s=aݛE\ ى_x(k?|pӦx߀{[~{vt+wo`@~QR hP`@RXMH dBYzPޟs[ǬMdYkI8?r j[H@ ĜpM`yQn٤ط ֬0]$;qRڸVsJg6t*@e"@92 cι}?hCY`8T )eEQ7h \1g;ZstuC~f nO/ݼiݵmf]G."-%7k7Wyauس?XO~ @RM*xEf}চ$&ֶM9倜ܔPڍcD(XN3,Z[c'/-dl$c 'Θ2@%Vmr;Zs i\--etfXy{!4aP$ cK8+x͡V3國f}@υ(GQVJITJA)gZkfmdnzfh]?IvNonT>O_ 9Ȩa"_G>g?V-@g`4H{%™bE- }Y}Pkyꉦ% I*A'jk&HjJL򻶂^a{jR13 *|I=8o0>FC d0D>~RJIOAE`b0Jch&)DLѣxc<DiL S+"o7`&ȁI`-׈5v+QF5W]LJCp˰P,LFbo 3EtZd/ ,gCʌ1IJf{ߛVLFh  (TS#8M$x9^Q5+Kjo)hbokG`%,A Q9jd.79AmYv 5.xu( 4 3&6?`<N3460зVl IDAT=N(oWyB"ӓǧu 5{]Օ^xɥ۞Σ`ib9bу L1h=NX ЈUءqBGa$MA[8v0@/[oQ`Rg1Z@@kη>48m.ݻdz2 6hcSSIbc]$(A5CnDCN ҲrWP c dOeDd"`s!`n!))Lde٢d7 Y$!QD}/,4gJ2 $؎uj]2 OЌZ,1Ac0qԍGdܓfKi_cK_3t͡cggy=< /">yu[A :oo 5đ8\qȩ[AK/|;?9DPK)ƍ,ߦ谍` ayq3XL`14Zs3 %m2D(i4b%6;o2PYּM(j0y©{$#D K=Y4\M+ki Q #e<@^Gh@Ho5nfsY0Ძ^X SJ@QJRq&ZXIX=z=>xvб]UQr~#؇љH,IWI?C 2OHǩqsr(6L$&Rr I( 2ySxZhQAt߭ܜCi.? LHӱPy^:̵#3+Rm ="wvӌ1"fs2-p!jOCk")(51gwf@L@k4Mw'M%J< 1 [`Cr0ňƓ`pjӌ|op&OQyL:b2It4$[/|3FY~#jҶ_1#wˤL1h a|G!znshUP s_hpg2mFqUں( /* <#&R,&B)A^ԙS0=z#`vo {X?Lpg*M\CVGKtҤ$!TL|\Iis <^idOmVהt]Z[5wt¤C%f-u5ۭMsHY!0Axȸ$0ӞWH^q&֪kZS@AkK7\BLp.<(#xPèek%!6Rҩ!8 cmK(%X1r@|)k d?oW?g`rC@d@cE̬ÒnϼK;ۗD>זٷEj lL5iHqjFAR%gٿJ[>M[ӏZ1-q:ņ,2nY[ϣ"/ Hz>8c /X26<(*(K%z\kDg(U,920BG KBJXPJ6J&$vU$4Xzxe+=5Up[xo7.:$Cd/9,tUkO6dp[$'c}RXL҈)ra+m&sNUjF C1ҿ5sK?y8ԋ,jjg]Mq9laDQGQ cJPX*%u֒6`&Й.U,yPk2880-L8 ck , ¨|a U((bPP36aI&-̈́&w %Q؁,~+mB#,qEbd)CrҜ.e5VH#g94ۖ$_P(,`k=pb) :'CxY'=I ~gKd '.{FVO`}ι !88D 47e<8a8kGp{ӬFƖH` 4nnCNໂ%RRqdq bߜ3(8㬄F$qx( Zbٲh8+ip{nڲdɒ+>O&TQh'΋T )őG YQPeclItnmȝ5gafD gد՟Y{V&Ef'Ϝ)8rR,ޱӠl@&^ AUA QJXI3J9BU] ?*Q I(" ˨}wpZzV9r62S,"PΒ6HGO2"{<3,uƬűP ɒ's V+ZϦkiE[5|1~ZapmP;םmm =rz FG 8e- K:Z{%&Aa4U9K{Ϧ@ u(i^X*g?A2#@G"8fF<Ӑ=8^UfgJ'YRĉe5L!,3ԨnWuRH8 nY;1"[-w mBa 7ey.tQ-U46J@ijF8DN~J)kG-7:}oZcV|l!>s!Ff=hEѶڭvY՚dgHt`*#;rBő%3!VY`RYZ\MݠH,Q۲8'<% [|Q:V6ˁֵno!ZEhiHfbZ)k FS8&CީPÈǙ6FRB(%h# $/dHM IWeҭ*yuAG'!9F^ةKӺϐsGx1`%0\3%Ic+~& &CSLETXzh,`#X'旃h]Ҩ B*bi`"{,3*DqG^/[b,P 6$'"?贩ioa暲̀2t 0O$"Bhc5@`00He ՊlF8d k2TZՔGE$KUe-iaqDs@T82G"_Z?瘮'M$qC3S&t!g(`$uU*󄈢8ӼXJ%eQH$;F#`}0٠D,SiCXu3!Ӥ$ٶ0MY:$(@MޏѴ3Wμd"L.F\~'}%6o~0횒Pɐ9XY+-u*-KR {`EmJN ޾$䤑ceTD4eQS )$)=_~I8T$oE9es-@UJ3I(9#zA ZKyAU4뮳&{aU˺o$YVM! Y Z'P '3܅׳ptS/@hDZNn2j>2KvJ 5Q%28G:h]xɠЙ]Ӣ|RpJ`u.\R r#jdHi+mr{2'Vu-(#Q"&` z݅FK8I*p.0=F)g\%Ux>yZRkH`dȨ{LJZRP# n&Z4&0=+̆g0/H,8~lki1-Ux13DwPS؞Bi4)S+R\JтW&: oK(9{VSr7zXIof[^ڥreo4FAlO\|AdRm5,>)/P0o|Gc5Hu0};gqac3v&1K ͔Zz`!`y5 vψ=ՙ-J(p)xhM7tH)} Xl zw :RJPOP !h*pDMNNlફW_ ^Fԧw RJ\8pn&o#opA}122ϳ*ݻW^y%,Yny4M\wu;=.2 o^[?olڴ gΜ>98pǏg?Y8p[lɎo} ˖-Fl߾Bxk˖-/_J)oqf!z/o;կbϞ=x M79chhk׮-F^"R{yȿ۔$G -QLc~K; eC=ǏaOcddx+0>>+s:֭ۖ[z XXXO.6lPg>;v`||W\q8f*Zk9sYu׾&`aafF###صkmt, @(Fq1H)1??%x _~3^.!*(ɛ/x$-mJKbVXz޽ؿ?z+6n܈|#?˰}v<3͛qWbݺuرcp غu+駟̅Ě5ko><8x vmyqUWaΝvxK_'Obq<^/ƽދ1,_1LNNc{V^m۶o͛ ?z(vڅ/6m Qհk׮o}[xի^u`̙3hZ8{,?y= 5.b!vZ]ؽ{7Ξ=({nr-qi8ܥҲNI>>u&׾xV^g ݼe .8r .rLLL'k_Zvm{~z<쳈fZ abnnΡql?V$z^a"~+V`ppRPJ1:=zNxlƍB nz*o67e@8ڵktRσVI;vpf1H)EzfNNNV"Ru۫CF3>(Μ9S8aӦ-,Lgb82 DWAw:<\Ξ=;eMEIJ}!ZXx3g H1ʎ[XXw\iY8rH&U 8qRYZf|Iz9&T!=zOPˋR$k bXYp{J%֠ex7Q iQi%|P@kQ0IlHeJEpU.ł2UB*5iע-e;A1FC8M!Q6G5R1Tq܎PayR@Hx7kg 㖷?VjXsRQ_LxO z0VA ,8q}\NlAUU?!o6q$P7ҶH6Ya!.C4IJ4 g)Geozb2O\tgc7i &!B% d1znh.THӤUBt.?KaA;amwB9H]mU?K{w!Ϟ~WpʻJYxh W>;;VPG:HpP0B) ðTKG B]A0HzEMt: N@)K'ڳ)LTޞʓNZy\j骉*b l(\b+Ucg39P.vO\+wOUZ{mxByG Ed,f'N6*us}?HJ6$9-hАHc-LS^9 Xw016%P h-Ab` PJ ۟K)_=?p yF6*kp͈X='#$X%,bz*[|~@:W K4Zy0x[L~;p)5)( /IضSYypkmɘ&l2wajUmϫ7LJJWJU.b wɕCICյp[k]>b*?gy lE$FAHtO!zX/3hƋ,6@r=F6vd<rj]L(Gow3UF[YIv|.hEf9ZԸ/)ˋR7tYs Up&=6?dut>lZQfb;_lK$K4RҒa($2+R($Va#?0+&E=%azm IM"^ >iE!|pfLpiK R6) E)"G@D܋N Ajd$iT8+e Q崹Έ+Xe̍h6N5U^yYN+0Ŕ{waWAh\./ֲ8\t)@"PV(#N1)C<뭷|zC.k{/.a^#5@)$: ,LC Qy6&g7cRktÛ\:ae<&eġ R#jPvr͙ {{QW+ӗ߹ d Mݐ2axptɱ':%bd1oޮ0ލ!l޺g*}Nw q>_!qYҕ'N-$ΥӪl c L j,49Cp ,Y \²͇`qτЌ0J0cgXtnT`jf> 0@e`Dc3 P& sʶgEz|^<#Gٳؿ? (,yu6w˭ S|JӕpUfE1t kʸp&v>c~e\VP9g $^/nIk6R-$!v6v?9P8UcK\ JGP 1j%V߀51&-#`|.L9Qk$ vBaGI,YرAd|Sw;QAA'&&cǎRF[vRuz\0(o.T嵧tҲ;N9ӵ/S9 a*Ӧ*b4 c> '-z9:t.u3u NA^\0a|85t+ea8mQDrQܵ0=8:m0|5d`@1ҪVc}{j!@[O3${ORÀb}ן߇с_njj0==;޻ NB’%Kӟwu ^ǃ>%EV1\{ڎnUNf*XWR,CcUA3Rd_]:֞Z3Vzmi ΀*Bs#BkA T+xn\T ] 9,~v<vО};1ǿu#n}mES03=6.X:p|qhnAmb1K5k/ҥKd%޺udq\0wXe(y^aBA󘟟x*JJ2TޖSe.kѽPzF-kr8]tZE?p?`r$->?_投 PY(m2R۔vwPx[f&ݴ!tf'1q3~=K='Q×M|+_ObЧX8tr ]k}C)Ǐ#"DQYhqchh(rS,D*TU%,FkteS||U}W 5]xUSHS Ĝ7 FTYYRJ%A0b4! qͳݯ;:?Gk=?mn4ظ? cf,aRIBRTURͪ!3+q<ܔA̛k6lz?~Fn4RWQqX~.*dWب"J shQ\y^q9&$W8ъvnAw]+bAOM+835f+ bu].iW[ml"ΝFqmn+%\x1: QPp1Dž#V(0tV)խ`n dzUZ.!JBzrK.Y@uvFܔ"73Pʖ)p Hb~rY!ҊrnC2h*7`\b+e!\.cffV† P. JrJX?|>BHYJ ˟eb kAS.PB9/A%~%Ȕ&47Íe%li]]PJZE.˥>oj "Ue/N֨JB7m-׬@ZE5A8,"ɥE(:71>9jQX4 xz`'4y.XTX\ \<"wtaN( ٬wJܡ4Mi PsdX+]d2ҷ,MI6B47tHG7»i2Z)ۀZ4 u^CJrGs4e4)Y Re:0b!D/PyGq04Abܙs3s2sX4NajhKhDnj .@Cbu֜Xi3Ma4t~mVDTlۮ+ŮLĠ0]Q1b63ߧE&ÔN*?o4W2P@7㿇KA0\*9VG.Z\ "P)#А5]8 ,c@W*V9QDiwiQYk(2z!LφpKǒVnY"?[ZZfQ.^^( /|&Fx 066۶dgc[Q$I{lfPBCCCXlYa3d|fQ%GȔ=G$"LVpY]jP5 µ"shM&mf?8?{%E( T3M3KE/`zzA#ga-w!sj\;52 X1 ch~"R1y-WXUK`0@qa 4,.dD<*#R~iJ%a|Sqc00СCD__.7, |E"ض B!DQ?~t_d`&2ȅB!8y$*a+ƦM+_J]-p8p8ٰ8(헧:~"L'ٴ&~BC=n'sӻnfaA |ת]Wih* :hPqMvݗ-G>_GQ+e 91uK_zsXԝtx!]Dž,Jf ad`yT7r #x#7 >fߏqb1躎J'N`xxhP< 8166D"H$MpqֵF2Ξ=RęnaĉHhmm(hmm|>sܸ 뢳k׮r\LJ~7,ObdW1kbFҨasoD ueez5lmY |^ׯVoޅ; tͅ*Uкhsݷ#^V܌\Bocgx0< lzkKbl|Yh1SE̎Blp P *. Sf|r,_r'O&''qWSO=0077k{a8rnf iꪫpu?9TUE"@2xӃ?^{-瞃d2'>ף5 (JXv-?S?Oᅬx@.$wFr͢I9U[(Go|:>iUu :LiDj* )r9t'Y).,øOބʼn.lĕbъV] }zv|@Qt eXK3HNhTAcU/Gڶ^{5+V`۶mÇd`Y^|_Ɖ'066H$ow}7># OO} 'Nヒgbݺuؽ{70JK/M6Ƿ-8믿^z)}YJ%\w\ݻ /099]va֭-ns8w\LLL7@84>O0 ;whmmŻヒ;vॗ^B__S|M'?46muyɸ2ټ0GJQb;:kF"ho~~>}Y@^q!E,-*k(p3cUŅiBϳϢ $I8+WBQtMPUBv\Ś5kڊ躎ou֭C:ƚ5kdj*$ ,,,qtwwƱcp5`ɒ%{qIضE(q1zLMMkʕ+%Kܝ~_9XxgΜ5\.,,,5h IDAT*‰a5l3ÔIn1e +kH"Tbvo?~KPZB)tY*jCX3(D8{~hxTdoR]\t24<΍bpdrPt,TL* ‪c' 6Rs( ]QF lݺW}ƍ*JE~0D===E.C&ի( wCu}`ye.aضmG=" 5k( "_X@+WĪU`Y8DD{Q}{`mh4AO~F|s[, PՁjUa]c]jU-voP! T*Z܃5kb!*eBU A#=B6AL`X @,`YA4ahlي v؎P עn䳅:Ƅ, 3ײ,㊹{}\EO>J ><* /tEbo`Ic[&1g)!-Leh2;M5l HĤbTuk*<+S*w DUM&ctlaGmk*B,12PuS|2{]ĵ۰uX҂#)dR8;2 *%08\G5;ؚUk?\btDVdmTĕ& jJUukooY*~t?K)S)EZCbnWs:'*(rjBSЀ6:M #`~DLEK4 )č ʮrsYwR [@XD,A@+,@-%و Zb \~-W] sssu_*s; ނ[e3+p* p;nB1LO4~F{l<hIm(Vbj#2? Ɍ CL94Xzu&=sy?ssi]P-3yC I{"P ;M|(5ԠNC[d2Ll#3M[3+:'>Z~F4hĎ2z;N/6@cŴF|t"Ũ2)`uiUb6ʹRTKAų|U4vP^LeOYkW RDĨŘqW.H=K;y2N Gh{DSt)vX\Y( }ō'3cBt3OXpYb}ju8-;˩n4*en`۶8HPjnLo,`,7 Д y"(*]h"[+J(ctCW]Txb1GshIhפ^%3UmJT@~D"Hm&][P,+JmOGel3hF]?<>J 5tqЩ65G*2xb"Jl.PKy~d3*_g*.tg.7Tf N[u^kq)Ux%'F\YCFYnՌDv N]#EdLN?=9Q}{n599BzxxORmW6sC7қHbdIĽqlԓQ?Lge$bâ8u`b-@SY٣ v{ Ж2fœ6C84 ǎQ(*R"{a~~U$Ek?fQd~-K d:U6^\`"2?f['ܤVLSdUbë Èz WU#(P.tyWGg%Tq`y<^P\Tl]#r6:t|V\}ppK.cnn{gG?7BLo^3P_L$j2B2rIy4J֏vjɦa:2ˏoAU3qd[~ϐDj%z0[/Žbi@a^ÔS*$ @.㑤\.ò:#UTh",]V$PxJF{JLcrT!zM$l=(VMۦq~ā+T,vh7AJؠB4>. 6(!/rKRP+5qeY(+L)P iVh eY͛1:: ]qW(ذa7}, ˖-,d"c9s9_kol(5UF0W5N# @%99%%!2tAdy*J6#L6L(p@P bn Ue@NSߵCH7˵X}CSR9qaXmT’%K,]`>l6x<3NR-q{*B:`LlNR9wkkkC:ƹsEQQ*0446@ 1<<0{ Dz!ey1Z2DA5[fS8E$~;US&YX@6E.4PT<ʏ(Va׶=Z.O{J-MP- *I[{  ׿u\vexG0??D"_x4MD">|C"ɓ'aٳ=FFFPTpM7ax07700=={ K.h3<twwoe]E,-܂kb޽8tyflܸBd ۶b |ѣG+@UUǣ>b~Gz}}}x1>>4q7ꫯ~@>JkϖT4Mc-(15 Z[[QU8#G k2T* zDu9sg/lj庲J[p8A,Y۾ ۶L&q߿PM|^z)z{{aocݺuǡC8r^x\wy'8^|EytwwX," zq{J<z!tvvrI|ӟƖ-[0==}kӟ4V^'x_~9^u]z+ԩS@:??ꫯb͚5?_|qUWE%kt1dp _6[L(<а`N݆ BܔC~PMڠ:DQ,}k8oWWWНl67齙ޢ5mahW|{L4qa  wկbnn*~_[@ ^>|K,qy>aǎp]{徵,/>{,0ޱ\LOO㥗^8H&mx7011ŋ[*P,H$ӃgϢP(@˗/a6ծjdY{uVirM(S%2E2u*uh@vi"l1;;1LMM!ˡX)#W,b[Xt)"OdEepG P8jPDZUf˲/F1==ɓF 5kp|+_c_ ֭ur=;k. &bǡ*^u`ݺuuttnÉ'o~ׇݻwGGO೟,6mڄ;Gw]zعs',k.?ŕW^#G%\cccxpwp<w܁YMhTHz 7`ӕo`jj vQTێɘѼyPV YKzj*V`] B-;pt@"ZH$\cccx7T*abbO~~a߇i|AB! S099{?PAȏ&-dqɛe#-4Mͥe6b1RN ͙{?KhƸa(MeUJUe :Tł|_cJYs];wiHPU˖-C ^L&uuu*JK/---u>0|A>Φ4M~tݛp lذwqΞ=^zs)>#Nc߾}E2q-ȑ#p㦛~K/w,oJ/1>>}sXjh~ђBb*sj %Cdj'[&pҎls3uyٲD.RR{BՒM<ԺNqm˗/(4޵krt<]wv ۶1;; EQс>&=bիWsKbaaxGP.˲`>ϠP(`PUOq_XXW\۽NQ*XlV^r9J%A}|Ht] 7܀EC(H&?γYS2?~کlq6>-.6Ryo󂧣)[š[% 6V\!db:1Ǧi)_5E6e={9!Y~ZHF@ D Q0N][ N cdht?Geǿ̨e4R?̢3/96/*& MRT:A68Z0Nmw``x d$vcKRUu2 de Y.>H*o([ "TƊ[M=)gC2DB&h~0g_oo*Sğ¡ D"6Oޱꁌt+Q̣uȔeA\u0€=-@Cs5 r})]נS gG~Ptz2Ln2M䀈VݖMO!pf[_0:6:80@A6 ઎n(ڀwݏAf(P1^ ÐX2dn<4g# ݬpM)N+)2O;igDzp "*1CCyl4-]T,%:k^4Jϡ52Ffժ4lZ: \Ԡ5FTJ%J%I^qмOAu4+V?z3-ʮ IDAT#3!21dJ !Ї{r1OYV]]܌4@{$6? AnTa"6o3+qz*Չؘ(uX~N]}h\@ 0o;.:?1[U峲JڏES4h(ى$s6PwIdRq#NfbzozhׅV^UA4C lkBPB`s , Õٝz4 WO+*,h#chz~OnͥzT<^eEL".ӳшK=轣y,?n 9-~Qgp(CD NydMs\oV5D+zb\x-ݚ[׽P6b,NYd j#/^ʊ:Ҕ;%(# CId2s&:_o{B7[ R -QN4[ jȅ4A0 hBaɠ!j D#RI2fGJ0œ_H&goC\BmfEO-.]lbAJ KbKf0B!"%n]ls*N>n|ޖXKm%s@P.`nqR Qj;mwʼHgIsfU=,8"J?/@،BHe)͏e2? ?5 uOʉdiMD($P$Gu`{XyY'ڍi+rz5q&,㷟"ӌ)DhIu\2n 1;9<ʬ_D2{{I74KM"(؆lV|)M ]뉫{{V4R*q*zEL8BCCԼt`fjY ZX00 o6Sxc$/iE'eǬ7vXNKX6YLN%}xt%yk&9  OVq$ wl Xu~t pǧ 4,sT۩0|T]188ȉ fc܀P(%CHF _P\ybdǎH,s}tB_xr~YGv @!,Lq7}/:nJ!,iWQ#[~)9 EȶpՆ߽;+ yTNqVUqWhr(B.(Ο?X,SN,Z DZl29sB7n\#sZ= d/(5bhGLDB%)5dh$dN6M\ ֒Ɇh*kH)͆mJJ:+^D1 u\כ]w\:TEuT-ZyhخV82oD @6ӧ.ڊwylہ4fgg u%h%!btK_WYG%:Q.qEd|acFEmk$xwр{=3eu(/DzY\kPk'8Vl/upؚ2:蚱)֭[q!e=X,M7B!ŢEP( 1Ї|$d( hmQr3YfH'>Huj'SZ}#&vrʲ,81 dy,/< .mfse8z̹t=]Mx?ÅiPmWQ]i4cٮ.$I48{,LUW]95\s-Rl5BsUqLVs7C~fFVT#e8)5:Y ۏ_^177u ˲T,_3͝`wp1UR3sɚ[y]u) $RX,ƽPTaZb +Hr(Vģ:ffb1"xd.32l,XAⷉ(V.l$)&&ÉGx]w9_2HS@4`>RnX(逦d rucTl^.]d{KeTGZDKC[H`L4"p& o\,#l#ʣ73΋Fu_<6-@6W4T6'D(R, ԾX,"Ŭ( $קEǹ>=p8h{Xl/t:-G>ǽ[6BFmvP%QBU\!D#1n^ ~02dzVd2GwXQTWT2:F}zZZZp!DQX UUDP.DZ~p;P(Jv|sCOOoG{{;< aӦM/Bu""bbb`gSr\.={\>Xj wヒ??Aoo/qؿ?nvl޼O'N`bbaK_^}Uwxp7J~?AUNFV?-wyIdYJa#`0Ox \ܛ.hcm*t+ ́aCV'T\7ODVL?~BFx҂={R  ܹs裏裏blF"@OOrR6oތ~tuu!bٲehkk(0ߏ;S./ w>|{C?ZZZ8p|(O4MM,ՙi8(Ra&)noo#9b̏#2#yRɦi" bƫg "2BњhCbQ;bmqbӦMB f{p^;xARq6L MLO׶U{Ӏ( Ҥh؇E"LMMa޽8v`Y֯_w򗿌~^ĢEF1::l608R|Iڵ V`k/|MtvvbٲeT*!HG??ƿcݸpwػw/&&&p]wqݻwW_0Ο?[o7nO?y8qK.-܂|Dž invy|BXQ,+̙38w3<;v;H$d2H/d(:G\F,úun:r9j*Z P vڅ˗cXd ~o똝Ů]pu᷿-8-Ze˖СC.L M ?!z{{Fr^ 1d/|V+94:V^iutuz' b~tX,D~M.jP5ʺuW~콑 *Uji7MW\q$:;;yى ೟,TUӧ1::/?xm6ݻVŽ;/0776  … $X})\p---8}4^\pzzzo>l۶ \$^{5\~ðmmmm8~8Μ9CS-[A ȑ#رc6n܈?~1(> ϣNBP?̱m?7u>oȜhdyaGsR7r,>Jk^@}Gxп(ng֥ Xԅ {;VsP`W?X3NsN>Öea֭x0 tww㮻B8eY(J+80;;(={矇a?{FQ.d(۱sN9sq=`ll ϟG?p]wT*/`jj = [n-[)ݍ[nH333سg-ZL&*$"E}`:];GdSO1[ԣu^v]F6_.ĩTz,džuοk]=09O@VH4vۏ\uZ u7 'YS-&v 0ML/d2 cӀXbG)rPL7h!ySwT*AQLdyAuDS>qf^<| O<z{k⭧Ytu./|l'`?fu֗jgq #LR<^KX:W .vcD1k32"QX,򑯬T*HR ~p/`MӐ1TE6MTQ E؆~6bIj/.~K=f *Kvyku@@ӫmbk`A/]2^Iy ~;PuSAMET SFS⌟OJGldNiL H=TIOY&,rPw`ÞodX*lg+*Ouoh"_]rD2 N"yndA\bk쳩 eNKD~$qRBL1B0(50ީI͡ tHU(ؼnff: XPEz%4K4y],H'NdN|\{)ɮ[ҕ)*8hdNi׊d& ~ d9Q|YYeN@(2SGס# cN8,<{T)Bjf(@S ʥ>ڲ~`$n6-؃Y#:{ H:kpF3;qӰ>8д> #+mf@%HS+q@ ؽ޼t1MҽhPoGPQ8/t}q8+.:VW*^3Js_0E̶TKEK4E4{suN(Db(9*k6r [hJS 9vU("RVQ}j!)dsNeu i@6 H>؞;>z g4:"(˾1!~82+eP f |(W ~4u.}' mLAGO+eBT4Q&]{liMjL~* jRtT}Xuͮ,[dT :^g HREM_sm&i \ƐbRe:YԨZQPs'-$vjbbV| ]T BP1ԌjT/bD(p(hawZbES@`Zb?Y.D.9#cYxB*uŊF{֚0㜨pTӉ梫XQt\2!d3G|]~*F1ē-d)ΈU (' `.sёyiFR7zA.\rt_H5k0_(.!@ViK@ğnPu3Yd~S< :AE#UpN:Gt 3Ak{I!=HŅ'~]>EVvVC(6… %CUetKŏ jܴ$?)m >Lctԃ;h~l)&F Q\'68U?|d@7G?Ԁ&OXD) m#CPuuTUE-"h%~i2~s]Gu.ldbC =m:Ո)#y%b2V2&=(4EWmN ׽XK1[,Ju/ZzES`,<}`Α,`F{R+we,{j4'>`Q. ~W6_-nZVty' eJ`qG7)Le]R<^A1}A:4ɸOO5fWTm$⢵\q dbddk4mbbyEC#8C4%]@:]G6L} Cv"4+XجkI]._ęUN]zD9*kpr^#TX(H̦Uy6`9\JL<&''p8ܹsF"4Ҭ ɑ:(|D Hb8:Hd"G"[+rFIL2BNӈMvz$ݻx*%@Բ\tfbiٮBX,.n( l8qfթ%EHc_V(AtQe膸8)UCLCVZWx-ʫC'ӓΏ&SfP^r'_VլɽjUmm`7uFJ#z5 z@Qj>>H4S7&FuCCC( ( d2-)l$KY-sQg IfL(5ؑF$Ȩ\EfYĕ9ڽ~Ѳ O|ߡnÏ%XaP͛88['K"\5(vẛىYnX#̀jO1NpiNd_1*S2e)6-cI$YRL<)"N'?-,*empJXUO[( h$_d-mG Wes(/_^ vyE^Zarw*Ϧrfnbn')I=xeب4f.~~1W2Ə LB[pi@DZO*CMd CQyzEz͕H@T*]BbeJ]'MK%2C%ښ3VUg3\k7g>-HGEl& *v $&U;2L$MJSu*cnR$*vQ bH#\Y IDAT pӟݮ5ck`xk5;yy5o ,M1mی9 5ĖaZEbN6hb c{/:Bg)]~b/{o#< xaBc ٦*'Wpj쐹)d(|P?ƚRZL|4hkkCkkkPX҂%Ml'*5mM6BN= U7GQQz*.+ʞ~e"C Ux9z; e]bHYz{{C677c֭رc|ǓO>Њ,4\H vLҳV'S[zJC~zlݺ5Tg2@OOOx]xػw/x <#عs'Ū&4g?Փ4ѿP(ǹsaÆ*(gR(=a=kmJhŴ E*+.8i o.7|yJR3h.o T縏=z{{fChI[;sL(Cב7\hЀ\.WE?rk 7 ꍍhmm3Ϡ)|XMMMPJ!Ʉ L"#\.׿5Jn݊{lNCt:T%\tMMMa.T* 'OV d%JΖZnh}No3E(AۿQHHMV^AAJ w\!w|< 3\j2:%;(RhhH&&EEklx88¥MgT*m۶]vahllD"@?6l؀'Obƌp`˖-x{ᮻɓxbyꫯ'NٳxGсK.s=;vo7bΝsR H&8r-[u0W}zj xp<Xf ;!<#Xp!l۶ gΜ+l6n!4\r%?6'[oɓ?R 6ld:GyK,ˑH$_ 1Y[l{gݻwٳ׾[ɓ[yf޽l֚/FFԘ/#>)* ۘckL0sYyy8{aPeQ}:n6`ƌhkkG$ЅBI000PE+xwo|_=Bם_~]]]ݍS"#͢ҥK1c ,[ 6=|>)%lՔ$ g̛7+Wą^3g _2.\+V`׮]hnnFww7Z[[l2\p3g,X'OyIt;;? pma{ȍvMX 6=bF6D"L&F axx8쵛rt?L1ٳdy\r%{088?Oؼy3v܉kӧO- !lm55bxx8`ĥ^|;{@0Z@/ֱжBFnhhoӧOwc ]]] a=KJоJ8<Ø7o/_fnRG}:HT ţBYsH(†d:cQb4N'LԡFWQ-bL*Иd>zRT֑ زe qH)1i$,\u]C^oss3Bw'|& >g~!0uԪW[jΛ7q}3 Z<سgVX^{᜸. رcXd Z[[+wvv⭷cH$q뭷bʔ)x뭷---8qқ>͢7\t4ۋCwq~ӟ?9:;;b \|X~=MC /P^&;Ja~M>4mGۆhzq1j~??⋯LfO< )LLs/6yЄ1H`ݺua-СC袋pW`ĉ` fB{{;,X"aժUp]\s -ZT*~3fW^FL:x`'?uTL2A{{;.2tttqua``(nfL:3gĻヒ o }wHRRbxWGahjjW\+W"H`ll ^x!LbsK.̙3ĉ&N .s|B+V`„ @{{;&NuC8nܹX`zzz ԩSl2qkonnƴiӐJڊ)S(if^FS'a$^{ h4,Bx7<a{<>`ڴ)'c=컡g?hhh|>18$8)>66vx8T*** !ô@6qqRzNbX8Ht:èH$144)%1::z*|x+@Xyغukh=g\wu!CV\b1_ΝC:}b1U]ym@FF8<<>=HX,׶Z6wJ~7<_~O~)k҅A4e &CdxxJH)%BB+W'dI=EKDw٦s΃Ν;gu]4w&/>00u:5}Z.»p0621#'Ӄ 5kWHY1ft)Jukhhh߅m\>cѢE_YfA=aybUq7~o}tCv>{Vb%SpcRO4I 8m~:0 ll*4CL$ :~ܗ5dB "r9𥦲 p*Рq^]1&ZTc^N[nDkS0GPimVW/z͠&ӑqY(][o@mQN5l)l([ `)P#i,!R)BfM$ +PY V$>a|^ea$u4劢9OGF)i)THycBMڥhM]A LGkFL7ﱉ0M8efŘ8樊_c?ҭ^Pb&)jH7*50JrmMmdr*-z6bcԩM%afVD6)6]|IpYbZs9>4ؼ<"l=jO#M`:|#l-&L>a3'BL)W6#ٛ0҆D<"h*yǃʡW.Gr\.1a:uyؼukG45L;NjWdLj;᡾_Q(o~Wʺb>R-VgS*+柩&ˠXtBzh$12x=(v,3 NkS|kSҮ"K$&| -RҳN!0VJSCTcr[ͱN|#z= MWQ4kAlLOOH cR_e rhSAb1 nD]h4w3Uڢ-LzGӡR6ID7_ QrzMԔ>cSGjlc? fs2M&Dɐ(^ bGHe @)DRD*٨N=&ʆK6q F:jl)OS 9֫4gУFFulBzLQ&zN6K(_:[g;qlib pRjioi+xsx,K#҆])`3rQ4r؎;FUQlzl>L"ߢf|c6[":dRMj+>IXMwhh(o\O+Åpt`͜fdL;hj> *̌ʣEآM+WȣPUڜ+El#ТMQ>:ɩd"IƱ2Y4Rt5T7VtɤBTE@EwmW:1fَkH혵6}-Ϣ 烥lGMe9ԿvF6@Դ(>tso;\Zц'N뺞eeDEstޤ#*rt_]x<\ׅyb5uQmS[ec;bn"Bibߛcâ:yEII.LۿtTnG kԋǃ1Ɗʀ`"e *H%xI&8qmފ"ك|>X,{DP%|9!022JB?,-fT\ll=:m'*w6[flfˇ~er&nڧiLa|j 67\BT.xR<´dܹs8~8̙uk.J%r98s sN47713g ###xb밒6]Z=_`Jx[kMF5ahH DLSZ66 |HIZFsv8ZN"xTCCCҧ;Q }S3gHRATܹs!;#ŋcĉ8p&L. f!O5폢Q E[жhC#u4-cWղU,Y65|QVZg[xK9PP׭\b RnlsCc9(c2!3Ə$I\r%ԩSxC/d2Ve̘1x/A$I+l9FTO;E,giH7-ÿitclm)tDabE^Iț0dۭy:,~~#n|> ^VWX\A\Bї;|]]]7o Ξ= 9&OSNT*#,p.:u RJb1|ӟF2D2D{{;j{BA-D͇B#̶T9ZiרߖE;m7@S,Osh΄碐|?ZE>5+T0Y#43МqFXT*]y/ vFeL2J0o|6m ZٳgC疁 ѣxCu툨Ga سgO5S- /='T@-msȀ|ΝrkBd2B`߾}Z35S}ھT;brO~Yb~kӂR\xxHld(GMOdi烘>ūxF?ǜd R`lh$W'b}Gss3:o}[ػw/bXh0oC<L/2^{iw_455!놋/ 1J楔hii믿{D'Nyرc^ypAR)ET*!J%Nfر7nD:Ӗ&x7o6RTT.6S/:/M&̝s|>z6e477# 755axx?8 BؙLRwG:FTtƠ"6i6OzܔQ1YW,Uuƛ1岬P%bw+ivӧyf,[,)k֬AKK :7\Sl"@TB:Fgg'qq,81gΜ;$Il޼øqlٲᦛnԩSSOرc`aժU⋱m6ܹmmm0}ttvvؼy3rf̘իW=tK/ŢEpQwÒ%KpUWa˖-xWڊu֡O=9\.n ]tQ``A6Y(R78Y[N2#R!U&6-( KL,Xu3ٖf5Ny'tR\uUM?</^z]tD~ꩧi&477㣏>?xֆ|+xwqǶmksطo===0uT,Y㥗^¢EpW_|N_x7oBOg?Y\r%x122 &K. [oaӦMЀ?믿%K.ã>ӧOWuhbcÆbtv- ?(-HM&A]"1>4O$K"bN򅂉 V[a۶m8r&O={!7 2򕯄3L&6"a„ صkpcҤI5kV)ϟB)a̟?w}7_:\f¬Y#}H&طoΜ9m۶all \{|M|A>ǴiBE .###8t89'OСC8p<1}t̛6YY IDAT77tSB,[ [lӧQR)̟?X|9>+?>,Y9s`ĉE:Ƨ>)L8۷oDze0||_;5kΝnt'N5p0՛lʸ-BU6(8*W#i/sãLk:M2tB  톞}Y.c*Xr;|p΍!ngtqd+&MwމO>$fϞ(n`5<ٳͬuscϞ=oUV X xkxSڒkhh( FGGn%:t "-Σf`|TUQ93VO}GcI81.$ 34SfXhnҥKtRO?flڴ 6m5eR{i/<88ӧ?Oáu܌;wbx饗~,^f3ѣa3|:ǏP(ફ8 288Eرcxqi„ ?ϑd0| rTQرBT*AiڮkACC~Gř3gBo:9r6l/~ L2f! fz`K $A6Wz^Qje!8dhPq?jGK:ZojlL{Ǐ8E)n2\êɓPxmT*X,}iL8X xll bҤIaljj "R:;;҂S"b̙8 V466"Ncԩӧq饗bŊ}Qx|fYxS횦LN۷\&Lٳ\.#͢+LML&qžDLb ([vq@!AҶo!w~Ms磡l.(=?L?tvP49BТ_ׅC'FU-i9ƪdO:Oeahh*7ץ=5*K}-b Xx1N:e˖+$KRuu?22Pn5F,fTln>6X.}7!5,mnn Uʅ (yr,溉D" ;@xQY$Ffү HqniZ7]555aŊ(J8ǩErSjӜtcc`rlL5frl$2sR.̞=|uG=3lf!k{> dz0[QD}jH3׬ Y*6 ʙ'\nc)8dy#DsssSTx6},0+ fI,])tSu¶97)I޾첩nmvG \4O4d |~h2l&"YPL:arCvbXIXTz?x&Bd5 L2SJ9691|A=zj* `ڴi={vǬYىxCCC3g֭[2Lcll ֭R ׯ… qW7 .2 n6RX2ʠDBBO*655J$Hm_"RP*B<%шQj2Ѥ3X{LfnFwsV=5]>g9e3ln-QҩedT l^V ÑMT=33 nܶ!ڊ}v 4A]GǶ6A)FK8vϟzFY&A& elSLIo~^ +~ 1M\oPds}IhգN~,^B6]v2ب6*\Rr```*/DWOܫЯ󬁁XW_}5~_{,XQ"K_y?,-[W^y70::ŋpqaى;w+d|}_Cpαyf %K`͚5XhQء6m/ _f̘Q!<>xtAPD̝Q׀'f˛JjT>kC>pB60*ͷLk+s^BUUU>Dq8Œ\X`*]]EH@+Ӄ &{1twwذa.°v?^\GGG8X`FI$!yHѣxgJߏuq̝;|\pcXp!1m47ߌg}[lA"ڵkM֭Ã>Gb׾.a H$Fsss™QA؊"`6!Mi-63⚦&f7'=h&p '86U?V3@1HS^Ԛ蛠 _ߏI&aUW]k6\tR,_c``^x!q9̙3'tѣ\կ:u*ZZZo}+Bd2~8qf͚*kzzQ=k6%]H-YRِҎ1~:*"sQ>5E7 (6^9C`6|TJyVkU܇00J*_)pL=} :u*|߯:Mº~غEKK &Lrj^^5}ĉӦM ۟I=&)R`F(|8yPE6D$ʊv;g'[h3޳2)bӦ- qkLXx!G fߩoF%svX,V9hn=)޼io&6NZб6/_ꇦA~AG A1+~@\Z=LSFfJ0IyhJ~l#LLmCqP@A'SOPH0aKz^03Q;yR)rHQ^gF;3jn5Ns$$LزRrkT6\J=LVmxȧ8ltZ9┦CtRМ5gnH>9C;4\Xdoo/iRh3+:w-} d2i9!f?~LjA鶱ˊb8{,N<z ԩS(u?Ƒ#GH$"ۣ6-~uO 9$6qlo뜙r:6Z/ZnQ|[ůsDhf  G Ϋ,8r@\y#D\q\-B$5]̈́tT;s x  P8ZZZd^hss38JP*L&C  @6E:FSSSȡfH&a9fػw/x 466 |ܹsxBcf0Ͳ(|cX|>Z2vhH?UGӸ&pkƁ~z466Vy#(\୥bJM"-,K+}Mmu$!QSz U̵gd>&.n+=JJSYP\R ccAA;j6ߏocҥذay<ԧ>D"6Cww7&N{/qp5ذa~ 3g S-_đ#GJ022+xo-[`˖-Xb88y$c{G@SSGi'oR" %BPaNތ2>hK@V,\( .ub-3e _sW6ϙmr* zj1M9TIN}t@sWP<s1z 4Y9#8AQ~eS-Pf. UaRft4!W[x T> TnEG?ͬfM(9(fOvlMܗ)**h`S(yPS(򱘛5)rrQ͝dmenF J;^6``Jن0T>KC|PհiݤFRmXb~9`km*2'Puq^W6VzK%ϘBE3JҾ/=!+qΜh mhDIGlsD'54ږctWT-| _?D P><`/?~{xTgK?(0L#cTJXiۖ:Jjl)i 6a6>~q2\> B)~+ `ʇ'px©(gք(`+l0[2l 2u=|ĝgڊEZhV1ߴc>(8 ;R)ߘNJ#RS5-L(5-QQt:56(CJtRP p)qf?C~ (H&S.S吿<(81_]ROXulǼvP6^[#ČBxjOV,HE2%Gg ѡ|k6m|.4Ť2ڢ2S6Q`QM3B[t$ ,&!HMfB ija?$&5aUiRxPRp"P KN .\󊈃5$ik~a7wsƔnz*DyzQ 3<J"ЮUjvuL[zSvgi&hxC4Zg7uf~-|𤃄T(Eps=P^|zFc @y# pByt>渚nRU5. ~?Ϝʅ#Q6٫S#RRTق JH58:ߵU@ONeiom돛mPsnQ =JԤ\\P 3 (Acґ`gW IDAT^ y}w ~<R:9O Qm\b.T}潤HOv/¢~chBr5&s)bd |!X 1X?N*!%WnG,)ǗAmD}ljA 0C*( p sj`pC*?FH&G ׌2)ϦhL:2آȑ9"}0uү̎v?ǂP"ʠ`О UfK)\B]- -j hiflF30H(̃Ph9uw ,8ޜ0K˿v-I0Vv 6^^ڤ^@ CFevj. TV㺮K0sPi6~C+̔2g|jekAS7:t2.Tu샹P}sx<x^ L9`B|1p0s8d Ά\_0[NgfTR;(QfA.{ $!d%%+ܻ'+[ 8Pc>DEjik[OLH))鎋M󡘄't!/^a8sQ.$\)OOKMi̚M1u~TѪ_kZC'BBf4LzEX{{{-W|%Ba4>|{jq-śM:mmXT&df74_h7iRUr%A@qGI(D__IpezP% 8kR(`hb#7EG^|fvli\j1O(tp]'.WHَA 6J惣}:Ҵ*Dl^DŽE1P$$pe2S% +20I) L[,ZЇF%ʞ?!Ce c RN:Ȗg[)S*iCe*+.-#'XvQV/jk#q&5*YUʐ|pYp4@3 6c۵F@S(3<QR~q{2L&BI(W)dq΅6"EA#+eS*jܶ$G6(=ϫRWbdRMfCIQFe2Gflhhۜ( UEh:AI T&2x<݅ 1mpAQ]umQe.RzPw../"B;_4([ltCl'imkPlԐ?aSy8PSu>m^:0&lxcKehKl\xRV=s%=!O?~imTچz}6bQspx&eU8A"sX8kS)=kQզ s4Cl[6mٴ^6\2jnUV\ 0liAD-z*ڄumL;x nB:#7ξ+В* yh yeU6U >4Y=*omd)cn Mer)dµ-~bJA2A9PML~ebROS-t1 2mstof}vM;wIM*\BI ),Xx`g^8GJI|35!m3(l"Bs.`4a 5vHt,I4ߓjÂx50Vy-d`1Rgx/oq0(8܅_Qqk=8 iDUf.j Q1"6A݅h*ڥs7y=oT?'<3s`ūrb1HQQTQ`Pm7g0ui6o$%nW' w3S=KcArt̀5p8\1dLd[!(Ȋ@2y#6qs#Qnue[]kZyʾCw|_zJ2ߜ+od٦a o2oЙ&qeDE(s@`r!Xr$J~ gfQCÇ ^Q4[Q|W`_ V+eA Cey IDlFzŠmQLQfQ69nmS] ǁşWCyxw8\<߫lFzmR[plQŒ&hli` ~S |ԻB< 8\LAƒgp|o7\~/4(ÇąCɠE V[ǰt(|6Q^=jscV3|baL3EibMiqDS j^R2̋BA SN&sG@2Lq8. [ ?xCse <00ɀspC ^x0Q3S96E%ZE6L,Xmkpp8/ʐ,ȘR!N9nڝ K,5}=m5 J5YHaت񭒃Aq\0D#wG**dҖ F|bU({Trdrs&?| e +2Ar\y߹{;>,Ń&> )J",E,'\e;)9`lmˢ"lU옉X,JtH6mǒMzD !AA`{N8En)p0=|:)E̳pMt5fY bq v \ ܭIOH;慒rBd`N&PE#f|A'l#P`.Ql -.wܨmXR}x9$QCZro H n6=CC[E\2Jf]u^w!n{QsEͬX[ 8o`+saآ@b1^ChX6@6-0řͰWAŮ'?Rr/괌l̕vI4;h.5vI۰AWY:hUAdn~kN[l`PP[wBpFHIHL3)P`ۋ(./3=08Aa; qw]P"Ѹ3z۞r2ȲQ#e-8BIpq lʤU0lV0c0Ŗw`814TgIIkoG4> S xUl"( HAql6AqsxG_ix!D!W"]Y\v4O0%~bVt P̥ancyuBMH@1Q@I)&~fÞXn8.W 8%pA1) Abd G&-VDǒX]&AIt)gNA=<0'XZdegܙ.W}rr㮘oem~w7詟V*3m2(0H+K_Rv9a^;)ɐ1X֟*gIRHP cݺuJ&WH"rs)߅Mi͹m큐t3Y9[6n,)g w5A]J+@B=**@y/:KlU?_)7-'r/f(9uͺ%=-1uI;k `r5^{1Oq๊IFٚ7yJdKU!jO?%?ʾ2]x FʋMW$ݻw`ӦMXYY,}? w<&}D@mRJѾi*!ei|.$JDؿ?UqѾRacll J)~fffpE@VR>[5 C@--˙fGJeH,V2E@U}sY*pۭJ!ͅع:1u\(I+Uv<2Z/2s;uxe[cq'E^Th$bpcWiVZ:0DVs†ׯ 0;; 4&"2v4qG1$4Ŝ7S0555GzL8v{99sDZ=vΜ9u^AlݼVq:Q 8{,Jw#%^xX^^ƍq!o>pqy,,,`͚5@ZXPm>,dReJ)El-EƼ( 'Oq%R$6|zͶm;wd3^/{xZ͛m#]4@:ˈAyZ.wlCŸ${4E4oAH+dtFT]jyc=O-uϹ}[@\o%H,---e0/%ò/"y z`M?<~%{VOjJ,xmbP<ϯ$WXẢ~BsSHX^^}~*944ٶݎsD3yc,Z1'/EEӛ"(*!<_d)07nW;w?k[mK^ϙvjEuR1r!CHRJ t7tbbO=*JFT&ֲs$A@qy8AP0VҒg#̝w(v \t\ DkeAr=2 E7?WzFIDAT}#k|i_l1k;4B$o2{Jk"AZWpͤa)PP}!m$` ت6V\)ΗybʩE8\7y^2Oѱ6<\+RB}Iv +lݹZ͉?:Jl# 699vM7ۇRȡ/ E jF0rdxcX,s\ϸ2֬5G>E)DVŐg}%']d>'cd_ė3ˎ8U.haȽpGϖS3&\*;U:q0ѡ`VjEx(6,'c-9O˻AWij$1ˋJ:2ֲәϻ{";ك-UtedZK==>=c;(Jߛ XlID9J+a D ۊ9z\h ^j4Y2de].sL e iWXH\2O Hn`tQ{/,k3p?YmzQگAض̪.PN9Dё"bx¦‡>`aCz`/Q:93PTEQR`F"Z9Tv]@˗vJچ("J [ҳW-O$ovro:n^kźv`eKxS,x+BY3ӟ[>,q  dS δ @Ie@گLzrܯC# e3 T]9U]}{6rR,g2]ǡja͘= RYx wr؜yV}\bt.z,!#\Wwo>7mVRq\~2^9ij>4Zxd 蚉%@6wnwI a!l20ie_eU=1ƪRYZ%j$L}Y=<{nA a-oݷKwwITDDȮv/T3w !P.S"X0q|o[Lf[c|kR5q&ۖQƗG2XfIcZ.0 7Is\.gUǡ DQsȍJ.K'ifO+WZՔP`$-KKԙ[Ca\L2,> յҽqn=7 g2'S}u`JAf~sU=-+w ,2AH1 ʯM V2)P}֌}vf܍[m't.c|zn}A($ڋ3T":>M~Oi5I:CYRؑ0ֱ2UO:$Kf-ul۶ 'O?ݵ"?0* y#}셓qÚO v;VA P $He>:dkIeK@” V $:s28:*[.bquP0|,_G[>>V y%PMYڿC(jsQ(‰}r۾s3[5{q%^/AVU?X = @Q_u~Pyur%UFu/:RH8.O:0޵8fZ)~Rf7ǩ+6,bca)`4V';Ee6p6|["mߴi^8Kŋ I *6\u PZMŮ;pSjy:WFҝcq^UYs'I"d6./nWed +tOnnX%ă[: \mo/|iAk9,,,*46d2SD+Cj@ aر%M6yZ{V76TG1)yy W֣ *ub:i8STGuq:=e'tge=oX*wꙁi?)2A:,@74Zǒ՗")4h4XZZXtjت'w?bbbdU&;"FT( }1{vi,//c,N@]ZZv.oHy{8 -V]6^Sndvf#` `(dޡ:Kqz|++Wc||<*{1Jt(m= &^@ܾg? Ν;!'w*3͒j[o3^P!LIg+k\]XMwBSBߟeܕp0$f֏SY-&jlbaaocYZZĚ5#_o ‚2*‚fר. 'O$:|gMڽ7L#lԴcm%UbY1^LoA"v#ˮpAXiFdF_9+M-v3.r§*ְ]3 H1W]O@J}2^HAV5}óǞv_2ŷ~r7c_,SVqhԦqQۮW'OrIڽ/A)lxHGR3 wrnX|2q<ܥ7WA+{-HĪgyZBSгTQF_XLq 8 fffS¡;wmƷK[s8@mAyuʓOx~0uZnp5bll Q+B$<bP=BdHj70@3OrJ\}zFJ]Jk 4pCn&_/Mbg"+HbkG )vfDhdV]{ry[n}+_>)Ŏy >_iDHPn;o> y5T$ Hi&5Pi`FyA;n=LUnFδ[bK5.^ߪ+k:HRQQHo)KJ!-ThXv K+_h5-{>=»ر<[@-,,d ,7:F=_ܼrZ/mW_Ay`066_B$Zk0wxu=.:f͏yTNm>F}1yqwwCckJBFjuJk9m@T0|?t]`l=c U%LYf„^nĉE gvy4 ʘۀ s(R[1&&c25zy^qy'OlwtJ%WUٲ,$iF 6z 6n܈;k_}3*ڽn,?#ooo0|$>2<ցxi#`|`VRx3>KkƟX^|9 Iq]w39%0P|=`dBPCvuz"\ 6ݽ7Ύ \RZ"KEW6b,kC)h4l6E8'E|㏁)^w{gϾ򀏛nڏsxǏi ~n@wu_er/~;x:x0=|^ʑ# ?o'呑w^* > o}簰 P,Q,P,>  8OrHg2SnQt;[tIL%^uU\4Xl*wei "BjWES0>6uk74P^zo|ҟX>||oS"]w݅wZ^5xG>և Vk6T0h7;x蓟{A:Ǟn P\xE> Lpʥ]jfAh C)m^ rX,y$X'<5^xRPY'X]acMȕvy6ٖvdߎYGmkbn͞DܷZMţvC@rebr#k ;^kɓP~*!#wq}+ˋc`@ vw܁x`I)/y{h%RxLk81Bj?i߾kT#U+ܕI^r.MM,C/?7+_xs7xGGǶ/,,ApVSy Z= cY4i֭{?MQۣ !ETF,]mBQ,h}05Q,! (+yc Q--..V^9y@-oʏ [wlv+cR.V[Fj! [ ExҕzK.0G۳oї^E-=*P =_9F+3\IU9^7cuc N9 >Mkz :wliCFTT<cJa`rrrԦk(Ka@R JVkZ];;77?>@z!@!׉'D%UwZW -ПGɐH1jB+ޖɕ'OqdGJY('orb|bjjݖk0::F+.Gpʇ1 EEh4.9s3OmaIFl@B~>| @%f1>RÿŒH~DDu jyľ>gϞoy{zoN:qx≳1^N,齽R|/Ə SSS7lذm```f !)FK6rP(Z<4^.x><cLE )EޘJR+hKsQRViIO^8C_ܲyz+&xhT)k"Ѣ0 S-DDS3=J1~ E^ H6ܫ'NJl`M`A6`gm~m sgGrΕR*8yO9ĺw&Wf8FPŐm.!\pw馛6mA?q9BYI0&H&x9|E 3\.?y^%t7qhAP "j`DvZ9qHj/灘|M,6H@BVZmeh,,7FVt;B$(BaDe=j#z06{ݻnjj@J%h4?y5,HPm 8,r8ۀE%20^rxbӠ CCJ_Y|[֮]jfɣ(>O0P)vi\`yE1ΘdyupcD !2 > 3&!$#e?@)dZ,2-Ø㯸B 9P()e/֞~ DRK\Ƴ9~3%hsye|r<ːM{쩼511!"!j5yCf>={za=~j<>f80LeTx͛89'_~_|“O>yKXllkG0*S]B{ =D gv6~'r˦M׮]!"/LA΄l6E^N KΝku0^rQvkCf**5D*ǒ* om۶ ㌳P((Ƙ"k MCy8z30===Riz(Zl6kz=}nyy|ZmN>] 2BLaݶis]^[E^k q).agJ#E R(zl'e,٭EJؿn=p^SJa*zAx?rߌ05U'*>s=R_v9<>5͏_ǣ=Ma|(H8Hw7ܰ)udq|,ƖL`H=*̦C\q2F$n̈́E;Jc"6tɱpZ2 Q^@ '/kmm64Hc7,ߗ?3-y܍is];<ӈMTQ{.]&Uf99jmyNe:ӈlyj{nl= [U;EhFS%˃n^樫Р;X|/f 8Tm$J>KFQ.1>]tLI #vMW6 -q0BuО7kuNutG<Ɲ˙i, . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: templateRow property string title property real titleWidth: units.gu(10) property alias spacing: contentRow.spacing default property alias content: contentRow.children height: Math.max(contentRow.height, label.height) width: parent.width Label { id: label text: templateRow.title width: templateRow.titleWidth anchors.left: parent.left anchors.verticalCenter: contentRow.verticalCenter elide: Text.ElideRight font.weight: Font.Light } Row { id: contentRow anchors.left: label.right anchors.leftMargin: units.gu(2) anchors.right: parent.right spacing: units.gu(2) /* FIXME: workaround for QTBUG 35095 where Row's content is not relaidout when the width changes and LayoutMirroring is enabled. Ref.: https://bugreports.qt-project.org/browse/QTBUG-35095 */ onWidthChanged: if (LayoutMirroring.enabled) forceRelayout() function forceRelayout() { spacing = spacing + 0.00001; } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Template.qml0000644000015301777760000000263512321005637031147 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: template width: units.gu(40) height: units.gu(75) default property alias content: layout.children property alias spacing: layout.spacing property Item tools: null property Flickable flickable: flickable Flickable { id: flickable anchors.fill: parent anchors.topMargin: units.gu(2) anchors.bottomMargin: units.gu(2) contentHeight: layout.height interactive: contentHeight > height Column { id: layout spacing: units.gu(6) anchors.left: parent.left anchors.right: parent.right anchors.margins: units.gu(2) } } Scrollbar { flickableItem: flickable } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Icons.qml0000644000015301777760000000400412321005637030437 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "iconsTemplate" TemplateSection { className: "Icon" TemplateRow { title: i18n.tr("Scaling") spacing: units.gu(2) Icon { name: "call-start" width: 16 height: 16 anchors.verticalCenter: parent.verticalCenter } Icon { name: "call-start" width: 48 height: 48 anchors.verticalCenter: parent.verticalCenter } Icon { name: "call-start" width: 96 height: 96 } } TemplateRow { title: i18n.tr("Colorization") spacing: units.gu(2) Icon { name: "computer-symbolic" width: 24 height: 24 } Icon { name: "computer-symbolic" color: UbuntuColors.orange keyColor: "#bebebe" width: 24 height: 24 } Icon { name: "computer-symbolic" color: UbuntuColors.lightAubergine keyColor: "#bebebe" width: 24 height: 24 } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/TextInputs.qml0000644000015301777760000001035612321005637031522 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "textinputsTemplate" property string longText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + "Suspendisse sed nulla in arcu dapibus vehicula ac eu tellus. "+ "Mauris malesuada nisl vitae neque auctor placerat. Ut vitae "+ "luctus libero. Praesent tempus nisl faucibus tellus semper "+ "eget iaculis purus congue. Donec elit tellus, malesuada non "+ "vehicula a, sagittis vel purus. Ut elementum vehicula accumsan. "+ "Pellentesque habitant morbi tristique senectus et netus et malesuada "+ "fames ac turpis egestas. Suspendisse ut rutrum sapien. Nullam id lobortis mauris"+ "Maecenas sollicitudin ipsum eu mauris vehicula rutrum. Proin aliquet "+ "justo ut mi luctus eu lobortis risus elementum. Cras sit amet "+ "sollicitudin magna. Quisque facilisis sodales tincidunt. Maecenas "+ "ligula tortor, luctus id elementum vel, varius vel augue. "+ "Nunc porta mattis bibendum. Nam vitae sapien ipsum, non viverra neque." property string richText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "+ "Nunc pretium iaculis risus, sed vehicula odio varius ac. "+ "Etiam orci lectus, bibendum in vulputate ac, tristique quis dui." TemplateSection { title: "Single line" className: "TextField" TemplateRow { title: i18n.tr("Standard") TextField { objectName: "textfield_standard" placeholderText: i18n.tr("Type me in...") width: parent.width } } TemplateRow { title: i18n.tr("Password") TextField { objectName: "textfield_password" echoMode: TextInput.Password text: "password" width: parent.width } } TemplateRow { title: i18n.tr("Numbers") TextField { objectName: "textfield_numbers" text: "123" validator: IntValidator {} width: parent.width } } TemplateRow { title: i18n.tr("Disabled") TextField { objectName: "textfield_disabled" enabled: false width: parent.width } } } TemplateSection { title: "Multi-line" className: "TextArea" TemplateRow { title: i18n.tr("Default") TextArea { objectName: "textarea_default" text: longText width: parent.width } } TemplateRow { title: i18n.tr("Expanding") TextArea { objectName: "textarea_expanding" placeholderText: "Expands up to 5 lines" autoSize: true maximumLineCount: 5 width: parent.width } } TemplateRow { title: i18n.tr("Rich Text") TextArea { objectName: "textarea_richtext" textFormat: TextEdit.RichText text: richText width: parent.width } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/WidgetsModel.qml0000644000015301777760000000534412321005637031763 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 ListModel { // Already in design guidelines ListElement { objectName: "navigationElement" label: "Navigation" source: "Navigation.qml" } ListElement { objectName: "togglesElement" label: "Toggles" source: "Toggles.qml" } ListElement { objectName: "buttonsElement" label: "Buttons" source: "Buttons.qml" } ListElement { objectName: "slidersElement" label: "Slider" source: "Sliders.qml" } ListElement { objectName: "textinputsElement" label: "Text Field" source: "TextInputs.qml" } ListElement { objectName: "optionSelectorsElement" label: "Option Selector" source: "OptionSelectors.qml" } // Not in design guidelines yet ListElement { objectName: "pickersElement" label: "Pickers" source: "Pickers.qml" } ListElement { objectName: "progressBarsElement" label: "Progress and activity" source: "ProgressBars.qml" } ListElement { objectName: "ubuntuShapesElement" label: "Ubuntu Shape" source: "UbuntuShape.qml" } ListElement { objectName: "iconsElement" label: "Icons" source: "Icons.qml" } ListElement { objectName: "labelsElement" label: "Label" source: "Label.qml" } // Already in design guidelines but should be reordered ListElement { objectName: "listItemsElement" label: "List Items" source: "ListItems.qml" } ListElement { objectName: "dialogsElement" label: "Dialog" source: "Dialog.qml" } ListElement { objectName: "popoversElement" label: "Popover" source: "Popover.qml" } ListElement { objectName: "sheetsElement" label: "Sheet" source: "Sheet.qml" } // Not in design guidelines yet ListElement { objectName: "animationsElement" label: "Animations" source: "Animations.qml" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ListItemsSection.qml0000644000015301777760000000203712321005637032632 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TemplateSection { id: section property alias delegate: repeater.delegate documentation: "qml-ubuntu-components-listitems0-%1.html".arg(className.toLowerCase()) Column { id: column anchors.left: parent.left anchors.right: parent.right Repeater { id: repeater model: 4 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ListItems.qml0000644000015301777760000003231112321005637031303 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 as Toolkit import Ubuntu.Components.ListItems 0.1 as ListItem Template { objectName: "listItemsTemplate" ListItemsSection { title: i18n.tr("Standard") className: "Standard" delegate: ListItem.Standard { text: i18n.tr("Label") } } ListItemsSection { title: i18n.tr("Subtitled") className: "Subtitled" delegate: ListItem.Subtitled { text: i18n.tr("Label") subText: i18n.tr("Secondary label") } } ListItemsSection { title: i18n.tr("Icon") className: "Standard" delegate: ListItem.Standard { text: i18n.tr("Label") iconSource: Qt.resolvedUrl("avatar_contacts_list.png") } } ListItemsSection { title: i18n.tr("Progression") className: "Standard" delegate: ListItem.Standard { text: i18n.tr("Label") progression: true } } ListItemsSection { title: i18n.tr("Single value") className: "SingleValue" delegate: ListItem.SingleValue { text: i18n.tr("Label") value: i18n.tr("Value") } } ListItemsSection { title: i18n.tr("Multi value") className: "MultiValue" delegate: ListItem.MultiValue { text: i18n.tr("Label") values: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } } ListItemsSection { title: i18n.tr("Item selector") className: "ItemSelector" Column { anchors.left: parent.left anchors.right: parent.right spacing: units.gu(3) ListItem.ItemSelector { text: i18n.tr("Expanding") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } ListItem.ItemSelector { text: i18n.tr("Expanded") expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } ListItem.ItemSelector { text: i18n.tr("Multiple Selection") expanded: false multiSelection: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } ListItem.ItemSelector { text: i18n.tr("Custom Model") model: customModel expanded: true colourImage: true delegate: selectorDelegate } Component { id: selectorDelegate Toolkit.OptionSelectorDelegate { text: name; subText: description; iconSource: image } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "images.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "images.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "images.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "images.png" } } ListItem.ItemSelector { text: i18n.tr("Label") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } ListItem.ItemSelector { text: i18n.tr("Label") expanded: true selectedIndex: -1 model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } } } ListItemsSection { title: i18n.tr("Control") className: "Standard" delegate: ListItem.Standard { text: i18n.tr("Label") control: Toolkit.Switch { anchors.verticalCenter: parent.verticalCenter } } } ListItemsSection { title: i18n.tr("Removable") className: "Standard" delegate: ListItem.Standard { text: i18n.tr("Slide to remove") removable: true confirmRemoval: (index % 2) backgroundIndicator: Rectangle { anchors.fill: parent color: Theme.palette.normal.base } } } TemplateSection { title: i18n.tr("Grouped list") className: "Header" Rectangle { color: Qt.rgba(0.0, 0.0, 0.0, 0.01) anchors.left: parent.left anchors.right: parent.right height: groupedList.height ListModel { id: groupedModel ListElement { name: "Orange"; type: "Fruit"} ListElement { name: "Apple"; type: "Fruit" } ListElement { name: "Tomato"; type: "Fruit" } ListElement { name: "Carrot"; type: "Vegetable" } ListElement { name: "Potato"; type: "Vegetable" } } ListView { id: groupedList model: groupedModel width: parent.width height: contentHeight interactive: false delegate: ListItem.Standard { text: i18n.tr(name) } section.property: "type" section.criteria: ViewSection.FullString section.delegate: ListItem.Header { text: i18n.tr(section) } } } } TemplateSection { title: i18n.tr("UbuntuListView") className: "UbuntuListView" ListModel { id: fruitModel ListElement { name: "Orange"; details: "The orange (specifically, the sweet orange) is the fruit of the citrus species Citrus × ​sinensis in the family Rutaceae. The fruit of the Citrus sinensis is called sweet orange to distinguish it from that of the Citrus aurantium, the bitter orange. The orange is a hybrid, possibly between pomelo (Citrus maxima) and mandarin (Citrus reticulata), cultivated since ancient times.\n-\nWikipedia"} ListElement { name: "Apple"; details: "Fruit" } ListElement { name: "Tomato"; details: "The tomato is the edible, often red fruit of the plant Solanum lycopersicum, commonly known as a tomato plant. Both the species and its use as a food originated in Mexico, and spread throughout the world following the Spanish colonization of the Americas. Its many varieties are now widely grown, sometimes in greenhouses in cooler climates. The tomato is consumed in diverse ways, including raw, as an ingredient in many dishes, sauces, salads, and drinks. While it is botanically a fruit, it is considered a vegetable for culinary purposes (as well as under U.S. customs regulations, see Nix v. Hedden), which has caused some confusion. The fruit is rich in lycopene, which may have beneficial health effects. The tomato belongs to the nightshade family (Solanaceae). The plants typically grow to 1–3 meters (3–10 ft) in height and have a weak stem that often sprawls over the ground and vines over other plants. It is a perennial in its native habitat, although often grown outdoors in temperate climates as an annual. An average common tomato weighs approximately 100 grams (4 oz).\n-\nWikipedia" } ListElement { name: "Carrot"; details: "Vegetable" } ListElement { name: "Potato"; details: "Vegetable" } } Toolkit.UbuntuListView { id: ubuntuListView anchors { left: parent.left; right: parent.right } height: units.gu(24) model: fruitModel clip: true delegate: ListItem.Expandable { id: expandingItem expandedHeight: contentColumn.height + units.gu(1) onClicked: { ubuntuListView.expandedIndex = index; } Column { id: contentColumn anchors { left: parent.left; right: parent.right } Item { anchors { left: parent.left; right: parent.right} height: expandingItem.collapsedHeight Toolkit.Label { anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter} text: model.name } } Toolkit.Label { anchors { left: parent.left; right: parent.right } text: model.details wrapMode: Text.WordWrap } } } } } TemplateSection { title: i18n.tr("ExpandablesColumn") className: "ExpandablesColumn" ListItem.ExpandablesColumn { anchors { left: parent.left; right: parent.right } clip: true height: units.gu(24) Repeater { model: 8 ListItem.Expandable { id: expandingColumnItem expandedHeight: contentColumn1.height + units.gu(1) collapseOnClick: index % 2 == 0 onClicked: { expanded = true; } Column { id: contentColumn1 anchors { left: parent.left; right: parent.right } Item { anchors { left: parent.left; right: parent.right} height: expandingColumnItem.collapsedHeight Toolkit.Label { anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter} text: "Item " + index + (expandingColumnItem.collapseOnClick ? " (with collapseOnClick)" : "") } } Toolkit.UbuntuShape { anchors { left: parent.left; right: parent.right } height: index % 2 == 0 ? units.gu(6) : units.gu(18) color: "khaki" } } } } } } TemplateSection { title: i18n.tr("Expandable") className: "Expandable" Column { anchors { left: parent.left; right: parent.right } clip: true Repeater { model: 2 ListItem.Expandable { id: expandingItem1 expandedHeight: contentCol1.height + units.gu(1) onClicked: { expanded = !expanded; } Column { id: contentCol1 anchors { left: parent.left; right: parent.right } Item { anchors { left: parent.left; right: parent.right} height: expandingItem1.collapsedHeight Toolkit.Label { anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter} text: "Item " + index } } Toolkit.UbuntuShape { anchors { left: parent.left; right: parent.right } height: index % 2 == 0 ? units.gu(6) : units.gu(18) color: "khaki" } } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml0000644000015301777760000000646612321005637031645 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "ubuntuShapesTemplate" TemplateSection { title: "Ubuntu Shape" className: "UbuntuShape" TemplateRow { title: i18n.tr("Color") titleWidth: units.gu(6) height: units.gu(8) UbuntuShape { objectName: "ubuntushape_color_hex" color: UbuntuColors.orange } UbuntuShape { objectName: "ubuntushape_color_lightblue" color: UbuntuColors.lightAubergine } UbuntuShape { objectName: "ubuntushape_color_darkgray" color: UbuntuColors.warmGrey } } TemplateRow { title: i18n.tr("Image") titleWidth: units.gu(6) height: units.gu(8) UbuntuShape { objectName: "ubuntushape_image" image: Image { source: "map_icon.png" fillMode: Image.PreserveAspectCrop } } } TemplateRow { title: i18n.tr("Radius") titleWidth: units.gu(6) height: units.gu(8) UbuntuShape { objectName: "ubuntushape_radius_small" color: Theme.palette.normal.foreground radius: "small" Label { anchors.centerIn: parent text: "small" fontSize: "x-small" color: Theme.palette.normal.foregroundText } } UbuntuShape { objectName: "ubuntushape_radius_medium" color: Theme.palette.normal.foreground radius: "medium" Label { anchors.centerIn: parent text: "medium" fontSize: "x-small" color: Theme.palette.normal.foregroundText } } } TemplateRow { title: i18n.tr("Sizes") titleWidth: units.gu(6) height: units.gu(20) UbuntuShape { objectName: "ubuntushape_sizes_15_6" color: Theme.palette.normal.foreground width: units.gu(15) height: units.gu(6) anchors.verticalCenter: parent.verticalCenter } UbuntuShape { objectName: "ubuntushape_sizes_10_14" color: Theme.palette.normal.foreground width: units.gu(10) height: units.gu(14) } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/small_avatar@8.png0000644000015301777760000000117512321005637032223 0ustar pbusernogroup00000000000000PNG  IHDRVΎWbKGD pHYs  tIME 4w IDAT8eKO+1 ?;2ZR@BBb_AbE;6,yTGK'b&iJ#b;\.`f*p "ghD:8""e$h lG6 1F13|`8$wUe^38==e4Rjd2!@QEC@EG33PU w咣5סR7 |/f'`Zʗ)bh4:s0*CB%Q a: ebqٹ& սpzMRJB{nKydQ٣ۖdjaSJ<<<0Opn`$͝mrmq37gJٵ^4j<:Y1tT3#T$zfXx_vUkb>s}}]F&ն-777LS>??w&!wwwG}I ޢctuu{_Vu]ӓ\IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Label.qml0000644000015301777760000000267012321005637030412 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "labelsTemplate" TemplateSection { className: "Label" Column { spacing: units.gu(2) Label { fontSize: "xx-small" text: "xx-small" } Label { fontSize: "x-small" text: "x-small" } Label { fontSize: "small" text: "small" } Label { fontSize: "medium" text: "medium" } Label { fontSize: "large" text: "large" } Label { fontSize: "x-large" text: "x-large" } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/images.png0000644000015301777760000000314412321005637030630 0ustar pbusernogroup00000000000000PNG  IHDR/.{@ bKGD pHYs  tIME ,IDATh޵k]S;i)CڊzTTB"ih-@LԻ i$|a4ţhBDD>0fFx RH eʲ=޹s>ZdrH߉*`)8 8>1|\3֪ l`0!粙ݷDGdv5ǝOsEh 4/l"Un +@MP vrxE9m#| S 5L|CIO`tr20.' V@WM, [nxBmnod= 2!Ñr/JXɽ8)kA|Mdjڤ ٣5HK|ҿHmRyOw9fKo&"ƕSj*:ƀs pUKq x8ˣ; `w#%+2YU/0Z*_#c1k?eVt5bn{SEZ003zTy&L; #yN~(EtL*sĿ JKU;t>WF(ijS8,M!>o phHRN%#q >EjTJK<8%."~NAE]H3MsK'W@d՗_I{* k7raFYc< +8+U/ +ʂKrÓͧ uaU_T6=p/ ZQW^+P);;:ZTtdJq+'->Ot,cEM?l˯5b6'Kz&10 !'zKэ3 eX᩸M -{Ƥz, 5C_KȎ./! \&`pv|8و+i" xbY9)RҢ]A'{' 㢦 )Jµ#eD:ɞ6F~'km~ݳN2Oj*K6ϜҴ9 <&wԚf* 渏TVJu BERlJniFmmZ]QG7#ߑnI?.">6Q׮BQ;:t3%+ XǺb &LIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/AnimationCircle.qml0000644000015301777760000000176212321005637032435 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: circle color: UbuntuColors.orange width: radius height: radius radius: units.gu(12) antialiasing: true gradient: Gradient { GradientStop { position: 0.0; color: Qt.lighter(circle.color, 1.3) } GradientStop { position: 1.0; color: circle.color } } } ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-galle0000644000015301777760000001201212321005637033274 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { id: gallery // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the .desktop filename applicationName: "ubuntu-ui-toolkit-gallery" width: units.gu(120) height: units.gu(75) /* This property enables the application to change orientation when the device is rotated. The default is false. */ automaticOrientation: true LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true state: width >= units.gu(80) ? "wide" : "narrow" states: [ State { name: "narrow" StateChangeScript { script: { pageStack.push(mainPage); if (selectedWidget) { pageStack.push(contentPage); } } } PropertyChanges { target: mainPage flickable: widgetList } PropertyChanges { target: contentPage flickable: contentLoader.item ? contentLoader.item.flickable : null } }, State { name: "wide" StateChangeScript { script: { pageStack.clear(); /* When pushing Pages into a PageStack they are reparented to internally created PageWrappers. This undoes it as to allow us to anchor the Pages freely again. */ mainPage.parent = gallery; contentPage.parent = gallery; } } PropertyChanges { target: mainPage width: units.gu(40) clip: true } AnchorChanges { target: mainPage anchors.right: undefined } PropertyChanges { target: contentPage clip: true } AnchorChanges { target: contentPage anchors.left: mainPage.right } } ] property var selectedWidget Page { id: mainPage title: "Ubuntu UI Toolkit" /* Page internally sets the topMargin of its flickable to account for the height of the header. Undo it when unsetting the flickable. */ onFlickableChanged: if (!flickable) widgetList.topMargin = 0; Rectangle { color: Qt.rgba(0.0, 0.0, 0.0, 0.01) anchors.fill: parent ListView { id: widgetList objectName: "widgetList" anchors.fill: parent model: widgetsModel delegate: ListItem.Standard { text: model.label objectName: model.objectName enabled: model.source != "" progression: true selected: enabled && selectedWidget == model onClicked: { selectedWidget = model; if (gallery.state == "narrow") { pageStack.push(contentPage); } } } } } } Page { id: contentPage title: selectedWidget ? selectedWidget.label : "" /* Page internally sets the topMargin of its flickable to account for the height of the header. Undo it when unsetting the flickable. */ onFlickableChanged: if (!flickable && contentLoader.item) contentLoader.item.flickable.topMargin = 0; onActiveChanged: if (gallery.state == "narrow" && !active) { selectedWidget = null; } ToolbarItems{ id: defTools} tools: contentLoader.item && contentLoader.item.tools ? contentLoader.item.tools : defTools Loader { id: contentLoader objectName: "contentLoader" anchors.fill: parent source: selectedWidget ? selectedWidget.source : "" } } PageStack { id: pageStack } WidgetsModel { id: widgetsModel } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/OptionSelectors.qml0000644000015301777760000000773412321005637032535 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Template { objectName: "optionSelectorsTemplate" TemplateSection { title: i18n.tr("Option Selector") className: "Option Selector" Column { anchors.left: parent.left anchors.right: parent.right spacing: units.gu(3) OptionSelector { objectName: "optionselector_collapsed" text: i18n.tr("Collapsed") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } OptionSelector { objectName: "optionselector_expanded" text: i18n.tr("Expanded") expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } OptionSelector { objectName: "optionselector_multipleselection" text: i18n.tr("Multiple Selection") expanded: false multiSelection: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } OptionSelector { objectName: "optionselector_custommodel" text: i18n.tr("Custom Model") model: customModel expanded: true colourImage: true delegate: selectorDelegate } Component { id: selectorDelegate OptionSelectorDelegate { text: name; subText: description; iconSource: image } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "images.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "images.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "images.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "images.png" } } OptionSelector { text: i18n.tr("Custom container height") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } OptionSelector { text: i18n.tr("No initial selection, scrollable.") expanded: true selectedIndex: -1 model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/nav_expansion@8.png0000644000015301777760000036315712321005637032440 0ustar pbusernogroup00000000000000PNG  IHDR{5bKGD pHYs  tIME.#W IDATxwGySo%[rcS)Lw5 @h;4Zǁ$BL3 `[ 1ƀ.V+~={9\INu_=w3O<qZpD`V% ÐF1)H)Egsd thA>o;( W_3N?+//z8c/Wj՛, ^WrQGsawK/s:>(k{g+I`4|Cguk?i6Br !u}ObEc*z▛cz2Gs=X7b͚K=܃W  104J%otoW9_ʗ?w7r}ګ/[s9OzyK_.Z)_;R!f#8CY7䤓= RJ/^[w}>q_oz-BeϷF ~ !mW}G<%HBXa97u-i6C(MSdvbBQP*U߽F}»ٱs'skT74=5kSOeht624`@,=Q-"0B(wAbI""%MlňwIɍ)-)e_#ث؟MݍkͬZy䑜Oqi3Y|9ǹ/{nn&_s饗ڻ^?kɦ28T9t 5?1_=SնTϝʕIN3y#۷"uF||ӟ[:?|}_Ê2597Oo~k~~Ծ^FT٬sŗ^_])'? owocdd,]x4 TR2>Mܠ}x~I+Ah(/"`uNKM43M?B6[a<8>Jy 8 h+ZS5ARQ d5&V u_F8 RM_P g(0n<^ }n8^U.b&t6n"@ZAsUsyOa?|裏F9xya.{v9eW?}E"B(J 0+Fau{3R.UFy!QHa5,_~۶mB"J)e}Q$juE3 Oye&w`ew%ya, вloj%STtZf#t]Zx^E硁A,^_F%_[oRɟ j_Xk>6lX*yՏI^-\3Ƙy^B-HkT|"N8uMЇ "0TEcbѡ b xhm)WxByK>aR΢Qha1 @VVo)&HcA{~uo 46 i:B`,C{{w1g}l}gsAC?g,}gVcǣLOO3;[/|><Ţ7:|ͧV'{s}t)|ڽyt$A<y8F o VX 煂s$C4M&'' O)5&#Rkhq^OE;M >R:cD;Ϩd׷ЭoAZ-KZUH Jя?.%˗p߽q^74!$ËF`׮]A0`ZPV155ٙ5~cccXZ[ ͌`;;x`={XlSSSrQGg4ldthUp03]':aȃn`\Rq :33S,]R̎0HFFaZSgjj 8 &?D4` %S{(%>\c .093K^ec ;w3<0RۈDV傏` Xd9| /T*%v`xx֐lti-k_Q&H f3&]IZ 1*i1d3-! b̿2=3ƍ|Ru$ggY "V* A`l!`vcZy"bhA*II%,!Ƅ})ӅMJ껅 J vn>o}_,] : 1w=TI~A2:0lg8RJ0&:P!4.iB$}#>MrakV>ɳtxxтXa6,!L7lBV$WQ)URo67*4Rd3hR† %,Z4"""+ riAGjjLQn$TR!EvKc^ʥ@jhWrB%g>PQj HtDE==ᔈauF76qbx|ϞIr4sQ*OV$&ES+8Z.6 thi6,he `ECt`Es% btY~ FpPI ]ǍE@y8xB+#ECApɢֻnN@ZAA CDa #|cexxm۶qWfppc ڂP0PLJDOqC+}-ԈD_LB2X)Gk`9cS`*xDBjAUOBkbffw]l|*QL'f|Qu//; kda3O?7 . HFRZd‘Yc]6fN$`]N,. S{v GpAX'Q3336RT)#=G i*@H =BF,gUXi "޽K:XDDJZ~ݾpa;+y#*jQOU.ӺvyC.꒩i9I \Ql'RJ4m1:KrΈ1Ƒ!<ɩ=U=1lDIH4!@m_i VZRMh`sGC/L싱GRD]XR, _uEa+r_صKƚrhmjC[FFF:t½_|InF|BYA1-tlm(@I gkW[B'aRcl2fmä.BeU䑇X"H&B[!Bq@FJb@hDY } ](44/Wv?y>*T-jW+18YNNmR4zh xhODYi#ntt O1AmWڦƻZ{3UYh_m[}v-#&Qh/SZnTo,35dT !^TDJP(H" &b©{,ȘmB`Q14 ] [_Mlo8+aUiZ!p2T!V`qĶbWpxl{[E['m0[X[U\jDkŹ?^y})g%XIʍ\eAW#OnyR)=X# a\-FS&2GcZ +QY|h3=N/y?Ouc(6"R`͓ȫITm?}Y~<X5x+27G22[oxv?$j$r ڰ 3'g?Wj^1<2ȶ-9D9ΣR 4:A)J(黐pTi:E. -is:\TۑXzί=xL{$1Tl7N׸H( $ ] ߇o-*R W;W0ohQ0Vm>w Ͼ_/y*}GF[u>Ua&EM'<i&֬j5B'1`k ŊcV DA&pO̯U GX{)K6˻g|B*Vkr{ $<gcJ9"Q`nc LfS]0e3r6We@)%#l[uB ,† dy͢zXcӞy&lg_|Ms~G3%Ӣ_tozcu޸zOiR0 Ќ Ju~m! Ȅr&_v/sދ8E;q-Eq,>;%u3 F s E#t/1xRbQ\Q~i= 1H< ;1&,.`,&C5R?.GBɼqww,t|t\jc_nr[2{hn_70f*:B;QZ1j51I&ߞ |]h|cp2yO9ӂ~޺;1Opk=g!0g2H;$]6]e{}iZ1}76(XkSU'dSg߷9[cL;#zTo"H=r[Z*P}KTr$l. #kk& cCQQs5HcQBamIlP ;nnuZ|ᱢEiCߗ@_`Q/TA?w]S2 ̑js+.9/dCđ tXg>>V2=GgVɖ.wbYgQ`[AVBH4&@ f+mtNƸ@YFGV $T&aF$;,D6tŁ IDATEjEYiY>Bܳ$k;$ذ"KϻL#^*uiRA^|;OʯV߬뛂].dG^WZ,$Pdo{yzᎣb֞CvUVEɸD ='+uu="eb娹:W$kA(cW$%FC ע^mj߫PFU&$ՃUVI,QX{ yǕT6;ᙍ :g!sl\A?r#u}ϜDZIdn M y2.ݔ}\nXf6zMxJDi&ݦWJٱ0rrݔ=YYʃ2@fsg[vi2듼s=ӆ0k`-z\=8re,/x"%Keyk`r<]"}][sӏ&wl6~7_i& bJH)rr Rh')f||s:*D3LFa~B&Y"#+x& Y%jf]2,bf]"na|eCkm7#ynv v6 iUkԭ=o mn$R,zuĶ!*yuǬN.## uS6&#kz)L$whF^3܍MayuI,cD;act[wL\|c}|J`g2U2 2?]g=hy-(P[rTg]"&PBR{5AF!%(js!֢ɲ.0glN:T, #آwP2Ƭ{)p on žx][kϙ .Ҝ eiSx9.]#`~HtSmP^br_Yq?B`ieCaڋ6݌X:.rUK6) ֖͜/=Δ3I/ZeNߍ0UvŖu/MgZkeѨ jB!9 #0;;M D'P %^Ei64;l?&W!ˆO\~3 'HEӢ4dF{ &{h<ɞ/Tn!(,,5J0t^$ØY̺ !mIV9~>U?Fvaz]dD2f nPIv=͇eJjk$ a.= w^9<',>yN$r{BZG1Om319^&}U*Um^J٦;y y>Rr1!BjthF,7G ч)%,e.+RihQum;#WE&þ t {Z&O 8OiVQCK,>rz0Y#NI0bDۢI|f֚I0":{ĵ썁F3-`myƵUjul5q}H>jm^L[ !(֝d%+JX*ڰAKi VZbKv&h RQ+Q0Ƙ󰀴&H}ˈ%ߓ3`E 15)F3H);yԴޠA[:#tҟmvn h3tsfN$CX3ŐE*Y(#A#cu/ <=i8&V*j;9ca:Gw q6yHCCybJ^`l4/U$GuгjZk0H2y Ou7t}d<1^G|2:XxBoʵJ<cXė %%sssmz=),Ah줔QxBE'`62րq`7T!Z]C|"hcv$ axF|,F fpŒU,@IB U{ w M>NP`tt4:ǩ0{vEcΑ)\>aE.D T2J>`c|&rV[Bg&3k^Z>pw000y4hO9S/.굯)t'BLnˇy(ݣh~tybet2jx~;Zc""~HяC͵Z$7)H"k4{F[ث*أ@3;609@(%VIQ Q 0==Wd9pB:8%A4֕$ϳ6nߺ%-FY2ڀ$9{T22$fPg>ѝt V 87s˱Ox \%֭JfNo䕥 @*#o+mjCZQo~%㏽ԸKXQt>,S,"333|cfv QߓaC̲t- dY9?g-_ʅ^~66m_B9)RQSJ$]%m=Mt@WH"4hHСh8g1t:@.TC=z3 '߅JWiS&Ui| GجauHAyFi i4BsBD)Z^D"jYoQ0Am569y&jC8NÍe<yx;pXCAVlyS!J362АG/0hkb@윘ĭ7gV`jJA#XF%fۧnjh& %A01r'P !OwO;y'o)^<ŵ +=\tELMꥫ en E2== *X<-[FTb8;v`ppr֚Xd =ɖ-[h6,Y{{&e֝ UTKT|OP8` /,333rTlܼ]vdlmS{}=Uopڂh0TS_p^ol4(({b5^MP`m4 J1Bx+lŽ;XdI<E`a֭$Zy1 S{rkX`bb±uw^G6n& C-Z䨗7P*JQo4h6EJRb&dEVX֚7233ŋqj"/^%f&U+QV:#8J숪2VW2[4ҁuQd":_d^RDzf~=yNf\Iyh㡼*^*%QX @7)Xkl0c=VpSie+d[ B=aMuòE=S;PسΖM!w޳KWUTUfjL#u^,h ހm &Ct!,+Jԭ%ZTrȊ঵ P2DS!KH 0Oxʑ4k(ܙdK L$VK Jm5֔A]neR5[x֞(iKX2s3<#.T ͠W\ʿ}uBs$'|2K=s|9w7%3_g}f=V /i8'Xv-͆aɲ1?N P,_1F0l߾/sW-BuDwEfys3ujsaѠ{x3?~#\C9_UW}Z^ =:mpۭSH\#@zMs!ђY{Q4B^ׯ_/η+~}݇`O\p!a쓞N>)Q(j^TBÛƟO88|?lxhv8OyظA~Ë9ø{f9ss˖-+9g>KEbYdl>YÐDZ :owMhB`q0S:# ǘQJuH,Iwڤu@H:uT#S'g索g3C9,J„!wߍtfV,̎=HSTE.1Z-RoV_4f-֌êe,߄V ;y۟î?`xDr,2n̜ϢjT-XUdyЎ̱fŪ ' FMٺus ,͛ٲy:mW4X>/=r<[~{ '|"07753w&]ëMlt'7\.x O{ ʃ4s]LNw g%_^~a64i4j^kk4B*@r޹8]vo{'q뭷22d׿ ͊qݼffX IDATJ̛Jŗ]MO.W'wpeWᇩ7/O|gO|˿ছnXIHjIO:_WQ+Ʃ ̡u jw?}}q_/w6Nx8V>G6l#jɓJcG9cغA>x%m{ˮ9O{177 H.r>|Y42PO BmSN:;wKyk38\@n}ڪSJNO`F4]NmY[/#3&y;ȍm1fXUZE/N:^Ɲ43lo!TL4 Ɇ=!EIQfxd 71^Jϓ )4RZβe:+tƝ+I.cU<28Te˦u+SL"䐃cph;ƹ9U}1,]͛RxlnԢ1+`;EYTUAZ}C]Eu-m+Wܹ쪨٣\vYb9]w+o}{8S_eyof˦LVXsS-sɥWpU7kvQo{ԵU:HcajX3&+cqRT@:Ǣ7BTdk̸Zl(Qbqct%dÀeKXr5wq;zWtPnX(7O|x?=,~k)XVRF aBdJaSLlذw *pS駿5ԚAJQ>XJ2dlH*ٛ[Vwޟx;5HA*F`DFmؙ1t5NNZ36VcID" LP@UQEMp{Xcs>{4>>ֽo}/e#Ok(ӟ4_W+ع @ЃGQo7\"@@t0$mlL@I0XEjZQeFddvWRa/tGwJ7Vj~%q(jԦ,<'H[]9"+lPH0Mc'JĆ! cP;'jZIB[i(1>2ebzZbEM(A(k 6f`Lw l6+^&zXEL\)C2p?11+c໏)RCY-E:sT-)a"om9~}oE #,Ax<>Zm}-:n^wJ!SWk }}}@H`hh_Zokno{'"5M)M]JQ g9i-<}eيJbA_OS̏cq W|5.m3e[s͛׳e.߲۷20ЇRJ?#w7b+ Yȇ? }-_bdh2id!.Rd7\ 333 o勼}ɓ'׻ n{-pӫ(x|An}۸|ne+^7+T DNN5ϟٲuj0UDг{lWAsB]$tQ.LOOs9x"sssŠYԭųRdFB,MpA 1jPQz[mO-8rPyDi&c%ahn<^c*"D$qlV#}7l޲{/DžFۂ}l\ϥP(|L&` Y!FFq=\|nGxNVL6cFXE֬~j(Wϱmlrݯel*U2# zJVǎAȎJQ+[]ίʯgw6Gɲ,AQ(%f6u #S>V7yEg48{{Dg>ڽ3Ǭ]שB)-o-~J4>K6^8E`늫S8qy119 +Z.L/|\}\p?E&PJ1 3XЊXgQZ=V!JFBJ({Ag_)|򓿌x9v% {cWqo3ᖷuy?';wۃl6(gjU¨vbelE xRiZES_6\1dhOtzڣP +z$zuץYΝ;/ş_җk9uFcY1oQE"݆ݳurY03-Jz=8y)VHJF5w1ZJPv"wT̀Vt@Ah$4t8 ڣΔhl#[L$BXZ@k<1BR 22:d0sAF. M5&/6cT BX}cA!Vl8[.[gVp59qqq_xw쯳z@_*M!λ~ȭ?>8/puT+!:a"(fxxO 18d("`#}7FyG9y(en>?#5QJ /{Mԃ3gN& (9* \}s̋LMg|rػn|`Ϟ=rxџrlX ,3 ևuBW(*2GkrZ0<33\??w{R,{~G?I>;|2_Cx;EvyArV[ pI~??_w>a .CqU÷xҾX-}Щ7v` +y=ocwܭ|1\U'G+oR+MƼt=T=q,VkswMv8SVj}o=/d P9r0G_u,DScG^6G>Oު!DG) sUfkkƸi<‘6`.h#qxgL f`k 8$brgfQB@0_pq2T=̾#3<[ ?brb뜨+k䐞O<8JOR4SM:?'XXXhDVJU>a}TeQ/bu~ĺDQ̳?ŝwC¶<3gxG*FZx}1T",qyg9ԓfrNs}{u7 ž<ٌORGq߽S)W4b1#癃V*M)jF>q0032f Pߧ|ȷ-FqlGyԧؿI֬$C2^"}Ϝ\\ק??/^B|v2MKx8<}L6CV_~b$zN~W? CSض|;L_F3O?w] Ǐ220\^)\<3OzP_{>#=`)xwG~j+-EBPױ,E2mTD vhZ)%zquU>Of=|]̛?~AvwZ%d"Ž+9s2jup}sgW WY\ZZ]H?73\e#SSSurx( Eusq'Km'\q31HX+8<[.5hX\:"rekHS\;nGdmفZB<[*T(&&6*& b jD G_;{fjFY/W!%_*]ɣU VđR]ӊȺ S,-cQZsyRL's+QeΞ=BYWJe\eƍƔ!F/u]ۼz6[/H^8rc\% 8A=hsע>|uٺe pqfضui`'O25;Jĺuo&'ZѣG}6oAXtP]Tu>g?_7LN09˖EDıf m* ĉX R044xkyEN<뙜l=7o628&e^|Er<_vY ym IRd2lٲƶm*2Nϸ)ULNepp+I8ϣf֭O9r)%[l1$Kٳ,.͓ 7RTU֮db|gr)'&ذaq%kfuifͰ;l]r&TMXDUQnd< Jc9q"Eb!pZ P!JP @Z6'wrz]dE&hv=d ԕ gU%#, 5*3q.L Z*[yY|=dxv2h(n2MłI"rӿ|l6˾Gn]Cno@\icv=&Ų5c%yٓUFijYI|2cےX?=77f0ɶ>]s4ș^z"5o-( UNtxMMs1h$fd&xuK(i+ @2c)%O[~~!Z2 .Wqx饗=F,ܳo7Wlڴ ZŋnIhƘ.kܺ+t~)2gyJAKЭb_URN290%-;*WuL B-M԰ηc7o͓GNIx""8q\kyJk%\,zjyL0=3<ٜ$ Krz}QR(GZ.N*J`.Kc:J|ǍR!&K5q};Nt+Iwqr6!Z/]22-;M.Ee9&28Q,":#.m) {$gL_Iޗ+<=a@ILXVLhv*6׶ќ Ni5)؄m: w'!(t&x5TAU-2A0j|Xc{j{`|?ÄB_-o& T*%nV#|/~KfETJӼ'kEeVDfځ-A@QI24Z Y.2ٽ/+>M{x@t`7J(,m`9,OA/Re|_.\`/,xg9{,?0N`dd!8w:MW3, IDATm\H/f/RF>.6DJds\.ZLbNZBtScǭ]_E0?,ٚL۱uN7ܸe"Msnɗ8[UW\@_j±S癛5۶vS,4 (e9lZ-[wPtsa+yG9~EFw_meȆ tTְpGDDHPJYubY[YJ.u"ʤѮ<ꑴس^.AYR,N2MvʘDP']rޅd,e[0]1]،k5eo2qy(4f&225\ӄP]BmFR*VugOe2*z[JGjz",у\;nGZI샛yhrxH&YQ4Ͽs, 1EJHi-wSX*=b -%ymg7??#"X6g뮻صka)8C__;whS%'MYR3*.ek3F1ވbKJ"mzLhTt+׃8Q̔SBA(&;x%t'"mz@ZWn۬IDHJ($R1#cpnǟY@xz)'57WSEvNqaJL4-C_}E܅89 '-Ux1Y-g䤃Ü<L9b3kGL?Z+Wjww$\`;N F):Xf7Rb%S-tkn t[CfI{יKav~Ɵ䍘F$F4u[ەq箷g fBK{WL(%)#jK\FC]&")mm!MnהJ/ h]s~6|P4}ߤ!+wؗqp#Sò,fffXv-_W>|_fm0wX(PHܼVz57JGN|V3EɴopAwY M"uIH:V8-mؠ@`c%Y X:6b:K.Bh˕.\%GI+!L XG"m&㸌,$w.^8{>z~ݯ~-Nh܌bTLkϽSWrTW젯P@c`{oz57lDXf5v 6 "z' qYD;DM쒻[{VS ,[GCCٱ&!efPU YFr&HE''=,M$sk,@3-Qq"u;ڮ kPJloT.vZ~skwMm{pv H&K4QgL#᩻u!Sh,C6u//ou_p{ХRo4(WJ>_dzz|>|ccǶIs\NV{fEN:Q z<κT'4]+|EJE2gNʨZ8?$Ve|\( ,'*Co*2ڒ#NR慀IRw1D%$Z0)e060H/2Wjc̔ں>YZBTYE7Crî]W%icCunfosNn-vMnN"04Ioz.aV}Lte'`ʤgIq72j?xkEZomJaӈÄ Z}Bi=6L6Y'C@,q-m"7" " n*a[6a],abl q4Nlv̝;{ Q_ݻ*4;O rkRz%Xm2RD9lI(+mVuF&RM35БeURRoČh4_X"&4zZ@&cF(Q'_.䤚,fQQ]j mo>|ZW@^EW=#){|{'-R&&J6]g+&V*lM[ӳ84W]u0==(gΜaϞ=\xݻww0dV?V;Co.A*cS@KZU3Z#B)!I)*8B`Y1a ˰r}RCVHi-͍Vt!1(A7BB[cIj۶m IlM?:q ܱKJHP&`G'Vu*ssШSUFD](Kp|$Jh.ssQ/mrP`iMW"zzmB|p2k[ΩS8ty|ߧQgy;AXDk͑#GxqlrcǭE5׿0 ]Ç#Fl={šq(D>G%eE^&y0P(pǩgd2TLLg~8s h&b-Tc ]vP9"mw eOR߭dM }2;5?2ZEךI^t>j %ݽ^2Նvdqz%{KpR0+軯R_* ۶mK#]f,dKgv+DyCw#7}*]KZdYywl٥"&^1Beԣؓ2@j.?#2L)B%\F3$M3J`II6E>"Y.^_j脱>pCD sUS4%2F]TΓ=,!4Ϟř1Vt+1PE"mzHk^{qT1IBI8h`KIo,^6z ~z+;ayRuVnz p10__}Qطq|oB]wŋ//0;;Sadd07Z~giKw# Pvߎr^>w7̛}vMeaa#G0?NZKTb V6o5v]=v|.cH# .buyH Aĭ~>oT-W:6RF~s|s UfŴ8n&PpbҎP(GKD Y{7> ٳK%ַ2==M?5+R|{[@w:VE5=9 Qr*T*jCC Jemz2~ KZH6F2K-b)V%=N֠L ~@ȶC[81.ϢQ]ŠhCjAP+trA/V<FxjťE`͛(*=Aڡ5d|^9.zf%rPAH˄p`$ t7{|{]U+~0ayn˕W^:hLLL004w-ӳ<Ѓ\ssvN>Oq<>?/fZ|i.NM/@P +\wu 1?z 6sO_uvÏgW0>6_fDqZ70::{JjҤ \wk߿RJTbtt=o{3277G Lx0;m3J =Ή\3k^*ϟu`rr\E&S48Ξ=ϺuX*y(&V!k'h'XV;{ =$^h5nS^A.͚ٝ  :-zb>w]EUJJ6KenujoZſ{@*OiNS+-n级(`y~mus^$.RC6QmPVQ6V1$,ݰ\ HzMl;\VO-&;qM8BHJ* 5Q-RzR], yB?;7]NP8͖M1~n|,WO]ٲQj_2.LȲiEF<4 *JcjD%E'-_}u@2̹._9O± epn{8}V(JhiCj-1PfIEr8–N0Я9,]Di8 <`q?vn}?q: 2:y߾@R%5vz (~…< 8R1nf~13sѰSFӷynٿ?۶]/҇T*ζmy#hsIyشl}ӧOo~ٿ &'zx]'%`Mіtha{G>߲]_?:Z|F*8ǹsS4{} KA`rr_{yx#Vƽ[ٵk'p=Zxqd/rw^4޾~,Kя~L.KZfxxq8ș3g~C>ajj AE1Lkאɚ{v#Q.d AI(' Bfdd\6KFZ~\Y0ı|p^Z\ap` '15qPgS5;M *݌FP]nEqP\1v B),==sfh&iPA#MX7+ѽ%{<9hRW*mty?D5DCxe f\@e #lKRaRQT(r~7rkG< R)jđFŦ嵴Xf߾ O? YZVj8&Ah;w ?`Inr{7x#֭c|bT*;vOGk/>O:Kďw]?/z-vXZmAE1B%B~g %qv)\ƫZ_*{ԓpz"bl"7$C`0J5؛T ]ZZ؎$ n&D4kojjS&.~)ݎ2_,r~_H9Pl02\\*12\$R1f癯KK߰Vñ$ibe)6*4_E`q.XeTCbA"ABBbP45jĬayy iKzMz%{|.1 8V0}>\/[,bg\cҰMa 1׿Uضŗ<*N,^MoGwUضhMo ]YnG[SJgrig3ywuN:5'OK@ll6 ؾo*;v'Mv6\.[]vqdK68A!m0 9Yu%O>qRdhar ?s̙J$ oyWb ɓO=e-kB ^HVS䤩g:{nĺPt{]W[ҼWmX ^amG̠Bq>|M7idjmNFATJD}Eg6cyQARjD[Ag/%aʡdA@ԉ(iDPRv9mD1DԿ[Lp4yi4*8AAAL-,P*Ek65ĂLc&3"2~AZ qɱ0Gm$)-PaDs\%[+bYPx"LWzc\ʥF=X+w@9*me1dxU\}l߾bKK%2d x~p?ݻTKP,r#ctd[355/}<˲8}epǵZܔm'=Z҆]Ȇ =zi[9}rc<w$"N4?`N!_VUqi#p! OE( #}9yFm2mcbT.paa_ЖeGp /!h+81|#U=SwRVۍV,RLNN2Y4;>`xsk" FG;p͟dž'vV)aJ%9b+]ӎukַ{)8u(q]rF Sؤy ^9 Clfbb\Q  %9!BZXڴ8=g|<0Έ8pI@ ^4uor?_T*$um$%b۫/S{}~Tɥ xUvܰaϝoF) :YWK:K,XD+>mlkT6Z7c[V[//RmO&x2mdjnQɰOIGh%5#-b!azj(j|Hpz"=5[_2s9l S-a E_qO)Tš1&&X^ qwTu󜙹- HQX@\qEؐkYaq+Z*;A@֙9Ǚ;w̽&ϽSywyfs:E9,y1&'(8%-ZlB!/kQ[8"\ZE|t I0=KE[Od!PP |1U!^|׃u}!)H2KBG*23.~@;XCT2g-FdMŮH)ѩK< m!#VR{L[0bcS ;15Judit`Mj~Ld%D$$:Z^bj4MlXT)յJx?+y؆U6)JvG$,| 4U*BZ a@ :R+,G-(8RK|a,P-ZHrPF(KRq]yldܔUR 9x69[P3? +4 0\aiM޲i*AAmb7*/ŢÔcv޳VMrüs3̓[o= c{BƲSUniP D`, G():Z@ {v8gL5#OP528#@A}{STv`wp Z~ū@BWO6R[:r 72fKqyE] ML>G^à=JZNQ uq<&:,g).=p>ρR0 3[?KB:G<;2MM'ײEAnğ* \K捃NT HT.X~)h.Fch.3RXMb@#oY$oYUFy`Ѳ͖'6{n%|OQmQ*:S8Xii9䤠99ng徸K\ö%~yY@csqyy/űMri4-!y.>jka;FP1@2ݒJz]~i# -Ywy/#1eܩf22u dnc[T~yGk"DX)VGטhtx0I唉DN&֞N14;`#)d3'IPazL$*&Î{܉{<@X~Tt gK9>>4N.fhiZ8sBcBߘeу/'./c:m(8=e) I@1ЁE%;ɜkvXol-t \˖`>D|IZs1!.rMwo[9i PB *l/0LW>Q(Y &''3!0z=[h0d>2IV zS<[%QBY8DEQiCex<89$i)g=g }bwJ%{ W>++{:i뷟tARdi.+Yx'U4&3$h盧%qM:bnn5Vd =(C/#*)W ˬ9̠,aea{v)8մ9|X:\fh0Urx,]–=l~l ~g6.`pU0Q()ia%/P߅jI:cEBȲEɶ-O^Ebh`Vm ?@aFGVdc=d9LHS3OCwFEFK|FDf&)<ŌM\wֻY"zd ީ;Ox0Eׇx"֗FS׌i8X$BOX4P+wC/͇EдZZ-ڌ^}Tz/{z} )lzQV;EK`ք֒'vN¢MSavvr% KyԢCRTr9N -B0=Sç-/ۂZVɧq;8avD Ki[wW4|2:EZx&+u[j ^YedW泱rc%xF7=A&eko=p$]!QwT,:*l|#F=O*dIJ)4gVvvʪhʶ;aE=e.=~PͿꌝtl[Ҭ7p[ u#xI|>oP7xe">>J9JMEwAF["^I[b4xr Mf/p!Gsfo]LNAEQ@>0:8Ă1r4|gvw,C Z V %Fxb69h5fl2.[:V9wوD)ӧ,0 $ ] 'uytzoI:IH<4l3$!4jăs iEݣ52[f^VSiYh Z,$:tʚZw TRf?iW LƉnCڴYBjP)UE?bEݴB ߏ yǰs \IHtM3|>{-P %MVx1!q5`) [7gvLXim 6B];rk~gwocGp=0XvNp4?_ǚfwDÒy{t3= ã1iJ%k4pPl(V9eĦw=bw1*?* ?pKI2ұ$ҔR*:08[= qy+a5O=&Eגend]y0z[BQ*Rv>06/Hmm掄 HI ZE]6|߀e˱Po Hl[".q*c+R>2H 02J OX8*5;-E {OƾêUv5kpq.pX0ʃL5h_tlk0ymP{XrV4Mr9(CabS9 .3-|k-u `|b=;~Ƕ;)}`=ao}Ldi:.3X]N%e1J^zrؑE!o)z 3FݽT ܰ,'OVDW8o zxkK65T8Pύ{ R{ eɕ e템Jp3V+{'MYcBJ$+/A>L۶M_H|!p)CK𱐸d0R"ebVQ7:)sya^D0RZ(Y9SWΥpo!x>Ҷi긮k:zFE:\JEhY~4 Csّx}D$mCc^(y2Qp4|5N|& ^^'`$ (b%fS ||:qomI\-:" NJ Prf.mNLC B-}hIaPZJ-9 KlP7#-@P(apZND h{8J'1ǍIYEHAT@k#^k_{1a.Kb TͤCKD+ -EDFP|,ahҷj!8si voPN,zi0 E8,2NI Ű¥/G%&,!K#s ?M-~8a쫫RHf=]DdPвKqs1Aܵb$Lx2s3xNgo(T齁EEK۶c\=TLqrQ փ>Z 롥@"J(PH2x{|s0Nktd)ihX!Uhmf( chXK2r܀%l\Ϙ[ ,0h]r !2^iˑ+dd/Q~)|PM ,|'#<؋(},-aB4"JaI`J#uKzmM !l0RMYNAYʒYsioFקE2_,)^0.Q k%Etr3g ?3~^ir>X ~eVWK'\L?^>r'EKn7ȮDgs(ֳZ%F$RT!-U x>n>;C*Zx$1P4lX\qtOMdi>ZdK/q %u蓮wZ;Y29sIsoZzѕ=\Zi=6Lj_k[v<'LI)fb)GDHm)i7u k82Ek I1LE"$cYf~ʏ`iCz!2IR ^Bm$ȳDzͲR!XT=22NisM$2$xu/Ɍ&-0}tӪ¤d߽gOdCݛ)K>{g0W;@kEP*^'4M8e0Zǂwa),KU^zaef<$'YA)nU I'!<+06|p%^SoCd)<`drG֙6s{oHkeR=Gh?Z}`|HJ[vH2l)a|<]_jȠl6i֪ ) 4k',`9RFhg-sFmlZ1Bk±&˽8Etłv_iڀ'˲.Q"w{b ؒa9d-¤}s utA{֠8hÉ'[S]5_r/Zq]4} {&qİ^p)ѴVaZKcNbQh}^V *Kڣ_FU0KFcwIK8F"@j۶i & Ok<磅T*( <#&k`DRh"gVmG#j^'a֠WBdSOGX氇$^lA&IVYJ`w& uF<-f ҆t*:J4OxK!;D[ZC=1EJ"Y he>*Aˏ$?1̲Atz]ZC>^2fI"HMWDNCů[9=c|g{rE +&_O18|ՎB;Xdvv!Z-k( VE V(_̀=*JO&סŰDݵ͞P%ڃڌ޳y{oo.6xmaE=BA5wdBXmT2H\īyed(#T^<ŮZ>v7e*vBq9!2KB-\eRŞ66BYvy؁>SUV_WiU"ޒv, yع _w_A[gXTw2EŒ+z~" rxbsn kKR-T@Ҳ$!OZ%e5鐚C[I0GBPG`a,J**\ff\ +l†˧V1W _ w1<Ku`]-'\Ym4aLEh\G'aޝn[&Va D0J)~]l6p)B%f8 4GJ16.j:0A3` \ϻ-|ګ?LZ kJ%LPŰ섎2Y g"xZk+0F?֮ !^7[- 7K -\ԝKb  DӨzߦ6Wȣq>@ey e h2ˏD:@VZkp}>/sss]^nFF77&{ڇ]( $@Z&i& 0/+Oxض4ZyA5h٪208¿|#Ysss OuS]_:bfӍ~F25{+UI:ߤpa>0YZő P pzIe0'gڳuro4ZcZFfo%qLև%AӀ/ Ki zϪX+cCB`>0WUaqLMM% [/{H6@he1JBͨQUɌq#vm(:m~dF{'qJ(e/81xe{UOF3 6Cs̆W" PV1P 9 ~Z<mjׇYm1:a)#!}eZ'Zx~MCBkvG%@%D㉃ v+Y ټC24~ 6e9fiS=aA4њ B u_uL'ew׿\s v6%qI|*>(6w3SrJ];v&##Cцj6])˔J%PX,jǖv$#cæ 7bBM&'"K6(B(lUcdl4RTJ155ETT*^019eܖe1<<ܡdnl[N%Zݻw288V!r9;̙6(WT*x.8Ԫ iG"RcO<;vk.qc 4FVukTA٪351RcQ KP0` _:,`pL23;3ёmv[TH 2'JJo#LK8mRE$sMۄ e[ _BBh搷ؖc! 2\c,A%Qȣr.g~lp΋_c`̶{?ч73228Xv5/N͏ӛo\q8߾[ǿfvvy}J^ʗrjؼy3< ضM377ř$?O73d5,l[r1GvZ.\yu]{ PJqpu Ygy:?O<KZtFZtFŋs!j ٳ{|3۷fd6 33<䍜s9T*enWG?1 ȷ9+!e2›.}Guw}7=ʢţ4./vrYJQ*5oc>m,R,X;/~ETHi3=3>]X,np.aV_J݃b1Oq1022=wFAVSO4=?LLN C42!DAO |5LEærց*dvU͏a 3KKP((L|g+ZIMT¶RxB5RZ(Χ%`nQmBdJF0ę&A !RTfuȡG3_/z^x!"_/3pH>H%s?bJ.Yj0y+/ZR, _J K,|cSHÒ?.LNNrͧ>+^~! _—WUW~)3^U<ñ*\qݗȧx '{/o +?Oog֭{vJ+Z*0yekxGbjbw\ytߘN>$b۹611Yg3_x6r wXt)u5|k[@Ж*я/8vիWs ׿5ozӛK8gܳi6x uÏÁܗϿ_&W(" Lf6K2n>+'dŊU+ !koܷvEPPy7cdx!_pF~߳b8∣Ϳ2.IV5Ӝ~\xUy%g-Z Gy$<; ?X,Ak7] X-5V7&y%rwS97_߂"˵kO d|zt\%D Y\e}1Mb,+ *tÛ( 8Y/HL[F=-0JplLR x-+i`ih`k,1.u,ۗ8z$o{i4 }% ,y9[~}+K,cxp9yͫgU\tE:`k|])12_fFFajr\J^ y.أOеrU%o|;=*ŒVW2:E~K:(tkpi Л&MwZei,[0==L8/G6d>,]|o󘜘'o._~a Mo~1S3h_E|._ZrI'PשV;0~Q*֛  3shJ|K_dǎ],\^t.˗R~h Fru_eɲuKqǯ(z-Pg t`ffOUXxkς߹_9nÑL77hmV zz)†N3I'3N{1Z=y(K͂Ec\Ox} rߦ{Mi ﷑g2[=u:˗ǮSӳ-Ռ,caY`_n-|kXv-jZ-ke˖N΢^or9xat!>Ahm]Zk5FGyM?gffF)%:[~sO<k]m0BljlḆcY|?>S.8a/ʗ7l`R&gJ|VZ9{ܖߡͶXz5't:~Ztݬ;P,Y|jWz Zm諦]`|jhxٹrJ"NFXf.nK-y+_JV`z<Ѝhe,eŌ*Bх^-\KtRm LrJof88E:g|Y}r\5~bw4T=c9Ry sTL=8רc\&ծ}F>P1fW`hh0z*B% }RmY'&QC c 7 JfBpJFH(2`G2>}RG?_ £V((Xp)&&ev -I; ("Lq\.@AGFx7 Ee\,EFFFRD$&d=+C/}޳ёx~ 8,cSWoGlBd @R6َ&C)Fd][ )x PM19QF ;qr%޲D079J9O!ШAyh!DИD^).&;$*m?.JBCE5A=フK/9nFry) Ô߾% n^@.ghx#9@22PFr§Q2<2`F #)(aE-%=x`iU -D]ԭh9'YP|1\ŶmvQr9 <];080lnG*7񖷾SO=;*%vy`MiZr|KG\.>K9O;5+z+ՙoz\p%mKK&YRѬ7( x~+@-i2Bɉ)j8ՓV]JCۇ? 7ez;s{."33SSko~Z M/JlV&A.F/X{iyRDiҶOFV,qDgv}2-6F̐ ܇\P@D@p7p |/ռ5i&FJGdk҇h K*C*(Ĵzռ$b6,g[sy7Q*Z,AP޴O윋2K2%AHy_ 691=}mtu,j խ-fguNi")ũ/8>ț/}˗/gfjAVF i4 ennh-Y !NO?$ܟ_(mQ8 -U!l )4.c< lyV:lyQTR^bF:f#^sټ=y_ٶihPϲxR윅cA(xn1z1sT*LmRX(ZQ%E@cde˖.!ph6|FxE03;KV;p`*\G}8wGRarjիfߕ_j`Ss%q_ќ3h2m`Z ,YSOmW/yp΋| mz.z}zeƍb<KF=8㺳l{f~B6ǯ~kʥva (&򘝝062֧[H Pn٪l6iZJ%-϶ o!̡h{_Z36Gʗ|7^r1FZ2 iYiGYirʙ]y"0&RNJ& y "mjLG[Cvf$&'՛%Dh KK}DK 5cD~I k@""2SZVmSOw޹xb* nȾ d n5J~ky)|cg?/8LMFcYu-7| c/9!|{*"uX?݅@pWeKFeGdٖeY(ߔt" e D~5^p߁vzy,\-UOzJA)J\rq'\o9{ɩUɈ.G> ֚ ^r-\0cccȦZN:[|~˼W7)%PY|60>>#?iGN\#י޹?Ss@kڵpˆfz~Gϸ 8qapA9#'|GYdi+Y^toٮĸHG xeBXc֜', .R(h4X ʀpA:(!>&&}iԉ)Z+P]48a W]y Í7~g{I]w^.>sٳg; Ɛ䘚rxʥP,>? a) Tryp/={ettۜrXBr=q~?a&ɏnfdo~swq+7΍7D<6hH+X |K/y3@z >e}μ~xQsY|y$g10POwwʇ*m,Y:UW^ÿ|h,˗-c\7?_[oMp jPβzJ>{Wؾi|d~` B3x!xF-X2 :&F _Kp]wC*|/03&v򗿒*Km=ӟ4o3 SSa'o~S|Ҩ8̳h4ZA;-?x\ogtx)zo`8+ eljfE\bLd1055\>}g(XvIfK5Gqkp[ =w4m8AI% E)ݖ*tJ5i>po뎂F( /GQÒN¶s^w9DZtRfl綃vdۑ4HX) ' HQnyvlUt/ddl!lpS,399 "jDP0#?&Cߺu+˗/裏T3>1?BVX,>4o߶Lk':(ÞDZxzy6aw?fBDYc ;0g@`7 g|鲈b/={&l}!z?ҥKeמ?(V:KH}Q}9J f;vp5}عsOlyڨo,:S]9|Orkl,G;uGejow -g}W6=g2`X,255懷0=3NlΈ;T}׻;l舰ioXdWl_?+1p(a6C*!r:!Emp~^ Mh_ӗM (M*1;L\h2Y[/_q%bm7ײvۡoKOERa  ˹%9j؛VYc#Ov^ \h'f{ 32:G<\j18#?ak#661ʄ8Ui) JGt}k-}||ɡN6Me(?`ՕJ100Pl>Qʴ彛le W rp^_w}\doA/M&2DTk-.#Mn[ & Gس]H ]7h Qx7e7Dԑ,l6E z~_82[ z=z_@BHucWGg0U/ <}zŇI>TÔ5#k`גC>?A+Vz6(lj*@%SBPZ{FE$B6Y첯 QD @^-:. \Sm>1:2O=+š5k:$xIDE4BE b-)`Xեc/֣B%WO3OyǞ#-3WFFʎݤߏt}7Ձ.pRJkZfE_6p~-!U3fwEl; ['^M-1Uե+՚SSQFD׵amD7QT~4r~[!%]~]XTh@!5;X-w{Ưm%])E5_z .~O!## YG&IZ1пEUY|hF Y_]ǫQZ$ݶt]Q$z@-{EmtY \rX_xG$Tf!!PdSieMт`o2Ufrt$B(Gix( v-m^0] , : 6"lZxWU;mBuz&rh5ˏ w:+j%<ũ< K(-q\m[F1c_]n!{L-dBKpY@PFz :[IY-2xM^e ]px.(u^UH/_~ID`a5'"=*\qW?amyǿb@$/$j3'Ԗ@V,];ʱ"Liu]sTx^7:)Pf㫶~ NցηdB)g[8zS)V׭[1P(}vɎǮT*ű˚5i4fGw_255i_nl'dzvwnZٔ^-mE^1ABjPMYcJ;{Up!)d<'bd7C8ue#W0NjUvjb00(Gmmš#YRu %[M:Xư EZNLW¡z ~@;FXK #SH >v Edj /дQ^1lY} ]nph ID€J-!tHth!/CrI۬\l6{WfUFr/;ֆq+e}idR!Yd9i|C'V+%6CyWL >K6GqAKM:AK֬[KZbb|//VÈ_9.BjJ6Olf9x&aRb||ՕEZ[.-kT! JJ|Fi@!MfgjE*fltav3dm4Ǎ}vsT*e^8EG/CfzjL(f>FLJ]xZ Z^<F2y6ZJ {.axT\.R1Пall _W(ʤ3.VL!L[b`&Ruc(!}ԫ s(_lϒSSS~l6Gb0ah(oT*Qk0dR GȠCPV19$yazj!}&,D'C'%*j VJnbkN/lhi-cW/@T\,O I4u<(ȶD-'MY=Rtt6uJZ%EX 2N$c)<\'DNtJ`a&nM{8Bn{hoNdhh_Cg:+\n'x+%/o( o?0vu7.re/݊#vuGi5=~puK?n*!6o~=ڕO8_\u->{rɾZr)5\+Lϼ;pguO?4wqɤ(J#yC.cӦɏc=JdJ$jv=;\7G~Zւoy#;lT=γbe/^{PTqM73<:BfUub6H=.B6BAUwvvLLLpϽpM2<4drIQ,Uկۏz 7]z5}Y,8?;o؁k8)׿qOCF͑+)Sβ;O[oCPnEn9z_xkbfrn6Ã|<ڞG:wﶁmVB)C<̕?%oseWRfh|sfLM6q.wѱ~tَ֬T*OJ 3H'ykW~fkKY儏)2\~FlNF=HHMv1_u|bK@IoH7\VFHۣ8<+=ѩ,LR:Եy(Ǡlg$McN)Baq" EDگ 0[)VB`8[Fr}KՋU Jnv:֯_O:mh+w_^^d)>rXv;y";ϦMSЃWnJn+:{ͯP/t*pӳ]k?.ֳN;xGS(V8餓ַ_^}}(cG'0Ϸq[X8q7p(Jhɏ/ď(˖n{P*γrrfq_]G>fff=%Y˟?|KSmZ^!]¶;G0ZpLhXl+sSN'Ͱ{r}wr'Rd*xBw 1}>#yٗѪ '|ᩧ?;Y֮ۆn 8#!Xe@pp#c\·ftt{9a\ed2nydY>r±~ۭoe|l>eKW0\* |SyᚫZC-j:$M]~sC:3nxssE^ˮ?z7lڽRmlVe^ޯۋ;ˈe'_߿aFdžYl o=%JR7c\t|G]%[|k~@:799lvVjw({,LAGywh_ ^Lo)u "Ӈu |qWJ /=G 7@s>\ěۛ[n>=cNӨ7Yt/4}=<oo|,,yon;8x׸馛[~s3kz2L@6FqÄbI}HvQK^YL'qrRJ@g-ޘ kR6]ߔe'V3\гH6=U\c bf[jkd^ya"f%`]ô2B>=ܓZyD֊+zA`ʞ/u;PTpSPV;1Bjۭ\O}XoB ;"U𘜜dp`ba_FN8]?I}V5IY:YٺEE!( 9g\Ë4"}>t+k?`tt|~y"Dfd)kHbzPZ09xyoB39|_%0;tSi6| m_5~ D(ZAxQo:3/ۮ;3؟Y.CAIї @ MQWYO|3|??Ə.1}u,\^yyq )7C9ó>˒c!WF)3V(M&Ρr~&錠Zdr^t>ff6ё H "x^N:\-r<5p{}WYtp W;~W Hg^dVM6v8j+|:T'",(*#ChMfm6רT*MFM.,)Lre6qc}h5³g>="ٖRJ_ҡhV[ .qͯDf!ߌaNui]дՕ±OjjucT˾Tڀμ@Z)eT~~\K.+BkՉα7)9fg va7Ss> Is>cƜMS+QYb+ڭNZ7#ĉJʕIs٥??Ff 3\O~Yv}W:WzB-NZ+= 8ni7]62Wkuv׻d(s|NGɟMo~o{)*jy Lza^z酈~0\lH#$~+Pxwp0Vyj|+?>zRͷ\c`qQwZ?b ٰIp,`nI F䉶7t)>T1(*ޣ%,y$ qK6U(4r")N~B[b@ .΢I8K&vvۣj|m,Th'*-i~IǬX;FSB2 q]kmN###lr%+ن+b6[brYUۭd(?"ĔP*vl \r)g) u+Ml51D1S oQBߊޙ'2޿WC`$2xNƛ~g|z06Bl"6VOmi:RbhnG’e<ȃMqݿ>0^|ro㠷K_Xg뭷FZ mEU|:^d:Û{=/ygO3^kv*r{F石XcG*myڗ`Ҡ\.S K A> /z׻xG8/O|R6;8\kB8n{q9焲r[U϶q;FQ&ezp\sJ!,7GO^^<;g~t:47o^[R,[:%? η9Cкk뮽>vt 4f2|擧+.W C?čD& .Yίt:Yšo= MSַ?˲%[GQHIK))̕, `R/=؃?~2VT*֊ӿx Om9?88_~FAnowpVevHS4m@/L.Y/1m!(zF B\+y?S_K.7UV1:6F>^q 7I{']3¯Gy8Qa%B|"^ PRj:dHHf;S]p@ !UwӨ p$:&ndS8BlU-O>Qֿ055RK#p( NÎfygrn y&V\z=ws-]B )]<&||s{<M+cLu&uΫ1ao] X{ q#Ltj1^5TO}`]m & u54@D i!R|C&}Ec'l%KX VmC\oL###h&ƇI2]Z0\.G. E6eɒe}d dɒP_Z366n\0lcؠ144~0}}}lܸ tlMN,ej7obl[U q(Gu8("61?;n_?tR'R{xXvWSx`bb JDъ+h4*?@b㸂tAb||<\1xx‷Gd}^DZ}$jꘖy <= _1(]m`=W|f " ,q,.^}O"a$O h#͑Z Rhf&VFiJvDZgBRΐUhKC\37]DDYWŚxč'*IMեY5}7Gl.=F5mzZE53g ҩei*}28t?nJ26>ҕ&F1vۮc=&v'?gy6Caio4wddxQH ,KRyjɺ&4NH/t>"F-;)%2t:dUV,*5,xtfzKcj#\Ii"RmM5Z{cNY|Hӡ1ygv H{yצuЌ iv+e#C^Q88Pw |n`mC%STjg5ivWpm^ $%j=h}bOmd"gEqǵDEf\"l˼:wkdGxOR^f;&Mek>GK)q\`|DD@t+H@icC(Pzz@ҎF[=q͏N; %@FèF23c6Iq,  c~+OJѳ)ґ.ƆrͷpUft,O*XRV[ XS'Fy.B8ֵeW;@ .u1Ap9cܮ)%~/p6;hŽ|h!t MT\FF4#TJkMLd-q'P:d ڀkHF:PITfaNاp]JDXj]ʺ*Lh Ync-Pųw 0OQ I:ƽZ1il=d3g_LTmOrBY}G)ȫlK\"̽L2i xV/I UunkL;,tѴJª_J(FWŦ!aU+c |T?;j!1o$n}7R(ݑyUQa' jsr'hS!cx2j-F'=i!# RXZ:c[x-@]'Xl+OH: VC ^hRPHTD@QG3Km) %eR!"{gw񊔅v; ᠥZ(|6 >WzJ4MCya` _aW҆mQ!dXmƼ] r$L"o>/2; 3Cz\ܴ^Bz IRxP][`ز9zWpkU6ЍLxlrlVt"ѡkZ;w&׏ƻo%qqRd.ZTj&CKϞfr0%pvZWL@BܲT80Œ||_@+FC^v6|cfI&ָ'̹r QB|#2/ܧ8}ٽJXԢ˴;1B#@B}r-,9d~P,4Ov;lhh9#&{ wt@ek?3n3%%JK<B Pv JHe&;eeDUG40[qDYZ?_-_(5mZ60-ӒҮ%:viR)`VppZjJ#y7H45 $ !R Iv*g-$[̤a.I^ $$N%̸eLV}L0 QHpp _viH.\X*# #fBA#>bʴO|𵲧c{ iSnj<>pg64mbhӶ YDL@mj>#`MՉ Ra߬;#n6fg~ $ fV'Z@U4!zX*[,"E"nTG;')iYKmb܅ZP%m }Si#5\Ob1ÅB!n4snIi8Rut.̢q*u[-"4x 0(o׹j 3Fewc}T(;z![pbU CE\|ϡBIZ^ku_? 8 }YR:2:bu3D&N>I>H6m^|q#ӛ) E+q=AQXZIvwځff:gau:DA nR,02rHfh-5( 9@r Z)k"&a=UG4dhk h*.p /c'M6l;*h* M6]u"<62̒ ww'6 iǝi4灱OQuX9|^A d/A(.2p)ڧݪ34_A%64VbAZg6[q]a("M`ˉz2AEDdeͪxlyPo܈kdeJؼ*NvZ $kH %֛5H@/x%cmjNZїsXabrLr(OAǞ4oX#Ź mN1*n4]t뮂4 '_W˯&xJbHI[HmFQ1ږ B1;;g?)յ19 L3Fwdצ \ݘ s 7.pn]eyt$#je!L>Qdk qhG>b̒Iڭւj"NdQS8KT*5ٞߵ;GyqmB3*ljCQtBQ.y޻r͵rfvv"cQ`2b|gz6RQƤ ߙb![080w%Iy*AmO12<ʕI==@jg-&"o9`?~y8Mj!L:șAg[ZI},/A&$IѫCPQRFTwP[ E Cde.}F!#JθadmtУCs8BD _%H @-)BШY|Yr%B+8.u~[g6uf%Jrxydz$%iX#vzьA&`[D6M|i R2;;_r fvˏK(%HٯC 囶Y00掱{_>wtSx;4Z ZMhrf5]ZʶG|h栴\њ'wۤڂL-44Oy4²h^p}q=qq#]x wo {!rm}}\UZJ hVi$L`]Ri۝kG~^]<(&k)Al6aLv4ЂT(NvmdPlU(0Ut>ٌU2nC']<ضU *uН`(Bu+1=A_8C=#|7vރwuK,od+CqPlB,jJald/}^ff򘞚"Jri+%*nS.ɤ]J;A]9e})/רTjhzٌ-29chM |߷>CCC4>$3Ke*5*ssE*sJYjyJR)\eJ|נgi[LsT7L2d3 r,bzfvgoy*P3Fa>˅0Sy11ڵkYv-+Yw[r( _8rB?Ϯ sh˜r'8K_\.ʦ}ᑇ`ҥKR.۸k;k=R)%\{﹍;ﺅk9JfN:Wry]#~<\rɏ~s{yg177gi~ӟrqQ,Ρ1PJ?pJyJG]q8T.,d&89n:VnNh6xGZS?˗tr!4"??RTU9틟+.Cŏ~=Vنp,wy3=?Ou F?2شi'Q6JslrqM~ņ]v cqƗb=w73JjW淿‰'O\Vg]w~ky>n ]-SH.<6n7+Y +^B׿~onV|NN?naffvݕ~q;ng]dbv]5\s;|~J;<!>(fmRfڵO255E&?? ;=|^Skwffgfa $].{"֋z=qrr-KQ3mB()C{m\ B!x#)a-!KBZ6Km;upm!SVO>Uw™·%\R(mq\o:^33wK<B @)$PU+ԁ%ݡť'XHnQHp(!u_9?Ιٽ{C}(!Wvwsy>݂wd[ " l;M?ڍ#w7wgk܏.Sb3 *ӮK-撋Ka{m47(qʮ;-O6cv;{;Uتi hRxs1|]cu7\d Gf6#Ave*O='8-[]wˈsσL%ٜVI"(72OII_O?;3#hoo'^r-/:wq\ty/-P b@0B:?O⮻˟7!a&_8.ߟƌn91e`itc}Š:bnnL"+ 5`םw̬oSOHQm>~8#=ab}60_SUU}? /LGW'el`;O~ݨe0:]w$>?<)S&ódu1x R!0P0wQuE逶DT_Verϟl!rp|,݊"ް|GS\Ew/\:F6DT]%JVx8R`ICˮ]kٹ' j/Pr:0Ql^a!M.+Adr)w[‹/Ls)\!NXnj,]_ywߝGy4|>eE"6Q+0_Imm=Oߏ?Cq0}e믳k?3!oaƛy9\y |D#qxA{~?J5lG~λlW_v =lW2m8q-W󏿝M"g3N=9?g~؋(Dz׵FR\|9~CHR̙BX IDAT4irکgqǝwnM%ʮ:ºƛn3ϚbY ,^b}李>ױaE 5Ԑ_r7n$LRWWǤI@9[4~4{I`z9俐/$ b(r2n3xk;\~ ?Mjt3TU%i؉GdUu@s: |xL8CXv~1Fq4tuvNSI%}5ul5ikjj|*rALنI&R[SOwO'k֬dR``65I/^ 'Z9 yf>Z7pȡ!HUU2MMiiiRPWpO\]Hrΰ[3eK{%Nq466K2GJ'm7_+:p^H=X.,(1eۉ} ab7F[Ƿ=Js`vC $ 6L%;n45UDu.]΋O-!ap3f<໻;{ֱwّ_⺽ˎC\ #F60exuHO0e$2YZGC\ԩ2e\ݵ؎ǔ |W"~ˋtm&NvSv뮤Lkb|;ns0&ͤIUtWQuJDkTj2 5|RmI'P~ol+0pGE;jLT2R=}4d3[x6LV? 1y.S4]IiǕL#煜e =?Td{c CVM!RhHTފeFפ*y/7yBCC'wο`&s!s.7|#w C4f: ={oa47@ðt򌡔ag`qeZFb6~rl!!s\l&SEeECJU_쭗9WsU7~iCI$#=N8ӈI r>C=L^]Ѧ)r8t:xR: 2t*p_b')]La XDPnx)Dp,Q= LdG~/`]vIRe,~mۡ,P53b "(u5\|Lk֎CWW|x4D^BmMRJ;I&fSLvK%Mq q S.jfө/j0=2E"Q QyL S`ZHpu7sw1jdCi6uu5TWbZYB D@M( yJC4놌\GU*W'*"^. ~#GmWJ)Ez1:^M݋d*d:vX,?@aބ#ǐ쥱C7 eEhAJɈQ/TzQ4ͨQ#`uttt   õU3zLﵐP ` LΣQ?CƊ-1Lĸks]r0yCJyʌJNey߷T Qe(*qmF̨tQD"ԡҖeA7Ȣ٧mLuK͋ecP_cSk;}u0r~A/%]]K[{;a;Y6Ave&#7eK!1rT }=ϼ 8's Hi+/KSc PAmheAfp.Z7eXq`eqFZ[d7;>;yrY* K(vx p؃aEr,HR_kFw߷\q8@n.\ץ?p\H2HaDcb ťiX_z2);LHx"M6W`ULf*u [nz{Nz\bN- +5ܢ gJ*Va9sw:;[줵B4b -m7tvy㍅47CN|AR;cU>ZΉ?֬YG{[7]]j$qsN:D8֭go;2u,x%r h 0%sYv=~St^-{[MܑA aӓQ3տZhljC L< -YJ|i8z㐡hA9}sИ2i6wr/(}!$U4-|U\{U16n`-ǀ2crӭ̜yUUUG?`Æ6'Hģ,^tnyso,xGy.]wJm]喻/FaY5DU-ф'U:.TX,12 r0駟DVreW1k̟"B=؃x^Ʊ=rw׮9O1L rYs=Wya]wfuuICQ'0{C{~aX HH$ #}CuMJx,E,V]X,@={ *׋Ftttp=r;m/Fvk6n܈' RLH$RzVCC< 1}?Zan&Fu3ŗ^勹ƛiob j%81w|^yev' MkeQ^s9\~mfͼO/ॗ冷um+{oՐuD7*셧s}uђDu`N{p= p6aW᠚+fB %\ç(3S%]diǭ7'pU%趓0$ `w>z5i2!X䂗qhKB}e&.јE ,Y&&guS]wml5qvキM6"C.|5#b%|;|$SqjlO 441}<|mjk-723g8lgDN?o]wƣ?F2 Z/qseriF =[.S|{osuٸM__<$Qr~"fe:9Y֯'M)bw\OEXjK/qqG|cB?xv(55i?|0}L?d?[_ WcX|,^TBʨ,b ,`⢋f_8 !$|,M5ihhO`k.od|Wb1q}cf8+ /̝7f]yԦt\y%lX>}#O9W_s^t).6O?0̼O:i <~>V(_M$٧M4jQ(OhJ$A Ӓ$\i`gɸ 8"O@9;TœQ"Z j0B"mCK%֬^tcn.;@:fɒ̝;kְ㴝=v y;, ix#\C ۓl ?3<`CS[E&td2OgW m6֭*۶0 Ək׮%HP[SCGGTF?V|g'#ZZHR8իB^J_#g̘1^i2 t:ͨѣMuA}CaJu:MS vttvd\mƆ"]]J6n8lG%|xKcc@twd0aѨ*k֬е^j 477֑L&5jvyAFgw[O<60A ݃hlh uQS[KJߋv$G[L?h׼okkkIy3fL(?˲شi}455D(pKs38K$awߑ9blnxݷߒiin)%6mb0aĈ؅4+2׬^Mss3uuuzR$`|k0rH(\29][aL09#&%j%JQdY0lWIq!.dp=5d+=л 楀-uU LOfkhosϙYV׭]xcƌgڎ;Hx{Rz ֯_ϮQ#P(=WyบSohA8lv< ?:}&|2MBU:U1l2;V$B</V3=nhZ1 uקeYxya0 vW|Y9(鯍L&MD"`C 7(ki"ٔ#3DH$`^V4 L G${`+K J֤? [)W7L+'I#,qSJ] aXXh,>KI kb1QL x=DtW4I 1DuOIJ4Vo.~$t]N/UUUW..QEXU{QA(B)Gox<ش}1siPH?Ex3 o,5`D\ 3 𜐡_X!19|M]*/x<^|N";3WUU yAtrߣ !vᅫ \95|8>zɲ7B!0N0J͐\6se{J;\?v*|4"Iv'Cq|~rd2=?,46E=* 4$J0̽dxR~eCapzחDWz *ocYb;Ɛ賓+/ViV B k,A(.RzaYN r+ ZZs#v a j8܄p+CpCzqV]94tWؾRHW>+n p^~_T!qeQ)u-b"]|YVpCnьr!?<J<XRCq$8M4%=l ]|LIsyHiJ"2]7efaL_ /(4FͥpYPJhnвr&i%2G_o__Rp%'p.hʯoͱTm4aF1?DV>lNEy.abM;_j؜f!͊0*X)Zgs` G'IbZ>Pg X,G_GIOH 4p 7 a|0aUO Sda*=:nfiF)eՐN ?آ ]?wWp|fMi(v'ώikOP(pӌ`bb yڷJW2R cDЄ+3_6.f?uG =tB56W |>_z*PaႀX|lұ":&RIU2 eB!!]0i#DOef3>MUXxƐП@P\2 fQ6 z w*>#t+?b9S'KF!B0d$7Ꮉ |{!n:~I9qȬ->Rᤇ;6*/JC6a;M q,kDrIWSOuBq,זky fq]АWQAk6&V$aSxSI,ah%f(s1$B(FǣItWVK)kĉJb8R5_/TWٲ]:!G ؤ7=+S !tJl.WrA4(-rd8E8>RE.eC $SAW?9j+ )a u =ֻOo&G IDATlޡ1z!8!Y!lS)9V&ܫ«Ui ybxG4%JYP. ,FUJYzy/)?NECf[ڀ 9fb!D$ЂDQ1 JcFU+ *.A7!L<ӈ#~7/ sߑ24tI",_pqܼRgYƍ :u }}}{w⟽{O=)K.n0RߛaԘ,Z*;}}AV) (HAJ<++1yrK9Pdstvv+ XSgjɺߵ{a[(;^! unCqa>wrTWDtU Vi;lǒ%?a >77_ЃjGg{bsS=D$Lse`pTi~O v<[Y[ސM4JϤIXx!l3>3vq{8r BS:8.s r%@K =#,/z =lFUF=`hp敢:W.MM,^{')?$r0mmme?ח's9k  wF}3@5nVwCXIM`q=<, B!O!5R)7x"5Avf )ƕ_I?ZSSaF(|+C 'AξSp7[䪨i;vsJRPȗ8VE,bM~5U "7SXx0$==}zꟹ뙶T7uՖ[N^(9xA&LUW]ìsΤGQ!"RJ̙qam+ B)A$Z90,*KNvn =wՅM+ժt,ǎ$ ŒԎ(Vax)۶`~JXLxΝ:glc!J֍a+=Rnn[(馛3sS1 ҩa%rWe(L VO$0"35D;z |ꟿiSd޸H V@i0pk*j Să{R46Nep{dk|us rw8(xNx ՜q7wM&69ņT%\-/+.CB8eDK(Şxg4ALc멍:(ʙjf u)4䣼C SvIaz@~fe .6=m/nu=Wo8;Eo_Of9nJr߽pG_#a3e[ܼ a! d2ɚΛ[HH.ǣ`Ltm0QƑHvnēNT).젋t;4Txx[C@BHlТv)s47ߗ-lrumnj>C4jhCf6;SQBŋ Q{o05[k@ yG6um]*N?4%hL7\}5rS8ۂDw -Cm"==Hf )QÓsr96|6#`f+Ϫ`&G!hJ`h3ZPϏ]P͘ Da5!7^ͣ.9$9$mӢϳ]aA'C_Fvy]:Wۍ$J%({u7H:6Lf{)B}BЮ$T +Ba\:;zI$Ltn%.'N hX"ei-Zy\e1$Y90\^8Ym1 i7-$bх%QeK,o{]ձs8L(Sw9@HuQE q CO. Lf-30pm O:@3LǍŔ)M;{quL::C!!0~ 2XQ)F ! ´ 00ѣG2ed\Wu>j\*:pztv@RzHn 3 illdNu]ivaGGMR|*Sycfdt,/]\pXd ѭS$kk8P3 GsT)4yX"Ɩ[gDcf.:JCNr>~Łnɩr8RG1P԰ajj܌%z:{PPmH$;.@m.ڜHO,[x1_Rf6GW `q+Xx)<̎vOᚽxyn<~~^yɞtwQ+U7]Od -ZyoUَGoo?wK.b˸44<]y=?ŋ[o?Mtqh <ݼ拜=s& kϯ}=rK-a%<p1ÏRЄ "+/1,!e XfO?Sg:;?+~%Kbeʋ~MooopBPk,]5]9v{8urUqEڶ)%8`$ Nx'?<,^-e׸3DLzd25a„qd291x8@/c[8Yv5U5 ^~e>/O9ߩPl0<:60}A|;,yU z2vn;kO3{Σ<̓<Doo.z.`=L6 `睧ߣ6.~~~_$ ul5<>![ =0]]]B-嶶6.|^r\epp-w x'tI@?=t;?<< o"s::ms 뮻x{hoo o.zモ^\,pnc~%w/pmDiyN<8-[ yg8_ыtuuqʟ~wH67 ;l#>,㷘`6S,Sv hlcWyfSyq^%@VZG$b2'1Mk+8?d–;g'fH%8Ӹ[9#(?ȿu6s|{{/ A:ga2nH:;dr\yepS?E?. vk<8Z?8#F``3O:z7 /OvZ+#;f5uqli=X[?c /¶mf?`! ںwq5ֶ.\;N;9Oa.Ǐ%s/it1OԩFWGvڎ38ڗN__X̢i\xu&M)$p=_RSS_~FKK Wի?sΝ7|%1 U{r464ՅJLޚz7Ɍ'N3sA3tȽZhTۏ_~F\#$O>#]UÂ知Pq5_wOlf̘1LrXNuֹTWu6$H3b;L}&Mˌѿ^t)wq7x;;-?4X$O>DBa Nd;/_9\aXpQ\qe8vgCzl3y[Eq<"FVpANiћA,'s嗫d2y\~]?D20JIKh˳Al.vAKmCKd'PdG9}}=%bR)CDZ#'8G/4?0,pIGx`­r{Z87 ~y#rs3 V'j**<7_Λ ic˜'"H|Gz!,^͜v?XB;DFݵ+W|:m M<=xr!@2ٹ 8wg=ȃAHsj( r9Q OACvp KVJԶ[/#KأOw= N8.  TfrL3O^c .&HИL7ފix oC{yW!HWy455ljX9}'HdšG̟" xRUxɛ+a1nxM|;Өg _x5G;6l\QGEK ays9O%09E]0%[oW_$HrDzۏ9cxgaڶlܴ'xZ6|FXmLNbqƆfj9YSG`ĈS |n#d,DTG}_0?z_|b.rL07ƮgCJ9Y pwaZA>3֬]C.YN*QHnۦ !b^e vUZ|79 &JW쥻;ƌm!/YgtU *4MnHLej[ &P[HoO~)G6e[T3o 47`豤bl&-M͌7~4`]w{$7跙v$Iƌmb;D-܂Ɔf0$7㉜N3<0\OG,>Q3Dd1qJ0a475݆+Vge=QA:U{Mk7̘q0<xÏ _eݚԦtpMI}_*_Hq&7~$ \ƪU_p{q5&^3_J~8=:.vAQGCg`QZ y0K55iƎ͈4f,D[nFjUo<`mɧIz$B2'a=~v1}A ƦzYbj+=$pQV>r؟B ]!#v&*M"/٘J/jX Ӑ:Z1Dp*DHDMӛ(o"dDm$zQ )q4X E#%+!>-Z&+O< s ՝q%xXV)J' +g7m:xB `lADU!;wlV + O(&tÓ>Sm,ZnkIG $*sH4 #a\"Q`=cqƹ4ַ˕ђH]8eJ qp@s ,CQxIbĢB-S:\I'3eݷbR NAT=G; j몑av/HAo.|>d"xң&믾e8<?0=>#՘IVsf]'||ŏ.|..h&gϼُ?A"G[NG}Cmp ^~6"ѨSb 1T2ְ)U15΂ %*3_N9V¤4jT>]ސHJd~CN:l} =r  -ptxkjmRPM  oA4 XC}ͻ@J+.-kb* )ywZ+EΐJ zGb1b|bӄH)aG3QLiRc/A%"_d[`45 9VURM6peĜg99 E\YaA:hEn7=G?kYvGm]O=93Θž?ƍ˖-@c}֌vC-F֢)pi!p<Fna7ߒf|hsx>_s }ټzѪ"|ĢGQ#PGDqۺ/>)mTOccc03Rbߴ͡LgiS̳gRLO_oǖL?H<#iʦK*"N9XxpQ (l'aHOz _v4 dI>;v,D}.;dyNnfL?X4En;7Losӵ7]4pmL R'!)0 ybև@X'ᬳ ] U*#GQNQ ]G1VZ{,?ĶmÆᆪLŃ[UXK.ɓ'aQRTT1jh21dZ2Qtv Ess36lo *o-c98˗/gݺ5ۡIX|9 |XZK ԚkVp}[ BN?t|.. $c &Y~ 2gڃ!Rmaj</=O#-"6!)%VH~޽OSIVe|Μx^Ʃn^C~-h޲X&=tnyzB'ct'o 4@iA…̾7!+5\g?s7xHYpthzjeS.P?855͊+ D* {ER15\s5\},^s7|=W_}5~;4cliK6u-ϳ~wʕ+y\ENX{+4o~ظi==O*"oDC?([N{~w\sU1(,_嫯Rpտg~N޴/.yً Wo9S1w]-[ƽlGw^.r8 ]k%>~bMd/8v|m4ƟkYV\NF~/}r > npfggo勿Ȼr0lg{xǻ?1֮^wy[֟]wŻk^Rļ፿M'Yoru]ǡCyrw}X9gn' /_I$Ns5g|sk9.|JKI}}}@._sl{^K9|po͚fOSMhqv~9v_*q! _7 zfYeڡAyU/TvN,lt\]veه_o2V=%O΃+WarjvW"A۴!M/cssJDmj TQcnmƸ'SŜwlx"KK\ FE'c)nlX38ײg.ogFC?B^Gz4)wzƎ;o3Yg;}{[9x z=Xչg ]wS7jN@`|b(|0?s=M6Qo|릛k_cͯ5S<917}&>M6{s8Yfwcsaf[oiq 'r=rw3<.{'t2R*ny3λ?"Vu97Uxhۃ<4cl [)SܿAy֖-Ɨ|5O=Oͧ0==LL6ysaݺu|_]1,=7|8gy66/q~ [[Xn5O<p`e<<ȣ|¢ys[`Yn69|($Mrw5 qH1\Z ЋvgHZM tRlNpp!Z4M8t:^/{ݻ^z߰nF9WPស뮻szj:7&l‘Rb&ݻqU˴m0a8??? ',F;=Բ'tA6O=;˲ִZ-N޼Z-bOE!?qSND"̐^1K7s`qq{2;%a9EcL ``-'oڔ)yJطocӦM4 عs7 GdnaYb&eO+m۶1;; #@ ~#Q͛OvI{>̡+`eƓ"7g8 6^+Vpcլ][o8Cg֮E]Hq?c}}9]gvX1oYkQlbٽp<5K ,r?‰m]o&O&+Q$=3Mkcbo"훢Q-pQa"Hv!T-kރT~7z!3oqL%4䅔~ivt2s\CtEq 1JOُ>k\ym|Lbcڍ_bƍ _F\sN whE!Vh~WhщEn洕BH~q[EcXRyılbbL!H>~NCT& "č)v/&5֨l֢zFL@(LݵJl!^:C9Xmx OɞHR ʰT4͘{=eH+J&k Ӳ'(dLb.OD)`iA@*CW1j !$I)T?ID9mJϢ0IA uGgf1اZ3IIz1*I`|Jrj&byZ.-LAjDq52F:!#8%ܶp"x9J^S&]+Qd2"rצ"\)'ų^HfqDD`*&dASE5a08ֻюu#=eASp3\O Mc7*Okc 5-,]l8a*iX }_.!=frjot+˦>g1WEH Q(%t&Զy&hEHAUҢD/,BvF`E* "=P Lh$Pׄ 0^:XRy 5JNI "VX8Q$2gl,5SUf.E0\p2̈́#ٽk]^a(3%/v6l0R;PDE[8F7蚧l*W-#hQ~n}/kfyb UvD5.\o[=/'%NƔڐMR05k !M`JT5-;,t*/%/uRvB>"f8%5 ' +9o[I̎L?,4e=PVj 7z`|Qrļߵjc[tۥ>eF|j;ȗs g-E1d徬xҲ-ʟ R[ mن[\+ ِǓЄYf.y ׽ s22W) .ZeOo~VN ,;y^ȫ]ی醥(J:\yQRZ qL6m̳t,ɻO`M*jA X|Sgn<&eC k2x6*7vf1pZfUv-l8DRB: ],AUNdMu*meHY0 e_b@M9 ,Fynq<{65 yPe4-J ؤeq͗0O]zI-ug@hڝlf'L> RD/3Ka? h2 (ZeqE9`UNWrUg0T>g+ )76!y w_WypdᚅO`fPd; 0BH'dnxAdE"5,ڠʞ۪JkUm$`bfTTsC7b"迯a.e9gfaLaii 5nˁ#R Z[&hEk*.uC 촖f?e c)sRi>\``L<*.\lJgt/4ʮS a+ϠY>ti5PR9V\F‚AUh_u`j ,d8EUU!QKuTUǂj70Ч`ψ.޵*H1668VIuͤ嘽fckai% ¸֕;ǵݿTaqL&h.gUE( 6r@6\^}}OAKQد(M ZilF,/ 5^B<8O0Y i%TTY/Jo_*s@rIGtU%k6K6UKR}ycq >x맶44" sA*-8"DBu#5i2S5du6!EȬpYQX~ ,ތa 2x {5 ",DPX9Z Lpwl?lDhfyYe*)=IQQW]XNUĠ$!c Y &EpZcUU.eeESɽDԵE y0P5j.faBP A%Z_Ϸ|hgsuNS 2,[)N,Q6ȜQ$`IDo49<]lxA&90taL)BHEJgU^:Rs7^M^_TIjR2,oW1v8.V0?/#4CVGv)"( IXk֩k1'a. W=^_b]fDVzV5qR;=C$PZ`S}n/9,3ЪD=}%Rǝ2cbX=B)|Je7oUƺ(.B2W՜I=( 4A"u̔mKSYY9UP2݁uUl,T#ey[h2 d2s URI@:Ҭ0GJB*`$P, s"J2Hʮ MUhDםts 1nτ?J|(M . ^K:S&8 IDAT#2<%5vְg:89}^zN5cR$I k*ޣ[Uc6Vs)p[X" p%VlG >ciN/lhӝKWeoAX ң.KB0|x%6$_c*!nؗh*$9.&JVYP9< wtC.h! T EaP_hEbPpGaMfGWAFeBq+n9)ԇae۠N-? )y ݎ"oKuT9mNivkʯK)ښiv)5,Yl3wl#p?V f$oyul;#$dYN,K,"AYK](L ϠUBdEqI`Fsb>@A zvL*&f[5e p/YM: JH"+:3^JY ctc1IjRrWNy0H1 ˈ.d9zg=t7pgh48vJnnr@L=Urχ>PTm|@q@`+b~KenaMy[*nփ6b .AaYT\ UX Ay_̡C;/Xg..El3I j(o>T(m)m11{5bwۜ $Fjϳ}'0IdzcI`^)>Gz?mS6i qnbXh;0+-z;9\WJ=s ,"&'&ޯM*1xmk V4s eGs}{?k׮ellC6Q ͩpRv议Me6MPA/iƄTmJf1,Qs=JnNk'Q%E, (`emn:#gfh}A $l2֭[ƍGO:Nz]1Id¯#l^&cbg Z:k6puiUZӑd0­'N\a@9g1}BI`\hhA{ ц|3 kMtڊўJ& IvluTFR29(hw:u?PeԮA*-v"ʗ-2 BڝmocƍLMMeũbC0v20He2Qq1ROksܐ-\".GMte2eiYF6E6KoioK % Zq]Ca{%ŵ=X'{)eH.??OLOO57q3fk,n0=:y`9 `n)8G/ҎR7p AJ!jJsL ;]X"%GVÌi0A42E {&Axk}zy$e=a!%t%IE(dܿkx{YI .\!5n ;mD€̌@25biiŬ7"#QYfB[C]Jb$c&'&&;}i')P+f%4?lVkMe5l޼9TR|q*àtЄebX|MqN`栦cU: : bTe!tS~Uz=kFh7)f 8iv()\WRgIV+pRO#!H@6X^x:fv]LOcH!LN롇sZĖejywwk{ kC$l X-Ho /Z#'`4!h#!rI|B}C!"7$5KR+5bbh_6[25 QgQ) 2Gt;:h8:PS"7"qJ)Xz5+WM`z\w 0bFĞ 1G*GfQڋa3883*C?(˰Mנ^vL2m%I͛sZs5)Z!JK)3wKa3ltnBnC,CYeÎǟ {m'>J"uR@= Q 8i`HG?ךSL:KH$ސaF3 R*ThIII*(^xM.TYSNDULMh%~r+n0|G7.AF1&e=7yp0@U*2f ǣwy"` ծN@"C, gt]<\36c7P:ٗM"t81 -4奄DF h tSk[s<.$\u#,پkn\Byʭ]:2}E:(OҒg=e\ıT{a cLv a ?/ Ǘ^J!KErk:3Y9p@5D#䯑nVgXidϒ~TyU^\/(M|IhcqtNSNt('(% ' ߐX)wHI7ќ$Lc7?085BruY)IҦ% }5,鴉cEHŒ g Δ1S7: lI9WQτRr1c=ơCfI65(Lᡵ $OO˩j}Ei{vVޱG7T2d4erA,lR*;oHzkpAA -*wD:d_E`d`?R}3%V 23<}6,3JuVfٚ?ߞaR \X]6 mRdzfzs+jƉIN}\]LVM6&bmi(,uY[9x8sd&3MR"oE^^ Ia8uo%Z>nC,dLJLou F8R, 0N3©y-e)B:9#i=H2c(m/"kzzIV~>=)[UB6Y*^{H-5a{$SV\akįAoRɜu%>Rk"!uսї+&DE˟Ν;YXX c\8hFݱ֎bv>m@JtDBD\rQ2C#t}~/,&Z u30?HǤӣDe7$wh$%3m$hn4}DN;I8r333Z-&^x!?ٷo7oVqO}zNۥlrsEa+_ YZZ5x;{?O|zLNMKTH׮j@dPS'Y+EL;f.imeM8aӣӹs}&vEdօpP;=dۤ䫯@@="RAX3DL4ndDWhDC1>јKPD;ً!n;]Љb|jּfG0 {QS`DŬ}%,?e c&/Ia!,[Ydą3mGbgYܰok +/2 ڰ u!=DsAT}s<`{]|a-D#AȚ&: Lv '4>>k.--gff'a/+m{h*O_Ʀ׼7at,q,0Rض٬{8|V}N8/z9$D->?ʃW_sCXܰm[ּ̞qG߼A:*&@*&M6X%K۲<شj&m1dS|NTRcDPަ Hd\kA&o&̞q'^jg8G$ 1{.mOMt9aSLmıKc"!hActϖT)t#ci,YVWͩ|uh6jD]e)prFc|Ә2r"A!6KțʻTl0D2(|k-{allu{СC|VEV2C>jah4x_W_ѣG\6 BW|+q\r%}!82DfqMaf(4}V@y#AJiW:y<{;SFRyܶз/TI塜(nKģd1"q¸Ѵah-jaJewP7]߸#wS9\f~|kױkf Vq~F %Z6E RŌFXB/Q3+8tbXZxI[-.:m{^ Ȇ7A,ؾ}VRaS-U#&fiIl9f'K,.-t_Zh ʦ 3 <4HiZ#l&Dƾ%M sTl6z,Rzz;z|3[}s|#aaa!=&MvZXz5gu[l郪RGw]\\tElٲnK.[lSN!17:\hV%"ez1i/s U ǭ^TP G͢3X |0 gs{ֻ#=?`gi{Da%ZHm"עvBCcKsR;۶rW0u&Ʒla$H4LXCs?,-bb!PI4Bj&U-$&DʒHA-2 A+u.cWaއҀ4! 3/1}p 2wr1#cI nV$M\SL/_Fk[Ƃ[jKuD*C-n8={ RH)&no*A%8Bf1̙n{ޯ'"#NMMoz<9sxͲe˘x=ZK^GeÆ t2gbbӟ4> w}ox\o?tx H17nzfeuN,~zVqisw笲R\JQ0p0~UE=1iMS Ѥ)YdH `쫐UnId&AH9s?w <9!|]!+|Z˲ coRiEfRJ'{ dD~e IDAT CFtš : 5 qMP_G|7OНo!MڇU7#DM` +%crՆHC$ItДUDqst/e|z 4mD$@!xFП}KV:R&WM[$L| eR Fp蚓[ҡh A3VcDq ZLA9FKw !CO/bʎ qT' ~||^Wn~ٻZ-|^])$;볟,r /}KsbXOx^8^z)Zk^W6fO= EÔdq'ӸCFJ,L2Z9t5OڬIg_}s 7`f678/ߐ^p`JH6 ^N*?ۻ.PUYjeM_kkk'瓞S*^_.2Jtm z&1Ơ~ >f( [K+Yu޲xz1+;眇ԂZC<6yLo3N 9^R(TM/zeMYܿđocͬ}IE4!S$CU;(@ނ%ɤVm`(zNZYn/$ &IELg1 fD&HMYgl2/V J?.e셃k׮lw;LOOw׽u\ve\vef۶m\z|scx;/_菸+PJb ~w/fӦM9W4_-15̕jRL8N48f H?#祤AC =!T~Xl2%"gT^髢s gl*Qٱz2~KⲌi[>?o,KK?,p7Kk }Kܔ9<\VL{0a:pi=sSOm5/y+>Zwi.g}[ܦ*댭X5/ȸ4G)+o4}[0 @Ďy;"t&(:SkjJ"„M|tIq )!I=uX]51;睢`|d6f"`Qo`oHhI&-UrMկkɆR?37|3w}7sssя}vϟٟWT&7vʩZoo5 IC6* )ޜJDv)^k's y6>05d4gPav2f !ddduQs(sNJQ2e8I)o=K7TS$=[Ҥt.Kru^朑l_hȴ&9vG|5⚥604^Eld|j4X:t}Q1aaD~ 89iTb YNzfO%$^0(MPJEn\2\Ε8+EHծ`/kڂŚ`qS)acyt.\pAϪ$]jQ̫_jRQ%".. vY9ny ^^$IBV~=ZZ՚ۿ/y !s`cJ*|(OܵNQo i_?], ^ 4t!fPf.{r!qPD%I{6q>wrrٌWNN5|dc)[澟L+d~1=K)0 (X :aD^eY.˪T;Nf'"+nz^e;BA30؊ }Jrbm"> 9(jrш0_0Yenqxa+>ʔ]nD襌_nfJ d2PԌ*躟Tvm1aa$ -lHjM &V5M\#A`r@A`ƾLdS+ ѩz !mK T5dE N1!Nh|,{]i%8fjFQ䎆))a4pzDdYV(XT)Hp=8~ט`vv6]+Ux0u`ff+WW1JH5$Y[H 2$ RfƮQ#єOF֏P[wQr|)7w|% '9 2U4S\T ,D)[[l!X _CN9xk56D;.)J 2?,1}yXCkaGyAt:+,V(Kir:BSPO" *HH&B!%ȸߕ%t-ZiX bhGqectiBK] AM2))\3' !jy&MK&aLB+#dFJ{Tgoc5tDWw“hТ)c+a(L:"rNwő#G[U1C" &BoH笳⬳ΪȊZ矟y,8RXA-6Gg CZVuItʱyai],7kc1z )w%Nľ+l$Dj@ uk4RJImA5ڒ:U}ι;3$$ = H` `!y&[` lpG,2$MF` +$cd$4H3{U;?Ou>w@V]kFwڵ>Xrs+⡠sR4Q籔)4Y9JsKpm $06Z5eRR .B:1$kCFEßЌaX$ L55&ݳV.| 8t7#O뇸a,"$՟Ms.c(h6ՋZ<}[~2TA{|O@}DYa$v>GQ `cilJ݆;o}v8bii9K`F$$!զc6"`-PAQ)2.&VWWw7ߌ[u< O%|=\ر ""'Liv͠l( W7OdlbVlC8{h><)8`0#Gp߿_K[t\A:p@ `/c1c.gta!!KD5?H x@uG_x : [GB+@ GAv=<:A $Rr>4MzomT f!s"a/Mepڷ1}~bfb<S>cTu;\v+^n}eR&bNz"1x ~O )?k*%[_D4C}BW(POu9Q Cbȼ6@"SP*D=5-[ʎ8yG2@@ BZMԥƲ2s ZOg.fv41a<1H{lǎ>X׵yG e)t#uuLv)W!oUж>C^4Rc𓷩 Jb<c~n Ԯjc$FDgal{jeJDL,dF*FQ( X__/fף1ԪEX{l(KsOjHm䜿?)j9XWɮ;h"mqSF6D_MMc( |%uzXݵ ^jg-BΗd7k#BCޅ~Rd2nn≌GO8X;EȺ?!,)j MlJym$LnFeX jF( kSRC@4A&"@MyU&KN K} P vi RDe?3"\ >(oeq7~b"@[%YsYeѯI:R6=־ aXKkg]uNNZUZ2x $@',UIY͆U+ H CDQIyH" OVC)e2}CC*%JrU!T(DUȾLA`˱ 懧ҧMhK`hjY>ϰrÆlxsաL 5}Q|WZ`ubxk1}X 1%95`ۈv3߽63ƎjT7󆨫rA(XMrsD|]y;*T̈hD&(34 (:xdF TU8R5wa`%̗KXa8Ƈ" ,Xb"ABC\7[Mf䗮k&vR oZ{1ך[@|nи6@nbB\ԏ3Ps4v!mpe(tStNX;XhCcZ>xEʽѸ4@UP7.D=3TkG33cB83xIɀ4 #ĉ8D9[-ZFW Bx6lN: NK $Lfh6jfS^Zx \yM.Qx=AWRV)c~׷1p%ov< m{sV.ʪ]ꢹis$ӢIpty;}mn4zuLiξ^#u94OU.25`mqSCTY,ER)q2Y9ts Ў|VXke@ QB5`dm)3F_B͞EY?Ù󉒡t1v :#sj]̐*]5Q&ԯ3uv%Z$g\~Z#6U2*M$8NJ'VC eb;v"ІPL3-`*o$)Ț1Q~R= }6یZI)U+^/gR5.Ad@LsrM[_x/P湹M,W?Ȩ.;ƨ ;'V*MU;[gu]RUTa8:\SK1G5VlUqTܢtњ0I9:: Ȁɬ4\Y{:'J0+ m9%dJ6"DPHHAߋk^1Ň1ƈ(<~2e5:$1&<{OrNTxԴY[5e%*J/` f<a%&Kn\+/cӃU+˛p& Ӡ n:TNj3OysQl@z6DpLβct:sG[ZYg(Ec-z>&߉& &屾Jk}IrӊeQ_r&u2 sIfob8BhYX:cB?@@kY&X].0- `26P\R}bs5^df]tChp8+pDq} ; h% ;!NTX<{! Ѝ0أRHYKa@56qœ!H V*^Ė*y8 EIM- ©:;h_f8xaF.֪U64MJTNeQvE5Mk=e)z~h.+yeWuӓCLu.*/JJ5ʡ@^c_IZ2Y&jl4#IҜÅ}M@JhR- jpɏ{P)Ra$$4D^)=/Kh$sj 6[jY]ɓ-)qL4RA6ְT |Y)nVհTDfj>ze\>t+5Fbk.(`%. 8$PRJ.EDZq[I_S Ȱ( mu@jk lH n=*!bClVfcLA0Ԣ%ZXh*騞HcU͋r4Iyy1}R& m ';/yx)[u^Y]"[zmaݵ_IgTƝ k]{IMZL=V縶ɲRfT4F_&I&YHRq(0ňNm-#&*V8uV2r Y##W”I0)#SiL݀Ví4ɻyŅq6iga│B(Mj9^akޮk۫mݞkZY,k+80\V%vM[D]LSU 67XޱAFX__3! Rb#0H2$ ?+`X Ͷ֋xC UǴèf0˱<cum7I7N{?Sr` ;hZ'ەj{p54vYH{qp&$hl4:$#p 4YBʥzq 60t/>Wk 88Ä-פr,@+O[gV=6Mͺf5Ru iQӴDVwwmv•j@=#!+nXH@iPxQAQaKU'x6V<&sZؽo8V;4ڭgl𶉾ԭ6MX,?ms;|O'Fyٵ7 98p'S׺*i|͛2יZ bF`+W}nҳWc4zNI@)ck( H66) HԠlk` $)1RպY;=%;\.Kڔ3e"Y(&!J$~M>&NAD[T*/@ rj Gb tHdtμhVWL1Ț$S- `móBe&:iHD x6B|?.77QuMPxOӚzH.r}oSitۜG\ߴξ3(NJ3(}ib:i¬L S)υv IS pOD(#h6*AJCpZݗ V$dCΓwM`M0ɨ]O X"*U.vbKrPc,SͳF^Ŵ9ϣ}=Js u^tOF:&EJ.n3Niה%T*~` O̤\TI@hJT}xUv,MAmjCQjlET*#q ÉEmp(FVVVrc'\"ggB&7Sk^?i\sq:kDT:vE9f)qj*&NiE~t^gI`b$ h!!!  5M?51n8XkN\JM@Irr, XܴZA6\I-KӀW t"vjX|w~OuTB,dn[MV6&)>߷;o2 4d l3}ɝfs\'v<aATQj  ߆cfDhښUQ @ =!l m+(u>+3ڡ\ $ F`ItI ! ^5tmH@$4A1 4$5HPI Mk)Ԇ hUQ0Z) h{+)CO|Rla(xX $c%cZt: a  Z3ps s "*Q:kh<*N,δj{lGl+y9F;uQ*U e j áj=3F`8~Ib  P.TRﭿ`WJ$t'9g+aX'gͺpUKZ:̦&1N CYJ p5zpZZ"&9? 2U K`<|cy;mB0 kcƏ1c }`$F;@ vvB,FgAK'vCvBuV@K X>ݝHнU˧$E$2bz8W88g #P 9nH(0-6 WN?رcR؊ SeTfHY#e0B)1þ'18\K]%HJ5_믿{.~ɛxÇӉG>^z)v\c Ě <[o^ȑy™uy. cmm W\qnF<+pCXY݉ /o+>!Mʗa+en\fILϚ7V u<NqXkhE %#ģMDQŵ* 4Ea?Vv|IQ4p8IV1 ۱'؉]ib!mr(2DAFphFӃa"$$ R2fF#Q54h0>cǎsA7 ZWEdڴCk}~gqq!|ӟ[okÇW{|eXYY4$bGqyygnh* >30 +J!F~$46bx}3ϜeQ|Mox3سg1va?Bqt} z׻g>x+p5ǃ ?zwkލ׽L05<(Jw~UWa]u\_C.~<jj5Y8K%槕nm2nU̬c؎,em泩(473L:Df)Nu0XY^ā͞섑f4N BZAm !媌OY4#ɐ ~  j핥 #`ee c*d@dMHt[*(V)H w@C:Հb(V!&xIRt ~YZ?w~[7v&YyDJ)SC<яƓt% /p8‡%C/gy&@|3qusB IO{:AGqӍ_@'!Mc,//`;ށÇG?Qݻ7?xfcc3t]\\W_ ر W+Zz8 Y0[w}u.1Q*߉E:!ǐT"W%HR&4BQ . )T`)RKA ˓cOmX(KSJ*H-- (Ħ{iM2U$CBHTJ 2 FSJPJ@pAkS[c2$n4M18V`!XA!%F0 |i8un|_p(CږjZ\V!I S3~os _EE翀o<$$k'Bum2^ 8 ^g? q<e; ()4뮻&OiOWDQ@b{ Wwy; ~կ#<7i\ySpl}ss]~Zy> FM nߟij"=:DDa:;J>PԩX JBSm%@3R/]< mۇЂMY+wcyy1 C0#E8yk^(qU`nn(o=[&z.5N޵W9cFU KcbsƮ]1G@< t!Ksa!- Mklx"Wa98N9d\';6>뱶(0z+[hHQfrmxq$,--A1>.#HIDATO˷|~OxN9, 5 ++$khcq4گ=_p.|$QH$ 1p忈e !g< UvکUj0R(g{`&cK+u!$=o|ӛolgD0Ԇ m¼ gC=t06y?KcDAMZ}V#)6771̪'J7VI{5MhƉDjA]RcUg !1 s~ }@n4g`(@/` ~|??}z71VGqh KXBDgu6; !g[C"=ʈ@' [)Y\D:삆cuJZHxc._E(]&o#r=Uk*(A u=wKr9^[/řgG"M50H=|@?(G>9J%6[x8q pm1_XXq45U2ޙGx ^|fĵ^[y0.;}>n;Ww ,`Ϟ0i4cٟ<$rB!%J@NH {>8MccSAJKKi,q~Ide83O"3CKԀR`FAA$ MK F HH8yg =ص<@:@WHpbaiq2 {ű#`[#hd `yi8Anw::^JG>dBX5!06Ʃ3߅D3$ vXC<y޿5b" ΪwU6t(ma`c !K xo+opB @}`c}G=7|W\$$)N?TFHm>%a? H/zы G&Bқ8spKhm"nK.ymFVenI\Rv-7ߊ?qE|%46s} 4c߷t<㢋.c c ձ!*,9H*X{۫hk׷vYYܶjTD gBbD LD uzH)P&SٵIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/TemplateFlow.qml0000644000015301777760000000264612321005637032001 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: templateFlow property string title property real titleWidth: units.gu(10) property real titleOffset: units.gu(1.5) property alias spacing: contentRow.spacing default property alias content: contentRow.children height: Math.max(contentRow.height, label.height) width: parent.width Label { id: label text: templateFlow.title anchors.left: parent.left width: templateFlow.titleWidth y: templateFlow.titleOffset elide: Text.ElideRight font.weight: Font.Light } Flow { id: contentRow anchors.left: label.right anchors.leftMargin: units.gu(2) anchors.right: parent.right spacing: units.gu(2) } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/ubuntu-ui-toolkit-gallery/Dialog.qml0000644000015301777760000000327112321005637030570 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 Template { objectName: "dialogsTemplate" TemplateSection { className: "Dialog" documentation: "qml-ubuntu-components-popups0-%1.html".arg(className.toLowerCase()) TemplateRow { title: i18n.tr("Standard") Button { text: i18n.tr("Open") width: units.gu(16) onClicked: PopupUtils.open(dialog, null) } } Component { id: dialog Dialog { id: dialogue title: "Sample Dialog" text: "Are you sure you want to delete this file?" Button { text: "Cancel" gradient: UbuntuColors.greyGradient onClicked: PopupUtils.close(dialogue) } Button { text: "Delete" onClicked: PopupUtils.close(dialogue) } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/0000755000015301777760000000000012321006415023722 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/calculator.desktop0000644000015301777760000000033112321005637027450 0ustar pbusernogroup00000000000000[Desktop Entry] Name=calculator Comment=My project description Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/calculator/calculator.qml Icon=qmlscene Terminal=false Type=Application X-Ubuntu-Touch=true ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/components/0000755000015301777760000000000012321006415026107 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/components/calculator.js0000644000015301777760000001511112321005637030602 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ .pragma library function Calculator(textInput, memoryIndicator) { var operationStage = 0; // 0-lvalue, 1-rvalue var lvalue = 0.0; var rvalue = 0.0; var lastOperation = -1; var memory = 0.0; var clearInputNext = true; textInput.text = lvalue; memoryIndicator.visible = false; function setValue(value) { if (operationStage === 0) { lvalue = parseFloat(value); return lvalue; } else if (operationStage === 1) { rvalue = parseFloat(value); return rvalue; } } function value() { return (operationStage === 0) ? lvalue : rvalue; } function clear() { operationStage = 1; lvalue = rvalue = 0; lastOperation = -1; textInput.text = 0.0; } function memClear() { memory = 0; memoryIndicator.visible = false; } function memRecall() { if (memory <= 0) return; textInput.text = setValue(memory); } function memAdd() { memory += value(); textInput.text = setValue(memory); memoryIndicator.visible = true; } function memDec() { memory -= value(); textInput.text = setValue(memory); memoryIndicator.visible = true; } // arythmetic functions function add() { lvalue += rvalue; } function dec() { lvalue -= rvalue; } function mul() { lvalue *= rvalue; } function div() { lvalue /= rvalue; } function sign() { textInput.text = setValue(-value()); } function invert() { textInput.text = setValue(1/value()); } function percent() { textInput.text = setValue(value() / 100); } function sqr() { textInput.text = setValue(Math.pow(value(), 2)); } function cube() { textInput.text = setValue(Math.pow(value(), 3)); } function power() { lvalue = Math.pow(lvalue, rvalue); } function powerOf2() { textInput.text = setValue(Math.pow(2, value())); } function factorial() { var rval = 1; for (var i = 2; i <= value(); i++) { rval *= i; } textInput.text = setValue(rval); } function sqrt() { textInput.text = setValue(Math.sqrt(value())); } function ln() { textInput.text = setValue(Math.log(value())); } function exp() { textInput.text = setValue(Math.exp(value())); } function sin() { textInput.text = setValue(Math.sin(value())); } function cos() { textInput.text = setValue(Math.cos(value())); } function tan() { textInput.text = setValue(Math.tan(value())); } function cot() { textInput.text = setValue(1/Math.tan(value())); } function sec() { textInput.text = setValue(1/Math.cos(value())); } function csc() { textInput.text = setValue(1/Math.sin(value())); } var operations = [ {code: "+", operationFunc: add}, {code: "-", operationFunc: dec}, {code: "*", operationFunc: mul}, {code: "/", operationFunc: div}, {code: "+/-", controlFunc: sign}, {code: "c", controlFunc: clear}, {code: "mc", controlFunc: memClear}, {code: "mr", controlFunc: memRecall}, {code: "m+", controlFunc: memAdd}, {code: "m-", controlFunc: memDec}, {code: "%", controlFunc: percent}, {code: "1/x", controlFunc: invert}, {code: "x!", controlFunc: factorial}, {code: "x^2", controlFunc: sqr}, {code: "x^3", controlFunc: cube}, {code: "x^y", operationFunc: power}, {code: "2^x", controlFunc: powerOf2}, {code: "sqrt", controlFunc: sqrt}, {code: "ln", controlFunc: ln}, {code: "e^x", controlFunc: exp}, {code: "sin()", controlFunc: sin}, {code: "cos()", controlFunc: cos}, {code: "tan()", controlFunc: tan}, {code: "cot()", controlFunc: cot}, {code: "sec()", controlFunc: sec}, {code: "csc()", controlFunc: csc}, ]; this.execute = function (operation) { if (operation === "=") { if (lastOperation > -1) { operations[lastOperation].operationFunc(); textInput.text = lvalue; } operationStage = 0; clearInputNext = true; } else { for (var i = 0; i < operations.length; i++) { if (operations[i].code === operation) { if (operations[i].operationFunc) { clearInputNext = true; if (operations[i].singleOp) { operations[i].operationFunc(); return; } lastOperation = i; if (operationStage === 0) { operationStage = 1; } else if (operationStage === 1) { // evaluate and continue receiving rvalue operations[i].operationFunc(lvalue, rvalue); textInput.text = lvalue; } } else if (operations[i].controlFunc) { operations[i].controlFunc(); clearInputNext = true; } return; } } // if no opeartion was performed, add operation to input if (clearInputNext) { clearInputNext = false; textInput.text = ""; } textInput.text = setValue(textInput.text + operation); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/components/Functions.qml0000644000015301777760000000252012321005637030576 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Grid { id: buttonGrid columns: 4 rows: 7 spacing: units.gu(1) property var operations Repeater { model: [ "%", "1/x", "x!", "x^2", "x^3", "x^y", "2^x", "sqrt", "ln", "e^x", "sin()", "cos()", "tan()", "cot()", "sec()", "csc()", ] delegate: Button { text: modelData width: (buttonGrid.width - 3 * buttonGrid.spacing) / 4 height: (buttonGrid.height - 3 * buttonGrid.spacing) / 4 onClicked: operations.execute(modelData) } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/components/DefaultLayout.qml0000644000015301777760000000777612321005637031432 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: buttonGrid Layouts.item: "buttons" property real spacing: units.gu(0.5) property real buttonHeight: (buttonGrid.height - 5 * buttonGrid.spacing) / 6 property real buttonWidth: (buttonGrid.width - 3 * buttonGrid.spacing) / 4 property var operations property var __model: [ {"label": "mc", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight}, {"label": "m+", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight}, {"label": "m-", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight}, {"label": "mr", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight}, {"label": "c", "color": "brown", "width" : buttonWidth, "height": buttonHeight}, {"label": "+/-", "color": "brown", "width" : buttonWidth, "height": buttonHeight}, {"label": "/", "color": "brown", "width" : buttonWidth, "height": buttonHeight}, {"label": "*", "color": "brown", "width" : buttonWidth, "height": buttonHeight}, {"label": "7", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "8", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "9", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "-", "color": "brown", "width" : buttonWidth, "height": buttonHeight}, {"label": "4", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "5", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "6", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "+", "color": "brown", "width" : buttonWidth, "height": buttonHeight}, {"label": "1", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "2", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "3", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, {"label": "=", "color": "orange", "width" : buttonWidth, "height": buttonHeight * 2 + spacing}, ] property var __lastRow: [ {"label": "0", "color": "#5f5f5f", "width" : 2 * buttonWidth + spacing, "height": buttonHeight}, {"label": ".", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight}, ] Grid { id: grid spacing: buttonGrid.spacing anchors.fill: parent // memory Repeater { model: __model delegate: Button { text: modelData.label color: modelData.color width: modelData.width height: modelData.height onClicked: operations.execute(modelData.label) } } } Row { anchors{ top: grid.bottom topMargin: -buttonHeight } spacing: buttonGrid.spacing // memory Repeater { model: __lastRow delegate: Button { text: modelData.label color: modelData.color width: modelData.width height: modelData.height onClicked: operations.execute(modelData.label) } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/components/components.pro0000644000015301777760000000045312321005637031025 0ustar pbusernogroup00000000000000TEMPLATE = subdirs filetypes = qml png svg js qmltheme jpg qmlproject desktop wav OTHER_FILES = "" for(filetype, filetypes) { OTHER_FILES += *.$$filetype } other_files.path = /usr/lib/ubuntu-ui-toolkit/examples/calculator/components other_files.files = $$OTHER_FILES INSTALLS += other_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/calculator.pro0000644000015301777760000000063412321005637026605 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += components filetypes = qml png svg js qmltheme jpg qmlproject desktop wav OTHER_FILES = "" for(filetype, filetypes) { OTHER_FILES += *.$$filetype } desktop_files.path = /usr/share/applications desktop_files.files = calculator.desktop other_files.path = /usr/lib/ubuntu-ui-toolkit/examples/calculator other_files.files = $$OTHER_FILES INSTALLS += other_files desktop_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/calculator.qml0000644000015301777760000001037312321005637026577 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 import "components" import "components/calculator.js" as Calculator /*! \brief MainView with a Label and Button elements. */ MainView { id: mainView // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the .desktop filename applicationName: "calculator" /* This property enables the application to change orientation when the device is rotated. The default is false. */ automaticOrientation: true width: units.gu(40) height: units.gu(71) property var calculator: new Calculator.Calculator(numericInput, memoryIndicator); // default portrait layout Page { id: page title: i18n.tr("Calculator") anchors.fill: parent Flickable { anchors.fill: parent contentWidth: column.width contentHeight: column.height Column { id: column width: page.width height: childrenRect.height spacing: units.gu(0.5) TextField { id: numericInput anchors { left: parent.left right: parent.right } readOnly: true font.pixelSize: FontUtils.sizeToPixels("x-large") font.bold: true horizontalAlignment: Text.AlignRight height: layout.currentLayout === "landscape" ? units.gu(5) : units.gu(7) primaryItem: Label { id: memoryIndicator width: units.gu(3) height: parent.height text: "M" fontSize: "large" font.bold: true } } Layouts { id: layout anchors { left: parent.left right: parent.right } height: page.height - numericInput.height - mainView.header.height layouts: [ ConditionalLayout { name: "landscape" when: mainView.width > mainView.height Item { anchors.fill: parent Functions { operations: calculator anchors.fill: parent anchors.rightMargin: parent.width / 2 + units.gu(0.25) spacing: units.gu(0.4) } ItemLayout { item: "buttons" anchors.fill: parent anchors.leftMargin: parent.width / 2 + units.gu(0.25) } } } ] DefaultLayout { anchors.fill: parent anchors.margins: units.gu(0.5) operations: calculator spacing: (layout.currentLayout === "landscape") ? units.gu(0.4) : units.gu(2) } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/calculator/calculator.qmlproject0000644000015301777760000000123012321005637030156 0ustar pbusernogroup00000000000000/* File generated by Qt Creator (with Ubuntu Plugin), version 2.7.1 */ import QmlProject 1.1 Project { mainFile: "calculator.qml" /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." } JavaScriptFiles { directory: "." } ImageFiles { directory: "." } Files { filter: "*.desktop" } Files { directory: "html" filter: "*" } Files { directory: "debian" filter: "*" } /* List of plugin directories passed to QML runtime */ importPaths: [ "." ,"/usr/bin","/usr/lib/*/qt5/qml" ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/examples.pro0000644000015301777760000000066012321005637024140 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += \ ubuntu-ui-toolkit-gallery\ locale \ unit-converter \ calculator #examples = jokes unit-converter #filetypes = qml png svg js jpg wav #OTHER_FILES = "" #for(example, examples) { # for(filetype, filetypes) { # OTHER_FILES += $$example/*.$$filetype # } #} #other_files.path = /usr/lib/ubuntu-ui-toolkit/examples #other_files.files = $$OTHER_FILES #INSTALLS += other_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/jokes/0000755000015301777760000000000012321006415022704 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/jokes/laugh.wav0000644000015301777760000033230012321005637024531 0ustar pbusernogroup00000000000000RIFFWAVEfmt Ddata                                                   ! !  " " ! " !# " ""$ " &% %&&( '&(((*(+*** ,,.+. ,./. 0/.1001 22 14242456578778999::;;<==>>?>??AB@ACBDCCCCEFCFEGFEGGGHIIJIJKKLMLMNPNRRQSTRRSRTUTU TWXWWX[Z\\[[]]_\_^^`a`bbacabbcecdgeffffgfeihjiijkknpoooopqopqqtsuwuzxyxy{{z}~}                                 {~z}~}}~y~~|}x|zwu{xy{{z~}~}{{yxzvvvy|zxy{v{xx}|~}~|y|y}y}~|z}z|yx{yxxxy|wwvypwnzoyryszpwxtunxrzlzk}fmrv{nmlkljmnigjifffb\a\\YWZZX[USRTQOLKIJJGHGEEEBFGGDCGGCIGEHDCB<B?D<BBBFFFCBCDEAEHFGGGB>@FJ@AD<9;945/-1//(&,*((&((&"!       !"*+-.(0013.535133.0-63/26949<C6.3<?>HJKF@F>?CEF?BEB;9<<<??@B@B>@FCBACD>@B?CB?>BCEEEILQNQQONSOIKQORLPPQVRWRNLVSKOMNMVSSX_Z]b`bfbd^`\_g_`bb`gfbfegjcadb_ed^fgpmlcjdkohjlllprpsnqktovwumrsuyst}yrsrwwvsnigaa`b\^ecefaWaYb^\b]Y]\YX]]`baTZaYXXTTb`c`\gaa\adg]UX]XUU]TSXMKDBHCLHICCCHLKCIDHJLMSQLCMPDC@HFEJMKEC:@;:DBI?@?:?;C?8C<;??DC@C<79;?7<>?@:81//+.-01.&.2/2/...*+!+&%/." '%&).2*2773766A;@132')*/%"%#%*&%%&"&&&&!+..3-<32877.:86:8?:A:@?DDB?C@@C>E@?C??G?CHDLMKIGOMK}LMvGvHxIyG{Fq@vDm@iCl?p8p;s:o;sKEPGOPMGHIJGGH?D@DAHC>FCKLJQLGOLLQHKPPOVMJRRXYWPOYOXLYJUKTOUIO?^<]?XC]C^;O4Q6O6P.Y3T5V6K/H.L*U'S&Q&Q#GHL!K&PMPTUQOLQHHL LP L DHT LHB?E G QPP O PUYP SQQTaaeakn]a]VWUPRGGIGKDMOKMLLKMPLQXPQPOQQT`]^X\baXaXTUQTTQQ[ZPPPTUUTKUYXZ[ZQY`fmjsur{{~zz|~   { ww sz w |}z!$%..'1.)-#)),) &# &%! $& }$ %&#.$$.(-,'2:9>KFCBAG=B;K0w $| xy!#|!~|(*v#}-{2v(w.p$v'w%~.},y(),24:;95:z9~-y0z2|,.}45w2u1w5}:v8q6z5q9v7p8v9q:pGkJjJmLwSuY:`SgK|lo[lOn\wcpWpap_gXjZf[k``\cW^O[]WRYRZPTNYSWSZXZWZ]VZ]OSSMPONKSLSKJCKCEe9\EeHl9l=h?dClCl=l0a,`)X,R.O"JLD!BP*N+F-K+N4OO?ZFdF`G\GWMaMVQ\JeRcZmScUi[`^_`_Yl`n_l`q_k]i]`ZcRhP`M_P\QeKhPdMcQ_O`QdL]JSJZEWES?V<]A\?O=W9N:J8K4G5B:KN2K4B2C->&9&:&6&0,;0=059>79423'5):-7.2#/-46))!!$!)'+)-,:3A061,,"&.$#"$&)) $         uoja^W]U\]Yakmw~ ##(0:;BCLSSUgfaYWTEA=91( p [QG?7=6??DCLb ez1?N_gcd\]c`^Y\TKy;4/..3+-##0%6&" *35";%J4?)4/<G#:-@-RCWMfPnYfXdOa@VDUGdTk^fW[PUNXKK67"0+ 6>G NKEDC@ 3"+BJMOWT@,)"   #&#,3;.-/: FV#V%Zk*j2j%`"Z]_a!h)t/t!q|){"}zg\ZSG3     /69K_#dZVaZL9'pgouaVgxolt$){u_Xhgfkfk {ox}wkdl|sW4  1/04E[ux9E:=@:# #u$39FZd} 4 ! *2&/$6+4&#ttg_P_VQWt )<(%61" (,xAlck_SMLNM C , )37CLN7 9 R#tWtjzVtGIcn{z`sGVOtpnaifaY|JjGcgg5F*86cCxAoBfJpKuPxwBk4NMkO4V+B>V#P E1,4/48kdn_ky~sg`wafsz^}Lg\gM7ZHdX9s/ W}eygAlO^L:JTE3@ahZe} >imoO{ ~ P{UzaIJSTEyDsSWFp*U_Sf6Yz)PL'&.&gJp:Y/36j7=3If]{nmFyZsyj{68-1}W0;PoD%g3bp !"6 svUwTPZ ep qFMu[ywoP8W@kUn)* 7m m1A9ZpW0z@sdrm4#PAa3#4` (Dd^Mn Rd\`\4"d yyj\9w0NJ{I K*FTDuE.Q^LgmbjV0 z4c\ P.]$ jKKzH1v9} `m @;`+Y*9~$ci:B&zbA&Gl%;tvT:c7lL<p!vliV5Xam^,Y(x T~2( 3r V(L,B9'e(tGL+94GOfVy_*neugLoc.%tDOvp>`/;CPHsP.PM{UX:2BmI _#E"p0OYYW4kF~ ^SYc|+&S"CWykgVd;A9e?;,xN?R$Th`%>0.i-! mhyF9E` c?h6eUSGqdY1\O</C<f>zyj&/4\'s[(`S GM y-L|rkyuz`yS\YK~f^?|?*pN%sFB>ZRxGq[{((5VFv9g`Hz`;SHpUP {bneri; |Q70|z`P@Q:PjBmkN>{5>~KE*(B7Fr1; >Hs_SKtVhiw|ex2uhMHdP xO}TK8a!]nO}_~;CB5@ANfNscZNUS-\8xbhhC=0[M[}1#>YKFMG(JNy= W7dUkfBP9:tAhdwP}kBbV^Eo`V{ZxrqBN ]e#4$NMWTju k6v1!Q-C 7qW`:\ 069:kVFqtOVuty0[`li\vbG+d#2+:G?c'Z?Byzv3057QgnU01 "LJ pDwqwO3VmRNsB_T:W=Un<Y =7CZ+',1:f[HwQj`CuJ.@72  yd*abg./S/$q<y:N O0w!]7eH/QYf|_o4] iJgNIrt9"A$ 5>P.H*NAeo& b}uA~R@'amk \MqIGN [4gq"XVPS}j6lS2D%8 kp(J}dQ88^w1F`- CsV V4Sks<ms0Ng;s}+;UbV54{%anD|I4Z~ga1OQsxC*NCKGJ{ -yotUnJ x N7'>oc/ZlK qmk) RM8-bwXm]d{Vv)Q\+ _kY[1F|P!y-fRCIkzY&vht8 }\l LBJDHcle2i%Hj7t6ip:UVR]sxwQ8Lb:A; %% VqSuVu7$v*s@BE3OoS 9$ z, $  + W 2 K -  K " $ $ 2H   X ?r ~ P S R8 S h    R MN +  )\ ( Fq  au&E /axd i  g 9'  A~  ! & N=     & N Q $  0 Z n #D   n o {J ?jGSY00W=n(L@t#~g3]H#R/({ g]UC- ;53`><{L mij;5VAM#MBhwz$ >Y<*[FnV JVCMk,qm_Ac SKc42AW`-%7Py-84e~"/ri c1Cr7w 2H@E#stfac=+GdspTQE"wt3'n -  " 39 B> 3O+ 9 4y33roEOeI|{EX3InI[? W  5c c /  >    kl ) _ 1 2 h  5 zL vv b( ,  r[  0 i   ]Q0G'5Fwl`JrH2eK.j}Nl$;Nr2G ?V  3 ~ V G. l"_hq >  V*kJHMk0b7 v:uL/XR lo H*23[S  O&GSkTs&mKluO)uyX?N'f* U {  ^n Q 5 } k T u  T  %    "J4pt3^uD+ 4Y 17 =  ubs6; 6 | M\dc @ f 0 d "@ j  / ID  b05lc WH wEgG$%4L#^&,G6:G$Dtso tc/-H?@}R!;NFLTnsp#NA)7+Je/?+ xq\%#K<)lH~ YpfiVAj)< LC] O >[QrY **;K,Gb2R/R%8?QRK07u[ZCy,>>&eSZm+_ /VyB yI<.2 bwshvG1, ]/0:cz5S\DJ 7O / M q j{ 5j   H ?  t  n f R b  1F  I49Y@(>` /r  r m6=_ r0 Dl 9  7 9 '    2Y J  ao /dY$h.&%k rSLR4r+/ IWg0Oe^\P$qRc[ZUy.htiOZ"-z 2Un2;V ~.[*o-G.{|_n6$*4>'"()9>+=r>qs6-q@EU(y[oBCmn}"6/E,^v!<;Ua2S`ko#ICRvlaO\!?XuJB-WliZ7zz4@ 6s0:{$YIQT3 CuZsStJ5sO c= oyn~AvyP <  c>o 3  p  L    V a :: ( & M  >    cDY&/v ME *Kml~ GLw0C { 7S,B,   )v? <? 4} & [k W g      y d f X ' mp L#C)*l@^xD  c5>:m63r.lhlJYc)s!_NJZ&O k2*{ty,.WInHpfr"v(z+f>P:RAo&-[ *=z^ #Cc]^D27TSvhy^u7y#Ms>JFg[E-.[T0qBvs8 kl $(Rs#]+G@~elbauT.*ANZg_OQ8*RWowv#p'3N6 M-LT/Xg*G"HZ]'3H5 ( !a0Kn {< l #?9+W>il  o 9#   ~  t . | K B | ! "  >  >      u  aF  G%  0  4  ^ )l K7 ^ \l zX 2 Q  } g p Y.  JEH\ i _ Q! >y o   wE ( !!2n~gcgb}+Ag 3 v F W /  P 4gc|:y<x%!p t4U&z}p+gC=P%Y-u(:=<-ngUmnpkICKDi&Fc [g" pcFOUr"+89dTScIH)^1   Q &  " + $z     =  ji Z ^#    wW    [ T#  `   'm   {XL C Q Y7 : ," I v    K  W ; 1m-SPy9<#{   6-{# 86' YBGeO5e"kP\5r)=pniB60{pd5{LT3 6f@.KPPwahAy&K ,8}!^CK@zV1qY7[5gj+tZ|9Cxbh#BNkY3BAXtc9Sc TtIffgb7xbBI/A>?mU Q<&Z:{z!/Ln'+fw@J~?]mSk_L& a`\q#0_o[Z8sBV=4El._&> <  v  Q  | T + s Y W  B o + { L  9 r & b R h 3 Z4  #8 qT W  HM   u = I N}   L ) A   H   i a#  K $} !m"!x!|H"l#P$o#"| !f X    ^3Fy5ny|^0] 6 Gi^s]bbDhW 4pP#u"#{AL%wzY djQDGfp-[5S~k*lrx<gcNZx5IQ64d80+/ =wR,will0A'_[WaFiQ iIpd%:eq{!bbm&f'scyP;D&nb9RtDNGF.;KdH_iZd =Z}YVl`oXPyixQ im ?% G Vu m   O M  - O 7  << 4  0 f d 0 ^  a N .d u {_  wF?bz&\Od2x`L+"Jr{0 .+F=/~!_"C$F$!1#"%zn'&Z&''f'V)+%-G/N.|-,,-Kq,~)!%J W'@Q=`Jp })<=1%7`JM"fGa,~!,Fa.= , /]  x[L 2Q, :QI Y0uuf&(0nMb!}+0HwGoRMe EWU=M{ %,?R!W'Zm Z7, w/<=oUAK#oK-m'NB&AbREXt*\`sMUJQ_FSLMde}& ocG R>15P<rLc \`Y`~ a   K   VD   h 5iJ `  DB v J F % d    v>j3[rnLnI;nr_ ~g!y#$ &Y!'!:(()\ m*N M)'(A)")@*)L(.b*Uf,M-c/0b0~i/!0>1jV1H(0.gA,7*g)*L)&$" 93T͝%É_%Y?$Ӈ} #F߮(~| , :x,j070p6=YbD*{[  mV3\n2W;cv\9Q'(en& c\0 +td9DVRFfZ9-FL b"YHN:EY;e>*<X+v&5 @  * >     X   d  tx<"aNF|` QpPI"XDuwYX# '<Y0    \ pmm X n Y  P  P[OYP 79reC3B6EA|V1d!# B!E !{"$<"%T#<$)!%s!2&!,&R#,'e$&$C%#r#?#*"%R$)s'N+' +&*E$$+#s,F$.d&/%/#/"0"44%7M)n9)8&>8#6_ 321)n-|$  tl!ayВr/ܿcQWXߌ ݁"gv7%ʘVQ iBλ.ݗNXP{}./Zg yJWcM~E\)f^1W ^X3f3I,K;u(+!߬hf| z\Uד<غdع׿EԊٖuRյrӨ$,Qۀ5Vp<$gdA~^ J+sMx  -VA I[cw  H 14  3 Q  xD  @  5 _  D vm^)`} j j c O x v  1: t L>a/UtG1N@lN80 B  :u R- . k $ md=x-lE-{ !!# #" $"&"&%#'$(t$A)%*).,~0t,00*L.),))o-'-}&N,$[*f"d(_&Ms$%4:%##z#` N# " " #"%b$&d&W&&O'[&'.%#G 9D ]&ZޜbP2 @NJ!4ǧIڒPͅɶI8¨N޲ ^ܵƝ+e հݓG:0L{[Up?nrG N # J br w U <{SAsC*[" o IOI|]#`Rzu0=5фC[ڽպૺx";̾׸Ib,zZ9Xƴ͓],?8533 J ]!M3!#!"9\ Ygq2!$M'a)K + -R!,B!*>(%W!M[ D-  1 7;d:kwv<Ren^XR:-r1yfi)J ; H   C f< 61f"J8(?2t^p c"%W }(#*j%+&U-)W/$,//--+++--0112122E254a9L98<=& '"m$"8 + D 3   /ky_QYEr[7?39IAe:C;lE >vHqA LE)OGPHQdIRiIPINILGIENEA@="<8!512+% M= O1´B$]>GǍǪ@s@ͽa%k8;% ԯְݴ{G¡5ʋΘ4ݰ>f-c\'փsA/)Ԧ:ިTogzT""*/32hz/,)(W''7(**-$:1)4,6.7-6*3B'04#u+M&$e   [X'yi8ke}hLgەK:̲AC/ı( 5.ñ"M%5C|aźjbDao?ֶ0#{t+" z:Z/#)$.0)2J,3,2*0'>-p#({$)9!-\A9Ri T9^+1QO (   {)|$hKP7atb|U9)MXvt  V@S 22\ 5!G"v#$'',*/+,w2.I6[2 ;7=:=:K>b:?V;A=Cn@EBHCLE\QJ.VNO/YQZQYPXNTKMDDe=i<53+ ), _+taLjݣõբ75ŝѵťCf.B@m벿HKWǘ̻q:iCܣe0/c҉tШaް ޳X?ARny  *%*q.0r0S./,y*2t*,s"0g(4-72l;r6p> 8:?7=S38".E3t(,!$fD7ZM & \UBG9#^[zތ"֑nI0ûC1ưs(”[p7npI S-"jŊ_τI5ف}߰s *O)wrIfw B 2 < :uUO%Gg 3-X]t(;% )@?F )S >I&( f>2-kRH[)gkN.THM#E&  Z N =IU ( "e!A$#t&?%(&)1)+G,o.h/9123j558K88=P    Z   0 Q drSQuIc=s$e IT~D~hKWw#RgurtB?' 6t2u'` hc ~.>)M ]/6O%!:# $"&^%(3'))++w-M-.P....y/.0.12-/V+s-5*i,.)*&a($%F"!N E ;\FZ_OѭݖϮ?ߎ@1ֽFCܸܺqg_73ܯک֒+݃}c\MCwEp~Y9|YH6 l: $b1),-"-Te+<(P&R$A#b""2{$&sU'!!' %#s Ly / 3" 3u5fh=Yv?RwY62~ڡ֣վּ(ՓwotcWJ>"ۿL`ט%jfYݼw}n)df    ; ;IFA"u;oo[9- r _ 2+k u}3A]JA"|cBwa?._ aY3 \   >t IzX\Q"Qؐ~4қ+|Dl "'5EULd`*[xyx\h@!9,D   > w T|A;/[j_=* 1'C6" Z M2@TK=yG?DdHZudRp7Z 5j`Xe{ .?rD? 0 & &p W>O1A!&!"9"$"b$"l$#j$D##"!#"z /"!!=5!!"!! "!!!" !'!  dtJ4fDi#]:J]Nem  {  "_{+؆NG~߂ԏ ,ݭ+q>A܀7ٱ.#Q:Rړގ:v~86/ gn; rG  9 &^ KV#0'1)([@'9$\y @+ S 1v z9? 7:euc" T({X 8(DG:+?[ _tۇ>ZO@Ջՙ1ڑlqKeR7z*-f(=/R,>   (  yGm { !"2##0#$"$!!-uY83(<# h B sKAk Ovى;^׎ق׺ oܬޡޥbޅKSE޲8w'-hV&c 1?l* | |eol&8a 6WRe+)Hdob @D<'\#Y-bI    L  {  3caZ15.7%$ !h8?65j'$8ur>Zdp +!6k ; @ ?  u a  J  eqi-G,"  r}GfZ$;A3i[(0% lWt?ݝX8E"RJAfASDl]e$Mk 52|~ # Z  c g 1 w o W 9f4  >W s > ] q : d 5 ) C d @ _ i zgH$d\    P   A a` 4  k_4K>ZrP*zj#70'*k *S . ]Q.cpzQ5 W- zk_Yne)CXI= j2K)_z9,ooP4fZroV_l {WU kw  H: "!%I$(%($%"}!K /kl_n s G_ sI b]@W.:"UGeX5&{uM;},DTX PQ c _ d W  <] g|G{?d  I h 7   z.u%U'R$Vl*f Y>7#JY8Fd7J$3A H\*^_ N eV( # c`gS JY * Y g"#w R@D[Ul0gHzw!""&!M~7V OCJmfdL<FQ!> ^$![)=&,^(!/)P1t*^1)J2#*g/&*y ~$nFW)Ƥށ(rJ4Ɋ,6wDLЫӞl7s„Øi-T֦*YpyOFVB ihAI ,Qw >#%'G3* *H(\,%! ^ u ~%#o+J+V013R66:s9G:y86f3/}*'u  =WZ d\\wJPAW v4/Iڲ٭ڂVBܦW@yJP4b} ݙیb܁؊ݺv߮&u[bPK @ Y6Md!U$(7$*'+*+-*.)/(E/_&-"T+_(,%!= pR X ~srh,Oz4"}s֋ܑԲڥ-xyNχ ՐGmhNJ"CߏӨ7Coއ 2($d6  ~   W{>,djV]jqryG h N Y T*#O8 o T9 . W  }`mJ!^N$3>(UY^ z b kfNx{, !i"j$(&(!*+, .c!8/U"r0<$w1%2&(A4*D47+5'-7/8/%:/z;/;.8(e4".& ζ,Ղ)W}Tbċ$5ѲI5NJ7óV30]̭, Ƥ/ӁcU C G&;QN[ E$d)-05495N;q39/3s*.&)"%!S$$%f)&)/ .7P5@=HCLGNHMGYI.BB97e.+4!  m!\&vo2fZE15G&I(znjǩŅ|ͩ>1ֵ7ݞjn)toT2gdG.E s  n=R ]Z}S!$wq$# 7~ e"6F yq`PH6FDA'mҚqZ#z ۛ7ܗL ߟߍ,HR~Zx@y~H 0 u .T?" r I Zy N<  n9 |ad rvO$Y1{   @   Ka 0 2   U2F%cq. 0!'M E": j 9 s  D . >W ~   MDFo $2m i e +u9 /Q{ f t - [c X k = O* j (](k F n    aަ܊]cޫH_=KGߟ#;Dg0n# q(ZY ~  .w V | j F %Fel 0R &f B-ckI T0 4 " > WgwA]l _nqLC_f[h vC u2~s}C8/tH{bK-E ^6QjH*#`~H3uNt 7&` @@?x#O2bCY{ Crm<1K=7($@d50<*@qdC l# :#B`]XT%XyG w  /  0 m.xJI;u  g< A0_+}u%1+6 N+{ & :  C 5/ GG R  +  &Q & [ # :     PU  I N(y  6 E R |  & V.u|8yO&F mhxRfYp8 Ru3<_%!"-c##r!g= Tl ( Uy; XWSUw9TyA%C 9o]FUb*:&v*'x'Mco._}9n U* mo  lX  rbD([  S G`hOyr\Etkbc4;`5PH9T"@=vqTIS"erOhq\W*Z8i?&geO5.. Vf@ADn{>?E D12mw>a9 f   %  n  !+  w]3 ?-'a(_KA.6t!oGMo;rL| GH+-1A3T=2f3`. qzondAT&KdB A.yG!KWS6d`isl8bV1Id?< ?YU~v0* ?1     r ' / ; f  m e @ _ s %` PyV_ YRnUzc18    1 F[piECC9-jF r&yF"\n/cy nc\5a"f[_F8x~s]m}   hgm  1 vD y Q Y f & C Y ; X  * Ki e g   : tc`;<G%L\C W+D:^ldV{-P2qG6W6m5^@V/mTQ!*`]| D|Z C   MN  M EVbs-4CuSP>!-`L\Y.6})Q}|u%}: MVf=b(afma0 ;8 T>Qw. h u G Nb0{^'J3n:py5utdx\3  7   I  y   ( | 8 ;  h P i r=x;A2wJf8dXpPe^fh4Oyz,D @, 2fuBߍ3ޕߏ߭by$ߡ7-CYo#`6" hqyDWr W u s 1{g-lGEEP"iE    w!jv0p'1Q6n6[2;6#5VXk^E,m2%KgWSu(i=6/+A]yL[QH1Ph[]xEi8FJ,^Fa%BQLna.Nv?9vDP-M s^&TR:?z#^ӿjӏ{RTr@0# ]Ch<g|r~ 0 ]0FYyV 0x:?On . !' mKDM ; e <p c@'{WU_*,eq[pfl i)k05# R/H  O?    &D5Q+b2y(4KR+%9F)n 0;| J{  M 0Tvs?rZ\  lQ,a8 msEr1P_Ew̨4|6F<_'K|paQEKҵݒCѧ@fݏյ٧wd4|{DoKvURZ ?T<K  .!!! "J!"~ /" Y GkU!2"%"&"y! @~ 7b0 B2}#WC-J| j_WDs0cKS_Y~.[CHGqzty8^( v ; ; v d eD\d (Y-| 3" A U:Sf8DDpSFP[ݐz܋ 6\9 ap$_;VoY2 ZR  ' ( s .-}[  R }  w  M  Qe3}5UC+*7V(Z,;7a6O4V\J'5Q"x!RlJb? ^ D Q  4cZ4!i>#+W%&7&''z'%t','&-&%%%# !x     :R n CsaJ =2nڪFɖÕ߿̗ˉ3d‚ 8.ҁi-ѻ~˾e[^ қJInhB| 0 (\A9C;XOr`"!& "E+_%_/(2H+4k-5P.4K-3!,1<*(/4'+#(G &%]@%c&&k''O('&%] R  K`s8adyr^%XһۜѕХLТ֍ְѨp/ӟ$TbUT:uEnMs4t/4 F2  T!| $%j!k'#x(K%p)G&)\&)%(%(%'$&#N%!f#6 s!UIg\ ":Z/lNg~ MTOօѴsЬTTԕ Ӯˎ dž8a@XWΣƄiPԉlۋxߍ#-;A9# E 0uS'!2#!%$'Y%'%''P% &#+$J"3" #]M9.iPyOQ1 |4SkMZ[pcx9|7B%A<%5R*\0PYv_N Z  2 vJ0B!#%X'Y6)*+ , s-b"-"-"."o.#.#.p$[/%/%h-r")M% 4$Z܃_׋ŠӐ°Èԕɛ̄~ЏҴ0ϪϘ>Ǔܼ_ TÆ;X |t=eebR&\S6H%z8 u qL'"#/)4/q8l3o9595 84 63E3;0g1Q.0-19,27,3,5R- 8-{9.7:.9-7r+3 (/#(cf!;i`0 =BPF+~`B6Py@8ףնDpϨ˨v&r5W2H6շlۜseܝ%P?\Kw~a&Z 9 9D "%Pk'n"`)$%+&,'M.U(-/(/'/&4/|%-#+!c)p&,#6 ] N% Z>t 66n!ځuN!GKٙγt>+pD!Ύpx*lqbgڞޔvk;^JXW3 RFW 3`,-~'@EXaT-  0C 8\+ \^=[z]dfYKw\P@G(/&/36A K{sxnuE r t+ P | w.:}'Amp N!M   ]!y!Y!! ;(UQ H'V,JNFT/1al@ՄZe,Ӣx-Ϡ2ОoЄѦ-۲.+xH9#2#6{_ ?H II#^($,(//<+/,}/},J.,W,*))''w&&%T&n&&&&%'l&'F&( &(f%w'"$ %& e "`ynJ#A<#W(/اEڕFݭk.9i(I%MY ,(* +K| X6m tfc@or4 !!$#%$0'%'%;'$%")#* z/+  !ir#^?Hb]Ex6l_jIEp2:b(a_޼ܶ /( pPb%<^LOuw3??* >  q 4z`[}; kYZ} k  x 2E M_9h]!<OZ@a8+MH;c*vBnu5<Vxm N  ,P 0A fj;>y,[8<. ~! b"!"n !A&x, wxuDXߕ^ ޏ߼a5X2`ݚ`ۮڝz֛ՃҍcjN=[ۙ5Q/T4gJ =Gc> & pz"A#$%%&$&"%[ #o!-tUr ! ##b%%,'8&'F%&#j$l  : H gc_76%Me!N2UATUPPbUOLF+Q(e@   v^^zsf+"VdW` "   Q  3  /   q:h.{LLT}g4"yP<@ +`tv%4-pY/y' CN _ Y  nY t %gq&[nI1 -L  x% U ; {sU[<2 J4mS)Z !j  mg ;f ( r P X} cc k tQ$.g=K Y.U" |=! E|Z59L:M_<=(Hl' q7 M~   5 2;qE AD 0EF%m:-3k y D C~V4ry2cbN:+#SmgW=< APW5>0kvwZ*@N{uQ$L h   : W G@  0  9 M c@  ^ S [ !/ (|6E to' IH"i%oGgC!w(D]Qfey&*7 #N+ADFs#sBeFA    $  R  | M f 2   K Y zp 5$(ysf)Y[.*dmj{Y}(ht pjHIx_sD@/A( ( d E ` cF  &t 6 c    f   & % d r } b  = 40@w'wu;UM4 MX!w$.\7@S~]`7d[R.mJ.JK97:K_m{wZ3?N! I3 hh[at]7'gew$f%[cpS>sy0]$`!O UbvH$WM25d]N>@xNV= !&*/$O~J< S^>S5h:y:FGG^Fg1QDrPf~nmi3O'p^Cn<mBI= / g |  > { 0  @ & W m i > l 4 C v!1) ?R  g  * i 6 = ) 2   =.]CCM LitK,, ._$ J>4KCb3> z iqw<BJb p R G O H>(   M ^  t  d k " } lK o.!6B@JDd x`/Pe{1:S?H9u VPfP;:ypH sGh->SS  m d f o &D 9 C & t  ! zVHZ,b6[RfDt" jPx&E%>Ul|/jeexEBh/H?s6 kg-v1  & 7 \  q _ 3 :y X' = 8 }  [Ahg$mP| A8 HPpgFI9|(b07`(j(+n5\`> :~Ent-.q F#h&SLsc/S#IF C#&V"o "FgE4 5QUBEnIUO{8q( ,i79,^~oogBe,Nl   O   v   H  \ XH" @Ir|F/:_XY8~RekMd|q[}U_I,?bBS{*Ackl+ ~E\C5$jW/:8@- V$NXl}\FyrxLtfH3Qq ~J`\_+)S4&!hZ@'f g<L)ksq8ugS:J7m|V,=&,c#_GA4|iS&z)6!#tLz] _y'B( !1R=^oEu~Bg(#pa.q2\Yh %,cxGRix+;nWHErXOXdtdc~_ /'}Q32V~EVC=g)q"R|1Y Y}#vkouo$k(wuV?N:q/^I+ {C}Gpoz$j2ysf)I6k0n"'Rkda\2$kl^>P"_0(   2 9M/{UlUQODbQ{eCC 0 2/J;a_%g*`HR{#;i<,cFx[V& 3#I}BuG=%U?&GgJ~Ez5k{1*'%/I+Cl5cO&qLL3 v4`t4] Ek/z=ZP'~_==#~]uj Ha;&D]?2UhP74,  ;(f;O8?-sGyT]uECxX4JMQ7Q[N6%HYsJ){GPD|&H>MrB"P`zz1])Ub#vY>b/O;E:6MX%8.EUv~U`bKndK7nmR$V +apO&BMH8/ <N9h$;enNAK59]Qard~p6[a;v@imH]YK}8;UlX#8OlTmgTK5>D4`"9<>uGc-tI-A2US3Wy}W ,_W70S!mKx#2/'<rgZa +#g S$_+H(zNp&`>8iquS<F#FLfLN!0-wzRo5# /(bHzRS6T,akfBROJS4:M4^KT999V=iO_&#jB&T;Z/; B)`>y1(BM1m~Hp"nxhs!h E7;%2 $ ;8bLxltx_qEJnzw[d<:F(94D1M@0/5@'Jl"xDKiunTgP & 6N$xAYc;E'0sC5>xoo. AE#H#K 71  W  tF P+pMF:8!`(9D+;H4k0y;ABX&jiqf98W6I1) %*?Cj|ggwlFQVPnAO/L-j&a(U&P5'\TQ>Pnql@v-A= :)1K>o3X&6*RDTPY~j| /9Dco&$8 bPH,;^bv U_}+eJ,2'EJYZZg~pnbG3ON`wP{BxJ]76|SP*5x.C:S0rGRJEm;!X fY#TchnM%n#|UH4 $2K/)u@hsG7Xzv-6 i& "r_t] D1Y B"CH?];TgKu.W*nDxVlKdTjbso~~ ?PSt%HL}r~lqy<^Fla]+I|=DU[Z_+M) 8#W8i:Yr,5K#(r:Q!(] l7|faq%Z@*{"]SknU=SrK;Z D= BYW1\i2V57c_UJDzF@`~iw ?hs[HR=!M.K.M'03L85 pH[eq|&{'c!l$0.* Biz#B7'5(D*B%&  ?t @s/;NMKLW!^?m7|T&  )=A*+* 130NHzau|ojgwyK65TAW}@{ JVZ>/5SKRxwBAB6g!S_;/]%f%Z&[XYG*IX/iS$m"z)'}AEe}hn{mcY!c? AA na){fe[Hx~au$K,)efuTXp#p $_4aW'/n~ %8JiYX|_=Na<)q5f4 nmA#y%?! pG~*P`>-+f)#iGNL&(b&[Wy8<Ur~k~tqCc^X8{a;j5}cpvcHLJ$/DX=}ia@R^dKhq"332NqVcUTJU-r[fx}anYrb`E,a."*0+i2n 1v;;{\;? N2to?@0iEAw$&5>l;!%B]o m|P2(JF sD{i+]Johvr~m9y,c,y\[|U*T4h Ern2aze? %2Iw2 hI\-Qby08-s=. _:w1@Q?51m:"b6`N UCIV,:QP[ZFkNx-Me!Iut7m'V?s [\?%8}9A+C@1W C0 z_RAxml.aye;n}6G8:1w62o,Z[gei#<~%[-pT(aG%2 !  $  K 9  L  , 4 F z |  Jy%(A-Z/J|9_r % wZY!1=:)H/zcXn$o8d3;%sm    4 % T   C {tfrt'k4r.t`BXBynDS0."#O0W~X"+,zdDy9=?LZA\i( CB H 3 YhO.2I'`e#H', 67@tGA+,;4@R>rE J-cz]ukN">F4:G-0$C]oR,xK5 ZW(^|l>83[,<F+}N0!n-ii4)Y^I= Tr$FY  h f   Wa 9  U  Sk1iW P)_~<x $ I~gn2$ 5;8VM%L,_Q|wX)H@ (=fj(;/fQds9@GT 2+`z_ Dzk7aW5n_+w?uBcvcpV3ssgI'J&,Ckt5y Yqx"}[wTSj-eSBr>{|Vxp$#@&HVDQmX; -BMNXnhkb?orX#z<#swI-^k CAGf^>+aCp\)mgD 1@b9Px]uHGMo9:fcrKuAm0r[Bv$=p#TrP'ldW0A;U n-J \ =!xBH3j?{yHE A+ <}SnduyK:6dU9T>3qHpQ`WiVFAEl{?l+JMo_a\aH?0SgRV{S|_F6t[8nX7 m(,_7G <9d=):j>n(uPnBx#PLo[  & LX;Y;<@x3/S.lZ0XTrz>oB/'v.Y LEc +{o1'M@> jh!F[q|Xooq>h]LdcYAA0mp<#Ey&r?p*](cp6 t4IgQ35d&DMxq J+|QxQQq 5&W+u9F<|G@5LwkzE5+ kRC'">J`vAYh-%(E{ >1mWm}g6 1 Rw>l6H42K),6 wwod>.>9rU }reU\3S"(>*h"Kt,Oo#wvhH`gES"Cit Em JfLC4*pivb7+zu\T\{MU]9w[C)3VUzrryyr|2 )xP6feLvgv fX\8=>!Q~Gu{53&./!cW+G:6D/G1]0w9L_chpwjYHC%7/ &*-|3IINSgvz,>LP<&wd_aiq }.MdbzT^HJD6L'G73Tw&?k-*~j= ?8`$$KF`NmjiOm6J3JU3G/54.D&P1|]ct|$Qq{{]D&V+~pb>!mRamI$N?)=*A"`$YN?vb\GKbokfo~~u~U_+1][C"{c,gd Ef7 7H3 lgHEWw@a{))-9:T<_9eIpl""=::4-+0':)5#+6>K&`/e>h+^G:& oicg|'AQ k+W{; a)}C[ 4)hKq2K_lox 'F R#E'+  uYo9eX A! zLe(THPZYi (6Hc5KIOm$+$H     !#   v1c ;y.uSz)^XPPYYabr"@(K6]=y\Lt8p OZ/^./  ]QODO/i\ tjtbYM 3xu0Uk|j@59PY[8'o.wC!`{'S_)XosnoFml\Bh/' q7p&(kZ/0uF2^B 4cTPd53_S"{Lw Ak&HFn&`wT6{Nx<~hA`'uYPrbZq+wag}tvu|9TqTh7BFlZ7i%9;dDDS]M.]p15~6?+U=}v4AZh>g{$~ixE([uDj Lr$= 35<?1;QbwIu|.Q:9x'ZJX$|nXe$io.lQ*lk,s!+ipZCLKWp-fgN1 a:tI]i6a'bD/zV3 ="j/Ga8Yy5] &<CJPx\\D3"  NeE >;9Vz9XLZlS< ,[5#< ga'9KJd|"hbA/.wk4 b+=J?>3';Sp` {^v56Z'`AmoeCWON\hz0w@Sn0r?~@t6|< mRU+y8f:L8%>C9a0Pt/N 5rT2 }V0 1J5qCUs #AUn'IqnIah> \*h8BP~S?Y3 -:P`u1XD1mIg=d<a| 6y?g;F8%5:2T:~gI,ndZZZey-Z "@`,~\</gX{ 8`~&.66;7.+/> S[i t~}{kxXMM8?$ pR6b8t[H/  !0?W\u)<KLWotrtsyocfG_,WHF2! eHfG)n VO@9"%z#rd Z*P-DE>G1['b%o),-./8DG+L;RC[Padkpmyolx  {nj\ P H<2.'&-*/12,.,+)'-(($0:?CPc rw.559FOR\_e[Walswsvqquypyulmmqtuqn pp ih c ` dd hk mr hquyxz$),69;HIY`jpu {zvsmjba_|aa\[][c_gjeibijklpnolvzyuo^~ombIiKpV`RRtmGyS}aY_Pu/\AhFvAx?m2[0d+i&`%i3y[`m'z!|vk& %.:;:CGJRORPV[_ksmlszrytuwv~xz}}{yy}$",39299@A?@ 90'  xqm|gmyescpes_k\f\dSb[c\f`faicjelhokuqsqtvv}}v}r}vv~~|{szppjbcyf{_s_yZ{]p[]\^nejlrtu~|}}~}yy~~xx~}qulhecd\VzXs[sWq]s\h[oTkMaJ_P`K`OYJXBWKREUKPGMENJJQPNKNPLHEIKOOSORBVBSKRJ\BgKhOiXiOmR|aZwds_v\\\[`\ghmlmcjd`ba[_`\~\{XW`_\[W[ySzOxTvR\ud_hqnu}|}||wpommlbb\]Y]Y\XTQIHIEC?<86/4-,2762+,((062/1/)&% !#~} }v~t ~ x {t}z rp tv}"#"!""#"%&%(++-,.5,%                  ## $#(#$-%$%$*("+,/+/("$&'$''&,#-./1/125=<@@EEEJIPJIIJDEDFDJMHNMJMMFE@DAEJPI EEAD B;=DBDEIJ8<89=:#93"8!534.6 2,'0/3,26 +/08"54348#8&:@D!E)=)?*E0E'D"I0I,J,C/=1=0J+@+D0K.L3M2S3V1L<V9S6V5P2U7[3[6Q1S3Q8N8Q9M5R@Q8M3N6J7N6M<E@@;888:4?0;,A4A4F4A3@+B(F&I+E(I&H,G/B(@(?,?"?#9"6#8$5"8'@"9':->+9&5,3'5$:5#<#>#=$9>@>C;:=AB >F ILKOTNVX`Y]X`U\W[V\[VYYRLPUUPSLFDGHDGIIG>EIOKG=?:94:85=>=4:>8<96501385/-./)).,2/,+-/++'$&&    ~}   } } } |~yzyzxihmt q pqqtp l r t} x ~u |vtzyyzz}}x~}~xuz|pyyuhpquuqh``d^[\a[WWWFPNHOMTSSSTVTW[SWNTOJPSRSOGFFBAC>95>?>::812,0--% $*+-)-3+%((*+-%$%)) #)          }{z}{}}{w{z}|~            ##!#+""#""(#((%'$ $ ""#(!#*/#*+"#$"$'" #%%-2+2///--/.32//82/3219:;;7<85560.782//.0-,)32(&()()(-+&(%%&$&#"" !&  !&(#%%&  %#&$ ! %$!%&&*-++()-*)(0**~()*-+{/~.%~),%(&%$&$&(&()()~!)%"!'!"  }~x~|}}zy}w~||y{ysv}~vtqv|v{rxy{z}zzy~}|y~zs~|}wz{y~v{z}|u{v}}~{vx{xuoq~}zzzx|~yx{yzt|z  "! )#(&((&*+(~+75z5{926y2v6|8q5v9w6v=r>r?v6s8q3s1l2j:o4v8v9v;rCq@v;{;|<y?5:4:;=>@?><8568w5z=~:A{A{C~H~JO~SXw]s[y]x`qcnbiggkmlncifginbmYs_wfrimijpinnnspvsnkomhikjmuesepgteoerfr\qbv]r\w\uaofv]y]v]wariseob{]a]``^e]a]]a^\b]ee_]\]\Y]]XYb`b]]jieinomnfmshjnjvmejjkjemkdZ^XYS]a^XZTXYSUPYPQJEOPQKLH?:;;:9;624178;777>/)&.-#! ~|xswsnqksomfjeaicjgYc_X\`_cc]Yfnqosz|zq vs yy x|y}|z }zqsvvsuyppmkmgeeifcbccc__\\^dededopjiigfiieijenkiqoomkqr trz rnm mkijllllf b d\Y[`_b]!_\`e!m*l*i*i&i c*f'e$d/f+i3i6j:jo@qDn@tKrMp>kAk>lIn?nLiMeBiHk;p?i?i@lBnDfCeDgDcD[?]C\=c?^>cDi?jZ@U:X@[H`G\HXH\DYF\H`HeHfLbCdLfDbAaGf?iAjCf>c?d@d?^Dd?`;`C_D[?\<\5]=Y>^<]>XAVCUDR5S$;"7&8)5!7)3(8-2*217+?"5%8)6+402(7#-#.(7/:+@*D,C(D(H-G'C1D.@+F,E-?(C'F(L(M+M-O)M*J3I9O2M5U3T8TASAL>QGPGOBPDP;M=G:H9K9M6G8D<?9B<H7G2I5H6K2E0C2D9C2E/=2@8707/?/>6*A5:17(C/@2;-7*;*>(?)L)H(H+C)C-?0E%D*H(C(?(L(K%R&OP!Q#P&Q'P*M%L%U%Y%W"Q#K!Q"U&U'Q,\%e,e-j(e(g*e'fd b `]i pa]aib^a)a'e)a$n'r"wn!n%i&o){+z)r*q(o&r)u(w/{0u+s(m)r%s%s"q{wzyswry|vmorvs#m%m&j"k&e%](\a"^!d%g%h#n"n#j!a#^&T$U&W"Y$Q#YPTU]XX^]]]UX\YXUY YY\Yf jh nxvrsinormkqw ~{ {w z{ |z w u ||#y#}%#$  "  !&w"v+-}(w+w({-q3w2r6w5w8z9w9u5t6{;}6x:A{4~6~99z5w67:;<=?;>?<97;@;=9?<88;C<=;@8;<<C<?=58>C?CDB<55625831/28=;@?9;@?B=B;@>?99?@F?EJADB?C?>?@BCBHIE?<>A????7:BACHGDG>>@@8998<;CIHLSNJOMULQWTWXZ[YVUVX`XY_a_`_ZYXZY\\_\a]X\cif_`]X_``bdb``U][]UUXKSKMCLIEEB?CJEDEB@;JHDBCE@CABC?8>8<<8=;7><:@FB<>@;987>@7A?ACBE??BAEKHJLLLPVYXWRPUYYZTVVPRSVVV`^_`\]`Zagffidefbdcb```^b`b`\][cacfge\\`eciidic_dcebbgbffijchgff^dedaiigiidff_`_]`\] ^ce jb_]\`]\[_Z\YWRSLOUV Z\UWX V WY[\ SVV U VU Y S SRPQO MRW OPONPKOI? ?? FC BCIKIBCBCGGGMKGDBIJEFIIIBB CCFGLMPKIP)P$Q%W R$X)Y*Z/U1W2P1S1Q4R;T8O:OAH>J:O9O=TBR:OBMFL>NAV>T5RBR>R>PFFFIKILGIIKIKIJHKJJRLRIXKQPWRQNMOIKBOIJIKFTDMMSHSG]DRFWGTBRESITLOKTHSCRFTFWAWDWBYFQI[L\L\F[B`C]E[EXT\I[E\FSA`J[H_HdJ_G\M[I]LVPWKaR\ZVXX`c`i]iUb\h]l[nah\cXi`d`hYcaa\Z_e_cda^_]a\_]aT`Zd\_[cc`_[baidf`fkpitdogourmtplhmnutwlxpzqvnyq|x~x~}|}u|}{syrtxqw}p|y{yzw{x{v~z{vsmssjoporoncekpkejmppulhmmoslmolljlkhkpfghfhikmrglekpslnusvwxv|tsyswwsxy|}z~}vtury}~||~xzt}{}|yywsqsqqlvmyussnshtgpakalbhbkbl`m_c_iZdYjWpXmSoUkNoKnUnJjEjHjEoChDlCmClHqJiFnJlJjLmLlHiIeHmBdDfHhEnBj?g:g:m@l:h4c4e4d8`4`3]6d4d3c2h0c/_2c-g0]/X,\,b1c,`.^+`.b3d,e*j,h2h-f*g(e,f'a&Y$_\ ^h h#dd"\$`!a`_d!`Y]b`abc___\XW]]\a\W W []` \ ]^Z `` ba ba d gc_cac\\__aee`\b][\W[Y[Z^X[YY\W\]Y\cdcb^bd`^X]efe`ceeghadeci_chcb^fYWVRYY\XY^XW[]\WX[\_feabYYZYZYV[UWSSYTRTQTTLJGHIKGFJKJ?FEEAFBABALFJEHFJHJGIJDKMQNOKONQSMOMKJNMJGJLOQLPMTUOKLRMIKKMSOPSVXQRQQPQUSWVXWVSQSSUU~W|T}UwSzUxQwQyUzR{UzR|UzUyQuRuQsPtSuQwPvTyVyTuRtTsSrSpTmTtSqNsQvSrKqQlLnRrSoQpPmSsVpPsSnNoMmOjKlLhKhNfLgQdMcOfNfSeVeUeSdUcVbV^U`W_Y`Z^Xa]_S[X]Y\Y\YZYX\XZXWZ`Z^YYYWTYWYT^SXWZVUTXVVPQRSRONQQNQROPNNMQNOKRMOKMKJJSGQFSGSGSEQERGQ@OCOENDPDO@QAQAQ>N=OAR>S:U:VVZ=V?Y>W>Y=X;[;[<]<[:[9[:W<]<_>a:]8`<`9c:b:f;c9c;c;c7bk=kAl@l=op>moo=p=rm;kAlCnCpGnHnEpFoEpCrItFvHwIvJrMvOtPuOuNxOtPuPtQxQyTuUvV{VwWwW{WyUyVxVwXvYvYw\u\w]x`x_v_yavawcxdybucvfsbsdseodteqdqbpdqdtdtfpftesfqfpcrhrgweyizfzezhxizlumwjxkulvkxivkvqxmymzmwnvqxpwq{oxq|p}m{q}n{q|oyqzsxuxxyxyx{{{zzxvwxzx|y{z{x{xzy|zyw~wyx|w{w{uxxyv{v~w{x~t~s}u|wus~uuuutuuxwvvtruuuswvy|z|y~y{zxuuxwwzwyswrrqsrqprqpqnopnopoqoonlnkjhkkjjjjggfhidefghegghgeidcbedebac^b_a`^`^_^[]\ZZZ[[ZZY[XYWXVVVUVSUTUUTRUTROSSRQQOOONMNMPLLNJKLMJLJIJGJIKHCGLFG?BP@GF?E?@C;:>:>;9;;8@86<4=929688577673403521.3201101..0+/-,.,++*+*(+)((%)'$'#&&"#$!&%"!# " # !    ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/jokes/jokes.desktop0000644000015301777760000000031612321005637025417 0ustar pbusernogroup00000000000000[Desktop Entry] Name=converter Comment=My project description Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/jokes/jokes.qml Icon=qmlscene Terminal=false Type=Application X-Ubuntu-Touch=true ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/jokes/jokes.pro0000644000015301777760000000056212321005637024551 0ustar pbusernogroup00000000000000TEMPLATE = subdirs filetypes = qml png svg js jpg qmlproject desktop wav OTHER_FILES = "" for(filetype, filetypes) { OTHER_FILES += *.$$filetype } desktop_files.path = /usr/share/applications desktop_files.files = jokes.desktop other_files.path = /usr/lib/ubuntu-ui-toolkit/examples/jokes other_files.files = $$OTHER_FILES INSTALLS += other_files desktop_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/jokes/jokes.qml0000644000015301777760000000737212321005637024550 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components 0.1 import QtMultimedia 5.0 /*! \brief A Joke Downloader Page for Examples Gallery Connects to an online service which returns a json from which the joke is parsed into a Label. Demonstrates following: - ActivityIndicator - UbuntuShape - Label - i18n Uses: - QtMultimedia / SoundEffect - QML State */ MainView { // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the .desktop filename applicationName: "jokes" /* This property enables the application to change orientation when the device is rotated. The default is false. */ automaticOrientation: true width: units.gu(100) height: units.gu(75) id: page property string url : "http://api.icndb.com/jokes/random?limitTo=[nerdy,explicit]"; readonly property string _stateLoading : "Loading" readonly property string _stateNormal : "Normal" function getJoke() { laugh.stop(); var xhr = new XMLHttpRequest(); xhr.open("GET",url,true); xhr.onreadystatechange = function() { if ( xhr.readyState === xhr.DONE) { if ( xhr.status === 200) { try { var obj = JSON.parse(xhr.responseText); if (obj.type === "success") { jokeHolder.text = obj.value.joke; page.state = page._stateNormal; laugh.play(); } } catch (e) { getJoke(); } } } } xhr.send(); } SoundEffect { id: laugh source: "laugh.wav" } UbuntuShape { color: Theme.palette.normal.base radius: "medium" anchors.centerIn: parent anchors.margins: units.gu(10) anchors.fill: parent ActivityIndicator { id: activityIndicator anchors.centerIn: parent running: true visible: false } Label { id: jokeHolder anchors.fill: parent text: "Tap here!" fontSize: "large" color: Theme.palette.normal.baseText textFormat: Text.RichText horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: TextInput.WrapAtWordBoundaryOrAnywhere } } MouseArea { anchors.fill: parent onClicked: { page.state = page._stateLoading; page.getJoke(); } } states: [ State { name: page._stateNormal PropertyChanges { target: activityIndicator; visible: false} PropertyChanges { target: jokeHolder; visible: true} }, State { name: page._stateLoading PropertyChanges { target: activityIndicator; visible: true} PropertyChanges { target: jokeHolder; visible: false} } ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/examples/jokes/jokes.qmlproject0000644000015301777760000000122312321005637026124 0ustar pbusernogroup00000000000000/* File generated by Qt Creator (with Ubuntu Plugin), version 2.7.0 */ import QmlProject 1.1 Project { mainFile: "jokes.qml" /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." } JavaScriptFiles { directory: "." } ImageFiles { directory: "." } Files { filter: "*.desktop" } Files { directory: "html" filter: "*" } Files { directory: "debian" filter: "*" } /* List of plugin directories passed to QML runtime */ importPaths: [ "." ,"/usr/bin","/usr/lib/*/qt5/qml" ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/export_modules_dir.sh0000755000015301777760000000137412321005637024233 0ustar pbusernogroup00000000000000#!/bin/sh # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # export QML_IMPORT_PATH=$PWD/modules export QML2_IMPORT_PATH=$PWD/modules export UBUNTU_UI_TOOLKIT_THEMES_PATH=$PWD/modules ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/0000755000015301777760000000000012321006415021115 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/license/0000755000015301777760000000000012321006415022537 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/license/checklicense.sh0000755000015301777760000000236712321005637025533 0ustar pbusernogroup00000000000000#!/usr/bin/env sh # # Copyright 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ################################################################################ PATTERN='\.(c(c|pp|xx)?|h(h|pp|xx)?|p(l|m)|php|py(|x)|java|js|css|vala|qml)$' SKIP='(Canonical|GENERATED FILE|Yahoo! Inc. All rights reserved)' COMMAND="licensecheck --noconf -r * --copyright -c $PATTERN" echo Executing $COMMAND RESULTS=$($COMMAND) test $? = 0 || exit 1 ERRORS=$(echo "$RESULTS" | egrep -v "$SKIP" | grep '*No copyright*') COUNT=$(echo "$ERRORS" | sed 's/^ *//g' | wc -l) if [ "$ERRORS" = "" ]; then echo No license problems found. exit 0 else echo Found $COUNT license problems: echo "$ERRORS" exit 1 fi ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/0000755000015301777760000000000012321006415023135 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/0000755000015301777760000000000012321006415026423 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/fixture_setup.py0000644000015301777760000001014112321005637031705 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import copy import os import tempfile import fixtures from ubuntuuitoolkit import base, environment DEFAULT_QML_FILE_CONTENTS = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Label { objectName: 'testLabel' text: 'Test application.' } } """) DEFAULT_DESKTOP_FILE_DICT = { 'Type': 'Application', 'Name': 'test', 'Exec': '{qmlscene} {qml_file_path}', 'Icon': 'Not important' } class FakeApplication(fixtures.Fixture): def __init__( self, qml_file_contents=DEFAULT_QML_FILE_CONTENTS, desktop_file_dict=None): super(FakeApplication, self).__init__() self._qml_file_contents = qml_file_contents if desktop_file_dict is None: self._desktop_file_dict = copy.deepcopy(DEFAULT_DESKTOP_FILE_DICT) else: self._desktop_file_dict = copy.deepcopy(desktop_file_dict) def setUp(self): super(FakeApplication, self).setUp() self.qml_file_path, self.desktop_file_path = ( self._create_test_application()) def _create_test_application(self): qml_file_path = self._write_test_qml_file() self.addCleanup(os.remove, qml_file_path) desktop_file_path = self._write_test_desktop_file(qml_file_path) self.addCleanup(os.remove, desktop_file_path) return qml_file_path, desktop_file_path def _write_test_qml_file(self): qml_file = tempfile.NamedTemporaryFile( mode='w+t', suffix='.qml', delete=False) qml_file.write(self._qml_file_contents) qml_file.close() return qml_file.name def _write_test_desktop_file(self, qml_file_path): desktop_file_dir = self._get_local_desktop_file_directory() if not os.path.exists(desktop_file_dir): os.makedirs(desktop_file_dir) desktop_file = tempfile.NamedTemporaryFile( mode='w+t', suffix='.desktop', dir=desktop_file_dir, delete=False) self._desktop_file_dict['Exec'] = ( self._desktop_file_dict['Exec'].format( qmlscene=base.get_qmlscene_launch_command(), qml_file_path=qml_file_path)) desktop_file.write('[Desktop Entry]\n') for key, value in self._desktop_file_dict.items(): desktop_file.write('{key}={value}\n'.format(key=key, value=value)) desktop_file.close() return desktop_file.name def _get_local_desktop_file_directory(self): return os.path.join( os.environ.get('HOME'), '.local', 'share', 'applications') class InitctlEnvironmentVariable(fixtures.Fixture): """Set the value of initctl environment variables.""" def __init__(self, **kwargs): super(InitctlEnvironmentVariable, self).__init__() self.variables = kwargs def setUp(self): super(InitctlEnvironmentVariable, self).setUp() for variable, value in self.variables.items(): self._add_variable_cleanup(variable) environment.set_initctl_env_var(variable, value) def _add_variable_cleanup(self, variable): if environment.is_initctl_env_var_set(variable): original_value = environment.get_initctl_env_var(variable) self.addCleanup( environment.set_initctl_env_var, variable, original_value) else: self.addCleanup(environment.unset_initctl_env_var, variable) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/emulators.py0000644000015301777760000006467712321005701031031 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013, 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import logging from distutils import version import autopilot from autopilot import ( input, logging as autopilot_logging, platform ) from autopilot.introspection import dbus _NO_TABS_ERROR = 'The MainView has no Tabs.' logger = logging.getLogger(__name__) class ToolkitEmulatorException(Exception): """Exception raised when there is an error with the emulator.""" def get_pointing_device(): """Return the pointing device depending on the platform. If the platform is `Desktop`, the pointing device will be a `Mouse`. If not, the pointing device will be `Touch`. """ if platform.model() == 'Desktop': input_device_class = input.Mouse else: input_device_class = input.Touch return input.Pointer(device=input_device_class.create()) def get_keyboard(): """Return the keyboard device.""" # TODO return the OSK if we are on the phone. --elopio - 2014-01-13 return input.Keyboard.create() def check_autopilot_version(): """Check that the Autopilot installed version matches the one required. :raise ToolkitEmulatorException: If the installed Autopilot version does't match the required by the emulators. """ installed_version = version.LooseVersion(autopilot.version) if installed_version < version.LooseVersion('1.4'): raise ToolkitEmulatorException( 'The emulators need Autopilot 1.4 or higher.') # Containers helpers. def _get_visible_container_top(containers): containers_top = [container.globalRect.y for container in containers] return max(containers_top) def _get_visible_container_bottom(containers): containers_bottom = [ container.globalRect.y + container.globalRect.height for container in containers if container.globalRect.height > 0] return min(containers_bottom) class UbuntuUIToolkitEmulatorBase(dbus.CustomEmulatorBase): """A base class for all the Ubuntu UI Toolkit emulators.""" def __init__(self, *args): check_autopilot_version() super(UbuntuUIToolkitEmulatorBase, self).__init__(*args) self.pointing_device = get_pointing_device() class MainView(UbuntuUIToolkitEmulatorBase): """MainView Autopilot emulator.""" def get_header(self): """Return the Header emulator of the MainView.""" try: return self.select_single('Header', objectName='MainView_Header') except dbus.StateNotFoundError: raise ToolkitEmulatorException('The main view has no header.') def get_toolbar(self): """Return the Toolbar emulator of the MainView.""" return self.select_single(Toolbar) @autopilot_logging.log_action(logger.info) def open_toolbar(self): """Open the toolbar if it's not already opened. :return: The toolbar. """ return self.get_toolbar().open() @autopilot_logging.log_action(logger.info) def close_toolbar(self): """Close the toolbar if it's opened.""" self.get_toolbar().close() def get_tabs(self): """Return the Tabs emulator of the MainView. :raise ToolkitEmulatorException: If the main view has no tabs. """ try: return self.select_single(Tabs) except dbus.StateNotFoundError: raise ToolkitEmulatorException(_NO_TABS_ERROR) @autopilot_logging.log_action(logger.info) def switch_to_next_tab(self): """Open the next tab. :return: The newly opened tab. """ logger.debug('Switch to next tab.') self.get_header().switch_to_next_tab() current_tab = self.get_tabs().get_current_tab() current_tab.visible.wait_for(True) return current_tab @autopilot_logging.log_action(logger.info) def switch_to_tab_by_index(self, index): """Open a tab. :parameter index: The index of the tab to open. :return: The newly opened tab. :raise ToolkitEmulatorException: If the tab index is out of range. """ logger.debug('Switch to tab with index {0}.'.format(index)) tabs = self.get_tabs() number_of_tabs = tabs.get_number_of_tabs() if index >= number_of_tabs: raise ToolkitEmulatorException('Tab index out of range.') current_tab = tabs.get_current_tab() number_of_switches = 0 while not tabs.selectedTabIndex == index: logger.debug( 'Current tab index: {0}.'.format(tabs.selectedTabIndex)) if number_of_switches >= number_of_tabs - 1: # This prevents a loop. But if this error is ever raised, it's # likely there's a bug on the emulator or on the QML Tab. raise ToolkitEmulatorException( 'The tab with index {0} was not selected.'.format(index)) current_tab = self.switch_to_next_tab() number_of_switches += 1 return current_tab @autopilot_logging.log_action(logger.info) def switch_to_previous_tab(self): """Open the previous tab. :return: The newly opened tab. """ tabs = self.get_tabs() if tabs.selectedTabIndex == 0: previous_tab_index = tabs.get_number_of_tabs() - 1 else: previous_tab_index = tabs.selectedTabIndex - 1 return self.switch_to_tab_by_index(previous_tab_index) @autopilot_logging.log_action(logger.info) def switch_to_tab(self, object_name): """Open a tab. :parameter object_name: The QML objectName property of the tab. :return: The newly opened tab. :raise ToolkitEmulatorException: If there is no tab with that object name. """ tabs = self.get_tabs() for index, tab in enumerate(tabs.select_many('Tab')): if tab.objectName == object_name: return self.switch_to_tab_by_index(tab.index) raise ToolkitEmulatorException( 'Tab with objectName "{0}" not found.'.format(object_name)) def get_action_selection_popover(self, object_name): """Return an ActionSelectionPopover emulator. :parameter object_name: The QML objectName property of the popover. """ return self.select_single( ActionSelectionPopover, objectName=object_name) @autopilot_logging.log_action(logger.info) def go_back(self): """Go to the previous page.""" toolbar = self.open_toolbar() toolbar.click_back_button() class Header(UbuntuUIToolkitEmulatorBase): """Header Autopilot emulator.""" def __init__(self, *args): super(Header, self).__init__(*args) self.pointing_device = get_pointing_device() def _get_animating(self): tab_bar_style = self.select_single('TabBarStyle') return tab_bar_style.animating @autopilot_logging.log_action(logger.info) def switch_to_next_tab(self): """Open the next tab. :raise ToolkitEmulatorException: If the main view has no tabs. """ try: tab_bar = self.select_single(TabBar) except dbus.StateNotFoundError: raise ToolkitEmulatorException(_NO_TABS_ERROR) tab_bar.switch_to_next_tab() self._get_animating().wait_for(False) class Toolbar(UbuntuUIToolkitEmulatorBase): """Toolbar Autopilot emulator.""" @autopilot_logging.log_action(logger.info) def open(self): """Open the toolbar if it's not already opened. :return: The toolbar. """ self.animating.wait_for(False) if not self.opened: self._drag_to_open() self.opened.wait_for(True) self.animating.wait_for(False) return self def _drag_to_open(self): x, y, _, _ = self.globalRect line_x = x + self.width * 0.50 start_y = y + self.height - 1 stop_y = y self.pointing_device.drag(line_x, start_y, line_x, stop_y) @autopilot_logging.log_action(logger.info) def close(self): """Close the toolbar if it's opened.""" self.animating.wait_for(False) if self.opened: self._drag_to_close() self.opened.wait_for(False) self.animating.wait_for(False) def _drag_to_close(self): x, y, _, _ = self.globalRect line_x = x + self.width * 0.50 start_y = y stop_y = y + self.height - 1 self.pointing_device.drag(line_x, start_y, line_x, stop_y) @autopilot_logging.log_action(logger.info) def click_button(self, object_name): """Click a button of the toolbar. The toolbar should be opened before clicking the button, or an exception will be raised. If the toolbar is closed for some reason (e.g., timer finishes) after moving the mouse cursor and before clicking the button, it is re-opened automatically by this function. :parameter object_name: The QML objectName property of the button. :raise ToolkitEmulatorException: If there is no button with that object name. """ # ensure the toolbar is open if not self.opened: raise ToolkitEmulatorException( 'Toolbar must be opened before calling click_button().') try: button = self._get_button(object_name) except dbus.StateNotFoundError: raise ToolkitEmulatorException( 'Button with objectName "{0}" not found.'.format(object_name)) self.pointing_device.move_to_object(button) # ensure the toolbar is still open (may have closed due to timeout) self.open() # click the button self.pointing_device.click_object(button) def _get_button(self, object_name): return self.select_single('ActionItem', objectName=object_name) @autopilot_logging.log_action(logger.info) def click_back_button(self): """Click the back button of the toolbar.""" self.click_button('back_toolbar_button') class Tabs(UbuntuUIToolkitEmulatorBase): """Tabs Autopilot emulator.""" def get_current_tab(self): """Return the currently selected tab.""" return self._get_tab(self.selectedTabIndex) def _get_tab(self, index): tabs = self._get_tabs() for tab in tabs: if tab.index == index: return tab else: raise ToolkitEmulatorException( 'There is no tab with index {0}.'.format(index)) def _get_tabs(self): return self.select_many('Tab') def get_number_of_tabs(self): """Return the number of tabs.""" return len(self._get_tabs()) class TabBar(UbuntuUIToolkitEmulatorBase): """TabBar Autopilot emulator.""" @autopilot_logging.log_action(logger.info) def switch_to_next_tab(self): """Open the next tab.""" self._activate_tab_bar() logger.debug('Click the next tab bar button.') self.pointing_device.click_object(self._get_next_tab_button()) def _activate_tab_bar(self): # First move to the tab bar to avoid timing issues when we find it in # selection mode but it's deselected while we move to it. self.pointing_device.move_to_object(self) if self.selectionMode: logger.debug('Already in selection mode.') else: # Click the tab bar to switch to selection mode. logger.debug('Click the tab bar to enable selection mode.') self.pointing_device.click_object(self) def _get_next_tab_button(self): current_index = self._get_selected_button_index() next_index = (current_index + 1) % self._get_number_of_tab_buttons() return self._get_tab_button(next_index) def _get_selected_button_index(self): return self.select_single('QQuickPathView').selectedButtonIndex def _get_number_of_tab_buttons(self): return len(self._get_tab_buttons()) def _get_tab_buttons(self): return self.select_many('AbstractButton') def _get_tab_button(self, index): buttons = self._get_tab_buttons() for button in buttons: if button.buttonIndex == index: return button raise ToolkitEmulatorException( 'There is no tab button with index {0}.'.format(index)) class ActionSelectionPopover(UbuntuUIToolkitEmulatorBase): """ActionSelectionPopover Autopilot emulator.""" def click_button_by_text(self, text): """Click a button on the popover. XXX We are receiving the text because there's no way to set the objectName on the action. This is reported at https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1205144 --elopio - 2013-07-25 :parameter text: The text of the button. :raise ToolkitEmulatorException: If the popover is not open. """ if not self.visible: raise ToolkitEmulatorException('The popover is not open.') button = self._get_button(text) if button is None: raise ToolkitEmulatorException( 'Button with text "{0}" not found.'.format(text)) self.pointing_device.click_object(button) if self.autoClose: try: self.visible.wait_for(False) except dbus.StateNotFoundError: # The popover was removed from the tree. pass def _get_button(self, text): buttons = self.select_many('Empty') for button in buttons: if button.text == text: return button class CheckBox(UbuntuUIToolkitEmulatorBase): """CheckBox Autopilot emulator.""" @autopilot_logging.log_action(logger.info) def check(self, timeout=10): """Check a CheckBox, if its not already checked. :parameter timeout: number of seconds to wait for the CheckBox to be checked. Default is 10. """ if not self.checked: self.change_state(timeout) @autopilot_logging.log_action(logger.info) def uncheck(self, timeout=10): """Uncheck a CheckBox, if its not already unchecked. :parameter timeout: number of seconds to wait for the CheckBox to be unchecked. Default is 10. """ if self.checked: self.change_state(timeout) @autopilot_logging.log_action(logger.info) def change_state(self, timeout=10): """Change the state of a CheckBox. If it is checked, it will be unchecked. If it is unchecked, it will be checked. :parameter time_out: number of seconds to wait for the CheckBox state to change. Default is 10. """ original_state = self.checked self.pointing_device.click_object(self) self.checked.wait_for(not original_state, timeout) class TextField(UbuntuUIToolkitEmulatorBase): """TextField Autopilot emulator.""" def __init__(self, *args): super(TextField, self).__init__(*args) self.keyboard = get_keyboard() def write(self, text, clear=True): """Write into the text field. :parameter text: The text to write. :parameter clear: If True, the text field will be cleared before writing the text. If False, the text will be appended at the end of the text field. Default is True. """ with self.keyboard.focused_type(self): self.focus.wait_for(True) if clear: self.clear() else: if not self.is_empty(): self.keyboard.press_and_release('End') self.keyboard.type(text) def clear(self): """Clear the text field.""" if not self.is_empty(): if self.hasClearButton: self._click_clear_button() else: self._clear_with_keys() self.text.wait_for('') def is_empty(self): """Return True if the text field is empty. False otherwise.""" return self.text == '' def _click_clear_button(self): clear_button = self.select_single( 'AbstractButton', objectName='clear_button') if not clear_button.visible: self.pointing_device.click_object(self) self.pointing_device.click_object(clear_button) def _clear_with_keys(self): if platform.model() == 'Desktop': self._select_all() else: # Touch tap currently doesn't have a press_duration parameter, so # we can't show the popover. Reported as bug http://pad.lv/1268782 # --elopio - 2014-01-13 self.keyboard.press_and_release('End') while not self.is_empty(): # We delete with backspace because the on-screen keyboard has that # key. self.keyboard.press_and_release('BackSpace') def _select_all(self): self.pointing_device.click_object(self, press_duration=1) root = self.get_root_instance() main_view = root.select_single(MainView) popover = main_view.get_action_selection_popover('text_input_popover') popover.click_button_by_text('Select All') class Flickable(UbuntuUIToolkitEmulatorBase): @autopilot_logging.log_action(logger.info) def swipe_child_into_view(self, child): """Make the child visible. Currently it works only when the object needs to be swiped vertically. TODO implement horizontal swiping. --elopio - 2014-03-21 """ containers = self._get_containers() if not self._is_child_visible(child, containers): self._swipe_non_visible_child_into_view(child, containers) else: logger.debug('The element is already visible.') def _get_containers(self): """Return a list with the containers to take into account when swiping. The list includes this flickable and the top-most container. TODO add additional flickables that are between this and the top container. --elopio - 2014-03-22 """ containers = [self._get_top_container(), self] return containers def _get_top_container(self): """Return the top-most container with a globalRect.""" root = self.get_root_instance() containers = [root] while len(containers) == 1: try: containers[0].globalRect return containers[0] except AttributeError: containers = containers[0].get_children() raise ToolkitEmulatorException("Couldn't find the top-most container.") def _is_child_visible(self, child, containers): """Check if the center of the child is visible. :return: True if the center of the child is visible, False otherwise. """ object_center = child.globalRect.y + child.globalRect.height // 2 visible_top = _get_visible_container_top(containers) visible_bottom = _get_visible_container_bottom(containers) return (object_center >= visible_top and object_center <= visible_bottom) @autopilot_logging.log_action(logger.info) def _swipe_non_visible_child_into_view(self, child, containers): while not self._is_child_visible(child, containers): # Check the direction of the swipe based on the position of the # child relative to the immediate flickable container. if child.globalRect.y < self.globalRect.y: self._swipe_to_show_more_above(containers) else: self._swipe_to_show_more_below(containers) @autopilot_logging.log_action(logger.info) def _swipe_to_show_more_above(self, containers): if self.atYBeginning: raise ToolkitEmulatorException( "Can't swipe more, we are already at the top of the " "container.") else: self._swipe_to_show_more('above', containers) @autopilot_logging.log_action(logger.info) def _swipe_to_show_more_below(self, containers): if self.atYEnd: raise ToolkitEmulatorException( "Can't swipe more, we are already at the bottom of the " "container.") else: self._swipe_to_show_more('below', containers) def _swipe_to_show_more(self, direction, containers): start_x = stop_x = self.globalRect.x + (self.globalRect.width // 2) # Start and stop just a little under the top and a little over the # bottom. top = _get_visible_container_top(containers) + 5 bottom = _get_visible_container_bottom(containers) - 5 if direction == 'below': start_y = bottom stop_y = top elif direction == 'above': start_y = top stop_y = bottom else: raise ToolkitEmulatorException( 'Invalid direction {}.'.format(direction)) self._slow_drag(start_x, stop_x, start_y, stop_y) self.dragging.wait_for(False) self.moving.wait_for(False) def _slow_drag(self, start_x, stop_x, start_y, stop_y): # If we drag too fast, we end up scrolling more than what we # should, sometimes missing the element we are looking for. self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate=5) @autopilot_logging.log_action(logger.info) def _scroll_to_top(self): if not self.atYBeginning: containers = self._get_containers() while not self.atYBeginning: self._swipe_to_show_more_above(containers) class QQuickListView(Flickable): @autopilot_logging.log_action(logger.info) def click_element(self, object_name): """Click an element from the list. It swipes the element into view if it's center is not visible. :parameter objectName: The objectName property of the element to click. """ try: element = self.select_single(objectName=object_name) except dbus.StateNotFoundError: # The element might be on a part of the list that hasn't been # created yet. We have to search for it scrolling the entire list. element = self._find_element(object_name) self.swipe_child_into_view(element) self.pointing_device.click_object(element) @autopilot_logging.log_action(logger.info) def _find_element(self, object_name): self._scroll_to_top() while not self.atYEnd: containers = self._get_containers() self._swipe_to_show_more_below(containers) try: return self.select_single(objectName=object_name) except dbus.StateNotFoundError: pass raise ToolkitEmulatorException( 'List element with objectName "{}" not found.'.format(object_name)) def _is_element_clickable(self, object_name): child = self.select_single(objectName=object_name) containers = self._get_containers() return self._is_child_visible(child, containers) class Empty(UbuntuUIToolkitEmulatorBase): """Base class to emulate swipe to delete.""" def exists(self): try: return self.implicitHeight > 0 except dbus.StateNotFoundError: return False def _get_confirm_button(self): return self.select_single( 'QQuickItem', objectName='confirmRemovalDialog') @autopilot_logging.log_action(logger.info) def swipe_to_delete(self, direction='right'): """Swipe the item in a specific direction.""" if self.removable: self._drag_pointing_device_to_delete(direction) if self.confirmRemoval: self.waitingConfirmationForRemoval.wait_for(True) else: self._wait_until_deleted() else: raise ToolkitEmulatorException( 'The item "{0}" is not removable'.format(self.objectName)) def _drag_pointing_device_to_delete(self, direction): x, y, w, h = self.globalRect tx = x + (w // 8) ty = y + (h // 2) if direction == 'right': self.pointing_device.drag(tx, ty, w, ty) elif direction == 'left': self.pointing_device.drag(w - (w*0.1), ty, x, ty) else: raise ToolkitEmulatorException( 'Invalid direction "{0}" used on swipe to delete function' .format(direction)) def _wait_until_deleted(self): try: # The item was hidden. self.implicitHeight.wait_for(0) except dbus.StateNotFoundError: # The item was destroyed. pass @autopilot_logging.log_action(logger.info) def confirm_removal(self): """Comfirm item removal if this was already swiped.""" if self.waitingConfirmationForRemoval: deleteButton = self._get_confirm_button() self.pointing_device.click_object(deleteButton) self._wait_until_deleted() else: raise ToolkitEmulatorException( 'The item "{0}" is not waiting for removal confirmation'. format(self.objectName)) class Base(Empty): pass class Standard(Empty): pass class ItemSelector(Empty): pass class SingleControl(Empty): pass class MultiValue(Base): pass class SingleValue(Base): pass class Subtitled(Base): pass class ComposerSheet(UbuntuUIToolkitEmulatorBase): """ComposerSheet Autopilot emulator.""" def __init__(self, *args): super(ComposerSheet, self).__init__(*args) @autopilot_logging.log_action(logger.info) def confirm(self): """Confirm the composer sheet.""" button = self.select_single('Button', objectName='confirmButton') self.pointing_device.click_object(button) self.wait_until_destroyed() @autopilot_logging.log_action(logger.info) def cancel(self): """Cancel the composer sheet.""" button = self.select_single('Button', objectName='cancelButton') self.pointing_device.click_object(button) self.wait_until_destroyed() ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/0000755000015301777760000000000012321006415027565 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py0000644000015301777760000010215712321005637033224 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import time import unittest import autopilot from autopilot import input, platform from autopilot.introspection import dbus from testtools.matchers import GreaterThan, LessThan try: from unittest import mock except ImportError: import mock from ubuntuuitoolkit import emulators, tests class CheckAutopilotVersionTestCase(unittest.TestCase): def test_lower_version_should_raise_exception(self): with mock.patch.object(autopilot, 'version', '1.3'): self.assertRaises( emulators.ToolkitEmulatorException, emulators.check_autopilot_version) def test_required_version_should_succeed(self): with mock.patch.object(autopilot, 'version', '1.4'): emulators.check_autopilot_version() def test_higher_version_should_succeed(self): with mock.patch.object(autopilot, 'version', '1.5'): emulators.check_autopilot_version() class UbuntuUIToolkitEmulatorBaseTestCase(tests.QMLStringAppTestCase): def test_pointing_device(self): self.assertIsInstance(self.app.pointing_device, input.Pointer) @unittest.skipIf(platform.model() != 'Desktop', 'Desktop only') def test_pointing_device_in_desktop(self): self.assertIsInstance(self.app.pointing_device._device, input.Mouse) @unittest.skipIf(platform.model() == 'Desktop', 'Phablet only') def test_pointing_device_in_phablet(self): self.assertIsInstance(self.app.pointing_device._device, input.Touch) def test_emulators_should_check_version_on_init(self): check_name = 'ubuntuuitoolkit.emulators.check_autopilot_version' with mock.patch(check_name, autospec=True) as mock_check: # Instantiate any emulator. self.main_view mock_check.assert_called_once_with() class MainViewTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) } """) def test_main_view_custom_emulator(self): self.assertIsInstance(self.main_view, emulators.MainView) def test_get_header_without_header(self): header = self.main_view.get_header() self.assertFalse(header.visible) def test_toolbar_custom_emulator(self): toolbar = self.main_view.get_toolbar() self.assertIsInstance(toolbar, emulators.Toolbar) def test_open_toolbar(self): with mock.patch.object(emulators.Toolbar, 'open') as mock_open: self.main_view.open_toolbar() mock_open.assert_called_once_with() def test_close_toolbar(self): with mock.patch.object(emulators.Toolbar, 'close') as mock_close: self.main_view.close_toolbar() mock_close.assert_called_once_with() def test_open_toolbar_returns_the_toolbar(self): toolbar = self.main_view.open_toolbar() self.assertIsInstance(toolbar, emulators.Toolbar) def test_get_tabs_without_tabs(self): error = self.assertRaises( emulators.ToolkitEmulatorException, self.main_view.get_tabs) self.assertEqual( str(error), 'The MainView has no Tabs.') def test_switch_to_next_tab_without_tabs(self): header = self.main_view.get_header() error = self.assertRaises( emulators.ToolkitEmulatorException, header.switch_to_next_tab) self.assertEqual( str(error), 'The MainView has no Tabs.') class PageTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Page { title: "Test title" } } """) def test_header_custom_emulator(self): header = self.main_view.get_header() self.assertIsInstance(header, emulators.Header) self.assertTrue(header.visible) self.assertEqual(header.title, "Test title") class ToolbarTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(50) // Make sure that for these tests the toolbar starts closed. Component.onCompleted: { __propagated.toolbar.close(); } Page { Label { id: "label" objectName: "clicked_label" anchors.centerIn: parent text: "Button not clicked." } tools: ToolbarItems { ToolbarButton { objectName: "buttonName" action: Action { text: "buttonText" onTriggered: label.text = "Button clicked." } } } } } """) def setUp(self): super(ToolbarTestCase, self).setUp() self.toolbar = self.main_view.get_toolbar() # toolbar may be opened or closed now, depending on whether # the application has been deactivated and resumed already def test_open_toolbar(self): self.toolbar.open() self.assertTrue(self.toolbar.opened) self.assertFalse(self.toolbar.animating) def test_opened_toolbar_is_not_opened_again(self): self.toolbar.open() with mock.patch.object( self.main_view.pointing_device, 'drag') as mock_drag: self.toolbar.open() self.assertFalse(mock_drag.called) self.assertTrue(self.toolbar.opened) def test_close_toolbar(self): self.toolbar.open() self.toolbar.close() self.assertFalse(self.toolbar.opened) self.assertFalse(self.toolbar.animating) def test_closed_toolbar_is_not_closed_again(self): self.toolbar.close() with mock.patch.object( self.main_view.pointing_device, 'drag') as mock_drag: self.toolbar.close() self.assertFalse(mock_drag.called) self.assertFalse(self.toolbar.opened) def test_click_toolbar_button(self): self.toolbar.close() label = self.app.select_single('Label', objectName='clicked_label') self.assertNotEqual(label.text, 'Button clicked.') self.toolbar.open() self.toolbar.click_button('buttonName') self.assertEqual(label.text, 'Button clicked.') def test_click_unexisting_button(self): self.main_view.open_toolbar() error = self.assertRaises( emulators.ToolkitEmulatorException, self.toolbar.click_button, 'unexisting') self.assertEqual( str(error), 'Button with objectName "unexisting" not found.') def test_click_button_on_closed_toolbar(self): self.toolbar.close() error = self.assertRaises( emulators.ToolkitEmulatorException, self.toolbar.click_button, 'buttonName') self.assertEqual( str(error), 'Toolbar must be opened before calling click_button().') class TabsTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: units.gu(70) height: units.gu(60) Tabs { id: tabs Tab { objectName: "tab1" title: "Tab1" Page { tools: ToolbarItems { ToolbarButton { text: "Test1" } } } } Tab { objectName: "tab2" title: "Tab2" Page { tools: ToolbarItems { ToolbarButton { text: "Test2" } } } } Tab { objectName: "tab3" title: "Tab3" Page { tools: ToolbarItems { ToolbarButton { text: "Test3" } } } } } } """) def test_tabs_custom_emulator(self): self.assertIsInstance(self.main_view.get_tabs(), emulators.Tabs) def test_get_current_tab(self): tabs = self.main_view.get_tabs() self.assertEqual(tabs.get_current_tab().title, 'Tab1') def test_switch_to_next_tab_from_header(self): header = self.main_view.get_header() header.switch_to_next_tab() current_tab = self.main_view.get_tabs().get_current_tab() self.assertEqual(current_tab.title, 'Tab2') def test_switch_to_next_tab_from_main_view(self): current_tab = self.main_view.switch_to_next_tab() self.assertEqual(current_tab.title, 'Tab2') def test_switch_to_next_tab_from_last(self): last_tab_index = self.main_view.get_tabs().get_number_of_tabs() - 1 self.main_view.switch_to_tab_by_index(last_tab_index) current_tab = self.main_view.switch_to_next_tab() self.assertEqual(current_tab.title, 'Tab1') def test_switch_to_tab_by_index(self): current_tab = self.main_view.switch_to_tab_by_index(2) self.assertEqual(current_tab.title, 'Tab3') current_tab = self.main_view.switch_to_tab_by_index(1) self.assertEqual(current_tab.title, 'Tab2') current_tab = self.main_view.switch_to_tab_by_index(0) self.assertEqual(current_tab.title, 'Tab1') def test_switch_to_opened_tab_is_not_opened_again(self): with mock.patch.object( emulators.Header, 'switch_to_next_tab') as mock_switch: current_tab = self.main_view.switch_to_tab_by_index(0) self.assertFalse(mock_switch.called) self.assertEqual(current_tab.title, 'Tab1') def test_get_number_of_tabs(self): tabs = self.main_view.get_tabs() self.assertEqual(tabs.get_number_of_tabs(), 3) def test_swith_to_tab_by_index_out_of_range(self): last_tab_index = self.main_view.get_tabs().get_number_of_tabs() - 1 error = self.assertRaises( emulators.ToolkitEmulatorException, self.main_view.switch_to_tab_by_index, last_tab_index + 1) self.assertEqual(str(error), 'Tab index out of range.') def test_switch_to_previous_tab_from_first(self): current_tab = self.main_view.switch_to_previous_tab() self.assertEqual(current_tab.title, 'Tab3') def test_switch_to_previous_tab_not_from_first(self): self.main_view.switch_to_tab_by_index(1) current_tab = self.main_view.switch_to_previous_tab() self.assertEqual(current_tab.title, 'Tab1') def test_switch_to_tab_by_object_name(self): current_tab = self.main_view.switch_to_tab('tab3') self.assertEqual(current_tab.title, 'Tab3') current_tab = self.main_view.switch_to_tab('tab2') self.assertEqual(current_tab.title, 'Tab2') current_tab = self.main_view.switch_to_tab('tab1') self.assertEqual(current_tab.title, 'Tab1') def test_switch_to_unexisting_tab(self): error = self.assertRaises( emulators.ToolkitEmulatorException, self.main_view.switch_to_tab, 'unexisting') self.assertEqual( str(error), 'Tab with objectName "unexisting" not found.') class ActionSelectionPopoverTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 MainView { width: units.gu(48) height: units.gu(60) Button { objectName: "open_popover" text: "Open Popover" onClicked: testActionsPopover.show(); } Label { id: "label" objectName: "clicked_label" anchors.centerIn: parent text: "Button not clicked." } ActionSelectionPopover { objectName: "test_actions_popover" id: testActionsPopover actions: ActionList { Action { text: "Action one" onTriggered: label.text = "Button clicked." } } } } """) def test_action_selection_popover_emulator(self): popover = self.main_view.get_action_selection_popover( 'test_actions_popover') self.assertIsInstance(popover, emulators.ActionSelectionPopover) def test_click_action_select_popover_button(self): label = self.app.select_single('Label', objectName='clicked_label') self.assertNotEqual(label.text, 'Button clicked.') self._open_popover() popover = self.main_view.get_action_selection_popover( 'test_actions_popover') popover.click_button_by_text('Action one') self.assertEqual(label.text, 'Button clicked.') def _open_popover(self): open_button = self.main_view.select_single( 'Button', objectName='open_popover') self.pointing_device.click_object(open_button) def test_click_unexisting_button(self): self._open_popover() popover = self.main_view.get_action_selection_popover( 'test_actions_popover') error = self.assertRaises( emulators.ToolkitEmulatorException, popover.click_button_by_text, 'unexisting') self.assertEqual( str(error), 'Button with text "unexisting" not found.') def test_click_button_with_closed_popover(self): popover = self.main_view.get_action_selection_popover( 'test_actions_popover') error = self.assertRaises( emulators.ToolkitEmulatorException, popover.click_button_by_text, 'Action one') self.assertEqual( str(error), 'The popover is not open.') TEST_QML_WITH_CHECKBOX = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Item { CheckBox { checked: false objectName: "test_checkbox" } } } """) TEST_QML_WITH_SWITCH = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Item { Switch { checked: false objectName: "test_switch" } } } """) class ToggleTestCase(tests.QMLStringAppTestCase): scenarios = [ ('checkbox', dict( test_qml=TEST_QML_WITH_CHECKBOX, objectName='test_checkbox')), ('switch', dict( test_qml=TEST_QML_WITH_SWITCH, objectName='test_switch')) ] def setUp(self): super(ToggleTestCase, self).setUp() self.toggle = self.main_view.select_single( emulators.CheckBox, objectName=self.objectName) self.assertFalse(self.toggle.checked) def test_toggle_emulator(self): self.assertIsInstance(self.toggle, emulators.CheckBox) def test_check_toggle(self): self.toggle.check() self.assertTrue(self.toggle.checked) def test_check_toggle_already_checked(self): self.toggle.check() with mock.patch.object(input.Pointer, 'click_object') as mock_click: self.toggle.check() self.assertFalse(mock_click.called) def test_uncheck_toggle(self): self.toggle.check() self.toggle.uncheck() self.assertFalse(self.toggle.checked) def test_uncheck_toggle_already_unchecked(self): with mock.patch.object(input.Pointer, 'click_object') as mock_click: self.toggle.uncheck() self.assertFalse(mock_click.called) def test_change_state_from_checked(self): self.toggle.check() self.toggle.change_state() self.assertFalse(self.toggle.checked) def test_change_state_from_unchecked(self): self.toggle.change_state() self.assertTrue(self.toggle.checked) def test_check_with_timeout(self): with mock.patch.object( emulators.CheckBox, 'change_state') as mock_change: self.toggle.check(timeout=1) mock_change.assert_called_once_with(1) def test_uncheck_with_timeout(self): self.toggle.check() with mock.patch.object( emulators.CheckBox, 'change_state') as mock_change: self.toggle.uncheck(timeout=1) mock_change.assert_called_once_with(1) def test_change_state_with_timeout(self): with mock.patch.object(self.toggle, 'pointing_device'): # mock the pointing device so the checkbox is not clicked. timestamp_before_call = time.time() self.assertRaises(AssertionError, self.toggle.change_state, 1) waiting_time = time.time() - timestamp_before_call self.assertThat(waiting_time, GreaterThan(1)) self.assertThat(waiting_time, LessThan(2)) class QQuickListViewTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: units.gu(48) height: units.gu(20) Page { Column { id: column width: units.gu(48) height: units.gu(20) Label { id: clickedLabel objectName: "clickedLabel" text: "No element clicked." } ListView { id: testListView objectName: "testListView" anchors.left: parent.left anchors.right: parent.right height: column.height - clickedLabel.paintedHeight clip: true model: 20 delegate: ListItem.Standard { objectName: "testListElement%1".arg(index) text: "test list element %1".arg(index) onClicked: clickedLabel.text = objectName height: units.gu(5) } } } } } """) def setUp(self): super(QQuickListViewTestCase, self).setUp() self.list_view = self.main_view.select_single( emulators.QQuickListView, objectName='testListView') self.label = self.main_view.select_single( 'Label', objectName='clickedLabel') self.assertEqual(self.label.text, 'No element clicked.') def test_qquicklistview_emulator(self): self.assertIsInstance(self.list_view, emulators.QQuickListView) def test_click_element(self): self.list_view.click_element('testListElement0') self.assertEqual(self.label.text, 'testListElement0') def test_click_element_outside_view_below(self): # Click the first element out of view to make sure we are not scrolling # to the bottom at once. self.assertFalse( self.list_view._is_element_clickable('testListElement5')) self.list_view.click_element('testListElement5') self.assertEqual(self.label.text, 'testListElement5') def test_click_element_outside_view_above(self): self.list_view.click_element('testListElement9') # Click the first element out of view to make sure we are not scrolling # to the top at once. self.assertFalse( self.list_view._is_element_clickable('testListElement4')) self.list_view.click_element('testListElement4') self.assertEqual(self.label.text, 'testListElement4') def test_click_element_not_created_at_start(self): objectName = 'testListElement19' self.assertRaises( dbus.StateNotFoundError, self.list_view.select_single, objectName=objectName) self.list_view.click_element(objectName) def test_click_unexisting_element(self): error = self.assertRaises( emulators.ToolkitEmulatorException, self.list_view.click_element, 'unexisting') self.assertEqual( str(error), 'List element with objectName "unexisting" not found.') class QQuickListViewOutOfViewTestCase(tests.QMLStringAppTestCase): """Test that we can make elements visible when the list is out of view.""" test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: units.gu(48) height: units.gu(20) Page { Flickable { Column { id: column width: units.gu(48) // The column height is greater than the main view height, so // the bottom of the list is out of view. height: units.gu(40) Label { id: clickedLabel objectName: "clickedLabel" text: "No element clicked." } ListView { id: testListView objectName: "testListView" anchors.left: parent.left anchors.right: parent.right height: column.height - clickedLabel.paintedHeight clip: true model: 20 delegate: ListItem.Standard { objectName: "testListElement%1".arg(index) text: "test list element %1".arg(index) onClicked: clickedLabel.text = objectName height: units.gu(5) } } } } } } """) def setUp(self): super(QQuickListViewOutOfViewTestCase, self).setUp() self.list_view = self.main_view.select_single( emulators.QQuickListView, objectName='testListView') self.label = self.main_view.select_single( 'Label', objectName='clickedLabel') self.assertEqual(self.label.text, 'No element clicked.') def test_click_element_outside_view_below(self): """Test that we can click an element that's out of view below. The list is also out of view, so we must scroll from the bottom of the main view. """ # Test for http://pad.lv/1275060. # Click the first element out of view to make sure we are not scrolling # to the bottom at once. self.assertFalse( self.list_view._is_element_clickable('testListElement9')) self.list_view.click_element('testListElement9') self.assertEqual(self.label.text, 'testListElement9') class SwipeToDeleteTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 MainView { width: units.gu(48) height: units.gu(60) Page { ListModel { id: testModel ListElement { name: "listitem_destroyed_on_remove_with_confirm" label: "Item destroyed on remove with confirmation" confirm: true } ListElement { name: "listitem_destroyed_on_remove_without_confirm" label: "Item destroyed on remove without confirmation" confirm: false } } Column { anchors { fill: parent } Standard { objectName: "listitem_standard" confirmRemoval: true removable: true text: 'Slide to remove' } Empty { objectName: "listitem_empty" } Standard { objectName: "listitem_without_confirm" confirmRemoval: false removable: true text: "Item without delete confirmation" } ListView { anchors { left: parent.left; right: parent.right } height: childrenRect.height model: testModel delegate: Standard { removable: true confirmRemoval: confirm onItemRemoved: testModel.remove(index) text: label objectName: name } } } } } """) def setUp(self): super(SwipeToDeleteTestCase, self).setUp() self._item = self.main_view.select_single( emulators.Standard, objectName='listitem_standard') self.assertTrue(self._item.exists()) def test_supported_class(self): self.assertTrue(issubclass( emulators.Base, emulators.Empty)) self.assertTrue(issubclass( emulators.ItemSelector, emulators.Empty)) self.assertTrue(issubclass( emulators.Standard, emulators.Empty)) self.assertTrue(issubclass( emulators.SingleControl, emulators.Empty)) self.assertTrue(issubclass( emulators.MultiValue, emulators.Base)) self.assertTrue(issubclass( emulators.SingleValue, emulators.Base)) self.assertTrue(issubclass( emulators.Subtitled, emulators.Base)) def test_standard_emulator(self): self.assertIsInstance(self._item, emulators.Standard) def test_swipe_item(self): self._item.swipe_to_delete() self.assertTrue(self._item.waitingConfirmationForRemoval) def test_swipe_item_to_right(self): self._item.swipe_to_delete('right') self.assertTrue(self._item.waitingConfirmationForRemoval) def test_swipe_item_to_left(self): self._item.swipe_to_delete('left') self.assertTrue(self._item.waitingConfirmationForRemoval) def test_swipe_item_to_wrong_direction(self): self.assertRaises( emulators.ToolkitEmulatorException, self._item.swipe_to_delete, 'up') def test_delete_item_moving_right(self): self._item.swipe_to_delete('right') self._item.confirm_removal() self.assertFalse(self._item.exists()) def test_delete_item_moving_left(self): self._item.swipe_to_delete('left') self._item.confirm_removal() self.assertFalse(self._item.exists()) def test_delete_non_removable_item(self): self._item = self.main_view.select_single( emulators.Empty, objectName='listitem_empty') self.assertRaises( emulators.ToolkitEmulatorException, self._item.swipe_to_delete) def test_confirm_removal_when_item_was_not_swiped(self): self.assertRaises( emulators.ToolkitEmulatorException, self._item.confirm_removal) def test_delete_item_without_confirm(self): item = self.main_view.select_single( emulators.Standard, objectName='listitem_without_confirm') item.swipe_to_delete() self.assertFalse(item.exists()) def test_delete_item_with_confirmation_that_will_be_destroyed(self): item = self.main_view.select_single( emulators.Standard, objectName='listitem_destroyed_on_remove_with_confirm') item.swipe_to_delete() item.confirm_removal() self.assertFalse(item.exists()) def test_delete_item_without_confirmation_that_will_be_destroyed(self): item = self.main_view.select_single( emulators.Standard, objectName='listitem_destroyed_on_remove_without_confirm') item.swipe_to_delete() self.assertFalse(item.exists()) class PageStackTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) PageStack { id: pageStack Component.onCompleted: push(page0) Page { id: page0 title: "Page 0" visible: false Button { objectName: "go_to_page1" text: "Go to page 1" onClicked: pageStack.push(page1) } } Page { id: page1 title: "Page 1" visible: false } } } """) def setUp(self): super(PageStackTestCase, self).setUp() self.header = self.main_view.get_header() self.assertEqual(self.header.title, 'Page 0') def test_open_page(self): self._go_to_page1() self.assertEqual(self.header.title, 'Page 1') def _go_to_page1(self): button = self.main_view.select_single( 'Button', objectName='go_to_page1') self.pointing_device.click_object(button) def test_go_back(self): self._go_to_page1() self.main_view.go_back() self.assertEqual(self.header.title, 'Page 0') class TextFieldTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Item { TextField { id: simpleTextField objectName: "simple_text_field" } TextField { id: textFieldWithoutClearButton objectName: "text_field_without_clear_button" hasClearButton: false anchors.top: simpleTextField.bottom } } } """) def setUp(self): super(TextFieldTestCase, self).setUp() self.simple_text_field = self.main_view.select_single( emulators.TextField, objectName='simple_text_field') def test_text_field_emulator(self): self.assertIsInstance(self.simple_text_field, emulators.TextField) def test_write(self): self.simple_text_field.write('test') self.assertEqual(self.simple_text_field.text, 'test') def test_clear_with_clear_button(self): self.simple_text_field.write('test') self.simple_text_field.clear() self.assertEqual(self.simple_text_field.text, '') def test_clear_without_clear_button(self): text_field = self.main_view.select_single( emulators.TextField, objectName='text_field_without_clear_button') text_field.write('test') text_field.clear() self.assertEqual(text_field.text, '') def test_clear_and_write(self): self.simple_text_field.write('test1') self.simple_text_field.write('test2') self.assertEqual(self.simple_text_field.text, 'test2') def test_write_without_clear(self): self.simple_text_field.write('test1') self.simple_text_field.write('test2', clear=False) self.assertEqual(self.simple_text_field.text, 'test1test2') def test_write_without_clear_writes_at_the_end(self): self.simple_text_field.write( 'long text that will fill more than half of the text field.') self.simple_text_field.write('append', clear=False) self.assertEqual( self.simple_text_field.text, 'long text that will fill more than half of the text field.append') def test_is_empty(self): self.assertTrue(self.simple_text_field.is_empty()) self.simple_text_field.write('test') self.assertFalse(self.simple_text_field.is_empty()) class ComposerSheetTestCase(tests.QMLStringAppTestCase): test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 MainView { width: units.gu(48) height: units.gu(60) Button { objectName: "openComposerSheetButton" text: "Open Composer Sheet" onClicked: PopupUtils.open(testComposerSheet); } Label { id: "label" objectName: "actionLabel" anchors.centerIn: parent text: "No action taken." } Component { id: testComposerSheet ComposerSheet { id: sheet objectName: "testComposerSheet" onCancelClicked: { label.text = "Cancel selected." } onConfirmClicked: { label.text = "Confirm selected." } } } } """) def setUp(self): super(ComposerSheetTestCase, self).setUp() self.label = self.main_view.select_single( 'Label', objectName='actionLabel') self.assertEqual(self.label.text, 'No action taken.') self._open_composer_sheet() self.composer_sheet = self._select_composer_sheet() def _open_composer_sheet(self): button = self.main_view.select_single( 'Button', objectName='openComposerSheetButton') self.pointing_device.click_object(button) def _select_composer_sheet(self): return self.main_view.select_single( emulators.ComposerSheet, objectName='testComposerSheet') def test_select_composer_sheet_custom_emulator(self): self.assertIsInstance(self.composer_sheet, emulators.ComposerSheet) def test_confirm_composer_sheet(self): self.composer_sheet.confirm() self.assertEqual(self.label.text, 'Confirm selected.') self._assert_composer_sheet_is_closed() def _assert_composer_sheet_is_closed(self): self.assertRaises( dbus.StateNotFoundError, self._select_composer_sheet) def test_cancel_composer_sheet(self): self.composer_sheet.cancel() self.assertEqual(self.label.text, 'Cancel selected.') self._assert_composer_sheet_is_closed() ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/test_environment.py0000644000015301777760000000474112321005637033555 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import uuid import testtools from ubuntuuitoolkit import environment class InitctlEnvironmentVariableTestCase(testtools.TestCase): def test_is_environment_variable_set_with_unset_variable(self): """Test that is_initctl_env_var_set returns False for unset vars.""" variable = 'I do not exist {}'.format(uuid.uuid1()) self.assertFalse(environment.is_initctl_env_var_set(variable)) def test_is_environment_variable_set_with_set_variable(self): """Test that is_initctl_env_var_set returns True for existing vars.""" variable = 'Testvariabletoset' self.addCleanup(environment.unset_initctl_env_var, variable) environment.set_initctl_env_var(variable, 'dummy') self.assertTrue(environment.is_initctl_env_var_set(variable)) def test_get_environment_variable(self): """Test that get_initctl_env_var returns the right value.""" variable = 'Testvariabletoget' self.addCleanup(environment.unset_initctl_env_var, variable) environment.set_initctl_env_var(variable, 'test value') self.assertEqual( 'test value', environment.get_initctl_env_var(variable)) def test_unset_environment_variable(self): """Test that unset_initctl_env_var removes the variable.""" variable = 'Testvariabletoget' environment.set_initctl_env_var(variable, 'dummy') environment.unset_initctl_env_var(variable) self.assertFalse(environment.is_initctl_env_var_set(variable)) def test_unset_environment_variable_with_unset_variable(self): """Test that unset_initctl_env_var does nothing with unset var.""" variable = 'I do not exist' environment.unset_initctl_env_var(variable) self.assertFalse(environment.is_initctl_env_var_set(variable)) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/test_base.py0000644000015301777760000000270212321005637032116 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import testtools from autopilot import input, platform from ubuntuuitoolkit import base class AppTestCase(base.UbuntuUIToolkitAppTestCase): """Empty test case to be used by other tests.""" def _runTest(self): pass class TestUbuntuUIToolkitAppTestCase(testtools.TestCase): @testtools.skipIf(platform.model() != 'Desktop', 'Desktop only') def test_desktop_input_device_class(self): test = AppTestCase('_runTest') test.setUp() self.assertIs(test.input_device_class, input.Mouse) @testtools.skipIf(platform.model() == 'Desktop', 'Phablet only') def test_phablet_input_device_class(self): test = AppTestCase('_runTest') test.setUp() self.assertIs(test.input_device_class, input.Touch) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/__init__.py0000644000015301777760000002334212321005637031707 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Ubuntu UI Toolkit autopilot tests.""" import os import tempfile from autopilot.input import Pointer from autopilot.matchers import Eventually from testtools.matchers import Is, Not, Equals from ubuntuuitoolkit import base, emulators, fixture_setup _DESKTOP_FILE_CONTENTS = ("""[Desktop Entry] Type=Application Exec=Not important Path=Not important Name=Test app Icon=Not important """) def _write_test_desktop_file(): desktop_file_dir = get_local_desktop_file_directory() if not os.path.exists(desktop_file_dir): os.makedirs(desktop_file_dir) desktop_file = tempfile.NamedTemporaryFile( suffix='.desktop', dir=desktop_file_dir, delete=False) desktop_file.write(_DESKTOP_FILE_CONTENTS.encode('utf-8')) desktop_file.close() return desktop_file.name def get_local_desktop_file_directory(): return os.path.join(os.environ['HOME'], '.local', 'share', 'applications') def _get_module_include_path(): return os.path.join(get_path_to_source_root(), 'modules') def get_path_to_source_root(): return os.path.abspath( os.path.join( os.path.dirname(__file__), '..', '..', '..', '..')) class QMLStringAppTestCase(base.UbuntuUIToolkitAppTestCase): """Base test case for self tests that define the QML on an string.""" test_qml = (""" import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) } """) def setUp(self): super(QMLStringAppTestCase, self).setUp() self.pointing_device = Pointer(self.input_device_class.create()) self.launch_application() def launch_application(self): fake_application = fixture_setup.FakeApplication( qml_file_contents=self.test_qml) self.useFixture(fake_application) self.app = self.launch_test_application( base.get_qmlscene_launch_command(), '-I' + _get_module_include_path(), fake_application.qml_file_path, '--desktop_file_hint={0}'.format( fake_application.desktop_file_path), emulator_base=emulators.UbuntuUIToolkitEmulatorBase, app_type='qt') self.assertThat( self.main_view.visible, Eventually(Equals(True))) @property def main_view(self): return self.app.select_single(emulators.MainView) class FlickDirection: """Enum for flick or scroll direction.""" UP, DOWN, LEFT, RIGHT = range(0, 4) class QMLFileAppTestCase(base.UbuntuUIToolkitAppTestCase): """Base test case for self tests that launch a QML file.""" test_qml_file_path = '/path/to/file.qml' desktop_file_path = None def setUp(self): super(QMLFileAppTestCase, self).setUp() self.pointing_device = Pointer(self.input_device_class.create()) self.launch_application() def launch_application(self): desktop_file_path = self._get_desktop_file_path() self.app = self.launch_test_application( base.get_qmlscene_launch_command(), "-I" + _get_module_include_path(), self.test_qml_file_path, '--desktop_file_hint={0}'.format(desktop_file_path), emulator_base=emulators.UbuntuUIToolkitEmulatorBase, app_type='qt') self.assertThat( self.main_view.visible, Eventually(Equals(True))) def _get_desktop_file_path(self): if self.desktop_file_path is None: desktop_file_path = _write_test_desktop_file() self.addCleanup(os.remove, desktop_file_path) return desktop_file_path else: self.desktop_file_path @property def main_view(self): return self.app.select_single(emulators.MainView) def checkListItem(self, itemText): item = self.getListItem(itemText) self.assertThat(item, Not(Is(None))) def getListItem(self, itemText): # XXX We shouldn't access the elements by text, because that's likely # to change often and might be translated. We should always use the # objectName instead. --elopio - 2013-06-26216 return self.main_view.select_single("Standard", text=itemText) def getWidgetLoaderAndListView(self): contentLoader = self.main_view.select_single( "QQuickLoader", objectName="contentLoader") listView = self.main_view.select_single( "QQuickListView", objectName="widgetList") self.assertThat(listView, Not(Is(None))) self.assertThat(listView.visible, Eventually(Equals(True))) return (contentLoader, listView) def loadItem(self, item): self.selectItem(item) contentLoader = self.main_view.select_single( "QQuickLoader", objectName="contentLoader") self.assertThat(contentLoader.progress, Eventually(Equals(1.0))) loadedPage = self.getListItem(item) self.assertThat(loadedPage, Not(Is(None))) #loadedPage is not a page, it is the list item which goes in #background when the item is selected, which changes the visible #property of item in list itself to False. So followin check #fails on Nexus 4. Commenting it for now. #self.assertThat(loadedPage.visible, Eventually(Equals(True))) def drag(self, itemText, itemTextTo): item = self.getListItem(itemText) itemTo = self.getListItem(itemTextTo) self.pointing_device.move_to_object(item) self.pointing_device.press() self.pointing_device.move_to_object(itemTo) self.pointing_device.release() def reveal_item_by_flick(self, item, flickable, direction): x1, y1, w1, h1 = item.globalRect x2, y2, w2, h2 = flickable.globalRect if direction is FlickDirection.UP: while y1 + h1 > y2 + h2: self.flick(flickable, direction) x1, y1, w1, h1 = item.globalRect elif direction is FlickDirection.DOWN: while y1 < y2: self.flick(flickable, direction) x1, y1, w1, h1 = item.globalRect def flick(self, flickable, direction, delta=40): """This funcito flicks the page from middle to the given direction.""" x, y, w, h = flickable.globalRect if direction == FlickDirection.UP: self.pointing_device.drag(x + w / 2, y + h / 2, x + w / 2, y + h / 2 - delta) flickable.flicking.wait_for(False) elif direction == FlickDirection.DOWN: self.pointing_device.drag(x + w / 2, y + h / 2, x + w / 2, y + h / 2 + delta) flickable.flicking.wait_for(False) else: raise ValueError("Invalid direction or not implementd yet") def selectItem(self, itemText): item = self.getListItem(itemText) x1, y1, w1, h1 = item.globalRect x2, y2, w2, h2 = self.main_view.globalRect orientationHelper = self.getOrientationHelper() rot = orientationHelper.rotation scrollTo = h2 / 2 - (y1 - h2 - h1) if rot == 0.0 and y1 > h2: self.pointing_device.drag(w2 / 2, h2 / 2, w2 / 2, scrollTo) self.assertThat(item.selected, Eventually(Equals(False))) self.pointing_device.move_to_object(item) self.pointing_device.click() self.assertThat(item.selected, Eventually(Equals(True))) def getOrientationHelper(self): orientationHelper = self.main_view.select_many( "OrientationHelper")[0] self.assertThat(orientationHelper, Not(Is(None))) return orientationHelper def checkPageHeader(self, pageTitle): orientationHelper = self.getOrientationHelper() header = orientationHelper.select_many("Header", title=pageTitle)[0] self.assertThat(header, Not(Is(None))) self.assertThat(header.visible, Eventually(Equals(True))) return header def getObject(self, objectName): obj = self.app.select_single(objectName=objectName) self.assertThat(obj, Not(Is(None))) return obj def tap(self, objectName): obj = self.getObject(objectName) self.pointing_device.move_to_object(obj) self.pointing_device.click() def mousePress(self, objectName): obj = self.getObject(objectName) self.pointing_device.move_to_object(obj) self.pointing_device.press() def mouseRelease(self): self.pointing_device.release() def type_string(self, string): self.keyboard.type(string) def type_key(self, key): self.keyboard.key(key) def tap_clearButton(self, objectName): textField = self.getObject(objectName) self.assertIsNotNone(textField) self.pointing_device.click_object(textField) self.assertThat(textField.focus, Eventually(Equals(True))) self.assertThat(textField.hasClearButton, Eventually(Equals(True))) btn = textField.select_single("AbstractButton") self.assertIsNotNone(btn) self.assertThat(btn.visible, Eventually(Equals(True))) self.pointing_device.click_object(btn) self.assertThat(btn.pressed, Eventually(Equals(False))) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/0000755000015301777760000000000012321006415031224 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.pyubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_options0000644000015301777760000001033512321005637033710 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Tests for the Ubuntu UI Toolkit Gallery - OptionSelector component""" import time from autopilot.matchers import Eventually from testtools.matchers import Equals from ubuntuuitoolkit.tests import FlickDirection from ubuntuuitoolkit.tests.gallery import GalleryTestCase class OptionSelectorTests(GalleryTestCase): """Generic tests for the Gallery""" def test_optionselector_collapsed(self): item = "Option Selector" self.loadItem(item) self.checkPageHeader(item) collapsed = self.getObject("optionselector_collapsed") styleditem = collapsed.select_single('StyledItem', objectName='listContainer') self.assertThat(collapsed.selectedIndex, Equals(0)) self.pointing_device.click_object(collapsed) self.assertThat(styleditem.currentlyExpanded, Eventually(Equals(True))) #try to search the following list entry few times #as it may not be available immediately. for t in range(0, 9): try: selectedValue = collapsed.select_single('Label', text='Value 4') self.assertIsNotNone(selectedValue) except: time.sleep(1) self.pointing_device.click_object(selectedValue) self.assertThat(collapsed.selectedIndex, Eventually(Equals(3))) self.assertThat(styleditem.currentlyExpanded, Eventually(Equals(False))) def test_optionselector_expanded(self): item = "Option Selector" self.loadItem(item) self.checkPageHeader(item) expanded = self.getObject("optionselector_expanded") self.assertThat(expanded.selectedIndex, Equals(0)) selectedValue = expanded.select_single('Label', text='Value 4') self.assertIsNotNone(selectedValue) self.pointing_device.click_object(selectedValue) self.assertThat(expanded.selectedIndex, Eventually(Equals(3))) selectedValue = expanded.select_single('Label', text='Value 1') self.assertIsNotNone(selectedValue) self.pointing_device.click_object(selectedValue) self.assertThat(expanded.selectedIndex, Eventually(Equals(0))) def test_optionselector_custommodel(self): item = "Option Selector" self.loadItem(item) self.checkPageHeader(item) custommodel = self.getObject("optionselector_custommodel") flickable = self.main_view.select_single('QQuickFlickable') self.assertIsNotNone(flickable) #Flick upward to reveal the hidden ui element. self.reveal_item_by_flick(custommodel, flickable, FlickDirection.UP) self.assertThat(flickable.flicking, Eventually(Equals(False))) self.assertThat(custommodel.selectedIndex, Equals(0)) selectedValue = custommodel.select_single('Label', text='Name 4') self.assertIsNotNone(selectedValue) self.pointing_device.click_object(selectedValue) self.assertThat(custommodel.selectedIndex, Eventually(Equals(3))) selectedValue = custommodel.select_single('Label', text='Name 1') self.assertIsNotNone(selectedValue) self.pointing_device.click_object(selectedValue) self.assertThat(custommodel.selectedIndex, Eventually(Equals(0))) #scroll the page downward now. collapsed = self.getObject("optionselector_collapsed") self.reveal_item_by_flick(collapsed, flickable, FlickDirection.DOWN) self.assertThat(flickable.flicking, Eventually(Equals(False))) ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.pyubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinp0000644000015301777760000000533512321005637033714 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013, 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Tests for the Ubuntu UI Toolkit Gallery - TextInput components""" from ubuntuuitoolkit import emulators from ubuntuuitoolkit.tests.gallery import GalleryTestCase class WriteAndClearTextInputTestCase(GalleryTestCase): scenarios = [ ('standard textfield', dict( objectName='textfield_standard', text_to_write='Hello World', expected_text='Hello World')), ('password textfield', dict( objectName='textfield_password', text_to_write='Test password', expected_text='Test password')), ('only integers textfield', dict( objectName='textfield_numbers', text_to_write='-100.123', expected_text='-100123')) ] def setUp(self): super(WriteAndClearTextInputTestCase, self).setUp() item = 'Text Field' self.loadItem(item) self.checkPageHeader(item) def test_write_on_textfield_must_update_text(self): textfield = self.main_view.select_single( emulators.TextField, objectName=self.objectName) textfield.write(self.text_to_write) self.assertEqual(self.expected_text, textfield.text) def test_clear_textfield_must_remove_text(self): textfield = self.main_view.select_single( emulators.TextField, objectName=self.objectName) textfield.write(self.text_to_write) textfield.clear() self.assertEqual('', textfield.text) class DisabledTextInputTestCase(GalleryTestCase): def setUp(self): super(DisabledTextInputTestCase, self).setUp() item = 'Text Field' self.loadItem(item) self.checkPageHeader(item) def test_textfield_disabled(self): textfield_disabled = self.main_view.select_single( emulators.TextField, objectName='textfield_disabled') self.assertFalse(textfield_disabled.enabled) self.pointing_device.click_object(textfield_disabled) textfield_disabled.keyboard.type('This should not be writen') self.assertEqual('', textfield_disabled.text) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py0000644000015301777760000000617312321005637033351 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Tests for the Ubuntu UI Toolkit Gallery""" import os import shutil from ubuntuuitoolkit import tests class GalleryTestCase(tests.QMLFileAppTestCase): """Base class for gallery test cases.""" local_desktop_file_path = None def setUp(self): if self._application_source_exists(): self.test_source_path = self._get_path_to_gallery_source() else: self.test_source_path = self._get_path_to_installed_gallery() assert os.path.exists(self.test_source_path) self.test_qml_file_path = self._get_test_qml_file_path() self.desktop_file_path = self._get_desktop_file_path() super(GalleryTestCase, self).setUp() def _get_path_to_gallery_source(self): return os.path.join( tests.get_path_to_source_root(), 'examples', 'ubuntu-ui-toolkit-gallery') def _application_source_exists(self): return 'UBUNTU_UI_TOOLKIT_AUTOPILOT_FROM_SOURCE' in os.environ def _get_test_qml_file_path(self): return os.path.join( self.test_source_path, 'ubuntu-ui-toolkit-gallery.qml') def _get_path_to_installed_gallery(self): return '/usr/lib/ubuntu-ui-toolkit/examples/ubuntu-ui-toolkit-gallery' def _get_desktop_file_path(self): desktop_file_path = os.path.join( self.test_source_path, 'ubuntu-ui-toolkit-gallery.desktop') if self._application_source_exists(): local_desktop_file_dir = tests.get_local_desktop_file_directory() if not os.path.exists(local_desktop_file_dir): os.makedirs(local_desktop_file_dir) local_desktop_file_path = os.path.join( local_desktop_file_dir, 'ubuntu-ui-toolkit-gallery.desktop') shutil.copy(desktop_file_path, local_desktop_file_path) # We can't delete the desktop file before we close the application, # so we save it on an attribute to be deleted on tear down. self.local_desktop_file_path = local_desktop_file_path return local_desktop_file_path else: return desktop_file_path def tearDown(self): super(GalleryTestCase, self).tearDown() # We can't delete the desktop file before we close the application, # so we save it on an attribute to be deleted on tear down. if self.local_desktop_file_path is not None: os.remove(self.local_desktop_file_path) ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.pyubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery0000644000015301777760000000763712321005637033667 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Tests for the Ubuntu UI Toolkit Gallery""" from autopilot.matchers import Eventually from testtools.matchers import Is, Not, Equals from ubuntuuitoolkit import emulators from ubuntuuitoolkit.tests import gallery class GenericTests(gallery.GalleryTestCase): """Generic tests for the Gallery""" def test_0_can_select_mainwindow(self): """Must be able to select the main window.""" rootItem = self.main_view self.assertThat(rootItem, Not(Is(None))) self.assertThat(rootItem.visible, Eventually(Equals(True))) def test_navigation(self): item = "Navigation" self.loadItem(item) self.checkPageHeader(item) def test_slider(self): item = "Slider" self.loadItem(item) self.checkPageHeader(item) item_data = [ ["slider_standard"], ["slider_live"], ["slider_range"] ] for data in item_data: objName = data[0] self.getObject(objName) self.tap(objName) # TODO: move slider value def test_progress_and_activity(self): item = "Progress and activity" self.loadItem(item) self.checkPageHeader(item) item_data = [ ["progressbar_standard"], ["progressbar_indeterminate"], ["activityindicator_standard"] ] for data in item_data: objName = data[0] self.getObject(objName) self.tap(objName) # TODO: check for properties def test_ubuntushape(self): item = "Ubuntu Shape" self.loadItem(item) self.checkPageHeader(item) item_data = [ ["ubuntushape_color_hex"], ["ubuntushape_color_lightblue"], ["ubuntushape_color_darkgray"], ["ubuntushape_image"], ["ubuntushape_radius_small"], ["ubuntushape_radius_medium"], ["ubuntushape_sizes_15_6"], ["ubuntushape_sizes_10_14"] ] for data in item_data: objName = data[0] self.getObject(objName) class OpenPagesTestCase(gallery.GalleryTestCase): names = [ 'navigation', 'toggles', 'buttons', 'sliders', 'textinputs', 'optionSelectors', 'pickers', 'progressBars', 'ubuntuShapes', 'icons', 'labels', 'listItems', 'dialogs', 'popovers', 'sheets', 'animations' ] scenarios = [ (name, dict( element_name=name+'Element', template_name=name+'Template')) for name in names ] def test_open_page(self): list_view = self.main_view.select_single( emulators.QQuickListView, objectName="widgetList") list_view.click_element(self.element_name) element = self.main_view.select_single( 'Standard', objectName=self.element_name) element.selected.wait_for(True) self.checkPageHeader(element.text) if self.template_name == 'textinputsTemplate': page_type = 'TextInputs' else: page_type = 'Template' self.main_view.wait_select_single( page_type, objectName=self.template_name) # TODO check that the template is visible. --elopio - 2013-11-28 ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.pyubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles0000644000015301777760000000567112321005637033670 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . from ubuntuuitoolkit import emulators from ubuntuuitoolkit.tests import gallery from testtools.matchers import Equals class EnabledTogglesTestCase(gallery.GalleryTestCase): scenarios = [ ('checkbox unchecked', dict( object_name='checkbox_unchecked', initial_state=False)), ('checkbox checked', dict( object_name='checkbox_checked', initial_state=True)), ('switch unchecked', dict( object_name='switch_unchecked', initial_state=False)), ('switch checked', dict( object_name='switch_checked', initial_state=True)) ] def setUp(self): super(EnabledTogglesTestCase, self).setUp() item = "Toggles" self.checkListItem(item) self.loadItem(item) self.checkPageHeader(item) def test_change_toggles_state(self): toggle = self.main_view.select_single( emulators.CheckBox, objectName=self.object_name) self.assertThat(toggle.enabled, Equals(True)) self.assertThat(toggle.checked, Equals(self.initial_state)) toggle.change_state(timeout=1) self.assertThat(toggle.checked, Equals(not self.initial_state)) class DisabledTogglesTestCase(gallery.GalleryTestCase): scenarios = [ ('checkbox disabled unchecked', dict( object_name='checkbox_disabled_unchecked', initial_state=False)), ('checkbox disabled checked', dict( object_name='checkbox_disabled_checked', initial_state=True)), ('switch disabled unchecked', dict( object_name='switch_disabled_unchecked', initial_state=False)), ('switch disabled checked', dict( object_name='switch_disabled_checked', initial_state=True)) ] def setUp(self): super(DisabledTogglesTestCase, self).setUp() item = "Toggles" self.checkListItem(item) self.loadItem(item) self.checkPageHeader(item) def test_change_toggles_state(self): toggle = self.main_view.select_single( emulators.CheckBox, objectName=self.object_name) self.assertThat(toggle.enabled, Equals(False)) self.assertThat(toggle.checked, Equals(self.initial_state)) self.assertRaises(AssertionError, toggle.change_state, timeout=1) ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.pyubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons0000644000015301777760000000554212321005637033717 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Tests for the Ubuntu UI Toolkit Gallery - Button component""" from autopilot.matchers import Eventually from testtools.matchers import Equals from ubuntuuitoolkit.tests.gallery import GalleryTestCase class ButtonsTestCase(GalleryTestCase): scenarios = [ ('standard button', dict( button_name="button_text", is_enabled=True, color=None, icon=None, text="Call")), ('button with color', dict( button_name="button_color", is_enabled=True, color=[174, 167, 159, 255], icon=None, text="Call")), ('button with icon', dict( button_name="button_iconsource", is_enabled=True, color=None, icon="call.png", text=None)), ('button with icon on the right', dict( button_name="button_iconsource_right_text", is_enabled=True, color=None, icon="call.png", text="Call")), ('button with icon on the left', dict( button_name="button_iconsource_left_text", is_enabled=True, color=None, icon="call.png", text="Call")), ('disabled button', dict( button_name="button_text_disabled", is_enabled=False, color=None, icon=None, text="Call")) ] def test_buttons(self): item = "Buttons" self.loadItem(item) self.checkPageHeader(item) button = self.app.select_single(objectName=self.button_name) self.assertIsNot(button, None) self.assertThat(button.enabled, Equals(self.is_enabled)) if self.color is not None: self.assertThat(button.color, Equals(self.color)) if self.icon is not None: self.assertTrue(button.iconSource.endswith(self.icon)) if self.text is not None: self.assertThat(button.text, Equals(self.text)) # try to interact with objects self.pointing_device.move_to_object(button) self.pointing_device.press() if button.enabled: self.assertThat(button.pressed, Eventually(Equals(True))) else: self.assertFalse(button.pressed) self.pointing_device.release() self.assertThat(button.pressed, Eventually(Equals(False))) ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.pyubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.p0000644000015301777760000002153312321005637033724 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import os try: # Python 3. from unittest import mock except ImportError: # Python 2 add-on: python-mock. import mock import testtools from autopilot import testcase as autopilot_testcase from testtools.matchers import Contains, Not, FileExists from ubuntuuitoolkit import base, environment, fixture_setup class FakeApplicationTestCase(testtools.TestCase): def assert_desktop_file_contents( self, desktop_file_contents, expected_contents_dict): desktop_file_lines = desktop_file_contents.splitlines() self.assertEqual('[Desktop Entry]', desktop_file_lines[0]) contents_dict = dict( [line.split('=') for line in desktop_file_lines[1:]]) self.assertDictEqual(expected_contents_dict, contents_dict) def test_qml_file_must_be_created_with_specified_contents(self): fake_application = fixture_setup.FakeApplication( qml_file_contents='Test') self.useFixture(fake_application) with open(fake_application.qml_file_path, 'r+t') as qml_file: qml_file_contents = qml_file.read() self.assertEqual('Test', qml_file_contents) def test_qml_file_with_default_contents(self): fake_application = fixture_setup.FakeApplication() self.useFixture(fake_application) with open(fake_application.qml_file_path, 'r+t') as qml_file: qml_file_contents = qml_file.read() self.assertEqual( fixture_setup.DEFAULT_QML_FILE_CONTENTS, qml_file_contents) def test_desktop_file_must_be_created_with_specified_values(self): test_desktop_file_dict = { 'test key 1': 'test value 1', 'test key 2': 'test value 2', 'Exec': 'test', } fake_application = fixture_setup.FakeApplication( desktop_file_dict=test_desktop_file_dict) self.useFixture(fake_application) with open(fake_application.desktop_file_path, 'r+t') as desktop_file: desktop_file_contents = desktop_file.read() self.assert_desktop_file_contents( desktop_file_contents, test_desktop_file_dict) def test_desktop_file_with_qmlscene_launch_command(self): test_desktop_file_dict = {'Exec': '{qmlscene} application'} qmlscene = 'ubuntuuitoolkit.base.get_qmlscene_launch_command' with mock.patch(qmlscene) as mock_qmlscene: mock_qmlscene.return_value = 'test_qmlscene_command' fake_application = fixture_setup.FakeApplication( desktop_file_dict=test_desktop_file_dict) self.useFixture(fake_application) with open(fake_application.desktop_file_path, 'r+t') as desktop_file: desktop_file_contents = desktop_file.read() self.assertThat( desktop_file_contents, Contains('Exec=test_qmlscene_command application')) def test_desktop_file_with_qml_file_path(self): test_desktop_file_dict = {'Exec': 'qmlscene {qml_file_path}'} fake_application = fixture_setup.FakeApplication( desktop_file_dict=test_desktop_file_dict) self.useFixture(fake_application) with open(fake_application.desktop_file_path, 'r+t') as desktop_file: desktop_file_contents = desktop_file.read() self.assertThat( desktop_file_contents, Contains( 'Exec=qmlscene {}'.format(fake_application.qml_file_path))) def test_desktop_file_with_default_contents(self): qmlscene = 'ubuntuuitoolkit.base.get_qmlscene_launch_command' with mock.patch(qmlscene) as mock_qmlscene: mock_qmlscene.return_value = 'qmlscene' fake_application = fixture_setup.FakeApplication() self.useFixture(fake_application) with open(fake_application.desktop_file_path, 'r+t') as desktop_file: desktop_file_contents = desktop_file.read() expected_desktop_file_dict = { 'Type': 'Application', 'Name': 'test', 'Icon': 'Not important', 'Exec': 'qmlscene {}'.format(fake_application.qml_file_path), } self.assert_desktop_file_contents( desktop_file_contents, expected_desktop_file_dict) def test_desktop_file_must_be_created_in_local_directory(self): fake_application = fixture_setup.FakeApplication() self.useFixture(fake_application) expected_desktop_file_directory = os.path.join( os.environ.get('HOME'), '.local', 'share', 'applications') self.assertEqual( expected_desktop_file_directory, os.path.dirname(fake_application.desktop_file_path)) def test_fake_application_files_must_be_removed_after_test(self): fake_application = fixture_setup.FakeApplication() def inner_test(): class TestWithFakeApplication(testtools.TestCase): def test_it(self): self.useFixture(fake_application) return TestWithFakeApplication('test_it') inner_test().run() self.assertThat(fake_application.qml_file_path, Not(FileExists())) self.assertThat(fake_application.desktop_file_path, Not(FileExists())) class LaunchFakeApplicationTestCase(autopilot_testcase.AutopilotTestCase): def test_launch_fake_application_with_qmlscene(self): fake_application = fixture_setup.FakeApplication() self.useFixture(fake_application) self.application = self.launch_test_application( base.get_qmlscene_launch_command(), fake_application.qml_file_path, '--desktop_file_hint={0}'.format( fake_application.desktop_file_path), app_type='qt') # We can select a component from the application. self.application.select_single('Label', objectName='testLabel') class InitctlEnvironmentVariableTestCase(testtools.TestCase): def test_use_initctl_environment_variable_with_unset_variable(self): """Test the initctl env var fixture when the var is unset. During the test, the new value must be in place. After the test, the variable must be unset again. """ initctl_env_var = fixture_setup.InitctlEnvironmentVariable( testenvvarforfixture='test value') result = testtools.TestResult() def inner_test(): class TestWithInitctlEnvVar(testtools.TestCase): def test_it(self): self.useFixture(initctl_env_var) self.assertEqual( 'test value', environment.get_initctl_env_var( 'testenvvarforfixture')) return TestWithInitctlEnvVar('test_it') inner_test().run(result) self.assertTrue( result.wasSuccessful(), 'Failed to set the environment variable.') self.assertFalse( environment.is_initctl_env_var_set('testenvvarforfixture')) def test_use_initctl_environment_variable_with_set_variable(self): """Test the initctl env var fixture when the var is unset. During the test, the new value must be in place. After the test, the old value must be set again. """ self.addCleanup( environment.unset_initctl_env_var, 'testenvvarforfixture') environment.set_initctl_env_var( 'testenvvarforfixture', 'original test value') initctl_env_var = fixture_setup.InitctlEnvironmentVariable( testenvvarforfixture='new test value') result = testtools.TestResult() def inner_test(): class TestWithInitctlEnvVar(testtools.TestCase): def test_it(self): self.useFixture(initctl_env_var) self.assertEqual( 'new test value', environment.get_initctl_env_var( 'testenvvarforfixture')) return TestWithInitctlEnvVar('test_it') inner_test().run(result) self.assertTrue( result.wasSuccessful(), 'Failed to set the environment variable.') self.assertEqual( 'original test value', environment.get_initctl_env_var('testenvvarforfixture')) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/__init__.py0000644000015301777760000000142312321005637030541 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Ubuntu UI Toolkit autopilot tests and emulators - top level package.""" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/base.py0000644000015301777760000000341512321005637027717 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . """Base classes for Autopilot tests using the Ubuntu UI Toolkit.""" import subprocess from autopilot import ( input, platform, testcase ) def get_qmlscene_launch_command(): """Return the command to launch qmlscene for autopilot tests.""" # We need to specify qt5 because qtchooser doesn't have a default # configuration on devices and it seems the environment variable # QT_SELECT=qt5 doesn't work for autopilot tests. --Mirv - 2013-10-03 arch = subprocess.check_output( ["dpkg-architecture", "-qDEB_HOST_MULTIARCH"], universal_newlines=True).strip() return '/usr/lib/{}/qt5/bin/qmlscene'.format(arch) class UbuntuUIToolkitAppTestCase(testcase.AutopilotTestCase): """Autopilot test case for applications using the Ubuntu UI Toolkit.""" def setUp(self): super(UbuntuUIToolkitAppTestCase, self).setUp() self.input_device_class = self._get_input_device_class() def _get_input_device_class(self): if platform.model() == 'Desktop': return input.Mouse else: return input.Touch ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/autopilot/ubuntuuitoolkit/environment.py0000644000015301777760000000376612321005637031362 0ustar pbusernogroup00000000000000# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import logging import subprocess from autopilot import logging as autopilot_logging logger = logging.getLogger(__name__) def is_initctl_env_var_set(variable): """Check True if an initctl environment variable is set. :param variable: The name of the variable to check. :return: True if the variable is set. False otherwise. """ try: get_initctl_env_var(variable) return True except subprocess.CalledProcessError: return False def get_initctl_env_var(variable): """Return the value of an initctl environment variable.""" output = subprocess.check_output( ['/sbin/initctl', 'get-env', variable], stderr=subprocess.STDOUT, universal_newlines=True) return output.rstrip() @autopilot_logging.log_action(logger.info) def set_initctl_env_var(variable, value): """Set the value of an initctl environment variable.""" subprocess.call( ['/sbin/initctl', 'set-env', '%s=%s' % (variable, value)], stderr=subprocess.STDOUT, universal_newlines=True) @autopilot_logging.log_action(logger.info) def unset_initctl_env_var(variable): """Remove an initctl environment variable.""" subprocess.call( ['/sbin/initctl', 'unset-env', variable], stderr=subprocess.STDOUT, universal_newlines=True) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/tests.pro0000644000015301777760000000053212321005637023006 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += unit unit_x11 autopilot_module.path = /usr/lib/python3/dist-packages/ubuntuuitoolkit autopilot_module.files = autopilot/ubuntuuitoolkit/* autopilot2_module.path = /usr/lib/python2.7/dist-packages/ubuntuuitoolkit autopilot2_module.files = autopilot/ubuntuuitoolkit/* INSTALLS += autopilot_module autopilot2_module ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/0000755000015301777760000000000012321006415022074 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_theme/0000755000015301777760000000000012321006415024070 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_theme/tst_theme.pro0000644000015301777760000000022212321005637026607 0ustar pbusernogroup00000000000000TESTS += $$system(ls tst_*.qml) include(../qmltest-include.pri) TARGET = tst_theme SOURCES += tst_theme.cpp OTHER_FILES += $$system(ls *.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_theme/tst_theme.cpp0000644000015301777760000000130312321005637026572 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include QUICK_TEST_MAIN(theme) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_theme/tst_popoverforegroundstyle.qml0000644000015301777760000000216212321005637032351 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 import Ubuntu.Components.Popups 0.1 TestCase { name: "PopupsPopoverAPI" function test_show() { popOver.show() } Popover { id: popOver foregroundStyle: testForegroundStyle Text { text: "Hello Popover!" } } Component { id: testForegroundStyle PopoverForegroundStyle { } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/testparser/0000755000015301777760000000000012321006415024270 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/testparser/testparser.pro0000644000015301777760000000021412321005637027210 0ustar pbusernogroup00000000000000QT += core xml QT -= gui TARGET = testparser CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/testparser/main.cpp0000644000015301777760000001523212321005637025730 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #include #include #include #include #include #include #include QStringList _testReports; int _testcaseCounter; int _testcasePassed; int _testcaseFailed; int _testcaseSkipped; int _testcaseXPass; int _testcaseXFail; void printResults() { int failedTests = 0; int passTests = 0; QStringList failedTestNames; foreach (QString fileName, _testReports) { QString testXmlData = ""; QString testName = QFileInfo(fileName).fileName();; QFile testXml(fileName); qDebug() << "\nResults @" << fileName.toLatin1().constData(); qDebug(); int testcaseCounter = 0; int testcaseSkipped = 0; int testcasePassed = 0; int testcaseFailed = 0; int testcaseXFail = 0; int testcaseXPass = 0; if (testXml.open(QIODevice::ReadOnly)) { testXmlData = testXml.readAll(); testXml.close(); } else { qWarning() << "Unable to open" << fileName << "for reading. Skipped."; continue; } if (testXmlData.trimmed().length()==0) { QFile::remove(fileName); qWarning() << "The file was empty, removing it."; continue; } QDomDocument xmlDocument; QString errorMsg; int errorLine; if (!xmlDocument.setContent(testXmlData,&errorMsg,&errorLine)) { qDebug() << "\n"; qWarning() << "\t" << "\033[0;41m error \033[0;0m" << errorMsg.toLatin1().constData() << " @ line:" << errorLine; continue; } QDomNodeList xmlTestCases = xmlDocument.elementsByTagName("testcase"); for (int idx = 0; idx < xmlTestCases.length(); idx++) { testcaseCounter++; QDomNode xmlTestCase = xmlTestCases.at(idx); QDomNamedNodeMap attributes = xmlTestCase.attributes(); QDomNode nameNode = attributes.namedItem("name"); if (nameNode.isNull()) { qWarning() << "Could not find name node"; continue; } QDomNode resultNode = attributes.namedItem("result"); QString result; if (resultNode.isNull()) { result = "SKIP"; testcaseSkipped++; } else { result = resultNode.nodeValue().toLatin1().constData(); if (result=="pass") { testcasePassed++; } else if (result=="fail") { testcaseFailed++; } else if (result=="xpass") { testcaseXPass++; } else if (result=="xfail") { testcaseXFail++; } } qDebug() << "\t" << (result=="pass" ? "\033[0;32m[PASS]\033[0;0m" : (result=="SKIP") ? "\033[0;33m[SKIP]\033[0;0m" : (result=="xpass") ? "\033[2;32m[XPASS]\033[0;0m" : (result=="xfail") ? "\033[2;31m[XFAIL]\033[0;0m" : "\033[0;31m[FAILED]\033[0;0m") << nameNode.nodeValue().toLatin1().constData(); } _testcaseCounter += testcaseCounter; _testcasePassed += testcasePassed; _testcaseFailed += testcaseFailed; _testcaseSkipped += testcaseSkipped; _testcaseXFail += testcaseXFail; _testcaseXPass += testcaseXPass; qDebug(); qDebug() << "\t" << "Total" << testcaseCounter << " - \033[0;32m[PASS]\033[0;0m" << testcasePassed << "\033[2;31m[XFAIL]\033[0;0m" << testcaseXFail << "\033[2;32m[XPASS]\033[0;0m" << testcaseXPass << "\033[0;31m[FAILED]\033[0;0m" << testcaseFailed << "\033[0;33m[SKIP]\033[0;0m" << testcaseSkipped << "\n"; if (testcaseFailed>0) { // FAILED failedTests++; failedTestNames << testName.toLatin1().constData(); qDebug() << "\033[0;41m FAILED \033[0;0m" << testName.toLatin1().constData(); } else { passTests++; qDebug() << "\033[0;42m PASSED \033[0;0m" << testName.toLatin1().constData(); } qDebug() << "-------------------------------------------------------"; } qDebug() << "\n\n"; qDebug() << "TEST SUITES\t" << QString("%0").arg(passTests+failedTests).toLatin1().constData(); qDebug() << "\033[0;42m PASSED \033[0;0m" << "\t" << passTests; qDebug() << "\033[0;41m FAILED \033[0;0m" << "\t" << failedTests; qDebug() << "\n"; qDebug() << "TEST CASES\t" << QString("%0").arg(_testcaseCounter).toLatin1().constData(); qDebug() << "\033[0;32m[PASS]\033[0;0m\t\t" << _testcasePassed; qDebug() << "\033[2;31m[XFAIL]\033[0;0m\t\t" << _testcaseXFail; qDebug() << "\033[2;32m[XPASS]\033[0;0m\t\t" << _testcaseXPass; qDebug() << "\033[0;31m[FAILED]\033[0;0m\t" << _testcaseFailed; qDebug() << "\033[0;33m[SKIP]\033[0;0m\t\t" << _testcaseSkipped; qDebug() << "\n"; if (failedTests>0) { qDebug() << "\tFailed tests:"; foreach (QString failedTest, failedTestNames) { qDebug() << "\t" << failedTest.toLatin1().constData(); } qDebug() << "\n"; } } void findTestResults(QString path) { QDir dir(path); QFileInfoList files = dir.entryInfoList(); foreach (const QFileInfo &file, files) { if (file.fileName()=="." || file.fileName()=="..") continue; if (file.isDir()) continue; if (file.completeSuffix()=="xml") { _testReports << file.absoluteFilePath(); } } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString searchPath = "."; int returnValue = 0; if (a.arguments().count()==2) { QString arg = a.arguments().takeAt(1).trimmed(); searchPath = arg; } if (!QFileInfo(searchPath).exists()) { qWarning() << "\n\nInvalid argument, file or folder does not exist:\n" << searchPath << "\n\n"; return -1; } if (QFileInfo(searchPath).isDir()) { findTestResults(searchPath); } else { _testReports << searchPath; } printResults(); return returnValue; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/0000755000015301777760000000000012321006415024130 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource@15.png0000644000015301777760000000000012321005637026726 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/tst_units.cpp0000644000015301777760000002206112321005637026676 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include "ucunits.h" class tst_UCUnits: public QObject { Q_OBJECT private Q_SLOTS: void singletonInstance() { UCUnits& units1 = UCUnits::instance(); UCUnits& units2 = UCUnits::instance(); QCOMPARE(&units1, &units2); } void defaultGridUnit() { UCUnits units; QCOMPARE(units.gridUnit(), 8.0f); } void setGridUnit() { UCUnits units; units.setGridUnit(0.0); QCOMPARE(units.gridUnit(), 0.0f); units.setGridUnit(42.0); QCOMPARE(units.gridUnit(), 42.0f); } void gridUnitEnvironmentVariable() { QByteArray gridUnit = QString::number(11).toLocal8Bit(); qputenv("GRID_UNIT_PX", gridUnit); UCUnits units; QCOMPARE(units.gridUnit(), 11.0); qputenv("GRID_UNIT_PX", ""); } void dpGridUnitDefault() { UCUnits units; QCOMPARE(units.dp(1.0), 1.0f); QCOMPARE(units.dp(1.32), 1.0f); QCOMPARE(units.dp(1.72), 2.0f); QCOMPARE(units.dp(0.23), 0.0f); QCOMPARE(units.dp(0.51), 1.0f); QCOMPARE(units.dp(0.9999), 1.0f); QCOMPARE(units.dp(1000.01), 1000.0f); } void guGridUnitDefault() { UCUnits units; QCOMPARE(units.gu(1.0), 8.0f); QCOMPARE(units.gu(1.32), 11.0f); QCOMPARE(units.gu(1.72), 14.0f); QCOMPARE(units.gu(0.23), 2.0f); QCOMPARE(units.gu(0.51), 4.0f); QCOMPARE(units.gu(0.9999), 8.0f); QCOMPARE(units.gu(1000.01), 8000.0f); } void dpGridUnitTen() { UCUnits units; units.setGridUnit(10); QCOMPARE(units.dp(1.0), 1.0f); QCOMPARE(units.dp(1.32), 1.0f); QCOMPARE(units.dp(1.72), 2.0f); QCOMPARE(units.dp(0.23), 0.0f); QCOMPARE(units.dp(0.51), 1.0f); QCOMPARE(units.dp(0.9999), 1.0f); QCOMPARE(units.dp(1000.01), 1250.0f); } void guGridUnitTen() { UCUnits units; units.setGridUnit(10); QCOMPARE(units.gu(0.5), 5.0f); QCOMPARE(units.gu(1), 10.0f); QCOMPARE(units.gu(1.5), 15.0f); QCOMPARE(units.gu(2), 20.0f); QCOMPARE(units.gu(4), 40.0f); QCOMPARE(units.gu(100000), 1000000.0f); QCOMPARE(units.gu(150.51983), 1505.0f); } void dpGridUnitSixteen() { UCUnits units; units.setGridUnit(16); QCOMPARE(units.dp(1.0), 2.0f); QCOMPARE(units.dp(1.32), 3.0f); QCOMPARE(units.dp(1.72), 3.0f); QCOMPARE(units.dp(0.23), 0.0f); QCOMPARE(units.dp(0.51), 1.0f); QCOMPARE(units.dp(0.9999), 2.0f); QCOMPARE(units.dp(1000.01), 2000.0f); } void guGridUnitSixteen() { UCUnits units; units.setGridUnit(16); QCOMPARE(units.gu(0.5), 8.0f); QCOMPARE(units.gu(1), 16.0f); QCOMPARE(units.gu(1.5), 24.0f); QCOMPARE(units.gu(2), 32.0f); QCOMPARE(units.gu(4), 64.0f); QCOMPARE(units.gu(100000), 1600000.0f); QCOMPARE(units.gu(150.51983), 2408.0f); } void dpGridUnitEighteen() { UCUnits units; units.setGridUnit(18); QCOMPARE(units.dp(1.0), 2.0f); QCOMPARE(units.dp(1.32), 3.0f); QCOMPARE(units.dp(1.72), 3.0f); QCOMPARE(units.dp(0.23), 0.0f); QCOMPARE(units.dp(0.51), 1.0f); QCOMPARE(units.dp(0.9999), 2.0f); QCOMPARE(units.dp(1000.01), 2250.0f); } void dpGridUnitTwenty() { UCUnits units; units.setGridUnit(20); QCOMPARE(units.dp(1.0), 2.0f); QCOMPARE(units.dp(1.32), 3.0f); QCOMPARE(units.dp(1.72), 3.0f); QCOMPARE(units.dp(0.23), 0.0f); QCOMPARE(units.dp(0.51), 1.0f); QCOMPARE(units.dp(0.9999), 2.0f); QCOMPARE(units.dp(1000.01), 2500.0f); } void resolveEmpty() { UCUnits units; QString resolved; QString expected; resolved = units.resolveResource(QUrl("")); expected = QString(""); QCOMPARE(resolved, expected); units.setGridUnit(18); resolved = units.resolveResource(QUrl("")); expected = QString(""); QCOMPARE(resolved, expected); } void resolveNonExisting() { UCUnits units; QString resolved; QString expected; resolved = units.resolveResource(QUrl::fromLocalFile("non_existing.png")); expected = QString(""); QCOMPARE(resolved, expected); } void resolveDirectory() { UCUnits units; QString resolved; QString expected; resolved = units.resolveResource(QUrl::fromLocalFile("")); expected = QString(""); QCOMPARE(resolved, expected); } void resolveExactMatch() { UCUnits units; QString resolved; QString expected; units.setGridUnit(8); resolved = units.resolveResource(QUrl::fromLocalFile("exact_match.png")); expected = QString("1/" + QDir::currentPath() + QDir::separator() + "exact_match@8.png"); QCOMPARE(resolved, expected); } void resolveExistsOnlyHigherGridUnit() { UCUnits units; QString resolved; QString expected; units.setGridUnit(10); resolved = units.resolveResource(QUrl::fromLocalFile("resource_only_higher.png")); expected = QString("0.769231/" + QDir::currentPath() + QDir::separator() + "resource_only_higher@13.png"); QCOMPARE(resolved, expected); } void resolveExistsOnlyHigherGridUnitQrc() { UCUnits units; QString resolved; QString expected; units.setGridUnit(10); resolved = units.resolveResource(QUrl("qrc:/test/prefix/resource_only_higher.png")); expected = QString("0.769231/:/test/prefix/resource_only_higher@13.png"); QCOMPARE(resolved, expected); } void resolveExistsOnlySmallerGridUnit() { UCUnits units; QString resolved; QString expected; units.setGridUnit(10); resolved = units.resolveResource(QUrl::fromLocalFile("resource_only_smaller.png")); expected = QString("1.42857/" + QDir::currentPath() + QDir::separator() + "resource_only_smaller@7.png"); QCOMPARE(resolved, expected); } void resolveExistsOnlySmallerGridUnitQrc() { UCUnits units; QString resolved; QString expected; units.setGridUnit(10); resolved = units.resolveResource(QUrl("qrc:/test/prefix/resource_only_smaller.png")); expected = QString("1.42857/:/test/prefix/resource_only_smaller@7.png"); QCOMPARE(resolved, expected); } void resolveExistsMultipleGridUnit() { UCUnits units; QString resolved; QString expected; units.setGridUnit(20); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("1.05263/" + QDir::currentPath() + QDir::separator() + "resource@19.png"); QCOMPARE(resolved, expected); units.setGridUnit(19); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("1/" + QDir::currentPath() + QDir::separator() + "resource@19.png"); QCOMPARE(resolved, expected); units.setGridUnit(18); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("1/" + QDir::currentPath() + QDir::separator() + "resource@18.png"); QCOMPARE(resolved, expected); units.setGridUnit(17); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("0.944444/" + QDir::currentPath() + QDir::separator() + "resource@18.png"); QCOMPARE(resolved, expected); units.setGridUnit(9); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("0.9/" + QDir::currentPath() + QDir::separator() + "resource@10.png"); QCOMPARE(resolved, expected); units.setGridUnit(8); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("1/" + QDir::currentPath() + QDir::separator() + "resource@8.png"); QCOMPARE(resolved, expected); units.setGridUnit(7); resolved = units.resolveResource(QUrl::fromLocalFile("resource.png")); expected = QString("0.875/" + QDir::currentPath() + QDir::separator() + "resource@8.png"); QCOMPARE(resolved, expected); } }; QTEST_MAIN(tst_UCUnits) #include "tst_units.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource@1.png0000644000015301777760000000000012321005637026641 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource@19.png0000644000015301777760000000000012321005637026732 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/lower_scale.png0000644000015301777760000000000012321005637027130 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource_only_higher@13.png0000644000015301777760000000000012321005637031313 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource@8.png0000644000015301777760000000000012321005637026650 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/tst_units.qrc0000644000015301777760000000044012321005637026676 0ustar pbusernogroup00000000000000 exact_match_no_suffix.png higher_scale.png lower_scale.png resource_only_smaller@7.png resource_only_higher@13.png ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource_only_smaller@7.png0000644000015301777760000000000012321005637031427 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/exact_match@8.png0000644000015301777760000000000012321005637027301 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/tst_units.pro0000644000015301777760000000012112321005637026705 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_units.cpp RESOURCES += tst_units.qrc ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource@10.png0000644000015301777760000000000012321005637026721 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/exact_match_no_suffix.png0000644000015301777760000000000012321005637031171 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resource@18.png0000644000015301777760000000000012321005637026731 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/resources_unit0000644000015301777760000000000312321005637027122 0ustar pbusernogroup0000000000000018 ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_units/higher_scale.png0000644000015301777760000000000012321005637027246 0ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/0000755000015301777760000000000012321006415025267 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/CheckBoxGrid.qml0000644000015301777760000000154712321005637030312 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 CheckBox{} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/RectangleGrid.qml0000644000015301777760000000143712321005637030526 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Rectangle {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/SliderStyleGrid.qml0000644000015301777760000000225712321005637031066 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Item { id: thisItem property Item item: thisItem property real minimumValue: 0.0 property real maximumValue: 1.0 property bool live function formatValue(v){return v} SliderStyle { property Item styledItem: thisItem } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/TextWithImport.qml0000644000015301777760000000130112321005637030755 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Text { } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/ButtonGrid.qml0000644000015301777760000000155712321005637030100 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Button { } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/LabelGrid.qml0000644000015301777760000000147012321005637027636 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Label {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/TextGrid.qml0000644000015301777760000000143212321005637027541 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Text {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/TextWithImportPopups.qml0000644000015301777760000000130712321005637032172 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Popups 0.1 Text { } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/UbuntuShapeGrid.qml0000644000015301777760000000147612321005637031070 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 UbuntuShape {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/CheckBoxStyleGrid.qml0000644000015301777760000000216112321005637031324 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Item { id: thisItem property Item item: thisItem property string text property color color property bool checked CheckBoxStyle { property Item styledItem: thisItem } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/SwitchStyleGrid.qml0000644000015301777760000000215712321005637031104 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Item { id: thisItem property Item item: thisItem property string text property color color property bool checked SwitchStyle { property Item styledItem: thisItem } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/tst_performance.pro0000644000015301777760000000103612321005637031211 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_performance.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" OTHER_FILES += \ UbuntuShapeGrid.qml \ ButtonStyleGrid.qml \ PairOfUbuntuShapeGrid.qml \ ButtonGrid.qml \ CheckBoxStyleGrid.qml \ CheckBoxGrid.qml \ SwitchStyleGrid.qml \ SwitchGrid.qml \ LabelGrid.qml \ SliderStyleGrid.qml \ SliderGrid.qml \ TextGrid.qml \ RectangleGrid.qml \ TextWithImport.qml \ TextWithImportGrid.qml \ TextWithImportPopupsGrid.qml \ TextWithImportPopups.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/tst_performance.cpp0000644000015301777760000000741312321005637031200 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include "uctheme.h" class tst_Performance : public QObject { Q_OBJECT public: tst_Performance() {} private: QQuickView *quickView; QQmlEngine *quickEngine; QQuickItem *loadDocument(const QString &document) { quickView->setSource(QUrl::fromLocalFile(document)); QTest::waitForEvents(); return quickView->rootObject(); } private Q_SLOTS: void initTestCase() { QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); quickView = new QQuickView(0); quickEngine = quickView->engine(); quickView->setGeometry(0,0, 240, 320); //add modules folder so we have access to the plugin from QML QStringList imports = quickEngine->importPathList(); imports.prepend(QDir(modules).absolutePath()); quickEngine->setImportPathList(imports); } void cleanupTestCase() { delete quickView; } void benchmark_GridOfComponents_data() { QTest::addColumn("document"); QTest::addColumn("theme"); QTest::newRow("grid with Rectangle") << "RectangleGrid.qml" << QUrl(); QTest::newRow("grid with Text") << "TextGrid.qml" << QUrl(); QTest::newRow("grid with Label") << "LabelGrid.qml" << QUrl(); QTest::newRow("grid with UbuntuShape") << "UbuntuShapeGrid.qml" << QUrl(); QTest::newRow("grid with UbuntuShapePair") << "PairOfUbuntuShapeGrid.qml" << QUrl(); QTest::newRow("grid with ButtonStyle") << "ButtonStyleGrid.qml" << QUrl(); QTest::newRow("grid with Button") << "ButtonGrid.qml" << QUrl(); // QTest::newRow("grid with CheckBoxStyle") << "CheckBoxStyleGrid.qml" << QUrl(); // QTest::newRow("grid with CheckBox") << "CheckBoxGrid.qml" << QUrl(); // QTest::newRow("grid with SwitchStyle") << "SwitchStyleGrid.qml" << QUrl(); // QTest::newRow("grid with Switch") << "SwitchGrid.qml" << QUrl(); // QTest::newRow("grid with SwitchStyle") << "SwitchStyleGrid.qml" << QUrl(); // QTest::newRow("grid with Switch") << "SwitchGrid.qml" << QUrl(); QTest::newRow("grid with SliderStyle") << "SliderStyleGrid.qml" << QUrl(); QTest::newRow("grid with Slider") << "SliderGrid.qml" << QUrl(); } void benchmark_GridOfComponents() { QFETCH(QString, document); QFETCH(QUrl, theme); QQuickItem *root = 0; QBENCHMARK { root = loadDocument(document); } if (root) delete root; } void benchmark_import_data() { QTest::addColumn("document"); QTest::newRow("importing Ubuntu.Components") << "TextWithImportGrid.qml"; QTest::newRow("importing Ubuntu.Components.Popups") << "TextWithImportGrid.qml"; } void benchmark_import() { QFETCH(QString, document); QBENCHMARK { loadDocument(document); } } }; QTEST_MAIN(tst_Performance) #include "tst_performance.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/SwitchGrid.qml0000644000015301777760000000154612321005637030064 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Switch {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/TextWithImportPopupsGrid.qml0000644000015301777760000000145412321005637033003 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Grid { width: 800 height: 600 rows: 16 columns: 160 Repeater { model: 16*160 TextWithImportPopups {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/PairOfUbuntuShapeGrid.qml0000644000015301777760000000162012321005637032160 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Item { UbuntuShape { } UbuntuShape { } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/SliderGrid.qml0000644000015301777760000000154612321005637030045 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Slider {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/TextWithImportGrid.qml0000644000015301777760000000144612321005637031575 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Grid { width: 800 height: 600 rows: 16 columns: 160 Repeater { model: 16*160 TextWithImport {} } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_performance/ButtonStyleGrid.qml0000644000015301777760000000224212321005637031111 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Themes.Ambiance 0.1 Grid { width: 800 height: 600 rows: 16 columns: 16 Repeater { model: 16*16 Item { id: thisItem property Item item: thisItem property string text property url iconSource property string iconPosition: "left" property color color ButtonStyle { property Item styledItem: thisItem } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/add_qmlmakecheck.pri0000644000015301777760000000070212321005637026051 0ustar pbusernogroup00000000000000# Do not use CONFIG += testcase that would add a 'make check' because it also # adds a 'make install' that installs the test cases, which we do not want. # Instead add a 'make check' manually. check.target = check check.commands = "set -e;" for(TEST, TESTS) { check.commands += ../../unit/runtest.sh $${TARGET} $${TEST} minimal; } check.commands += cd ../../..; check.commands += sh tests/qmlapicheck.sh || exit 1; check.commands += cd tests/unit ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_ubuntu_shape/0000755000015301777760000000000012321006415025470 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_ubuntu_shape/tst_ubuntu_shape.pro0000644000015301777760000000026412321005637031615 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_ubuntu_shape.cpp OTHER_FILES += no_distortion.qml \ no_distortion_source.png \ no_distortion_expected.png ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_ubuntu_shape/tst_ubuntu_shape.cpp0000644000015301777760000000360112321005637031575 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include #include class tst_UbuntuShape: public QObject { Q_OBJECT private: QQuickView *m_quickView; private Q_SLOTS: void initTestCase() { m_quickView = new QQuickView; m_quickView->setGeometry(0, 0, 900, 500); m_quickView->show(); // add modules folder so we have access to the plugin from QML QQmlEngine *engine = m_quickView->engine(); QString modules("../../../modules"); QStringList imports = engine->importPathList(); imports.prepend(QDir(modules).absolutePath()); engine->setImportPathList(imports); } void noDistortion() { QSKIP("This test passes on local machines but not in CI as it requires working OpenGL"); m_quickView->setSource(QUrl::fromLocalFile("no_distortion.qml")); QCoreApplication::processEvents(); QImage result = m_quickView->grabWindow(); QVERIFY(!result.isNull()); QImage expected = QImage("no_distortion_expected.png"); QVERIFY(!expected.isNull()); QCOMPARE(result, expected); } }; QTEST_MAIN(tst_UbuntuShape) #include "tst_ubuntu_shape.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_ubuntu_shape/no_distortion_expected.png0000644000015301777760000001037012321005637032757 0ustar pbusernogroup00000000000000PNG  IHDRtsBITOtEXtSoftwaregnome-screenshot>IDATxݱwB6f)-+"^U.x k.(HRmnL@wFXFwf>eYl8\(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1(1,CnGW/_|w}_?o_^^^^^O͛o~7zw}~7oܸ>ݎEyXlqJrJY>|WU T*Ç?>hX>9B?8pOχso~'ܺu+}Q*Dv;<}zzz>cgϞ SٳgC\1F8;;K8^c_~%} zmQ*^x>pJ6(@^J8^c?#} zmQ*P1Fl?IJ6(1oiT*Sʲz@Ruj jJR9, T*]ld1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @2}XT*erJrlT*ieY\R\e&QbQbQbQbQbQbQbQbQbQbQbhJR9, T*]ΠݴeRTN+Je-G7=gccccccccccL`G4V*)eY\R\5p-JrZYV/T*.m<*9ccccccccccce;ڧRTN)Je35F7m٨T*ʲz@RunQM`,>JrJYV/T*.WA1iFRV*ʮu[6o2{           f>iT*Sʲz@Ruj jM[6*J崲^.PTv]۲yT~s(1(1(1(1(1(1(1(1(1(1(1vOcRR*ʮUgPknڲQT*erJrݖͣ 3F1F1F1F1F1F1F1F1F1F1FY}+J唲^.PTv]?8ZctӖJR9, T*]ld1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @2}XT*erJrlT*ieY\R\e&QbQbQbQbQbQbQbQbQbQbQbhJR9, T*]ΠݴeRTN+Je-G7=gccccccccccL`G4V*)eY\R\5p-JrZYV/T*.m<*9ccccccccccce;ڧRTN)Je35F7m٨T*ʲz@RunQM`,>JrJYV/T*.WA1iFRV*ʮu[6o2{           f>iT*Sʲz@Ruj jM[6*J崲^.PTv]۲yT~s(1(1(1(1(1(1(1(1(1(1(1vOcRR*ʮUgPknڲQT*erJrݖͣ 3F1F1F1F1F1F1F1F1F1F1FY}+J唲^.PTv]?8ZctӖJR9, T*]ld1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @1 @2}XT*erJrlT*ieY\R\e&QbQbQbQbQbQbQbQbQbQbQbhJR9, T*]ΠݴeRTN+Je-G7=gccccccccccL`G4V*)eY\R\5p-JrZYV/T*.m<*9ccccccccccce;ڧRTN)Je35F7m٨T*ʲz@RunQM`,>JrJYV/T*.WA1iFRV*ʮu[6o2{           f>iT*Sʲz@Ruj jM[6*J崲^.PTv]۲yT~s(1(1(1(1(1(1(1(1(1(1(1vOcRR*ʮUgPknڲQT*erJrݖͣ 3F1F1F1F1F1F1F1F1F1F1FY}+J唲^.PTv]?8ZctӖJR9, T*]ld1 PQA(U,~u W^ck׮R1 PGB#kcT믧R1 PŽ{ѳ ޽{C\TΝ)}w΃҇bTqrrxp\}sÓ9Uܿxhqr2ܼ> n\ ݿ?}+)[. oggëWs~}qw>pxR~ngbH8u짟~_|l.//Gptt47_{[nݹsݻS1 ;?n\^$IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_ubuntu_shape/no_distortion.qml0000644000015301777760000000201412321005637031077 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 900 height: 500 Row { spacing: 50 anchors.centerIn: parent Image { id: grid source: "no_distortion_source.png" } Shape { id: shape width: grid.width height: grid.height image: grid } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_ubuntu_shape/no_distortion_source.png0000644000015301777760000000261612321005637032462 0ustar pbusernogroup00000000000000PNG  IHDR{n`%#bKGD pHYs  tIME223[%tEXtCommentclip2gif 0.7.2 by Yves Piguet@IDATxܱ 1ñTؑz.$0$O;;;;ӽ'b =b = yKy^K= =b =b =e|8K;;;z {@{@ziggg_/ b =b = _/%@{@{{2^륝]|`=b =b b /.^0@@{@{@(%^K= =b =b =e|8K;;;z {@{@ziggg_/ b =b = _/%@{@{{2^륝]|`=b =b bPK| {@{@{@{z pvvvvb =b =b=b@_/.^0@@{@{@(%^K= =b =b =e|8K;;;z {@{@ziggg_/ b =b = _/%@{@{{2^륝]|`=b =b bPK| {@{@{@{z pvvvvb =b =b=b@_/.^0@@{@{@(%^K= =b =b =e|8K;;;z {@{@ziggg_/ b =b = /UjNIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/plugin_dependency.pri0000644000015301777760000000113012321005637026304 0ustar pbusernogroup00000000000000COMPONENTS_PATH = ../../../modules/Ubuntu/Components INCLUDEPATH += $$COMPONENTS_PATH/plugin INCLUDEPATH += ../../../modules/Ubuntu/Test/plugin PRE_TARGETDEPS = $$COMPONENTS_PATH/libUbuntuComponents.so PRE_TARGETDEPS += ../../../modules/Ubuntu/Test/libUbuntuTest.so LIBS += $$COMPONENTS_PATH/libUbuntuComponents.so LIBS += ../../../modules/Ubuntu/Test/libUbuntuTest.so DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$_PRO_FILE_PWD_\\\"\" QMAKE_CXXFLAGS += -Werror components.target = $$PRE_TARGETDEPS components.commands = cd $$COMPONENTS_PATH/plugin && $(QMAKE) && make QMAKE_EXTRA_TARGETS += components ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_page/0000755000015301777760000000000012321006415023702 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_page/AnchorToPage.qml0000644000015301777760000000156312321005637026741 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(20) height: units.gu(40) Page { id: page Rectangle { color: "red" anchors.fill: page } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_page/tst_page.cpp0000644000015301777760000000501612321005637026223 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #include #include #include #include #include #include #include "ucunits.h" class tst_Page : public QObject { Q_OBJECT private: QQuickView *view; public: tst_Page() : view(0) { } QQuickItem *loadTest(const QString &document) { // load the document view->setSource(QUrl::fromLocalFile(document)); QTest::waitForEvents(); return view->rootObject(); } QQuickItem *testItem(QQuickItem *that, const QString &identifier) { if (that->property(identifier.toLocal8Bit()).isValid()) return that->property(identifier.toLocal8Bit()).value(); QList children = that->findChildren(identifier); return (children.count() > 0) ? children[0] : 0; } private Q_SLOTS: void initTestCase() { QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); view = new QQuickView; QQmlEngine *quickEngine = view->engine(); view->setGeometry(0,0, UCUnits::instance().gu(40), UCUnits::instance().gu(30)); //add modules folder so we have access to the plugin from QML QStringList imports = quickEngine->importPathList(); imports.prepend(QDir(modules).absolutePath()); quickEngine->setImportPathList(imports); } void cleanupTestCase() { delete view; } void testAnchorToPage_bug1249386() { QSignalSpy spy(view->engine(), SIGNAL(warnings(QList))); spy.setParent(view); QQuickItem *root = loadTest("AnchorToPage.qml"); QVERIFY(root); // No warnings from QML QCOMPARE(spy.count(), 0); } }; QTEST_MAIN(tst_Page) #include "tst_page.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_page/tst_page.pro0000644000015301777760000000014712321005637026241 0ustar pbusernogroup00000000000000include(../test-include.pri) QT += gui SOURCES += tst_page.cpp OTHER_FILES += $$system(ls tst_*.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/qmltest-include.pri0000644000015301777760000000017612321005637025733 0ustar pbusernogroup00000000000000include( plugin_dependency.pri ) include( add_qmlmakecheck.pri) TEMPLATE = app QT += qml quick qmltest CONFIG += no_keywords ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/0000755000015301777760000000000012321006415023545 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/diversion/0000755000015301777760000000000012321006415025547 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/diversion/locale/0000755000015301777760000000000012321006415027006 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/tst_i18n.pro0000644000015301777760000000035112321005637025744 0ustar pbusernogroup00000000000000include(../test-include.pri) QT += gui DEFINES += SRCDIR=\\\"$$PWD/\\\" system(msgfmt po/en_US.po -o appropriate/locale/en/LC_MESSAGES/localizedApp.mo) SOURCES += \ src\/tst_i18n.cpp OTHER_FILES += \ src\/LocalizedApp.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/appropriate/0000755000015301777760000000000012321006415026073 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/appropriate/locale/0000755000015301777760000000000012321006415027332 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/appropriate/locale/en/0000755000015301777760000000000012321006415027734 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/appropriate/locale/en/LC_MESSAGES/0000755000015301777760000000000012321006415031521 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/appropriate/localizedApp/0000755000015301777760000000000012321006415030502 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/po/0000755000015301777760000000000012321006415024163 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/po/en_US.po0000644000015301777760000000060712321005637025544 0ustar pbusernogroup00000000000000msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Christian Dywan \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "Welcome" msgstr "Greets" msgid "Count the kilometres" msgstr "Count the clicks" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/src/0000755000015301777760000000000012321006415024334 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/src/tst_i18n.cpp0000644000015301777760000001474212321005637026526 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace C { #include } #include "ucunits.h" #include "i18n.h" class tst_I18n : public QObject { Q_OBJECT private: QQuickView *view; public: tst_I18n() : view(0) { } QQuickItem *loadTest(const QString &document) { // load the document view->setSource(QUrl::fromLocalFile(document)); QTest::waitForEvents(); return view->rootObject(); } QQuickItem *testItem(QQuickItem *that, const QString &identifier) { if (that->property(identifier.toLocal8Bit()).isValid()) return that->property(identifier.toLocal8Bit()).value(); QList children = that->findChildren(identifier); return (children.count() > 0) ? children[0] : 0; } private Q_SLOTS: void initTestCase() { // Set test locale folder in the environment // Using setenv because QProcessEnvironment ignores changes QString wrongDataFolder(QCoreApplication::applicationDirPath() + "/diversion"); QString testDataFolder(QCoreApplication::applicationDirPath() + "/appropriate"); setenv("XDG_DATA_DIRS", (wrongDataFolder + ":" + testDataFolder).toUtf8(), 1); // Verify that we set it correctly QString dataPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "localizedApp", QStandardPaths::LocateDirectory)); QDir dataDir(dataPath); QVERIFY(dataDir.cdUp()); QVERIFY(dataDir.cd("locale")); QString doubleCheckLocalePath(dataDir.path()); QCOMPARE(doubleCheckLocalePath, testDataFolder + "/locale"); QVERIFY(QFileInfo(testDataFolder + "/locale/en/LC_MESSAGES/localizedApp.mo").exists()); QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); view = new QQuickView; QQmlEngine *quickEngine = view->engine(); view->setGeometry(0,0, UCUnits::instance().gu(40), UCUnits::instance().gu(30)); //add modules folder so we have access to the plugin from QML QStringList imports = quickEngine->importPathList(); imports.prepend(QDir(modules).absolutePath()); quickEngine->setImportPathList(imports); } void cleanupTestCase() { delete view; } void testCase_LocalizedApp() { UbuntuI18n* i18n = &UbuntuI18n::instance(); // By default no domain is set QCOMPARE(i18n->domain(), QString("")); // Start out with no localization i18n->setLanguage("C"); // Load the app which should pick up the locale we prepared QQuickItem *root = loadTest("src/LocalizedApp.qml"); QVERIFY(root); QQuickItem *mainView = root; // Sanity checks to avoid confusion QString applicationName(mainView->property("applicationName").toString()); QCOMPARE(applicationName, QString("localizedApp")); QCOMPARE(applicationName, QCoreApplication::applicationName()); QCOMPARE(applicationName, i18n->domain()); // Was the locale folder detected and set? QString boundDomain(C::bindtextdomain(i18n->domain().toUtf8(), ((const char*)0))); QString dataPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation, i18n->domain(), QStandardPaths::LocateDirectory)); QDir dataDir(dataPath); QVERIFY(dataDir.cdUp()); QVERIFY(dataDir.cd("locale")); QString expectedLocalePath(dataDir.path()); QCOMPARE(boundDomain, expectedLocalePath); // Is the domain gettext uses correct? QString gettextDomain(C::textdomain(((const char*)0))); QCOMPARE(gettextDomain, i18n->domain()); // Is the compiled en_US message catalog in the right location? QString messageCatalog(boundDomain + "/en/LC_MESSAGES/localizedApp.mo"); QVERIFY(QFileInfo(messageCatalog).exists()); /* For manual testing one can do something like env LANGUAGE=en_US TEXTDOMAINDIR=./tests/unit/tst_i18n/locale/ gettext localizedApp 'Welcome' */ // Check if system has en_US locale, otherwise gettext won't work QProcess localeA; localeA.start("locale -a"); QVERIFY(localeA.waitForFinished()); QVERIFY(QString(localeA.readAll()).split("\n").contains("en_US.utf8")); i18n->setLanguage("en_US.utf8"); QSignalSpy spy(i18n, SIGNAL(languageChanged())); spy.wait(); // Inspect translated strings in QML QQuickItem* page(testItem(mainView, "page")); QVERIFY(page); QCOMPARE(page->property("title").toString(), QString("Greets")); QQuickItem* button(testItem(page, "button")); QVERIFY(button); QCOMPARE(button->property("text").toString(), QString("Count the clicks")); // Translate in C++ QCOMPARE(i18n->dtr(i18n->domain(), QString("Welcome")), QString("Greets")); QCOMPARE(i18n->tr(QString("Count the kilometres")), QString("Count the clicks")); } }; // The C++ equivalent of QTEST_MAIN(tst_I18n) with added initialization int main(int argc, char *argv[]) { // LC_ALL would fail the test case; it must be unset before execution unsetenv("LC_ALL"); QGuiApplication app(argc, argv); app.setAttribute(Qt::AA_Use96Dpi, true); tst_I18n* testObject = new tst_I18n(); return QTest::qExec(static_cast(testObject), argc, argv); } #include "tst_i18n.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_i18n/src/LocalizedApp.qml0000644000015301777760000000205512321005637027425 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) applicationName: 'localizedApp' Page { objectName: 'page' title: i18n.dtr('localizedApp', 'Welcome') Button { objectName: 'button' anchors.centerIn: parent text: i18n.tr('Count the kilometres') width: units.gu(15) } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/test-include.pri0000644000015301777760000000017512321005637025220 0ustar pbusernogroup00000000000000include( plugin_dependency.pri ) include( add_makecheck.pri ) TEMPLATE = app QT += testlib qml quick CONFIG += no_keywords ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/0000755000015301777760000000000012321006415025313 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_qmltemplate.cpp0000644000015301777760000000131112321005637031237 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include QUICK_TEST_MAIN(qmltemplate) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_example_mouse.qml0000644000015301777760000000741112321005637031573 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: root width: 200 height: 200 // The object under test MouseArea { id: objectUnderTest anchors.fill: parent hoverEnabled: true // required for pure mouseMove events acceptedButtons: Qt.LeftButton | Qt.RightButton onCanceled: { console.debug("onCancelled"); } onClicked: { console.debug("onClicked b:" + mouse.button); } onDoubleClicked: { console.debug("onDoubleClicked b:" + mouse.button); } onEntered: { console.debug("onEntered"); } onExited: { console.debug("onExited"); } onPositionChanged: { console.debug("onPositionChanged x:" + mouseX + " y:" + mouseY); } onPressAndHold: { console.debug("onPressAndHold b:" + mouse.button); } onPressed: { console.debug("onPressed b:" + mouse.button); } onReleased: { console.debug("onReleased b:" + mouse.button); } } TestCase { name: "ExampleMouse" when: windowShown function init() { console.debug(">> init"); console.debug("<< init"); } function cleanup() { console.debug(">> cleanup"); mouseMove(root); mouseRelease(root); console.debug("<< cleanup"); } function initTestCase() { console.debug(">> initTestCase"); console.debug("<< initTestCase"); } function cleanupTestCase() { console.debug(">> cleanupTestCase"); console.debug("<< cleanupTestCase"); } /* * test for a signal existence */ // API: function mouseRelease(item, x, y, button, modifiers, delay) // API: function mousePress(item, x, y, button, modifiers, delay) // API: function mouseDrag(item, x, y, dx, dy, button, modifiers, delay) // API: function mouseClick(item, x, y, button, modifiers, delay) // API: function mouseDoubleClick(item, x, y, button, modifiers, delay) // API: function mouseMove(item, x, y, delay, buttons) // API: function mouseWheel(item, x, y, xDelta, yDelta, buttons, modifiers, delay) function test_mouse_click() { mouseClick(objectUnderTest,2,2,Qt.LeftButton,Qt.NoModifiers,100); mouseClick(objectUnderTest,10,2,Qt.RightButton); } function test_mouse_doubleclick() { mouseDoubleClick(objectUnderTest,10,2,Qt.RightButton); mouseDoubleClick(objectUnderTest,2,2,Qt.LeftButton,Qt.NoModifiers,100); } function test_mouse_move() { mouseMove(objectUnderTest,20,20); } function test_mouse_drag() { mouseDrag(objectUnderTest,1,1,10,10,Qt.LeftButton); } // end of tests } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_example_checks.qml0000644000015301777760000000617312321005637031707 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: root width: 200 height: 200 property string testString : "i am set" property string anotherTestString : "" TestCase { name: "ExampleChecks" when: windowShown function init() { console.debug(">> init"); console.debug("<< init"); } function cleanup() { console.debug(">> cleanup"); console.debug("<< cleanup"); } function initTestCase() { console.debug(">> initTestCase"); console.debug("<< initTestCase"); } function cleanupTestCase() { console.debug(">> cleanupTestCase"); console.debug("<< cleanupTestCase"); } // API: function verify(cond, msg) // API: function fail(msg) // API: function compare(actual, expected, msg) // API: function fuzzyCompare(actual, expected, delta, msg) // API: function grabImage(item) // API: function tryCompare(obj, prop, value, timeout) // API: function skip(msg) // API: function expectFail(tag, msg) // API: function expectFailContinue(tag, msg) // API: function warn(msg) // API: function wait(ms) // API: function waitForRendering(item, timeout) // API: function sleep(ms) /* When you find a bug and you write a test for it, use expectFail or expectFailContinue, as then you will notice when it has been fixed as XFAIL will turn to XPASS */ // You should NOT use skip as then the bug might be forgotten. function test_expectFailContinue() { expectFailContinue("","The next check will fail, but we WILL continue further"); compare(root.testString,root.anotherTestString,"The strings does not match"); verify(root.testString==="i am set","this check gets called even tho we failed earlier"); } function test_expectFail() { expectFail("","The next one will fail, but we _WILL NOT_ continue any further") compare(root.testString,root.anotherTestString,"The strings does not match"); console.debug("you wont get this far"); root.testString = ""; compare(root.testString,root.anotherTestString,"The strings does match"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_example_benchmark.qml0000644000015301777760000000336212321005637032376 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ExampleBenchmarkObject" when: windowShown function init() { console.debug(">> init"); console.debug("<< init"); } function cleanup() { console.debug(">> cleanup"); console.debug("<< cleanup"); } function initTestCase() { console.debug(">> initTestCase"); console.debug("<< initTestCase"); } function cleanupTestCase() { console.debug(">> cleanupTestCase"); console.debug("<< cleanupTestCase"); } /* * the data for the benchmark_create_component(data) */ function benchmark_create_component_data() { return [ { tag: "Button", fileName: "../../../modules/Ubuntu/Components/Button.qml" } ]; } /* * a data driven test function */ function benchmark_create_component(data) { var component = Qt.createComponent(data.fileName) var obj = component.createObject(top) obj.destroy() component.destroy() } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_example_property.qml0000644000015301777760000000523612321005637032332 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: root width: 200 height: 200 // The objects Button { id: objectUnderTest anchors.margins: 20 anchors.fill: parent } Label { id: testObject1 } TestCase { name: "ExampleCheckProperty" when: windowShown function init() { console.debug(">> init"); console.debug("<< init"); } function cleanup() { console.debug(">> cleanup"); console.debug("<< cleanup"); } function initTestCase() { console.debug(">> initTestCase"); console.debug("<< initTestCase"); } function cleanupTestCase() { console.debug(">> cleanupTestCase"); console.debug("<< cleanupTestCase"); } /* * the data for the test_text(data) */ function test_text_data() { return [ { tag: "A normal text", text: "Hello World!", expectFail: false }, { tag: "Unable to set object* to text", text: testObject1, expectFail: true } ]; } /* * a data driven test function */ function test_text(data) { // check if the expectFail flag is up in data if (data.expectFail) { expectFail("",data.tag); } // try to set the data try { objectUnderTest.text = data.text; } catch (e) { // catched an exception, check if we are expecting a failure, if we are then lets ignore. if (!data.expectFail) { console.error(e); } else { console.debug(e); } } // do the comparing compare(objectUnderTest.text,data.text,"Was able to set " + data.text + " as text."); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_example_keyboard.qml0000644000015301777760000000465012321005637032245 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: root width: 200 height: 200 focus: true // required for Keys property string text : "" Keys.onPressed: { console.debug("onPressed: " + event.key); text += event.text; } Keys.onReleased: { console.debug("onReleased: " + event.key); } TestCase { name: "ExampleKeys" when: windowShown function init() { console.debug(">> init is called before each test"); console.debug("<< init is called before each test"); } function cleanup() { console.debug(">> cleanup"); root.text = ""; console.debug("<< cleanup"); } function initTestCase() { console.debug(">> initTestCase"); console.debug("<< initTestCase"); } function cleanupTestCase() { console.debug(">> cleanupTestCase"); console.debug("<< cleanupTestCase"); } // API: function keyPress(key, modifiers, delay) // API: function keyRelease(key, modifiers, delay) // API: function keyClick(key, modifiers, delay) function test_keyClick() { keyClick(Qt.Key_H); keyClick(Qt.Key_E); keyClick(Qt.Key_L); keyClick(Qt.Key_L); keyClick(Qt.Key_O); compare(root.text,"hello","Text was inserted by keyboard events"); } function test_keyPress_and_keyRelease() { keyPress(Qt.Key_E); keyRelease(Qt.Key_E); compare(root.text,"e","Text was inserted by keyboard events"); } // end of tests } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_qmltemplate.pro0000644000015301777760000000023612321005637031262 0ustar pbusernogroup00000000000000TESTS += $$system(ls tst_*.qml) include(../qmltest-include.pri) TARGET = tst_qmltemplate SOURCES += tst_qmltemplate.cpp OTHER_FILES += $$system(ls *.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qmltemplate/tst_example_signals.qml0000644000015301777760000000500012321005637032073 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: root width: 200 height: 200 // The objects Button { id: objectUnderTest anchors.margins: 20 anchors.fill: parent } TestCase { name: "ExampleCheckSignals" when: windowShown SignalSpy { id: signalSpy target: objectUnderTest } function init() { console.debug(">> init"); console.debug("<< init"); } function cleanup() { console.debug(">> cleanup"); console.debug("<< cleanup"); } function initTestCase() { console.debug(">> initTestCase"); console.debug("<< initTestCase"); } function cleanupTestCase() { console.debug(">> cleanupTestCase"); console.debug("<< cleanupTestCase"); } /* * test for a signal existence */ function test_signals_exists_data() { return [ { tag: "clicked", signalName: "clicked", validSignal: true }, { tag: "hovered", signalName: "hovered", validSignal: true } ];  } function test_signals_exists(data) { signalSpy.signalName = data.signalName; compare(signalSpy.signalName,data.signalName,"signalName is set to " + data.signalName); compare(signalSpy.valid,data.validSignal,"valid is " + data.validSignal); } function test_signal_emission_clicked() { signalSpy.signalName = "clicked"; mouseMove(objectUnderTest,10,10); mouseClick(objectUnderTest,10,10); tryCompare(signalSpy,"count",1,"clicked was emitted"); } // end of tests } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/add_makecheck.pri0000644000015301777760000000043512321005637025342 0ustar pbusernogroup00000000000000# Do not use CONFIG += testcase that would add a 'make check' because it also # adds a 'make install' that installs the test cases, which we do not want. # Instead add a 'make check' manually. check.target = check check.commands = ../../unit/runtest.sh $${TARGET} $${TARGET} minimal; ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_scaling_image_provider/0000755000015301777760000000000012321006415027462 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_scaling_image_provider/input.png0000644000015301777760000000443612321005637031343 0ustar pbusernogroup00000000000000PNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<fiTXtXML:com.adobe.xmp -NIDATxڤXIO:t2vCH! BB\י0Yj:,$c.WW/&H薾q."ʲ̡ߎAt:wa,Ǡ%I2HB<#Ad"dzVŻ]>Ӝ; 3@cAˀe`lü;orfprp]9waf4}Ӵ\+;H#k}L"L8Ƃ~ي|K57fAxf vʊuSSS29DfQ??9ZZ$@r?lx'dkkˍkڱg QdSd@?Hh,6'yw ߂A[ZZ VrnjlT̊U]MQQs`½=fEs'r༁YB_6XP榛A_زuȑ jV3̀.//I1o 6h! 0k LY 4ic^̖Ea]cMӉewnG Q ykp=&n!qr#b 5dM&S;~&33Y[k뛞o6]/Ԙd%A޶t٦V RYj:=|!߼ Q܌U׾!h: JSlMLP*> R߅eɌEb6#YYe=ǵ } Z4#c;/溘tȔG+~$1N>ҵ/C TBNOOU_\rYA2LfKJDmsXxqtK&p&ѢՉP;]2[('/KJ'𸟚 q'b\e2wp `, SQv 0eK<נ =Aʣq9F_4tCgJJg8} q$2U{^P `ۭi;H\&x4s@1yEpKI w/[]]lXxx㣯zؤ'WM 4gmll]=9oQ-O#p. * * Author: Florian Boucault */ #include #include "ucscalingimageprovider.h" class tst_UCScalingImageProvider: public QObject { Q_OBJECT private Q_SLOTS: void scaleToHalfSize() { UCScalingImageProvider provider; QImage result; QSize returnedSize; QImage expected; result = provider.requestImage("0.5/" + QDir::currentPath() + QDir::separator() + "input.png", &returnedSize, QSize()); expected = QImage("scaled_half.png"); QCOMPARE(result, expected); QCOMPARE(returnedSize, expected.size()); } void qrcSupport() { UCScalingImageProvider provider; QImage result; QSize returnedSize; QImage expected; result = provider.requestImage("0.5/:/test/prefix/input.png", &returnedSize, QSize()); expected = QImage("scaled_half.png"); QCOMPARE(result, expected); QCOMPARE(returnedSize, expected.size()); } void respectRequestedSize_data() { QTest::addColumn("inputFile"); QTest::addColumn("scalingFactor"); QTest::addColumn("requestedSize"); QTest::addColumn("returnedSize"); QTest::addColumn("resultSize"); QString inputFile(QDir::currentPath() + QDir::separator() + "input128x256.png"); QTest::newRow("no scaling, bigger width and height") << inputFile << "1.0" << QSize(1000, 1000) << QSize(128, 256) << QSize(128, 256); QTest::newRow("no scaling, smaller width") << inputFile << "1.0" << QSize(50, 1000) << QSize(128, 256) << QSize(50, 100); QTest::newRow("no scaling, smaller height") << inputFile << "1.0" << QSize(1000, 50) << QSize(128, 256) << QSize(25, 50); QTest::newRow("no scaling, smaller width and height")<< inputFile << "1.0" << QSize(50, 50) << QSize(128, 256) << QSize(25, 50); QTest::newRow("downscaling, bigger width and height")<< inputFile << "0.5" << QSize(1000, 1000) << QSize(64, 128) << QSize(64, 128); QTest::newRow("downscaling, smaller width") << inputFile << "0.5" << QSize(50, 1000) << QSize(64, 128) << QSize(50, 100); QTest::newRow("downscaling, smaller height") << inputFile << "0.5" << QSize(1000, 50) << QSize(64, 128) << QSize(25, 50); QTest::newRow("downscaling, smaller width and height")<< inputFile << "0.5" << QSize(50, 50) << QSize(64, 128) << QSize(25, 50); QTest::newRow("upscaling, bigger width and height") << inputFile << "2.0" << QSize(1000, 1000) << QSize(256, 512) << QSize(256, 512); QTest::newRow("upscaling, smaller width") << inputFile << "2.0" << QSize(50, 1000) << QSize(256, 512) << QSize(50, 100); QTest::newRow("upscaling, smaller height") << inputFile << "2.0" << QSize(1000, 50) << QSize(256, 512) << QSize(25, 50); QTest::newRow("upscaling, smaller width and height") << inputFile << "2.0" << QSize(50, 50) << QSize(256, 512) << QSize(25, 50); } void respectRequestedSize() { UCScalingImageProvider provider; QImage result; QSize size; QFETCH(QString, inputFile); QFETCH(QString, scalingFactor); QFETCH(QSize, requestedSize); QFETCH(QSize, returnedSize); QFETCH(QSize, resultSize); result = provider.requestImage(scalingFactor + "/" + inputFile, &size, requestedSize); QCOMPARE(size, returnedSize); QCOMPARE(result.size(), resultSize); } }; QTEST_MAIN(tst_UCScalingImageProvider) #include "tst_scaling_image_provider.moc" ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_scaling_image_provider/tst_scaling_image_provider.qrcubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_scaling_image_provider/tst_scaling_image_pr0000644000015301777760000000014312321005637033565 0ustar pbusernogroup00000000000000 input.png ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_scaling_image_provider/input128x256.png0000644000015301777760000002666612321005637032234 0ustar pbusernogroup00000000000000PNG  IHDR{~bKGD pHYs  tIME !HJ IDATx]kr㸮&(=_Y 2 HɉTزD?WJ RJy=p  "_e)?|%_f׻?shZ5a@XrH/oP<C,#iv_"m[X;zzF+ Xd@x0n[\N׵>~3ZcN7!e]\S=Rg|i z봿y=cue#끡u >&ŭli!AjsZ#z9D|^- Ep@#޳D=xU{M{a'H>49s[Q{X- BtkxާcQ:PXH\8&"F,5QBsbH(M9?845y\'gAGb.Je FvVȂвg^5ZloymwŮi 1"QyZ: :3hȈ:_vI_%艋#6 U Xl+:vco&&tTRz3wwt|գg ^}p4O}Q ߟJwYŔR22E7hj܏BIEe1ْ^Fha׌jK)xq,gerGA8w]S{]̐Gc*Ej" #N]$pηgC # rzzƝ;빿*&2t, pL=!RU}"0oC543a+?f5n+~eۓhN>@;{HIXk-`Ukpy0a#ÀE=}@ta ~ЈpH܇L. 0brv?є6l~ABIE4RC1Ѳq9?1tyGcocIDW wt{$0 :T'AdQE".hiZaoY~4|X%V~^b]:؈#98 8kSՌ 4bqgc-2ʨ`N)ꫜ j՛R玟!xd L8CķP =D#>T^U-&Ф<88 9\El4>=``JnGFMvLː?V>2#̬HL+p>(fGT$A)%>(*9᜺{ZgncڪjuPV٢]PML eY6h1"x9_1`/`ָ]7 m( /<)[bF4">"C#vFΏE' A7ïn3d3Ű%ʵ0Afxh *@C`.c9p` %xs~(>N5hIi =xicH 9*s؃ 荬:2rs@P " @j>J)ifr2)a%7\ EAfo< mPDM*RNF4MS* d8əa8HkhNn&v_eX5Eo#@zփp3^Js bz+7; ,xACibЎrg)qU5+SD|n83pS . VV̆ݐz.-B~{G (YGx-a4ps`1GQUzQ Z+V"JDG12v~o}mѕć-ҕEZӟ@#e#}K;U1u% x֏L .7#=ԖfבrUI3K)Jz/k=(Aœ7 iXfLK#Kh(Q«?J)py/"gQiFT^S5*(*jƘHTMJ<-[7:Ig y7H&z^]ǝvIYxzMwhqNVgzQAܣ'$?"/ӷb3e- kOZjNZWs7!=#7!8[4-N[wI>2l·@`gKDDUIA_b[C/k>4Wx+'E[pFGr_!UJ(G& I@MJI0wGRo5}|V}_ mTs2*U@ONBfM$:ȳ3~`o^`݄0WM@b9oO p^k"vUI8Z1z(DqEߊmۆ!|eYvS;A礉iTU& nH֏KZ_**ioA^d 7 "򌟌_&f4&v-TpLϪېK3pPܿLjյ%R9v1?6q(ʏ+xN B)NHU ӧdnNjϱ|)S ,0T+bG]Vh ?a 6`a< zQ>Q xM"sV{^mmƿyӈ.Z>whָGgΠ$p$,f@G}Ž<1+=V @kw,dD*}64s3ě,ƽ| NtW5 tWp5_cio\T8"ȭxW34T3=Z`~FʲH& ց}jDN|ML F]rA=7`zy|#[,(=<^SA+39)~#{:Gp=BODށ DwG>BѽCo빭Wv3ӎ'uhD@+n}OSGܑu0qhQ|ž3&o-ud&8ѯŸ9a|:[EGMh#ث~']cʺ0- >'| ^j9Dwq_fV :f;@guT7?%oFr&Ϟ[ps !k\m>3<"6jHt56DŸkrzBQc}h?̽weLRv3}K Bc>A Q)Ń "q'Ǚ'0(7Gµ ۫pFri죭CAΝ Mh'5]a`KU@1~D2AڅxE!$*{LY+hocz=Z!O+خiL86A:Πd8 颓C!VhXkwp{Fu^FyoO=r6Gj[+ GgO1P$#J"&?l*dXq#?JM΋>5hO !~&"?ϳB~Ěy "?c|*(!7=ڦa_"[;rRbʹɌ(™[*pP`咏ڿ p^ : 1HKeѫmM55S25}ָ?Sr (rY___i/: H+zdâΣjSkSCA9Jy߿[Пu7K'!%3vvKm34 ui܎uQ>aޡіFmhoMkx;<MӔ2|$l"7g;c0kBB/L "L-.xB+ό {Zd9]ק9ap甧 > `·G^u絇fkXD7oFp" >'g^|}=oX#К"~Gčw{VGw֡1L`z~OM EOSҩ2 &ؙݵF.zl!`dZ Tј/"R <_$޲ 5k 7 {-K+P5EBQ  MT>Q,p0O!}" F`iX%}nRJ)]rQC6<1:R3@2#P9URR8~hFpRZ9}}}UQs&UT%:3xr姢YԺi-Ӯ@ƨqtm;Y Ć>rod+p3!ً)LK*? tz> :l~J,)j?Ä%RUoQj!r܉;$|,#(,g knaNIFTϗ`\RiӨ=zxTƦ&w#P1j @@6kwaF{B#6g{ Ac4#X{_` Lk0*S?-`;K[eJ צaY͡y ;<6_wld%|b#h@-?4-ǟڰKawHuZ7ؼ m$4>@,=Oc]ҳQ ,S-ҚC֮ /Cjs8wϹ* ֹG{[16TD ?&?]N~kY&,){VS?eU~r3L{@vH,P4"SeNA>``VjYi-y#@~MBO!~K3F#\_7մN*;#j!l 7IDAT?^bG-pv >SnGS_%~u/aEOX>vLш"kSZx\v0)Zזޞ'dxKK4˷d۲ nXHZcՒ-fMIv#(8=;[#__(5{+\j ^,i%nE6a]v2'77p|Vt"|$R(@]9AiJ'~&LDNjqf66LAh /Xv Adϖݣ˶+ZA6n͹b3eq8,˲M iJ~b٭>? Q%Ɍ VIN (^IRpo!|:i"rIej^-1M=P 41ηuʙ wLŁ߲lLjRJ?MxU9^`I9>zU.=͌5йCHU&<;|*qwY6Ri#ҏـޢ˺~cJ eyƻvukXJ@g@PTջ6՚M'zwjK);'?e2HB>Fkpm-hN.tgvCG/ HWko3W_`NJ@5q7/x>kiʐ&* ɿ<5GbHJc !I)o%>UzFTR/g(jAgVW/l3#%?eʠxè1"*!ĴszeY*`>&S#554l1Y!?6gCNSi*S*Yʀ(E4Ua"!r3 +|Eī޲lKbUCTU_JRȳW^˗E#$ږ18bUi{]Q)vyi8)RJgw=naQexH;K).pݪ( 2A3+gdz*Bz<y/&o'"i:MN;e<#MC|z^rd7fнSB5|2a$QH~j&2=X ̶<::`RZKݧP'YڙB \w5 Ch6YHoO*ymR[YAo|e(%]Vl"(~ws:nj?Z~{0(j76yP+3BLRƵrUi%|Ǧ, wRnkvkd 汕G31(@4g50C^ FEĝ01ͦx\VKƘ.Fp883"1,bֿHS 3LrZtF( FZI ZhsjȩUCmф͒?]G%^oޥNS]}˥h=N#&$pZ˲ȣE,)G܈z,rY>#(\, h :qeo*Y+޸*74+v3*+|; RQ:NOO9??'Ѷ-tJJR "$wUR ,1Y13kD7E???@T|N܌Yeef2Uv1' p 쌱@q.ņ!M&8L݇]|7#]U*XV{pwcZ1j~rC=!UܝfC۶{l^__k {V5QS t^+ivam}l4hrwR,r]⒫&{^^^hۖCbF4Mb{6*,Kx~ww')^(VW,$4IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/unit.pro0000644000015301777760000000120312321005637023576 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += testparser ####################################### # these tests are failing in armhf/qemu # can not create QQuickView # tested with Qt 5 beta 1 and beta 2 # # https://bugs.launchpad.net/qemu-linaro/+bug/1084148 ####################################### #!contains(QMAKE_HOST.arch,armv7l) { SUBDIRS += tst_components \ tst_components_benchmark #} SUBDIRS += tst_units \ tst_scaling_image_provider \ tst_qquick_image_extension \ tst_performance \ tst_ubuntu_shape \ tst_mainview \ tst_page \ tst_i18n \ tst_arguments \ tst_argument \ tst_alarms \ tst_theme ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/0000755000015301777760000000000012321006415024605 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/PageStack.qml0000644000015301777760000000162712321005637027175 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { objectName: "pageStack" applicationName: "once.upon.a.time" PageStack { objectName: "stack" Page { objectName: "page" title: 'Far far away' } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/TabsTitle.qml0000644000015301777760000000176612321005712027224 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { objectName: "tabsTitle" applicationName: "once.upon.a.time" Tabs { objectName: "tabs" Tab { title: 'Not the title you are looking for' page: Page { objectName: "page" title: 'Long long ago' } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/PageTitle.qml0000644000015301777760000000153012321005637027202 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { objectName: "pageTitle" applicationName: "once.upon.a.time" Page { objectName: "page" title: 'Once upon a time' } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/LocalStorage.qml0000644000015301777760000000216112321005637027704 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import QtQuick.LocalStorage 2.0 MainView { objectName: "localStorage" applicationName: "tv.island.pacific" Component.onCompleted: { var db = LocalStorage.openDatabaseSync("pacific.island.tv", "1.0", "lorem ipsum", 1000) db.transaction(function(tx){ tx.executeSql('CREATE TABLE IF NOT EXISTS Island(name TEXT)') tx.executeSql('INSERT INTO Island VALUES(?)', ['Tuvalu']) }) } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/AppName.qml0000644000015301777760000000141112321005637026643 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { objectName: "appName" applicationName: "org.gnu.wildebeest" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/tst_mainview.cpp0000644000015301777760000001510412321005712030022 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ucapplication.h" #include "ucunits.h" #include "uctestcase.h" class tst_MainView : public QObject { Q_OBJECT private: QQuickView *view; public: tst_MainView() : view(0) { } QQuickItem *loadTest(const QString &document) { // load the document view->setSource(QUrl::fromLocalFile(document)); QTest::waitForEvents(); return view->rootObject(); } QQuickItem *testItem(QQuickItem *that, const QString &identifier) { if (that->property(identifier.toLocal8Bit()).isValid()) return that->property(identifier.toLocal8Bit()).value(); QList children = that->findChildren(identifier); return (children.count() > 0) ? children[0] : 0; } private Q_SLOTS: void initTestCase() { QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); view = new QQuickView; QQmlEngine *quickEngine = view->engine(); view->setGeometry(0,0, UCUnits::instance().gu(40), UCUnits::instance().gu(30)); //add modules folder so we have access to the plugin from QML QStringList imports = quickEngine->importPathList(); imports.prepend(QDir(modules).absolutePath()); quickEngine->setImportPathList(imports); } void cleanupTestCase() { delete view; } void testCase_AppName() { QQuickItem *root = loadTest("AppName.qml"); QVERIFY(root); QQuickItem *mainView = root; QString applicationName(mainView->property("applicationName").toString()); QCOMPARE(applicationName, QString("org.gnu.wildebeest")); QCOMPARE(applicationName, QCoreApplication::applicationName()); QCOMPARE(QString(""), QCoreApplication::organizationName()); } void testSetApplicationName() { QString appName("com.ubuntu.foo"); UCApplication::instance().setApplicationName(appName); QCOMPARE(UCApplication::instance().applicationName(), appName); QCOMPARE(QCoreApplication::applicationName(), appName); QCOMPARE(QString(""), QCoreApplication::organizationName()); } void testExpectedDataFolder() { QString appName("net.weight.gain"); UCApplication::instance().setApplicationName(appName); QString dataFolder(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); QString xdgDataHome(QProcessEnvironment::systemEnvironment().value("XDG_DATA_HOME", QProcessEnvironment::systemEnvironment().value("HOME") + "/.local/share")); QString expectedDataFolder(xdgDataHome + "/" + appName); QCOMPARE(dataFolder, expectedDataFolder); } void testExpectedCacheFolder() { QString appName("cat.long.very"); UCApplication::instance().setApplicationName(appName); QString cacheFolder(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); QString xdgCacheHome(QProcessEnvironment::systemEnvironment().value("XDG_CACHE_HOME", QProcessEnvironment::systemEnvironment().value("HOME") + "/.cache")); QString expectedCacheFolder(xdgCacheHome + "/" + appName); QCOMPARE(cacheFolder, expectedCacheFolder); } void testLocalStorage() { QQuickItem *root = loadTest("LocalStorage.qml"); QVERIFY(root); QQuickItem *mainView = root; QString applicationName(mainView->property("applicationName").toString()); QCOMPARE(applicationName, QString("tv.island.pacific")); QCOMPARE(applicationName, QCoreApplication::applicationName()); QCOMPARE(QString(""), QCoreApplication::organizationName()); QString dataFolder(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); QString databaseFolder(dataFolder + "/Databases"); QVERIFY(QFile::exists(databaseFolder)); QString hash(QCryptographicHash::hash("pacific.island.tv", QCryptographicHash::Md5).toHex()); QString database(databaseFolder + "/" + hash + ".sqlite"); QVERIFY(QFile::exists(database)); } void testNoWarnings_bug186065() { QSignalSpy spy(view->engine(), SIGNAL(warnings(QList))); spy.setParent(view); QQuickItem *root = loadTest("AppName.qml"); // An empty MainView would suffice QVERIFY(root); // No warnings from QML QCOMPARE(spy.count(), 0); } void testWindowTitleFromPage() { QScopedPointer testCase(new UbuntuTestCase("PageTitle.qml")); QQuickItem *page = testCase->findItem("page"); QCOMPARE(QString("Once upon a time"), page->property("title").toString()); QCOMPARE(testCase->title(), page->property("title").toString()); } void testWindowTitleFromStack() { QScopedPointer testCase(new UbuntuTestCase("PageStack.qml")); QQuickItem *page = testCase->findItem("page"); QCOMPARE(QString("Far far away"), page->property("title").toString()); QCOMPARE(testCase->title(), page->property("title").toString()); } void testWindowTitleFromTabs() { QScopedPointer testCase(new UbuntuTestCase("TabsTitle.qml")); QQuickItem *page = testCase->findItem("page"); QCOMPARE(QString("Long long ago"), page->property("title").toString()); QCOMPARE(testCase->title(), page->property("title").toString()); } }; QTEST_MAIN(tst_MainView) #include "tst_mainview.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_mainview/tst_mainview.pro0000644000015301777760000000015312321005637030044 0ustar pbusernogroup00000000000000include(../test-include.pri) QT += gui SOURCES += tst_mainview.cpp OTHER_FILES += $$system(ls tst_*.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_alarms/0000755000015301777760000000000012321006415024245 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_alarms/tst_alarms.cpp0000644000015301777760000002005512321005637027131 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #define protected public #include "ucalarm.h" #include "ucalarm_p.h" #include "alarmmanager_p.h" #include "ucalarmmodel.h" #include "alarmrequest_p.h" #include "adapters/alarmsadapter_p.h" #undef protected #include #include #include #include #include class tst_UCAlarms : public QObject { Q_OBJECT public: tst_UCAlarms() {} private: void syncFetch() { // initiate fetch AlarmsAdapter *adapter = AlarmsAdapter::get(); if (!adapter->fetchRequest) { adapter->fetchAlarms(); } if (adapter->fetchRequest) { adapter->fetchRequest->wait(); } QTest::waitForEvents(); } void waitForRequest(UCAlarm *alarm) { UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm); if (pAlarm->request) { pAlarm->request->wait(); } QTest::waitForEvents(); // also complete any pending fetch! syncFetch(); } bool containsAlarm(UCAlarm *alarm) { UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm); QList alarms = AlarmManager::instance().alarms(); Q_FOREACH(AlarmData i, alarms) { if (i == pAlarm->rawData) { return true; } } return false; } bool compareAlarms(UCAlarm *alarm1, UCAlarm *alarm2) { UCAlarmPrivate *pAlarm1 = UCAlarmPrivate::get(alarm1); UCAlarmPrivate *pAlarm2 = UCAlarmPrivate::get(alarm2); return pAlarm1->rawData.compare(pAlarm2->rawData); } private Q_SLOTS: void initTestCase() { AlarmManager::instance(); // make sure the first fetch is completed AlarmsAdapter *adapter = AlarmsAdapter::get(); if (adapter->fetchRequest) { adapter->fetchRequest->wait(); } } void cleanupTestCase() { // remove all test alarms UCAlarmModel model; int i = 0; while (i < model.count()) { UCAlarm *alarm = model.get(i); if (alarm && alarm->message().startsWith("test_")) { alarm->cancel(); waitForRequest(alarm); i = 0; } else { i++; } } } void test_singleShotAlarmXFail() { UCAlarm alarm; alarm.save(); QVERIFY(alarm.error() == UCAlarm::EarlyDate); } void test_singleShotAlarmPass() { UCAlarm alarm(QDateTime::currentDateTime().addSecs(10), "test_singleShotAlarmPass"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); } void test_repeating_autoDetect() { UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::AutoDetect, "test_repeating_autoDetect"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); } void test_repeating_daily() { UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::Daily, "test_repeating_daily"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); } void test_repeating_givenDay() { UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::Wednesday, "test_repeating_givenDay"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); } void test_repeating_moreDays() { UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::Monday | UCAlarm::Wednesday, "test_repeating_moreDays"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); } void test_setAlarmObjectFail_WrongRecurence1() { UCAlarm alarm(QDateTime::currentDateTime().addDays(1), UCAlarm::Monday | UCAlarm::Tuesday); alarm.setType(UCAlarm::OneTime); alarm.save(); QCOMPARE(alarm.error(), (int)UCAlarm::OneTimeOnMoreDays); } void test_setAlarmObjectFail_WrongRecurence2() { UCAlarm alarm(QDateTime::currentDateTime().addDays(1), UCAlarm::Daily); alarm.setType(UCAlarm::OneTime); alarm.save(); QCOMPARE(alarm.error(), (int)UCAlarm::OneTimeOnMoreDays); } void test_cancelFail() { UCAlarm alarm(QDateTime::currentDateTime().addDays(1), "test_cancelFail"); alarm.cancel(); QCOMPARE(alarm.error(), (int)UCAlarm::InvalidEvent); } void test_cancelPass() { UCAlarm alarm(QDateTime::currentDateTime().addDays(1), "test_cancelPass"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); alarm.cancel(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(!containsAlarm(&alarm)); } void test_twoAlarmsOnSameTime() { QDateTime dt = QDateTime::currentDateTime().addSecs(60); UCAlarm alarm1(dt, "test_twoAlarmsOnSameTime"); UCAlarm alarm2(dt, "test_twoAlarmsOnSameTime"); alarm1.save(); waitForRequest(&alarm1); alarm2.save(); waitForRequest(&alarm2); QCOMPARE(alarm1.error(), (int)UCAlarm::NoError); QCOMPARE(alarm2.error(), (int)UCAlarm::NoError); } void test_twoAlarmsOnSameTime2() { QDateTime dt = QDateTime::currentDateTime().addSecs(60); UCAlarm alarm1(dt, "test_twoAlarmsOnSameTime2"); UCAlarm alarm2(dt, UCAlarm::Daily, "test_twoAlarmsOnSameTime2"); alarm1.save(); waitForRequest(&alarm1); alarm2.save(); waitForRequest(&alarm2); QCOMPARE(alarm1.error(), (int)UCAlarm::NoError); QCOMPARE(alarm2.error(), (int)UCAlarm::NoError); } void test_updateAlarm_SameType() { QDateTime dt = QDateTime::currentDateTime().addSecs(120); UCAlarm alarm(dt, "test_updateAlarm_SameType"); UCAlarm copy(dt, "test_updateAlarm_SameType"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); alarm.setDate(QDateTime::currentDateTime().addDays(5)); QVERIFY(!compareAlarms(&alarm, ©)); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); QVERIFY(!containsAlarm(©)); } void test_updateAlarm_DifferentType() { QDateTime dt = QDateTime::currentDateTime().addSecs(120); UCAlarm alarm(dt, "test_updateAlarm_DifferentType"); UCAlarm copy(dt, "test_updateAlarm_DifferentType"); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); alarm.setType(UCAlarm::Repeating); QVERIFY(!compareAlarms(&alarm, ©)); alarm.save(); waitForRequest(&alarm); QCOMPARE(alarm.error(), (int)UCAlarm::NoError); QVERIFY(containsAlarm(&alarm)); QVERIFY(!containsAlarm(©)); } }; QTEST_MAIN(tst_UCAlarms) #include "tst_alarms.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_alarms/tst_alarms.pro0000644000015301777760000000010712321005637027143 0ustar pbusernogroup00000000000000include(../test-include.pri) QT += organizer SOURCES += tst_alarms.cpp ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/qtprivate_dependency.pri0000644000015301777760000000020212321005637027024 0ustar pbusernogroup00000000000000QT += quick-private qml-private core-private equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { QT += v8-private } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/runtest.sh0000755000015301777760000000676112321005637024156 0ustar pbusernogroup00000000000000#!/bin/bash # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # Author: Juhapekka Piiroinen ################################################################################ _CMD="" _TARGET=$1 _TESTFILE=$2 _MINIMAL=$3 _XML="../../test_$_TARGET_$_TESTFILE.xml" _ARGS="-o $_XML,xunitxml -o -,txt" set +e function create_test_cmd { _CMD="./$_TARGET" if [ "$_MINIMAL" = "minimal" ]; then _CMD="$_CMD -platform minimal" fi if [ $_TARGET != $_TESTFILE ]; then _CMD="$_CMD -input $_TESTFILE" fi _CMD="$_CMD -maxwarnings 4" } function execute_test_cmd { echo "Executing $_CMD $_ARGS" if [ $DISPLAY ]; then # https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1256999 # https://bugreports.qt-project.org/browse/QTBUG-36243 QML2_IMPORT_PATH=../../../modules:$QML2_IMPORT_PATH UBUNTU_UI_TOOLKIT_THEMES_PATH=../../../modules \ $_CMD $_ARGS 2>&1 | grep -v 'QFontDatabase: Cannot find font directory' # Note: Get first command before the pipe, $? would be ambiguous RESULT=${PIPESTATUS[0]} WARNINGS=$(grep -c qwarn $_XML) EXCEPTIONS='tst_components_benchmark \ tst_toolbaritems.qml \ tst_tabbar.qml \ tst_alarms \ tst_pickerpanel.qml \ tst_picker.qml \ tst_i18n \ tst_listitems_standard.qml \ tst_optionselector.qml \ tst_arguments \ tst_mainview \ tst_popups_actionselectionpopover.qml \ tst_layouts tst_datepicker.qml \ tst_listitems_valueselector.qml \ tst_listitems_itemselector.qml \ tst_ubuntu_shape \ tst_page.qml \ tst_qquick_image_extension \ tst_listitems_divider.qml tst_layouts \ tst_checkbox.qml \ tst_performance \ tst_inversemousearea \ tst_listitems_base.qml \ tst_statesaver \ tst_theme_engine \ tst_orientation \ tst_tabs.qml \ tst_textfield.qml \ tst_mousefilters' if [ $WARNINGS -ne 0 ]; then if [[ $EXCEPTIONS == *$_TARGET_$_TESTFILE* ]]; then echo "FIXME: $WARNINGS warnings - Known problematic test" else echo "Error: $WARNINGS warnings in $_TARGET_$_TESTFILE" RESULT=666 fi elif [[ $EXCEPTIONS == *$_TARGET_$_TESTFILE* ]]; then echo Woot! Known problematic test did pass afterall! echo Consider removing $_TARGET_$_TESTFILE from EXCEPTIONS in $0 fi else echo "Skipped because no DISPLAY available" RESULT=0 fi # segfault if [ $RESULT -eq 139 ]; then RESULT=2 fi # abort if [ $RESULT -eq 134 ]; then RESULT=2 fi echo "$_TARGET_$_TESTFILE exited with $RESULT" return $RESULT } create_test_cmd execute_test_cmd RESULT=$? exit $RESULT ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_argument/0000755000015301777760000000000012321006415024610 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_argument/tst_argument.cpp0000644000015301777760000000635012321005637030041 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #define protected public #include "ucargument.h" #undef protected #include #include class tst_UCArgument : public QObject { Q_OBJECT private Q_SLOTS: void testAt() { UCArgument argument; QCOMPARE(argument.at(-2).type(), QVariant::Invalid); QCOMPARE(argument.at(0).type(), QVariant::Invalid); QCOMPARE(argument.at(1).type(), QVariant::Invalid); QCOMPARE(argument.at(2).type(), QVariant::Invalid); QStringList values; values << "value1" << "value2"; argument.setValues(values); QCOMPARE(argument.at(-2).type(), QVariant::Invalid); QCOMPARE(argument.at(0).type(), QVariant::String); QCOMPARE(argument.at(1).type(), QVariant::String); QCOMPARE(argument.at(2).type(), QVariant::Invalid); QCOMPARE(argument.at(0).toString(), QString("value1")); QCOMPARE(argument.at(1).toString(), QString("value2")); } void testSyntax() { QFETCH(QString, name); QFETCH(QStringList, valueNames); QFETCH(bool, required); QFETCH(QString, expectedSyntax); UCArgument argument; argument.setName(name); argument.setRequired(required); argument.setValueNames(valueNames); QCOMPARE(argument.syntax(), expectedSyntax); } void testSyntax_data() { QTest::addColumn("name"); QTest::addColumn("valueNames"); QTest::addColumn("required"); QTest::addColumn("expectedSyntax"); QStringList valueNames; valueNames << "VALUE1" << "VALUE2"; QTest::newRow("no name, no valueNames, not required") << "" << QStringList() << false << ""; QTest::newRow("name, no valueNames, not required") << "argument" << QStringList() << false << "--argument"; QTest::newRow("no name, 2 valueNames, not required") << "" << valueNames << false << "[VALUE1] [VALUE2]"; QTest::newRow("name, 2 valueNames, not required") << "argument" << valueNames << false << "--argument=VALUE1 VALUE2"; QTest::newRow("no name, no valueNames, required") << "" << QStringList() << true << ""; QTest::newRow("name, no valueNames, required") << "argument" << QStringList() << true << "--argument"; QTest::newRow("no name, 2 valueNames, required") << "" << valueNames << true << "VALUE1 VALUE2"; QTest::newRow("name, 2 valueNames, required") << "argument" << valueNames << true << "--argument=VALUE1 VALUE2"; } }; QTEST_MAIN(tst_UCArgument) #include "tst_argument.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_argument/tst_argument.pro0000644000015301777760000000007112321005637030051 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_argument.cpp ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_template/0000755000015301777760000000000012321006415024601 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_template/tst_template.pro0000644000015301777760000000007112321005637030033 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_template.cpp ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_template/tst_template.cpp0000644000015301777760000000162712321005637030025 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include class tst_Template: public QObject { Q_OBJECT private Q_SLOTS: void dummy() { QCOMPARE(true, true); } }; QTEST_MAIN(tst_Template) #include "tst_template.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/README0000644000015301777760000000037412321005637022765 0ustar pbusernogroup00000000000000== How to execute a single qml test == When current path is tests/unit/tst_components: QML2_IMPORT_PATH=../../../modules:$QML2_IMPORT_PATH UBUNTU_UI_TOOLKIT_THEMES_PATH=../../../modules qmltestrunner -input tst_yourtest.qml -import "../../../modules" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/0000755000015301777760000000000012321006415027521 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/test@18.sci0000644000015301777760000000021312321005637031452 0ustar pbusernogroup00000000000000source: "test@18.png" border.left: 9 border.right: 2 border.top: 9 border.bottom: 0 horizontalTileMode: Stretch verticalTileMode: Stretch ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/tst_qquick_image_extension.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/tst_qquick_image_ext0000644000015301777760000000763212321005637033672 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include // Make protected methods of QQuickImageExtension public in order to test them #define protected public #include "ucqquickimageextension.h" #undef protected unsigned int numberOfTemporarySciFiles() { QStringList nameFilters; nameFilters << "*.sci"; return QDir::temp().entryList(nameFilters, QDir::Files).count(); } class tst_UCQQuickImageExtension : public QObject { Q_OBJECT private Q_SLOTS: void scaledBorderIdentity() { UCQQuickImageExtension image; QString border = "border: 13"; QString expected = "border: 13"; QString result = image.scaledBorder(border, "1"); QCOMPARE(result, expected); } void scaledBorderHalf() { UCQQuickImageExtension image; QString border = "border: 13"; QString expected = "border: 7"; QString result = image.scaledBorder(border, "0.5"); QCOMPARE(result, expected); } void scaledBorderDouble() { UCQQuickImageExtension image; QString border = "border: 13"; QString expected = "border: 26"; QString result = image.scaledBorder(border, "2"); QCOMPARE(result, expected); } void rewriteContainsBorderInName() { UCQQuickImageExtension image; QString sciFilePath = "borderInName.sci"; QString result; QTextStream resultStream(&result); image.rewriteSciFile(sciFilePath, "1", resultStream); QString expected; QTextStream expectedStream(&expected); expectedStream << "source: \"image://scaling/1/./borderInName.png\"" << endl; expectedStream << "border.left: 9" << endl; expectedStream << "border.right: 2" << endl; expectedStream << "border.top: 9" << endl; expectedStream << "border.bottom: 0" << endl; expectedStream << "horizontalTileMode: Stretch" << endl; expectedStream << "verticalTileMode: Stretch" << endl; QCOMPARE(result, expected); } void cachingOfRewrittenSciFiles() { /* This tests an internal implementation detail of UCQQuickImageExtension, namely making sure that only one temporary rewritten .sci file is created for each source .sci file. */ QQuickImageBase baseImage; UCQQuickImageExtension* image1 = new UCQQuickImageExtension(&baseImage); UCQQuickImageExtension* image2 = new UCQQuickImageExtension(&baseImage); QUrl sciFileUrl = QUrl::fromLocalFile("./test.sci"); unsigned int initialNumberOfSciFiles = numberOfTemporarySciFiles(); image1->setSource(sciFileUrl); QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1); image2->setSource(sciFileUrl); QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1); delete image1; QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1); /* The temporary files will be deleted when the cache is destroyed when the application exits. */ delete image2; QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1); } }; QTEST_MAIN(tst_UCQQuickImageExtension) #include "tst_qquick_image_extension.moc" ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/tst_qquick_image_extension.proubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/tst_qquick_image_ext0000644000015301777760000000013312321005637033657 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_qquick_image_extension.cpp QT += quick-private ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_qquick_image_extension/borderInName.sci0000644000015301777760000000022012321005637032565 0ustar pbusernogroup00000000000000source: "borderInName.png" border.left: 9 border.right: 2 border.top: 9 border.bottom: 0 horizontalTileMode: Stretch verticalTileMode: Stretch ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components_benchmark/0000755000015301777760000000000012321006415027165 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components_benchmark/tst_components_benchmark.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components_benchmark/tst_components_benchma0000644000015301777760000000612012321005637033650 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include #include #include #include class tst_components_benchmark: public QObject { Q_OBJECT private Q_SLOTS: void benchmark_creation_components_data() { QTest::addColumn("fileName"); QDir dir; dir.setPath("../../../modules/Ubuntu/Components"); QStringList nameFilters; nameFilters << "*.qml"; dir.setNameFilters(nameFilters); dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setSorting(QDir::Size | QDir::Reversed); QFileInfoList list = dir.entryInfoList(); qDebug() << "Found" << list.size() << "tests."; for (int i = 0; i < list.size(); ++i) { QFileInfo fileInfo = list.at(i); QTest::newRow(fileInfo.fileName().toLatin1()) << fileInfo.fileName(); } } void benchmark_creation_components() { QFETCH(QString, fileName); qDebug() << "Loading" << fileName; QQmlComponent component(&engine, fileName); QObject *obj = component.create(); obj->deleteLater(); QBENCHMARK { QObject *obj = component.create(); obj->deleteLater(); } } void benchmark_creation_listitems_data() { QTest::addColumn("fileName"); QDir dir; dir.setPath("../../../modules/Ubuntu/Components/ListItems"); QStringList nameFilters; nameFilters << "*.qml"; dir.setNameFilters(nameFilters); dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setSorting(QDir::Size | QDir::Reversed); QFileInfoList list = dir.entryInfoList(); qDebug() << "Found" << list.size() << "tests."; for (int i = 0; i < list.size(); ++i) { QFileInfo fileInfo = list.at(i); QTest::newRow(fileInfo.fileName().toLatin1()) << fileInfo.fileName(); } } void benchmark_creation_listitems() { QFETCH(QString, fileName); qDebug() << "Loading" << fileName; QQmlComponent component(&engine, fileName); QObject *obj = component.create(); obj->deleteLater(); QBENCHMARK { QObject *obj = component.create(); obj->deleteLater(); } } private: QQmlEngine engine; }; QTEST_MAIN(tst_components_benchmark) #include "tst_components_benchmark.moc" ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components_benchmark/tst_components_benchmark.proubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components_benchmark/tst_components_benchma0000644000015301777760000000010612321005637033646 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_components_benchmark.cpp ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/0000755000015301777760000000000012321006415025153 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_mainview.qml0000644000015301777760000000446412321005637030414 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "MainViewAPI" MainView { id: mainView } Action { id: action0 } function initTestCase() { compare(mainView.active, true, "MainView always active."); compare(mainView.automaticOrientation, false, "Automatic orientation off by default."); compare(mainView.applicationName, "", "Application name is empty string by default."); compare(mainView.actions.length, 0, "No actions defined by default") } function test_automaticOrientation() { mainView.automaticOrientation = true; compare(mainView.automaticOrientation, true, "Automatic orientation can be enabled."); mainView.automaticOrientation = false; compare(mainView.automaticOrientation, false, "Automaic orientation can be disabled."); } function test_applicationName() { var appName = "testAppName"; mainView.applicationName = appName; compare(mainView.applicationName, appName, "Applicatin name can be set."); mainView.applicationName = ""; compare(mainView.applicationName, "", "Application name can be unset."); } function test_actions() { // FIXME: Check the contents of mainView.actions. This is currently not // possible because UnityActions.ActionContext.actions does not support it, // so changes to UnityActions are needed. mainView.actions = [action0]; compare(mainView.actions.length, 1, "Actions can be added to page actions"); mainView.actions = []; compare(mainView.actions.length, 0, "Page action list can be cleared"); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_tab.qml0000644000015301777760000000272012321005637027334 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "TabAPI" function test_iconSource() { compare(tab.iconSource,"","iconSource is not set by default") var newIcon = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" tab.iconSource = newIcon compare(tab.iconSource,Qt.resolvedUrl(newIcon),"Can set/get iconSource") } function test_page() { compare(tab.page,null,"page is null by default") } function test_title() { compare(tab.title,"","is not set by default") var newTitle = "Hello World!" tab.title = newTitle compare(tab.title,newTitle,"can set/get") } function test_index() { compare(tab.index, -1, "is -1 by default") } Tab { id: tab } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_caption.qml0000644000015301777760000000207012321005637032316 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsCaptionAPI" function test_text() { compare(listItemCaption.text,"","text is '' by default") var newText = "Hello World!" listItemCaption.text = newText compare(listItemCaption.text,newText,"set/get") } ListItem.Caption { id: listItemCaption } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_action.qml0000644000015301777760000000434412321005637030047 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ActionAPI" function initTestCase() { compare(action.text, "", "text is empty string set by default") compare(action.iconSource, "", "iconSource is empty string by default") compare(action.iconName, "", "iconName is empty string by default") } function test_iconSource() { compare(action.iconSource, "", "iconSource is empty string by default") var newIconSource = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" action.iconSource = newIconSource compare(action.iconSource, Qt.resolvedUrl(newIconSource), "iconSource can be set") action.iconSource = "" compare(action.iconSource, "", "iconSource can be unset") } function test_iconName() { compare(action.iconName, "", "iconName is empty string by default") var newIconName = "compose" action.iconName = newIconName compare(action.iconName, newIconName, "iconName can be set") action.iconName = "" compare(action.iconName, "", "iconName can be unset") } function test_trigger() { compare(triggeredSignalSpy.count, 0) action.triggered(null); compare(triggeredSignalSpy.count, 1) } function test_signal_triggered_exists() { compare(triggeredSignalSpy.valid, true, "triggered signal exists") } Action { id: action } SignalSpy { id: triggeredSignalSpy target: action signalName: "triggered" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_singlevalue.qml0000644000015301777760000000251612321005637033204 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsSingleValueAPI" function test_text() { compare(listItemSingleValue.text,"","text is '' by default") var newText = "Hello World!" listItemSingleValue.text = newText compare(listItemSingleValue.text,newText,"set/get") } function test_value() { compare(listItemSingleValue.value,"","value is '' by default") var newValue = "New Value" listItemSingleValue.value = newValue compare(listItemSingleValue.value,newValue,"set/get") } ListItem.SingleValue { id: listItemSingleValue } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_activityindicator.qml0000644000015301777760000000205212321005637032315 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ActivityIndicatorAPI" function test_running() { compare(activityIndicator.running,false,"Running is boolean and false by default") activityIndicator.running = true compare(activityIndicator.running,true,"can set/get running") } ActivityIndicator { id: activityIndicator } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_popups_popover.qml0000644000015301777760000000461512321005637031673 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 TestCase { name: "PopupsPopoverAPI" function test_show() { popOver.show() } function test_hide() { popOver.hide() } function test_caller() { compare(popOver.caller,null,"caller is not set by default") } //PopupBase properties function test_dismissArea() { compare(popOver.dismissArea, popOver, "Default sensing area is the popover"); } function test_grabDismissAreaEvents() { compare(popOver.grabDismissAreaEvents, true, "Default grabs dismiss area events"); } // Popover properties function test_contentWidth() { expectFail("", "Content width is wrong due to rootItem not being initialized."); compare(popOver.contentWidth, units.gu(40), "Content width is 40 GU"); } function test_contentHeight() { expectFail("", "Content height is wrong due to rootItem not being initialized."); compare(popOver.contentHeight, units.gu(2), "Content height is 1.9 GUs with the default theme"); } function test_pointerTarget() { compare(popOver.pointerTarget, popOver.caller, "pointerTarget is the same as caller"); } function test_edgeMargins() { compare(popOver.edgeMargins, units.gu(2), "Default edgeMargins are 2 GU"); } function test_callerMargin() { compare(popOver.callerMargin, 0, "Default callerMargin is 0"); } function test_autoClose() { compare(popOver.autoClose, true, "autoClose is set by default"); } // contentHeight testing is not possible as it follows clientRect height Popover { id: popOver Text { text: "Hello Popover!" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_subtitled.qml0000644000015301777760000000250612321005637032664 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsSubtitledAPI" function test_text() { compare(listItemSubtitled.text,"","text is '' by default") var newText = "Hello World!" listItemSubtitled.text = newText compare(listItemSubtitled.text,newText,"set/get") } function test_subText() { compare(listItemSubtitled.subText,"","subText is '' by default") var newText = "Hello World!" listItemSubtitled.subText = newText compare(listItemSubtitled.subText,newText,"set/get") } ListItem.Subtitled { id: listItemSubtitled } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_base.qml0000644000015301777760000000342012321005637031573 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsBaseAPI" function test_fallbackIconSource() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076762") compare(listItemBase.fallbackIconSource,undefined,"fallbackIconSource is not set by default") } function test_icon() { compare(listItemBase.icon,undefined,"icon is not set by default") // test with item listItemBase.icon = testItem compare(listItemBase.icon,testItem,"set/get from Item") // test with url var newIcon = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" listItemBase.icon = newIcon compare(listItemBase.icon,newIcon,"set/get from url") } function test_iconFrame() { compare(listItemBase.iconFrame,true,"iconFrame is true by default") } function test_progression() { compare(listItemBase.progression,false,"progression is false by default") } Rectangle { id: testItem } ListItem.Base { id: listItemBase } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_singlecontrol.qml0000644000015301777760000000224512321005637033547 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsSingleControlAPI" function test_control() { compare(listItemSingleControl.control,null,"control is null by default") listItemSingleControl.control = testControl compare(listItemSingleControl.control,testControl,"set/get") } AbstractButton { id: testControl } ListItem.SingleControl { id: listItemSingleControl } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_plugin_ucunits.qml0000644000015301777760000000331712321005637031641 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "UCUnitsAPI" function test_gridUnitChanged() { signalSpy.signalName = "gridUnitChanged"; compare(signalSpy.valid,true,"gridUnitChanged signal exists") } function test_gridUnit() { var readValue = units.gridUnit; units.gridUnit += 1.0; readValue += 1.0; compare(units.gridUnit,readValue,"can set/get value"); } function test_gu() { var testValue = 1.0; var readValue = units.gu(testValue); var calculatedValue = Math.round(testValue*units.gridUnit); compare(readValue,calculatedValue,"can use units.gu"); } function test_dp() { var testValue = 1.0; var default_grid_unit_px = 8; var readValue = units.dp(testValue); var calculatedValue = Math.round(testValue*units.gridUnit / default_grid_unit_px); compare(readValue,calculatedValue,"can use units.dp"); } SignalSpy { id: signalSpy target: units } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_header.qml0000644000015301777760000000206212321005637032112 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsHeaderAPI" function test_text() { compare(listItemHeader.text,"","text is '' by default") var newText = "Hello World!" listItemHeader.text = newText compare(listItemHeader.text,newText,"set/get") } ListItem.Header { id: listItemHeader } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_empty.qml0000644000015301777760000000322012321005637032015 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsEmptyAPI" function test_highlightWhenPressed() { compare(listItemEmpty.highlightWhenPressed,true,"highlightWhenPressed is true by default") listItemEmpty.highlightWhenPressed = false compare(listItemEmpty.highlightWhenPressed,false,"set/get") } function test_hovered() { compare(listItemEmpty.hovered,false,"hovered is false by default") } function test_pressed() { compare(listItemEmpty.pressed,false,"pressed is false by default") } function test_selected() { compare(listItemEmpty.selected,false,"selected is false by default") } function test_showDivider() { compare(listItemEmpty.showDivider,true,"showDivider is true by default") listItemEmpty.showDivider = false compare(listItemEmpty.showDivider,false,"set/get") } ListItem.Empty { id: listItemEmpty } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_ubuntushape.qml0000644000015301777760000000162712321005637031136 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "UbuntuShapeAPI" function test_radius() { compare(shape.radius, "small", "radius is a string and \"small\" by default") } UbuntuShape { id: shape } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_popups_defaultsheet.qml0000644000015301777760000000351312321005637032652 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 TestCase { name: "PopupsDefaultSheetAPI" function test_show() { defaultSheet.show() } function test_hide() { defaultSheet.hide() } function test_title() { compare(defaultSheet.title,"","title is not set by default") var newTitle = "Hello World!" defaultSheet.title = newTitle compare(defaultSheet.title,newTitle,"set/get") } function test_contentsWidth() { compare(defaultSheet.contentsWidth,units.gu(64),"contentsWidth is 64 grid units by default") } function test_contentsHeight() { compare(defaultSheet.contentsHeight,units.gu(40),"contentsHeight is 40 grid units by default") } function test_doneButton() { compare(defaultSheet.doneButton,false,"doneButton is set to false by default") var newValue = true defaultSheet.doneButton = newValue compare(defaultSheet.doneButton,newValue,"set/get") } function test_modal() { compare(defaultSheet.modal, true, "Sheets are modal by default"); } DefaultSheet { id: defaultSheet } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_valueselector.qml0000644000015301777760000000502712321005637033543 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsValueSelectorAPI" function test_expanded() { compare(listItemValueSelector.expanded,false,"expanded is false by default") } function test_fallbackIconSource() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076762") compare(listItemValueSelector.fallbackIconSource,undefined,"fallbackIconSource is not set by default") } function test_icon() { compare(listItemValueSelector.icon,undefined,"icon is not set by default") // test with item listItemValueSelector.icon = testItem compare(listItemValueSelector.icon,testItem,"set/get from Item") // test with url var newIcon = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" listItemValueSelector.icon = newIcon compare(listItemValueSelector.icon,newIcon,"set/get from url") } function test_iconFrame() { compare(listItemValueSelector.iconFrame,true,"iconFrame is true by default") } function test_text() { compare(listItemValueSelector.text,"","text is '' by default") var newText = "Hello World!" listItemValueSelector.text = newText compare(listItemValueSelector.text,newText,"set/get") } function test_selectedIndex() { compare(listItemValueSelector.selectedIndex,0,"selectedIndex is 0 by default") } function test_values() { compare(listItemValueSelector.values,undefined,"values is undefined by default") var newValues = ["value1","value2","value3"] listItemValueSelector.values = newValues compare(listItemValueSelector.values,newValues,"set/get") } Rectangle { id: testItem } ListItem.ValueSelector { id: listItemValueSelector } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_progressbar.qml0000644000015301777760000000363412321005637031124 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ProgressBarAPI" function test_indeterminate() { compare(progressBar.indeterminate,false,"is not set by default") var newIndeterminated = true progressBar.indeterminate = newIndeterminated compare(progressBar.indeterminate,newIndeterminated,"can set/get") } function test_maximumValue() { compare(progressBar.maximumValue,1.0,"is set to 1.0 by default") var newMaximumValue = 20.0 progressBar.maximumValue = newMaximumValue compare(progressBar.maximumValue,newMaximumValue,"can set/get") } function test_minimumValue() { compare(progressBar.minimumValue,0,"is set to 0 by default") var newMinimumValue = -20.0 progressBar.minimumValue = newMinimumValue compare(progressBar.minimumValue,newMinimumValue,"can set/get") } function test_value() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076764") compare(progressBar.value,0,"is set to 0 by default") var newValue = 5 progressBar.value = newValue compare(progressBar.value,newValue,"can set/get") } ProgressBar { id: progressBar } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_button.qml0000644000015301777760000000627412321005637030111 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ButtonAPI" function test_text() { compare(button.text,"","Button does not have text set by default") var newText = "Hello World!" button.text = newText compare(button.text,newText,"Can set/get text") } function test_action() { compare(actionButton.action, null, "Action is null by default") actionButton.action = action1 compare(actionButton.action, action1, "action can be set") var newText = "Hello action!" action1.text = newText compare(actionButton.text, newText, "action can be used to define text") var newIcon = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" action1.iconSource = newIcon compare(actionButton.iconSource, Qt.resolvedUrl(newIcon), "action can be used to define iconSource") } function test_iconPosition() { compare(button.iconPosition,"left","The default value for iconPosition is 'left'") var newIconPosition = "right" button.iconPosition = newIconPosition compare(button.iconPosition,newIconPosition) } function test_color() { var newColor = "#f00baa" button.color = newColor compare(button.color,newColor,"Can set/get color") } function test_hovered() { compare(button.hovered,false,"Hovered is boolean and false by default") } function test_iconSource() { compare(button.iconSource,"","iconSource is not set by default") var newIcon = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" button.iconSource = newIcon compare(button.iconSource,Qt.resolvedUrl(newIcon),"Can set/get iconSource") } function test_pressed() { compare(button.pressed,false,"Pressed is boolean and false by default") } function test_signal_clicked() { signalSpy.signalName = "clicked"; compare(signalSpy.valid,true,"clicked signal exists") } function test_signal_pressAndHold() { signalSpy.signalName = "pressAndHold"; compare(signalSpy.valid,true,"pressAndHold signal exists") } Button { id: button SignalSpy { id: signalSpy target: parent } } // Use a new button for action tests, because other tests override // the button's default text and iconSource so they are no longer // automatically taken from the action. Button { id: actionButton } Action { id: action1 } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_divider.qml0000644000015301777760000000165512321005637032317 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsDividerAPI" function test_divider() { verify((listItemDivider),"Divider can be loaded") } ListItem.Divider { id: listItemDivider } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_components.cpp0000644000015301777760000000131012321005637030736 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include QUICK_TEST_MAIN(components) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_page.qml0000644000015301777760000001436312321005637027510 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { width: 200 height: 200 Action { id: action0 } Flickable { id: testFlickable } MainView { anchors.fill: parent id: mainView Page { id: page Flickable { id: pageFlickable anchors.fill: parent contentHeight: column.height Column { id: column Repeater { model: 100 Label { text: "line "+index } } } } } } TestCase { name: "PageAPI" when: windowShown function initTestCase() { compare(page.title, "", "is not set by default") compare(page.__propagated, mainView.__propagated, "page propagated equals mainView propagated") compare(page.__propagated.header, mainView.__propagated.header, "page header equals mainView header") compare(page.__propagated.header.title, page.title, "header title is same as page title") compare(page.__propagated.header.visible, false, "header is not visible initially because there is no title") compare(page.actions.length, 0, "page actions list empty by default") } function test_0_noHeader_bug1162028_bug1161910() { compare(mainView.__propagated.header.title, "", "no header title by default") compare(mainView.__propagated.header.visible, false, "header is hidden when title is not set") compare(page.height, mainView.height, "page uses full height when there is no header") } function test_title() { var newTitle = "Hello World!" page.title = newTitle compare(page.title, newTitle, "can set/get") page.title = "" compare(page.title, "", "can unset") } function test_header() { var newTitle = "Hello header!" page.title = newTitle compare(mainView.__propagated.header.title, newTitle, "header title updated by changing page title") compare(mainView.__propagated.header.visible, true, "header is visible when title is set") compare(mainView.__propagated.header.height > 0, true, "header has a height when title is set") page.title = "" compare(mainView.__propagated.header.title, "", "header title unset by unsetting page title") compare(mainView.__propagated.header.visible, false, "header is hidden when title is unset") } function test_tools() { compare(mainView.__propagated.toolbar.tools, page.tools, "Page updates toolbar tools"); } function test_active() { compare(page.active, true, "Page is active by default"); } function test_pageStack() { compare(page.pageStack, null, "is not set by default") } function test_actions() { // FIXME: Check the contents of page.actions. This is currently not // possible because UnityActions.ActionContext.actions does not support it, // so changes to UnityActions are needed. page.actions = [action0]; compare(page.actions.length, 1, "Actions can be added to page actions"); page.actions = []; compare(page.actions.length, 0, "Page action list can be cleared"); } function test_flickable_bug1200642_bug1192591() { compare(page.flickable, pageFlickable, "page flickable is correctly detected"); compare(page.__propagated.header.flickable, pageFlickable, "header flickable is correctly detected"); // bug 1200642 FAIL page.flickable = testFlickable; compare(page.flickable, testFlickable, "flickable can be set"); compare(page.__propagated.header.flickable, testFlickable, "updating page flickable updates header flickable"); page.flickable = null; compare(page.flickable, null, "flickable can be unset"); compare(page.__propagated.header.flickable, null, "unsetting page flickable unsets header flickable"); } function test_flickableY_bug1201452() { var pageTitle = "Hello bug!"; page.title = pageTitle; var header = page.__propagated.header; compare(header.visible, true, "header is visible when title is set") compare(header.height > 0, true, "header has a height when title is set") var headerHeight = header.height var flickableY = 150; page.flickable.contentY = flickableY; compare(page.flickable.contentY, flickableY, "flickable.contentY can be set"); compare(page.flickable.topMargin, headerHeight, "topMargin of the flickable equals header height"); page.title = ""; compare(header.visible, false, "header is hidden when title is unset") compare(page.flickable.topMargin, 0, "topMargin becomes 0 because header is hidden"); // used to be headerHeight compare(page.flickable.contentY, flickableY + headerHeight, "contentY is updated when header is made invisible to compensate for the change in topMargin"); page.title = pageTitle; compare(page.flickable.contentY, flickableY, "Making header visible again does not reset flickable.contentY"); compare(page.flickable.topMargin, headerHeight, "topMargin is updated when header becomes visible.") } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_fontutils.qml0000644000015301777760000000427512321005637030624 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "FontUtilsAPI" function test_modularScale() { compare(FontUtils.modularScale("xx-small"), 0.606, "xx-small scale"); compare(FontUtils.modularScale("x-small"), 0.707, "x-small scale"); compare(FontUtils.modularScale("small"), 0.857, "small scale"); compare(FontUtils.modularScale("medium"), 1.0, "medium scale"); compare(FontUtils.modularScale("large"), 1.414, "large scale"); compare(FontUtils.modularScale("x-large"), 1.905, "x-large scale"); } function test_modularScale_failures() { compare(FontUtils.modularScale("xxsmall"), 0.0, "xxsmall not defined"); compare(FontUtils.modularScale("undefined"), 0.0, "undefined scale"); } function test_sizeToPixels() { compare(FontUtils.sizeToPixels("xx-small"), 0.606 * units.dp(14), "xx-small scale"); compare(FontUtils.sizeToPixels("x-small"), 0.707 * units.dp(14), "x-small scale"); compare(FontUtils.sizeToPixels("small"), 0.857 * units.dp(14), "small scale"); compare(FontUtils.sizeToPixels("medium"), 1.0 * units.dp(14), "medium scale"); compare(FontUtils.sizeToPixels("large"), 1.414 * units.dp(14), "large scale"); compare(FontUtils.sizeToPixels("x-large"), 1.905 * units.dp(14), "x-large scale"); } function test_sizeToPixels_failures() { compare(FontUtils.sizeToPixels("xxsmall"), 0.0, "xxsmall not defined"); compare(FontUtils.sizeToPixels("undefined"), 0.0, "undefined scale"); } } ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_popups_actionselectionpopover.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_popups_actionselectionpopove0000644000015301777760000000236112321005637034021 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 TestCase { name: "PopupsActionSelectionPopoverAPI" ActionSelectionPopover { id: popOver } function test_target() { compare(popOver.target, null, "Target is undefined by default"); } function test_actions() { compare(popOver.actions, undefined, "Actions are undefined by default"); } function test_delegate() { expectFail("", "Delegate should not be undefined by default"); compare(popOver.delegate, undefined, "popOver.delegate"); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_popups_dialog.qml0000644000015301777760000000376212321005637031442 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 TestCase { name: "PopupsDialogAPI" function test_show() { dialog.show() } function test_hide() { dialog.hide() } function test_caller() { compare(dialog.caller,null,"caller is not set by default") } function test_text() { compare(dialog.text,"","text is not set by default") var newText = "Hello World!" dialog.text = newText compare(dialog.text,newText,"set/get") } function test_title() { compare(dialog.title,"","title is not set by default") var newTitle = "Hello World!" dialog.title = newTitle compare(dialog.title,newTitle,"set/get") } function test_contentWidth() { expectFail("", "Content width is wrong due to rootItem not being initialized."); compare(dialog.contentWidth, units.gu(40), "Content width is 40 GU"); } function test_edgeMargins() { compare(dialog.edgeMargins, units.gu(2), "Default edgeMargins are 2 GU"); } function test_callerMargin() { compare(dialog.callerMargin, units.gu(1), "Default callerMargin is 1 GU"); } function test_modal() { compare(dialog.modal, true, "Dialogs are modal by default"); } Dialog { id: dialog } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_quickutils.qml0000644000015301777760000000240412321005637030762 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 Item { id: root width: units.gu(40) height: units.gu(40) TestCase { id: test name: "QuickUtilsAPI" when: windowShown function test_rootItem() { compare(QuickUtils.rootItem(test) != 0, true, "Root item is not null"); } function test_className() { compare(QuickUtils.className(test), "TestCase", "className for TestCase"); compare(QuickUtils.className(root), "QQuickItem", "className for Item"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_toolbaritems.qml0000644000015301777760000001002012321005637031262 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { width: 200 height: 200 MainView { anchors.fill: parent PageStack { id: pageStack0 } Page { id: page0 tools: ToolbarItems { id: emptyToolbarItems } } Page { id: page1 tools: ToolbarItems { id: toolbarItems ToolbarButton { id: button } } } } TestCase { name: "ToolbarItemsAPI" when: windowShown function initTestCase() { compare(toolbarItems.pageStack, null, "pageStack initially null"); compare(toolbarItems.locked, false, "toolbar items unlocked with children"); compare(emptyToolbarItems.locked, true, "toolbar items unlocked without visible children"); compare(toolbarItems.back === undefined, false, "back item set by default"); compare(toolbarItems.back.hasOwnProperty("text"), true, "back item has text property"); compare(toolbarItems.back.hasOwnProperty("visible"), true, "back item has visible property"); } function test_opened() { compare(toolbarItems.opened, true, "Toolbar items opened when page is first loaded"); toolbarItems.opened = false; compare(toolbarItems.opened, false, "Toolbar items can be closed"); toolbarItems.opened = true; compare(toolbarItems.opened, true, "Toolbar items can be opened"); } function test_locked() { compare(emptyToolbarItems.locked, true, "Toolbar items initially locked for empty toolbar"); compare(toolbarItems.locked, false, "Toolbar items initially unlocked for non-empty toolbar"); toolbarItems.locked = true; compare(toolbarItems.locked, true, "Toolbar items can be locked"); toolbarItems.locked = false; compare(toolbarItems.locked, false, "Toolbar items can be unlocked"); } function test_back() { compare(pageStack0.depth, 0, "pageStack is empty by default"); compare(page0.tools.back.visible, false, "back item not visible without pageStack"); compare(page0.tools.pageStack, null, "back.pageStack null by default"); pageStack0.push(page0); compare(pageStack0.depth, 1, "pageStack.depth == 1 after pushing one page"); compare(page0.tools.pageStack, pageStack0, "pushing a page updates the pageStack of tools item"); compare(page0.tools.back.visible, false, "back item not visible with only one page on the stack"); pageStack0.push(page1); compare(pageStack0.depth, 2, "pageStack.depth == 2 after pushing two pages"); compare(page1.tools.pageStack, pageStack0, "pushing a page updates the pageStack of tools item"); compare(page1.tools.back.visible, true, "back item visible with two pages on the stack"); pageStack0.pop(); compare(pageStack0.depth, 1, "pageStack.depth == 1 after popping second page"); compare(page0.tools.back.visible, false, "back item not visible with only one page on the stack"); pageStack0.pop(); compare(pageStack0.depth, 0, "pageStack is empty after popping both pages"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_multivalue.qml0000644000015301777760000000255412321005637033057 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsMultiValueAPI" function test_text() { compare(listItemMultiValue.text,"","text is '' by default") var newText = "Hello World!" listItemMultiValue.text = newText compare(listItemMultiValue.text,newText,"set/get") } function test_values() { compare(listItemMultiValue.values,undefined,"values is undefined by default") var newValues = ["value1","value2","value3"] listItemMultiValue.values = newValues compare(listItemMultiValue.values,newValues,"set/get") } ListItem.MultiValue { id: listItemMultiValue } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_CrossFadeImage.qml0000644000015301777760000000761512321005637031412 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "CrossFadeImage" property alias status: crossFadeImage.status property alias source: crossFadeImage.source property alias running: crossFadeImage.running property alias fadeDuration: crossFadeImage.fadeDuration CrossFadeImage { id: crossFadeImage } SignalSpy { id: signalSpy target: crossFadeImage } CrossFadeImage { id: crossFadeImagePreset sourceSize { width: 123 height: 321 } source: Qt.resolvedUrl("../../../examples/ubuntu-ui-toolkit-gallery/demo_image.jpg") } function loadImage(url) { console.log("Loading image..."); source = url; signalSpy.signalName = "statusChanged"; if (status == Image.Null) { signalSpy.clear(); signalSpy.wait(); } if (status == Image.Loading) { signalSpy.clear(); signalSpy.wait(); } compare(status, Image.Ready, "Image not ready"); console.log("Image loaded."); } function waitForAnimation() { signalSpy.signalName = "runningChanged"; if (!running) { signalSpy.clear(); signalSpy.wait(); compare(running, true, "Animation did not start"); } signalSpy.clear(); console.log("Waiting for animation to finish..."); signalSpy.wait(); compare(running, false, "Animation did not stop within 5 seconds."); } function cleanupTest() { fadeDuration = UbuntuAnimation.FastDuration ; // default compare(running, false, "Animation is running after testcase"); } function test_fade() { loadImage("../../../examples/ubuntu-ui-toolkit-gallery/demo_image.jpg"); loadImage("../../../examples/ubuntu-ui-toolkit-gallery/map_icon.png"); waitForAnimation(); cleanupTest(); } function test_fadeDuration() { fadeDuration = UbuntuAnimation.SleepyDuration; loadImage("../../../examples/ubuntu-ui-toolkit-gallery/demo_image.jpg"); loadImage("../../../examples/ubuntu-ui-toolkit-gallery/map_icon.png"); sleep(UbuntuAnimation.SleepyDuration / 2); // < fadeDuration compare(running, true, "Animation stopped before 1000 ms"); waitForAnimation(); cleanupTest(); } function test_sourceSize() { loadImage("../../../examples/ubuntu-ui-toolkit-gallery/demo_image.jpg"); compare(crossFadeImage.sourceSize.width, 640, "Source width incorrectly initialized."); compare(crossFadeImage.sourceSize.height, 427, "Source height incorrectly initialized."); crossFadeImage.sourceSize.width = 100; crossFadeImage.sourceSize.height = 101; compare(crossFadeImage.sourceSize.width, 100, "Source width incorrectly updated."); compare(crossFadeImage.sourceSize.height, 101, "Source height incorrectly updated."); waitForAnimation(); cleanupTest(); } function test_sourcePreset() { compare(crossFadeImagePreset.sourceSize.width, 123, "Source width incorrectly taken from preset."); compare(crossFadeImagePreset.sourceSize.height, 321, "Source height incorrectly take from preset."); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_pagestack.qml0000644000015301777760000001142712321005637030534 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "PageStackAPI" function initTestCase() { compare(pageStack.currentPage, null, "is not set by default"); compare(pageStack.__propagated, mainView.__propagated, "propagated property of pageStack equals mainView.__propagated") compare(mainView.__propagated.toolbar.tools, null, "no tools by default"); compare(mainView.__propagated.header.title, "", "empty title by default"); } function test_depth() { compare(pageStack.depth, 0, "depth is 0 by default"); pageStack.push(page1); compare(pageStack.depth, 1, "depth is correctly increased when pushing a page"); pageStack.push(page2); compare(pageStack.depth, 2, "depth is correctly updated when pushing a page"); pageStack.pop(); compare(pageStack.depth, 1, "depth is correctly decreased when popping a page"); pageStack.clear(); compare(pageStack.depth, 0, "depth is after clearing"); } function test_currentPage() { compare(pageStack.currentPage, null, "currentPage is null by default"); pageStack.push(page1); compare(pageStack.currentPage, page1, "currentPage properly updated"); pageStack.clear(); compare(pageStack.currentPage, null, "currentPage properly reset"); } function test_active() { pageStack.push(page1); compare(page1.active, true, "Page is active after pushing"); pageStack.push(page2); compare(page1.active, false, "Page no longer active after pushing a new page"); compare(page2.active, true, "New page is active after pushing"); pageStack.pop(); compare(page1.active, true, "Page re-activated when on top of the stack"); compare(page2.active, false, "Page no longer active after being popped"); pageStack.clear(); } function test_title_bug1143345() { pageStack.push(page1); compare(mainView.__propagated.header.title, "Title 1", "Header is correctly set by page"); page1.title = "New title"; compare(mainView.__propagated.header.title, "New title", "Header title correctly updated by page"); pageStack.push(page2); compare(mainView.__propagated.header.title, "Title 2", "Header is correctly set by page"); pageStack.clear(); page1.title = "Title 1"; } function test_tools_bug1126197() { pageStack.push(page1); compare(mainView.__propagated.toolbar.tools, page1.tools, "Page successfully updated toolbar tools"); pageStack.push(page2); compare(mainView.__propagated.toolbar.tools, page2.tools, "Page successfully updated toolbar tools again"); pageStack.pop(); compare(mainView.__propagated.toolbar.tools, page1.tools, "Tools updated after popping a page"); pageStack.clear(); } function test_tabs_inside_stack_bug1187850() { pageStack.push(tabs); compare(pageStack.currentPage, tabs, "Tabs can be pushed on a PageStack"); compare(tabs.active, true, "Tabs on top of a PageStack are active"); compare(mainView.__propagated.header.contents, tabs.tabBar, "Pushing Tabs on PageStack updates the header contents"); pageStack.push(page1); compare(pageStack.currentPage, page1, "A page can be pushed on top of a Tabs"); compare(tabs.active, false, "Tabs on a PageStack, but not on top, are inactive"); compare(mainView.__propagated.header.contents, null, "Contents of inactive Tabs is not applied to header"); pageStack.pop(); compare(tabs.active, true, "Tabs on top of PageStack is active"); compare(mainView.__propagated.header.contents, tabs.tabBar, "Active Tabs controls header contents"); pageStack.clear(); } MainView { id: mainView PageStack { id: pageStack } } Page { id: page1 title: "Title 1" tools: ToolbarItems { id: tools1 } } Page { id: page2 title: "Title 2" tools: ToolbarItems { id: tools2 } } Tabs { id: tabs } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_popups_composersheet.qml0000644000015301777760000000312312321005637033052 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 TestCase { name: "PopupsComposerSheetAPI" function test_show() { composerSheet.show() } function test_hide() { composerSheet.hide() } function test_title() { compare(composerSheet.title,"","title is not set by default") var newTitle = "Hello World!" composerSheet.title = newTitle compare(composerSheet.title,newTitle,"set/get") } function test_contentsWidth() { compare(composerSheet.contentsWidth,units.gu(64),"contentsWidth is 64 grid units by default") } function test_contentsHeight() { compare(composerSheet.contentsHeight,units.gu(40),"contentsHeight is 40 grid units by default") } function test_modal() { compare(composerSheet.modal, true, "Sheets are modal by default"); } ComposerSheet { id: composerSheet } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_switch.qml0000644000015301777760000000240412321005637030066 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "SwitchAPI" function test_checked() { compare(switchComponent.checked,false,"checked is false by default") switchComponent.checked = true compare(switchComponent.checked,true,"Can set/get checked") } function test_hovered() { compare(switchComponent.hovered,false,"Hovered is boolean and false by default") } function test_pressed() { compare(switchComponent.pressed,false,"Pressed is boolean and false by default") } Switch { id: switchComponent } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_checkbox.qml0000644000015301777760000000433612321005637030361 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Unity.Action 1.1 as UnityActions TestCase { name: "CheckBoxAPI" function test_checked() { compare(checkbox.checked,false,"CheckBox.checked is false by default") checkbox.checked = true compare(checkbox.checked,true,"Can set/get checked") } function test_hovered() { compare(checkbox.hovered,false,"Hovered is boolean and false by default") } function test_pressed() { compare(checkbox.pressed,false,"Pressed is boolean and false by default") } function test_triggered() { checkbox.checked = false checkbox.clicked() signalSpy.wait() compare(checkbox.checked, true, "click flipped from unchecked to checked") checkbox.clicked() signalSpy.wait() compare(checkbox.checked, false, "click flipped from checked back to unchecked") // clicked and trigger both flip the checked state checkbox.trigger() signalSpy.wait() compare(checkbox.checked, true, "trigger flipped from unchecked to checked") checkbox.trigger() signalSpy.wait() compare(checkbox.checked, false, "trigger flipped from checked back to unchecked") } CheckBox { id: checkbox action: Action { enabled: true name: "check" text: "Check" parameterType: UnityActions.Action.Boolean } } SignalSpy { id: signalSpy signalName: "triggered" target: checkbox } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_slider.qml0000644000015301777760000000507212321005637030053 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "SliderAPI" function test_live() { compare(slider.live,false,"Live is boolean and false by default") var newLive = true slider.live = newLive compare(slider.live,newLive,"can set/get") } function test_maximumValue() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076764") compare(slider.maximumValue,1.0,"is set to 1.0 by default") var newMaximumValue = 20.0 slider.maximumValue = newMaximumValue compare(slider.maximumValue,newMaximumValue,"can set/get") } function test_minimumValue() { compare(slider.minimumValue,0,"is set to 0 by default") var newMinimumValue = -20.0 slider.minimumValue = newMinimumValue compare(slider.minimumValue,newMinimumValue,"can set/get") } function test_value() { compare(slider.value,0,"is set to 0 by default") var newValue = 5 slider.value = newValue compare(slider.value,newValue,"can set/get") } // SliderUtils API tests function test_zzz_liveValue() { slider.live = true slider.minimumValue = 0.0 slider.maximumValue = 1.0 slider.value = 0.2 compare(slider.value, SliderUtils.liveValue(slider), "are identical") } function test_zzz_normalizedValue() { slider.live = true slider.minimumValue = 0.0 slider.maximumValue = 1.0 slider.value = 0.2557 compare(slider.value, SliderUtils.normalizedValue(slider), "are identical") } function test_signal_touched() { signalSpy.signalName = "touched"; compare(signalSpy.valid,true,"touched signal exists") } Slider { id: slider SignalSpy { id: signalSpy target: parent } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_abstractbutton.qml0000644000015301777760000000370112321005637031625 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "AbstractButtonAPI" function test_action() { compare(absButton.action, null,"Action is null by default") absButton.action = action1 compare(absButton.action, action1, "Action can be set") var numTriggers = action1.triggerCount absButton.clicked() compare(action1.triggerCount, numTriggers+1, "Button clicked triggers action") absButton.action = null } function test_hovered() { compare(absButton.hovered,false,"Hovered is boolean and false by default") } function test_pressed() { compare(absButton.pressed,false,"Pressed is boolean and false by default") } function test_signal_clicked() { signalSpy.signalName = "clicked"; compare(signalSpy.valid,true,"clicked signal exists") } function test_signal_pressAndHold() { signalSpy.signalName = "pressAndHold"; compare(signalSpy.valid,true,"pressAndHold signal exists") } AbstractButton { id: absButton SignalSpy { id: signalSpy target: parent } } Action { id: action1 property int triggerCount: 0 onTriggered: triggerCount++ } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_label.qml0000644000015301777760000000466412321005637027656 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "LabelAPI" function test_fontSize() { compare(textCustom.fontSize,"medium","fontSize is 'medium' by default") var fontSizes = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large" ] for (var i=0;i. */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 /* Implementation note: We use Date(year, month, day) everywhere, Date(format) cannot be used as of Qt 5.2 */ TestCase { name: "DateUtilsAPI" function test_midnight() { var midnight = Date.prototype.midnight.call(new Date); compare(midnight.getHours(), 0, "hour is zero"); compare(midnight.getMinutes(), 0, "minutes is zero"); compare(midnight.getSeconds(), 0, "seconds is zero"); midnight = new Date(); var date = midnight.midnight(); compare(midnight.getHours(), 0, "hour is zero"); compare(midnight.getMinutes(), 0, "minutes is zero"); compare(midnight.getSeconds(), 0, "seconds is zero"); compare(date.getHours(), 0, "hour is zero"); compare(date.getMinutes(), 0, "minutes is zero"); compare(date.getSeconds(), 0, "seconds is zero"); } function test_getInvalidDate() { var date = Date.prototype.getInvalidDate.call(); verify(date.getFullYear() < 0, "year is invalid"); } function test_0isValid() { compare((new Date()).isValid(), true, "any date is valid"); compare((new Date(-1, -1)).isValid(), false, "a year and month set to -1 is invalid"); compare((Date.prototype.getInvalidDate.call()).isValid(), false, "getInvalidDate() returns an invalid date"); compare(Date.prototype.isValid.call(null), false, "null date is invalid"); compare(Date.prototype.isValid.call(undefined), false, "undefined date is invalid"); } function test_daysInMonth_data() { var date = new Date; return [ { "month": 0, "days": 31 }, { "month": 1, "days": 28 + (date.leapYear() ? 1 : 0) }, { "month": 2, "days": 31 }, { "month": 3, "days": 30 }, { "month": 4, "days": 31 }, { "month": 5, "days": 30 }, { "month": 6, "days": 31 }, { "month": 7, "days": 31 }, { "month": 8, "days": 30 }, { "month": 9, "days": 31 }, { "month": 10, "days": 30 }, { "month": 11, "days": 31 }, ]; } function test_daysInMonth(data) { var date = new Date; date.setDate(1); date.setMonth(data.month); compare(date.daysInMonth(), data.days, "daysInMonth() failed for month " + (data.month + 1)); } function test_leapYear_data() { return [ {"year": 2013, "result": false}, {"year": 2100, "result": false}, {"year": 2000, "result": true}, {"year": 2004, "result": true}, ]; } function test_leapYear(data) { var date = new Date(data.year, 0, 1) compare(date.leapYear(), data.result, "leapYear() failed for " + data.year); } function test_monthsTo_data() { return [ {"from": new Date(2000, 0, 1), "to": new Date(2000, 0, 31), "result": 0}, {"from": new Date(2000, 0, 1), "to": new Date(2000, 1, 1), "result": 1}, {"from": new Date(2000, 0, 31), "to": new Date(2000, 1, 1), "result": 1}, {"from": new Date(2000, 0, 31), "to": new Date(2001, 0, 1), "result": 12}, {"from": new Date(2000, 0, 31), "to": new Date(2002, 0, 31), "result": 24}, ]; } function test_monthsTo(data) { compare(data.from.monthsTo(data.to), data.result, "monthsTo() failed for " + Qt.formatDate(data.from, "yyyy/MM/dd") + " - " + Qt.formatDate(data.to, "yyyy/MM/dd")); } function test_daysTo_data() { return [ {"from": new Date(2000, 0, 1), "to": new Date(2000, 0, 31), "result": 30}, {"from": new Date(2000, 0, 1), "to": new Date(2000, 1, 1), "result": 31}, {"from": new Date(2000, 0, 31), "to": new Date(2000, 1, 1), "result": 1}, {"from": new Date(2000, 0, 1), "to": new Date(2001, 0, 1), "result": 366}, // 2000 is a leap year {"from": new Date(2000, 0, 1), "to": new Date(2000, 0, 2), "result": 1}, {"from": new Date(2000, 6, 1), "to": new Date(2000, 8, 1), "result": 62}, ]; } function test_daysTo(data) { compare(data.from.daysTo(data.to), data.result, "daysTo() failed for " + Qt.formatDate(data.from, "yyyy/MM/dd") + " - " + Qt.formatDate(data.to, "yyyy/MM/dd")); } function test_getWeek_data() { return [ {"date": new Date(2013, 0, 1), "week": 1}, {"date": new Date(2012, 11, 31), "week": 1}, {"date": new Date(2013, 11, 3), "week": 49}, {"date": new Date(2013, 11, 31), "week": 1}, {"date": new Date(2011, 11, 31), "week": 52}, ]; } function test_getWeek(data) { compare(data.date.getWeek(), data.week, "getWeek() failed for " + Qt.formatDate(data.date, "yyyy/MM/dd")); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_listitems_thindivider.qml0000644000015301777760000000170012321005637033171 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components.ListItems 0.1 as ListItem TestCase { name: "ListItemsThinDividerAPI" function test_divider() { verify((listItemThinDivider),"ThinDivider can be loaded") } ListItem.ThinDivider { id: listItemThinDivider } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_scrollbar.qml0000644000015301777760000000516112321005637030553 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ScrollbarAPI" function initTestCase() { } function test_a() { compare(scrollbar.flickableItem, null, "Scrollbar does not have flickableItem set by default") var defaultAlign = Qt.AlignRight compare(scrollbar.align, defaultAlign, "Scrollbar is aligned to the right by default") } function test_flickableItem_Flickable() { scrollbar.flickableItem = flickable compare(scrollbar.flickableItem, flickable, "Cannot get/set flickableItem property") } function test_flickableItem_ListView() { scrollbar.flickableItem = listView compare(scrollbar.flickableItem, listView, "Cannot get/set flickableItem property") } function test_align_left() { scrollbar.align = Qt.AlignLeft compare(scrollbar.align, Qt.AlignLeft, "Cannot get/set align property") } function test_align_top() { scrollbar.align = Qt.AlignTop compare(scrollbar.align, Qt.AlignTop, "Cannot get/set align property") } function test_align_right() { scrollbar.align = Qt.AlignRight compare(scrollbar.align, Qt.AlignRight, "Cannot get/set align property") } function test_align_bottom() { scrollbar.align = Qt.AlignBottom compare(scrollbar.align, Qt.AlignBottom, "Cannot get/set align property") } function test_nonFlickable() { var failed = false try { scrollbar.flickableItem = nonFlickable } catch (e) { failed = true } finally { compare(failed,true,"can not set non-flickable item to flickableItem") } } Rectangle { id: nonFlickable } Flickable{ id: flickable } ListView { id: listView } Scrollbar { id: scrollbar SignalSpy { id: signals signalName: "styleChanged" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_components.pro0000644000015301777760000000023412321005637030760 0ustar pbusernogroup00000000000000TESTS += $$system(ls tst_*.qml) include(../qmltest-include.pri) TARGET = tst_components SOURCES += tst_components.cpp OTHER_FILES += $$system(ls *.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_clipboard.qml0000644000015301777760000001012512321005637030523 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ClipboardAPI" function initTestCase() { // clear the clipboard Clipboard.clear(); } function test_0_formats() { compare(Clipboard.data.formats, [], "Empty clipboard formats is empty"); } function test_clipboard_push_data() { return [ {tag: "text data", property: "text", data: "test string", result: "test string", expectFail: false}, {tag: "HTML data", property: "html", data: testHtml, result: testHtml, expectFail: false}, {tag: "URL list", property: "urls", data: testUrls, result: testUrls, expectFail: false}, {tag: "Color data", property: "color", data: testColor, result: testColor, expectFail: false}, {tag: "MIME data1", property: "data", data: mimeData1, result: mimeData1, expectFail: false}, // note that result of mimeData2 should be mimeData1 (the returned // list of mime datas is always a single list) {tag: "MIME data2", property: "data", data: mimeData2, result: mimeData1, expectFail: false}, ]; } function test_clipboard_push(data) { if (data.expectFail) expectFail("", data); Clipboard.clear(); Clipboard.push(data.data); compare(Clipboard.data[data.property], data.result, data.tag); } function test_clipboard_push_standalone() { Clipboard.clear(); Clipboard.push(standalone); compare(Clipboard.data.text, standalone.text, "Standalone text"); compare(Clipboard.data.html, standalone.html, "Standalone HTML"); compare(Clipboard.data.urls, standalone.urls, "Standalone URL list"); compare(Clipboard.data.color, standalone.color, "Standalone color"); standalone.text = "Modified text"; Clipboard.push(standalone); compare(Clipboard.data.text, standalone.text, "Standalone text"); } function test_push_color() { Clipboard.push(testColor); compare(Clipboard.data.color, "#ff0000", "Color pushed"); Clipboard.push(["application/x-color", "green"]); compare(Clipboard.data.color, standalone.color, "Color pushed"); } MimeData { id: standalone text: "Standalone text" html: testHtml urls: testUrls color: "green" data: [ "application/x-color", "blue", "text/richtext", "This is a rich text" ] } property string testHtml: " Title of the document The content of the document...... " property color testColor: "red" property url testUrl: Qt.resolvedUrl("tst_clipboard.qml") property var testUrls: [testUrl, "http://www.canonical.com", "http://www.google.com"] property var mimeData1: [ "text/plain", "this is a plain text", "application/x-color", "blue", "text/richtext", "This is a rich text" ] property var mimeData2: [ ["text/plain", "this is a plain text"], ["application/x-color", "blue"], ["text/richtext", "This is a rich text"] ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_components/tst_actionitem.qml0000644000015301777760000000674112321005637030731 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 TestCase { name: "ActionItemAPI" function initTestCase() { compare(item1.action, null, "action is null by default") compare(item1.text, "", "text is empty string set by default") compare(item1.iconSource, "", "iconSource is empty string by default") } function test_action() { compare(item1.action, null,"Action is null by default") item1.action = action1 compare(item1.action, action1, "Action can be set") compare(item1.text, action1.text, "text is automatically set to action text") compare(item1.iconSource, action1.iconSource, "iconSource is automatically set to action iconSource") var numTriggers = action1.triggerCount item1.triggered(null) compare(action1.triggerCount, numTriggers+1, "ActionItem triggered() triggers action") item1.action = null } // NOTE: This test must be run AFTER test_action(), otherwise setting the action will // not update the text function test_text() { compare(item1.text, "", "text is empty string by default") var newText = "new text" item1.text = newText compare(item1.text, newText, "text can be set") item1.text = "" compare(item1.text, "", "text can be unset") } // NOTE: This test must be run AFTER test_action(), otherwise setting the action will // will not update the iconSource function test_iconSource() { compare(item1.iconSource, "", "iconSource is empty string by default") var newIconSource = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" item1.iconSource = newIconSource compare(item1.iconSource, Qt.resolvedUrl(newIconSource), "iconSource can be set") item1.iconSource = "" compare(item1.iconSource, "", "iconSource can be unset") } // NOTE: This test must be run AFTER test_action(), otherwise setting the action will // will not update the iconName function test_iconName() { compare(item1.iconName, "", "iconName is empty string by default") var newIconName = "compose" item1.iconName = newIconName compare(item1.iconName, newIconName, "iconName can be set") item1.iconName = "" compare(item1.iconName, "", "iconName can be unset") } function test_signal_triggered() { signalSpy.signalName = "triggered"; compare(signalSpy.valid,true,"triggered signal exists") } ActionItem { id: item1 SignalSpy { id: signalSpy target: parent } } Action { id: action1 text: "actionText" iconSource: "imageURL" property int triggerCount: 0 onTriggered: triggerCount++ } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_arguments/0000755000015301777760000000000012321006415024773 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_arguments/tst_arguments.cpp0000644000015301777760000004612612321005637030414 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #define protected public #include "ucarguments.h" #undef protected #include #include #include #include #include class tst_UCArguments : public QObject { Q_OBJECT public: tst_UCArguments() : m_application(NULL) {} private: QVector m_arguments; int m_argumentsSize; QCoreApplication* m_application; void clearCommandLine() { m_arguments.clear(); m_argumentsSize = 0; if (m_application != NULL) { delete m_application; m_application = NULL; } } void setCommandLine(QString commandLine) { clearCommandLine(); QStringList arguments = QString(commandLine).split(' ', QString::SkipEmptyParts); Q_FOREACH (QString argument, arguments) { QByteArray text = argument.toLocal8Bit(); char *data = new char[text.size() + 1]; strcpy(data, text.data()); m_arguments.append(data); } char* binaryName = (char*)"binary"; m_arguments.prepend(binaryName); m_argumentsSize = m_arguments.size(); m_application = new QCoreApplication(m_argumentsSize, m_arguments.data()); } void testCommandLine(QString commandLine, bool expectedError, QString dataTag=QString()) { if (dataTag.isEmpty()) { dataTag = commandLine; } QTest::newRow(dataTag.toLocal8Bit().constData()) << commandLine << expectedError; } void testCommandLineForUnicode(QString argumentValue) { QTest::newRow(argumentValue.toLocal8Bit().constData()) << QString("--unicodeArgument ").append(argumentValue) << argumentValue; } private Q_SLOTS: void testNoArguments() { QFETCH(QString, commandLine); QFETCH(bool, error); setCommandLine(commandLine); UCArguments arguments; arguments.componentComplete(); QCOMPARE(arguments.error(), error); } void testNoArguments_data() { QTest::addColumn("commandLine"); QTest::addColumn("error"); testCommandLine("", false, "NO ARGUMENTS"); testCommandLine("--boolArgument", false); testCommandLine("--boolArgument --boolArgument", false); testCommandLine("--boolArgument --otherBool", false); testCommandLine("--boolArgument --otherArg1=value --otherArg2 value", false); testCommandLine("--boolArgument --otherArg=value defaultValue1 defaultValue2", false); testCommandLine("--otherArg=value --boolArgument defaultValue1 defaultValue2", false); testCommandLine("--otherArg=value defaultValue1 defaultValue2 --boolArgument", false); testCommandLine("--otherArg=value defaultValue1 defaultValue2", false); } void testUsage() { QFETCH(QString, commandLine); QFETCH(bool, error); setCommandLine(commandLine); UCArguments arguments; arguments.componentComplete(); QCOMPARE(arguments.error(), error); } void testUsage_data() { QTest::addColumn("commandLine"); QTest::addColumn("error"); testCommandLine("", false, "NO ARGUMENTS"); testCommandLine("--usage", true); testCommandLine("--help", true); testCommandLine("-h", true); testCommandLine("--boolArgument --usage", true); testCommandLine("--boolArgument --otherArgument --usage", true); testCommandLine("--usage --boolArgument --otherArgument", true); } void testUnicodeArgument() { /* Pretend that the system is UTF-8 so that the inputted command line * that is itself UTF-8 is correctly decoded by Qt. */ QTextCodec* previousCodec = QTextCodec::codecForLocale(); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QFETCH(QString, commandLine); QFETCH(QString, expectedValue); setCommandLine(commandLine); UCArguments arguments; QStringList valueNames; valueNames << "VALUE1"; UCArgument unicodeArgument; unicodeArgument.setName("unicodeArgument"); unicodeArgument.setValueNames(valueNames); arguments.appendArguments(&unicodeArgument); arguments.componentComplete(); QCOMPARE(arguments.values()->property("unicodeArgument").type(), QVariant::String); QCOMPARE(arguments.values()->property("unicodeArgument").toString(), expectedValue); QTextCodec::setCodecForLocale(previousCodec); } void testUnicodeArgument_data() { QTest::addColumn("commandLine"); QTest::addColumn("expectedValue"); testCommandLineForUnicode(QString("DIRECCIÓN")); testCommandLineForUnicode(QString("ファイル名を")); testCommandLineForUnicode(QString("☭☢€→☎❄♫✂▷✇♎⇧☮♻⌘⌛☘")); testCommandLineForUnicode(QString("file://Vidéos/Le.goût.des.autres.-.DIVX[www.makingoff.org]")); } void testOneRequiredNamedBoolArgument() { QFETCH(QString, commandLine); QFETCH(bool, error); setCommandLine(commandLine); UCArguments arguments; UCArgument boolArgument; boolArgument.setName("boolArgument"); arguments.appendArguments(&boolArgument); arguments.componentComplete(); QCOMPARE(arguments.values()->property("boolArgument").type(), QVariant::Bool); QCOMPARE(arguments.values()->property("boolArgument"), QVariant(!error)); QCOMPARE(arguments.error(), error); } void testOneRequiredNamedBoolArgument_data() { QTest::addColumn("commandLine"); QTest::addColumn("error"); testCommandLine("", true, "NO ARGUMENTS"); testCommandLine("--boolArgument", false); testCommandLine("--boolArgument --boolArgument", false); testCommandLine("--boolArgument --otherBool", false); testCommandLine("--boolArgument --otherArg1=value --otherArg2 value", false); testCommandLine("--boolArgument --otherArg=value defaultValue1 defaultValue2", false); testCommandLine("--otherArg=value --boolArgument defaultValue1 defaultValue2", false); testCommandLine("--otherArg=value defaultValue1 defaultValue2 --boolArgument", false); testCommandLine("--otherArg=value defaultValue1 defaultValue2", true); } void testOneRequiredNamedArgument() { QFETCH(QString, commandLine); QFETCH(bool, error); setCommandLine(commandLine); UCArguments arguments; QStringList valueNames; valueNames << "VALUE1"; UCArgument argument1; argument1.setName("argument1"); argument1.setValueNames(valueNames); arguments.appendArguments(&argument1); arguments.componentComplete(); QCOMPARE(arguments.error(), error); if (!error) { QCOMPARE(arguments.values()->property("argument1").type(), QVariant::String); QCOMPARE(arguments.values()->property("argument1").toString(), QString("value1")); } else { QCOMPARE(arguments.values()->property("argument1").type(), QVariant::Invalid); } } void testOneRequiredNamedArgument_data() { QTest::addColumn("commandLine"); QTest::addColumn("error"); testCommandLine("", true, "NO ARGUMENTS"); testCommandLine("--argument1=value1", false); testCommandLine("--argument1 value1", false); testCommandLine("--otherArgument --argument1 value1", false); testCommandLine("--argument1 value1 --otherArgument", false); testCommandLine("--argument1 value1 defaultValue --otherArgument", false); testCommandLine("--argument1=value1 defaultValue --otherArgument=value", false); testCommandLine("--argument1 value1 defaultValue", false); } void testTwoRequiredNamedArguments() { QFETCH(QString, commandLine); QFETCH(bool, error); setCommandLine(commandLine); UCArguments arguments; QStringList valueNames; valueNames << "VALUE1" << "VALUE2"; UCArgument argument1; argument1.setName("argument1"); argument1.setValueNames(valueNames); arguments.appendArguments(&argument1); UCArgument argument2; argument2.setName("argument2"); argument2.setValueNames(valueNames); arguments.appendArguments(&argument2); arguments.componentComplete(); QCOMPARE(arguments.error(), error); if (!error) { QCOMPARE(arguments.values()->property("argument1").type(), QVariant::StringList); QCOMPARE(arguments.values()->property("argument1").toStringList().size(), 2); QCOMPARE(arguments.values()->property("argument2").type(), QVariant::StringList); QCOMPARE(arguments.values()->property("argument2").toStringList().size(), 2); } } void testTwoRequiredNamedArguments_data() { QTest::addColumn("commandLine"); QTest::addColumn("error"); testCommandLine("", true, "NO ARGUMENTS"); testCommandLine("--argument1=value1 value2 --argument2=value1 value2", false); testCommandLine("--argument1 value1 value2 --argument2 value1 value2", false); testCommandLine("--otherArgument --argument1 value1 value2 --argument2 value1 value2", false); testCommandLine("--argument1 value1 value2 --argument2 value1 value2 --otherArgument", false); testCommandLine("--argument1 value1 value2 --argument2 value1 value2 defaultValue --otherArgument", false); testCommandLine("--argument1 value1 value2 --argument2 value1 value2 defaultValue", false); testCommandLine("--argument1=value1 value2 --argument2=value1", true); } void testRequiredDefaultArgument() { QFETCH(QString, commandLine); QFETCH(bool, error); setCommandLine(commandLine); UCArguments arguments; QStringList valueNames; valueNames << "DEFAULTVALUE1" << "DEFAULTVALUE2"; UCArgument defaultArgument; defaultArgument.setValueNames(valueNames); arguments.setDefaultArgument(&defaultArgument); arguments.componentComplete(); QCOMPARE(arguments.error(), error); if (!error) { QCOMPARE(arguments.defaultArgument(), &defaultArgument); QCOMPARE(arguments.defaultArgument()->at(0).type(), QVariant::String); QCOMPARE(arguments.defaultArgument()->at(0).toString().isEmpty(), false); QCOMPARE(arguments.defaultArgument()->at(0).toString(), QString("defaultValue1")); QCOMPARE(arguments.defaultArgument()->at(1).type(), QVariant::String); QCOMPARE(arguments.defaultArgument()->at(1).toString().isEmpty(), false); QCOMPARE(arguments.defaultArgument()->at(1).toString(), QString("defaultValue2")); QCOMPARE(arguments.defaultArgument()->at(2).type(), QVariant::Invalid); } } void testRequiredDefaultArgument_data() { QTest::addColumn("commandLine"); QTest::addColumn("error"); testCommandLine("", true, "NO ARGUMENTS"); testCommandLine("--boolArgument", true); testCommandLine("--boolArgument --otherArg1=value --otherArg2 value", true); testCommandLine("--boolArgument --otherArg=value defaultValue1 defaultValue2", false); testCommandLine("--otherArg=value --boolArgument defaultValue1 defaultValue2", false); testCommandLine("--otherArg=value defaultValue1 defaultValue2 --boolArgument", false); testCommandLine("--otherArg=value defaultValue1 defaultValue2", false); } void testAPIdefaultArgument() { UCArguments arguments; arguments.componentComplete(); // getter UCArgument* defaultArgument = arguments.defaultArgument(); QCOMPARE(defaultArgument->name(), QString()); QCOMPARE(defaultArgument->help(), QString()); QCOMPARE(defaultArgument->required(), true); QCOMPARE(defaultArgument->valueNames().size(), 0); QCOMPARE(defaultArgument->at(0).type(), QVariant::Invalid); // setter: custom UCArgument UCArgument customDefaultArgument; QSignalSpy spy(&arguments, SIGNAL(defaultArgumentChanged())); arguments.setDefaultArgument(&customDefaultArgument); QCOMPARE(spy.count(), 1); QCOMPARE(arguments.defaultArgument(), &customDefaultArgument); // setter: NULL arguments.setDefaultArgument(NULL); QCOMPARE(arguments.defaultArgument(), (UCArgument*)NULL); } void testAPIprintUsage() { UCArguments arguments; arguments.printUsage(); } void testAPIquitWithError() { UCArguments arguments; QString errorMessage("error message"); QCOMPARE(arguments.error(), false); QCOMPARE(arguments.errorMessage(), QString()); arguments.quitWithError(errorMessage); QCOMPARE(arguments.error(), true); QCOMPARE(arguments.errorMessage(), errorMessage); } // unit tests for private API: only done to simplify error tracking // do not hesitate to rip off when refactoring UCArgument's implementation void testAPIbuildExpectedArguments() { UCArguments arguments; QStringList valueNames; valueNames << "VALUE1" << "VALUE2"; UCArgument argument1; argument1.setName("argument1"); argument1.setValueNames(valueNames); arguments.appendArguments(&argument1); UCArgument argument2; argument2.setName("argument2"); argument2.setValueNames(valueNames); arguments.appendArguments(&argument2); QList declaredArguments; QHash result; QHash expectedResult; result = arguments.buildExpectedArguments(declaredArguments); QCOMPARE(result, expectedResult); declaredArguments.append(&argument1); declaredArguments.append(&argument2); result = arguments.buildExpectedArguments(declaredArguments); expectedResult.insert("argument1", valueNames); expectedResult.insert("argument2", valueNames); QCOMPARE(result, expectedResult); } void testAPIparseRawArguments() { UCArguments arguments; QStringList values; values << "value1" << "value2"; QStringList rawArguments; QHash expectedArguments; QHash result; QHash expectedResult; result = arguments.parseRawArguments(rawArguments, expectedArguments); QCOMPARE(result, expectedResult); expectedArguments.insert("argument1", values); expectedArguments.insert("argument2", values); expectedResult.insert("argument1", values); expectedResult.insert("argument2", values); rawArguments << "binary" << "--argument1" << "value1" << "value2" << "--argument2" << "value1" << "value2"; result = arguments.parseRawArguments(rawArguments, expectedArguments); QCOMPARE(result, expectedResult); rawArguments.clear(); rawArguments << "binary" << "--argument1=value1" << "value2" << "--argument2" << "value1" << "value2"; result = arguments.parseRawArguments(rawArguments, expectedArguments); QCOMPARE(result, expectedResult); } void testAPIcollectArgumentValues() { UCArguments arguments; QStringList::const_iterator i; QStringList::const_iterator end; int nValues = 0; QStringList result; QStringList expectedResult; result = arguments.collectArgumentValues(i, end, nValues); QCOMPARE(result, expectedResult); QStringList rawArguments; rawArguments << "binary" << "--argument1" << "value1" << "value2" << "--argument2" << "value1" << "value2"; i = rawArguments.constBegin(); i++; // i points to "--argument1" end = rawArguments.constEnd(); nValues = 2; expectedResult << "value1" << "value2"; result = arguments.collectArgumentValues(i, end, nValues); QCOMPARE(result, expectedResult); QStringList::const_iterator iExpected = rawArguments.constBegin(); iExpected++; iExpected++; iExpected++; // iExpected points to "value2" QCOMPARE(i, iExpected); } void testAPIusageRequested() { UCArguments arguments; QStringList argumentNames; QCOMPARE(arguments.usageRequested(argumentNames), false); argumentNames.clear(); argumentNames.append("usage"); QCOMPARE(arguments.usageRequested(argumentNames), true); argumentNames.clear(); argumentNames.append("h"); QCOMPARE(arguments.usageRequested(argumentNames), true); argumentNames.clear(); argumentNames.append("help"); QCOMPARE(arguments.usageRequested(argumentNames), true); argumentNames.clear(); argumentNames.append("anything"); argumentNames.append("usage"); QCOMPARE(arguments.usageRequested(argumentNames), true); argumentNames.clear(); argumentNames.append("anything"); QCOMPARE(arguments.usageRequested(argumentNames), false); } }; // Do not use QTEST_MAIN. QTEST_MAIN is 99.99% of the times what you // want when running a Qt testcase but it creates a Q*Application and in // this case that is not wanted since we are creating and destroying them as // part of the test and Qt doesn't like when there's more than one Q*Application // at the same time, so do without creating a Q*Application in main. // This can of course have some implications but it seems that // for this testcase all is fine. int main(int argc, char *argv[]) { int myArgc = argc; char **myArgv = new char*[argc + 1]; // Eat -platform xyz, we're just using QCoreApplications here so // no need to say the gui platform to use // We are techically leaking the myArgv char** and it's strdup'ed contents // but it happens the binary just finishes after, so not a problem int j = 0; for (int i = 0; i < argc; i++) { if (argv[i] == QString("-platform")) { if (i < argc) { i++; // skip also the platform value myArgc -= 2; } else { myArgc -= 1; } } else { myArgv[j] = strdup(argv[i]); j++; } } myArgv[myArgc] = 0; tst_UCArguments tc; return QTest::qExec(&tc, myArgc, myArgv); } #include "tst_arguments.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit/tst_arguments/tst_arguments.pro0000644000015301777760000000007212321005637030420 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_arguments.cpp ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/0000755000015301777760000000000012321006415022565 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_recreateview/0000755000015301777760000000000012321006415026144 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_recreateview/tst_recreateview.pro0000644000015301777760000000020112321005637032243 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_recreateview.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" OTHER_FILES += \ SimpleApp.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_recreateview/tst_recreateview.cpp0000644000015301777760000000341212321005637032234 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include class RecreateViewTest : public QObject { Q_OBJECT public: RecreateViewTest() {} private Q_SLOTS: void initTestCase(); void testCase_recreateView(); private: QString m_modulePath; }; void RecreateViewTest::initTestCase() { QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); m_modulePath = QDir(modules).absolutePath(); } void RecreateViewTest::testCase_recreateView() { QQuickView *view = new QQuickView; view->engine()->addImportPath(m_modulePath); view->setSource(QUrl::fromLocalFile("SimpleApp.qml")); QVERIFY(view->rootObject() != 0); view->show(); QTest::qWaitForWindowExposed(view); delete view; view = new QQuickView; view->engine()->addImportPath(m_modulePath); view->setSource(QUrl::fromLocalFile("SimpleApp.qml")); QVERIFY(view->rootObject() != 0); view->show(); QTest::qWaitForWindowExposed(view); delete view; } QTEST_MAIN(RecreateViewTest) #include "tst_recreateview.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_recreateview/SimpleApp.qml0000644000015301777760000000176412321005637030566 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(48) height: units.gu(60) Component.onCompleted: i18n.domain = "any" Page { title: "Simple page" Button { anchors.centerIn: parent text: "Push me" width: units.gu(15) onClicked: print("Click!") } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/0000755000015301777760000000000012321006415027034 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaClip.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaClip.q0000644000015301777760000000356112321005637033255 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { color: "yellow" width: units.gu(70) height: units.gu(70) property InverseMouseArea ima: imaItem Label { anchors { horizontalCenter: parent.horizontalCenter top: parent.top } text: "Root" } Rectangle { color: "green" width: units.gu(50) height: units.gu(50) anchors.centerIn: parent clip: true Label { anchors { horizontalCenter: parent.horizontalCenter top: parent.top } text: "Clipper" } Rectangle { width: units.gu(30) height: units.gu(30) color: "lightgrey" anchors.centerIn: parent Label { anchors { horizontalCenter: parent.horizontalCenter top: parent.top } text: "Inverse mouse area" } InverseMouseArea { id: imaItem objectName: "Test_IMA" anchors.fill: parent topmostItem: true clip: false } } } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/OverlappedMouseArea.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/OverlappedMouseArea.qm0000644000015301777760000000241612321005637033306 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(50) height: units.gu(50) property string log: "" Item { id: nil width: 0 height: 0 } InverseMouseArea { anchors.fill: nil onClicked: { color.color = "red" root.log = "IMA" // FAIL } } Rectangle { id: color anchors.fill: parent color: "blue" MouseArea { onClicked: { parent.color = "green" root.log = "MA" // PASS } anchors.fill: parent } } } ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/tst_inversemousearea.proubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/tst_inversemousearea.p0000644000015301777760000000136212321005637033473 0ustar pbusernogroup00000000000000include(../test-include.pri) QT += quick-private gui-private SOURCES += tst_inversemouseareatest.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" OTHER_FILES += \ InverseMouseAreaPropagateEvents.qml \ InverseMouseAreaDoNotPropagateEvents.qml \ SensingAreaError.qml \ InverseMouseAreaInWindow.qml \ OverlappedMouseArea.qml \ InverseMouseAreaOnTop.qml \ InverseMouseAreaSignals.qml \ InverseMouseAreaNormalEventStack.qml \ InverseMouseAreaTopmostItem.qml \ InverseMouseAreaSensingArea.qml \ InverseMouseAreaOnTopNoAccept.qml \ Defaults.qml \ InverseMouseAreaInListView.qml \ InverseMouseAreaInPage.qml \ InverseMouseAreaInFlickable.qml \ InverseMouseAreaParentClipped.qml \ InverseMouseAreaClip.qml ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInFlickable.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInFlic0000644000015301777760000000265012321005637033271 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 MainView { id: root width: units.gu(40) height: units.gu(71) property InverseMouseArea ima: null Page { title: "Test" Flickable { id: list objectName: "ListView" anchors.fill: parent contentHeight: units.gu(100) Rectangle { width: 100 height: 100 anchors.centerIn: parent InverseMouseArea { id: ima objectName: "Test_IMA" anchors.fill: parent topmostItem: true Component.onCompleted: root.ima = ima } } } } } ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInPage.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInPage0000644000015301777760000000242112321005637033264 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: root width: units.gu(40) height: units.gu(71) property InverseMouseArea ima: imaItem Page { title: "Test" Rectangle { objectName: "Card" width: parent.width - units.gu(5) height: units.gu(50) anchors.centerIn: parent color: "blue" InverseMouseArea { id: imaItem objectName: "Test_IMA" anchors.fill: parent topmostItem: true Component.onCompleted: root.ima = ima } } } } ././@LongLink0000000000000000000000000000016200000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaPropagateEvents.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaPropag0000644000015301777760000000164212321005637033355 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { objectName: "root" width: 100 height: 100 InverseMouseArea { objectName: "testObject" anchors.centerIn: parent propagateComposedEvents: true width: 50 height: 50 } } ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/tst_inversemouseareate0000644000015301777760000004542312321005637033574 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include "inversemouseareatype.h" #include "ucunits.h" #include #include #define DOUBLECLICK_TIMEOUT 400 using QTest::QTouchEventSequence; class tst_InverseMouseAreaTest : public QObject { Q_OBJECT public: tst_InverseMouseAreaTest() : quickView(0), quickEngine(0), device(0) {} private: QQuickView *quickView; QQmlEngine *quickEngine; QTouchDevice *device; QObjectCleanupHandler eventCleanup; InverseMouseAreaType *testArea(const QString &document, const QString &imaName = QString()) { // delete previous root QObject *rootObject = quickView->rootObject(); if (rootObject) delete rootObject; QTest::waitForEvents(); quickView->setSource(QUrl::fromLocalFile(document)); QCoreApplication::processEvents(); rootObject = quickView->rootObject(); if (!rootObject) return 0; if (!imaName.isEmpty()) { return rootObject->findChild(imaName); } QList items = rootObject->findChildren(); Q_FOREACH(QQuickItem *item, items) { InverseMouseAreaType *area = qobject_cast(item); if (area) return area; } return 0; } QPoint guPoint(qreal guX, qreal guY) { return QPointF(UCUnits::instance().gu(guX), UCUnits::instance().gu(guY)).toPoint(); } void touchClick(QWindow *window, const QPoint &point) { QTest::touchEvent(window, device).press(0, point, window); QTest::qWait(10); QTest::touchEvent(window, device).release(0, point, window); } protected Q_SLOTS: void capturePressed(QQuickMouseEvent *event) { eventCleanup.add((QObject*)event); } private Q_SLOTS: void initTestCase() { QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); quickView = new QQuickView(0); quickEngine = quickView->engine(); device = new QTouchDevice; device->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(device); quickView->setGeometry(0,0, 240, 320); //add modules folder so we have access to the plugin from QML QStringList imports = quickEngine->importPathList(); imports << QDir(modules).absolutePath(); quickEngine->setImportPathList(imports); } void cleanupTestCase() { delete quickView; } void testCase_Defaults() { InverseMouseAreaType *area = testArea("Defaults.qml"); QVERIFY(area); QCOMPARE(area->pressed(), false); QCOMPARE(area->acceptedButtons(), Qt::LeftButton); QCOMPARE(area->pressedButtons(), Qt::NoButton); QCOMPARE(area->propagateComposedEvents(), false); } void testCase_DoNotPropagateEvents() { eventCleanup.clear(); InverseMouseAreaType *area = testArea("InverseMouseAreaDoNotPropagateEvents.qml"); QVERIFY(area); // connect pressed signal to capture mouse object QObject::connect(area, SIGNAL(pressed(QQuickMouseEvent*)), this, SLOT(capturePressed(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(10, 10)); QTest::waitForEvents(); QVERIFY(eventCleanup.isEmpty()); } void testCase_PropagateEvents() { eventCleanup.clear(); InverseMouseAreaType *area = testArea("InverseMouseAreaPropagateEvents.qml"); QVERIFY(area); // connect pressed signal to capture mouse object QObject::connect(area, SIGNAL(pressed(QQuickMouseEvent*)), this, SLOT(capturePressed(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(10, 10)); QTest::waitForEvents(); QVERIFY(eventCleanup.isEmpty()); } void testCase_sensingAreaError() { InverseMouseAreaType *area = testArea("SensingAreaError.qml"); QVERIFY(area); QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(20, 20)); QTest::waitForEvents(); QCOMPARE(quickView->rootObject()->property("log").toString(), QString("IMA")); } void testCase_InverseMouseAreInWindow() { InverseMouseAreaType *area = testArea("InverseMouseAreaInWindow.qml"); QVERIFY(area); quickView->show(); QList l = quickView->rootObject()->findChildren("isawindow"); QVERIFY(l.count()); QTest::mouseClick(l[0], Qt::LeftButton, 0, QPoint(20, 10)); QTest::waitForEvents(); QCOMPARE(quickView->rootObject()->property("log").toString(), QString("IMA")); } void testCase_OverlappedMouseArea() { InverseMouseAreaType *area = testArea("OverlappedMouseArea.qml"); QVERIFY(area); quickView->show(); QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(20, 10)); QTest::waitForEvents(); QCOMPARE(quickView->rootObject()->property("log").toString(), QString("MA")); } void testCase_InverseMouseAreaOnTop() { InverseMouseAreaType *area = testArea("InverseMouseAreaOnTop.qml"); QVERIFY(area); quickView->show(); QTest::qWaitForWindowExposed(quickView); QQuickItem *ma1 = quickView->rootObject()->findChild("MA1"); QVERIFY(ma1); QQuickItem *ma2 = quickView->rootObject()->findChild("MA2"); QVERIFY(ma2); QSignalSpy imaSpy(area, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy ma1Spy(ma1, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy ma2Spy(ma2, SIGNAL(pressed(QQuickMouseEvent*))); // click in the top rectangle, use 800msec delay to prevent dblclick detection QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(10, 10), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma1Spy.count(), 0); QCOMPARE(ma2Spy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); // click in the second rectangle, use 800msec delay to prevent dblclick detection QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(10, 65), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma1Spy.count(), 0); QCOMPARE(ma2Spy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); // click in the button, use 800msec delay to prevent dblclick detection QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(25, 85), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma1Spy.count(), 0); QCOMPARE(ma2Spy.count(), 1); QCOMPARE(imaSpy.count(), 0); // double click in the second rectangle QSignalSpy imaDSpy(area, SIGNAL(doubleClicked(QQuickMouseEvent*))); QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(10, 65)); QTest::waitForEvents(); // FIXME: this is flaky QCOMPARE(imaDSpy.count(), 1); imaDSpy.clear(); // double click in the first rectangle QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(10, 10)); QTest::waitForEvents(); QCOMPARE(imaDSpy.count(), 1); imaDSpy.clear(); } void testCase_InverseMouseAreaOnTopNoAccept() { InverseMouseAreaType *area = testArea("InverseMouseAreaOnTopNoAccept.qml"); QVERIFY(area); quickView->show(); QTest::qWaitForWindowExposed(quickView); QQuickItem *ma1 = quickView->rootObject()->findChild("MA1"); QVERIFY(ma1); QQuickItem *ma2 = quickView->rootObject()->findChild("MA2"); QVERIFY(ma2); QSignalSpy imaSpy(area, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy ma1Spy(ma1, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy ma2Spy(ma2, SIGNAL(pressed(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(10, 10), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma1Spy.count(), 1); QCOMPARE(ma2Spy.count(), 0); QCOMPARE(imaSpy.count(), 1); ma1Spy.clear(); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(10, 65), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma1Spy.count(), 0); QCOMPARE(ma2Spy.count(), 1); QCOMPARE(imaSpy.count(), 1); ma2Spy.clear(); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(25, 80), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma1Spy.count(), 0); QCOMPARE(ma2Spy.count(), 1); QCOMPARE(imaSpy.count(), 0); // double click should not reach inverse mouse area as onPressed did not accept the events QSignalSpy imaDSpy(area, SIGNAL(doubleClicked(QQuickMouseEvent*))); QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(10, 65)); QCOMPARE(imaDSpy.count(), 0); imaDSpy.clear(); QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(10, 10)); QCOMPARE(imaDSpy.count(), 0); imaDSpy.clear(); } void testCase_InverseMouseAreaOnTopTopmost() { InverseMouseAreaType *area = testArea("InverseMouseAreaOnTop.qml"); QVERIFY(area); quickView->show(); QTest::qWaitForWindowExposed(quickView); area->setProperty("topmostItem", true); QQuickItem *ma2 = quickView->rootObject()->findChild("MA2"); QVERIFY(ma2); QSignalSpy imaSpy(area, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy ma2Spy(ma2, SIGNAL(pressed(QQuickMouseEvent*))); // click on the topmost rectangle QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(10, 10), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma2Spy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); // click on the second rectangle QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(10, 65), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma2Spy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); // click on the button QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(25, 85), DOUBLECLICK_TIMEOUT); QTest::waitForEvents(); QCOMPARE(ma2Spy.count(), 1); QCOMPARE(imaSpy.count(), 0); // double click on the second rectangle QSignalSpy imaDSpy(area, SIGNAL(doubleClicked(QQuickMouseEvent*))); QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(10, 65)); QCOMPARE(imaDSpy.count(), 1); imaDSpy.clear(); // double click on the first rectangle QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(10, 10)); QCOMPARE(imaDSpy.count(), 1); imaDSpy.clear(); } void testCase_InverseMouseAreaSignals() { InverseMouseAreaType *area = testArea("InverseMouseAreaSignals.qml"); QVERIFY(area); quickView->show(); QTest::qWaitForWindowExposed(quickView); QSignalSpy pressSpy(area, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy releaseSpy(area, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clickSpy(area, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy enteredSpy(area, SIGNAL(entered())); QSignalSpy exitedSpy(area, SIGNAL(exited())); QTest::mouseClick(quickView, Qt::LeftButton, 0, QPoint(5, 5), DOUBLECLICK_TIMEOUT); QCOMPARE(pressSpy.count(), 1); QCOMPARE(releaseSpy.count(), 1); QCOMPARE(clickSpy.count(), 1); QCOMPARE(enteredSpy.count(), 1); QCOMPARE(exitedSpy.count(), 1); QSignalSpy doubleClickSpy(area, SIGNAL(doubleClicked(QQuickMouseEvent*))); QTest::mouseDClick(quickView, Qt::LeftButton, 0, QPoint(5, 5)); QCOMPARE(doubleClickSpy.count(), 1); } void testCase_InverseMouseAreaNormalEventStack() { InverseMouseAreaType *ima = testArea("InverseMouseAreaNormalEventStack.qml"); QVERIFY(ima); quickView->show(); QTest::qWaitForWindowExposed(quickView); QQuickItem *ma = quickView->rootObject()->findChild("MA"); QVERIFY(ma); QSignalSpy imaSpy(ima, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy maSpy(ma, SIGNAL(pressed(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(15, 15)); QCOMPARE(imaSpy.count(), 0); QCOMPARE(maSpy.count(), 0); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(115, 15)); QCOMPARE(imaSpy.count(), 0); QCOMPARE(maSpy.count(), 1); maSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(115, 115)); QCOMPARE(imaSpy.count(), 1); QCOMPARE(maSpy.count(), 0); } void testCase_InverseMouseAreaTopmost() { InverseMouseAreaType *ima = testArea("InverseMouseAreaTopmostItem.qml"); QVERIFY(ima); quickView->show(); QTest::qWaitForWindowExposed(quickView); QQuickItem *ma = quickView->rootObject()->findChild("MA"); QVERIFY(ma); QSignalSpy imaSpy(ima, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy maSpy(ma, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy imaDblClick(ima, SIGNAL(doubleClicked(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(15, 15), DOUBLECLICK_TIMEOUT); QCOMPARE(imaSpy.count(), 0); QCOMPARE(maSpy.count(), 0); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(115, 15), DOUBLECLICK_TIMEOUT); QCOMPARE(imaSpy.count(), 1); QCOMPARE(maSpy.count(), 0); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(115, 115), DOUBLECLICK_TIMEOUT); QCOMPARE(imaSpy.count(), 1); QCOMPARE(maSpy.count(), 0); QTest::mouseDClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(115, 15)); QCOMPARE(imaDblClick.count(), 1); } void testCase_InverseMouseAreaSensingArea() { InverseMouseAreaType *ima = testArea("InverseMouseAreaSensingArea.qml"); QVERIFY(ima); quickView->show(); QTest::qWaitForWindowExposed(quickView); QQuickItem *ma = quickView->rootObject()->findChild("MA"); QVERIFY(ma); QSignalSpy maSpy(ma, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy imaSpy(ima, SIGNAL(clicked(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(75, 75)); QCOMPARE(maSpy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(25, 25)); QCOMPARE(maSpy.count(), 1); QCOMPARE(imaSpy.count(), 0); maSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(175, 175)); QCOMPARE(maSpy.count(), 1); QCOMPARE(imaSpy.count(), 0); } void testCase_InverseMouseAreaSensingAreaChange() { InverseMouseAreaType *ima = testArea("InverseMouseAreaSensingArea.qml"); QVERIFY(ima); quickView->show(); QTest::qWaitForWindowExposed(quickView); QQuickItem *ma = quickView->rootObject()->findChild("MA"); QVERIFY(ma); QSignalSpy maSpy(ma, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy imaSpy(ima, SIGNAL(clicked(QQuickMouseEvent*))); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(75, 75)); QCOMPARE(maSpy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(25, 25)); QCOMPARE(maSpy.count(), 1); QCOMPARE(imaSpy.count(), 0); maSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(175, 175)); QCOMPARE(maSpy.count(), 1); QCOMPARE(imaSpy.count(), 0); maSpy.clear(); ima->setProperty("sensingArea", QVariant()); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(75, 75)); QCOMPARE(maSpy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(25, 25)); QCOMPARE(maSpy.count(), 0); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, QPoint(175, 175)); QCOMPARE(maSpy.count(), 1); QCOMPARE(imaSpy.count(), 0); } void test_MouseClicksOnHeaderNotSeen_bug1288876_data() { QTest::addColumn("document"); QTest::newRow("InverseMouseArea in a Page") << "InverseMouseAreaInPage.qml"; QTest::newRow("InverseMouseArea with clip") << "InverseMouseAreaClip.qml"; QTest::newRow("InverseMouseArea parent clipped") << "InverseMouseAreaParentClipped.qml"; QTest::newRow("InverseMouseArea in a ListView") << "InverseMouseAreaInListView.qml"; QTest::newRow("InverseMouseArea in a Flickable") << "InverseMouseAreaInFlickable.qml"; } void test_MouseClicksOnHeaderNotSeen_bug1288876() { QFETCH(QString, document); testArea(document); InverseMouseAreaType *ima = quickView->rootObject()-> property("ima").value(); QVERIFY(ima); QCOMPARE(ima->objectName(), QString("Test_IMA")); quickView->show(); QTest::qWaitForWindowExposed(quickView); QSignalSpy imaSpy(ima, SIGNAL(clicked(QQuickMouseEvent*))); // make sure we click on the header QTest::mouseClick(quickView, Qt::LeftButton, Qt::NoModifier, guPoint(20, 5)); QCOMPARE(imaSpy.count(), 1); imaSpy.clear(); touchClick(quickView, guPoint(20, 5)); QCOMPARE(imaSpy.count(), 1); } }; QTEST_MAIN(tst_InverseMouseAreaTest) #include "tst_inversemouseareatest.moc" ././@LongLink0000000000000000000000000000016700000000000011221 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaDoNotPropagateEvents.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaDoNotP0000644000015301777760000000164312321005637033271 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { objectName: "root" width: 100 height: 100 InverseMouseArea { objectName: "testObject" anchors.centerIn: parent propagateComposedEvents: false width: 50 height: 50 } } ././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaOnTopNoAccept.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaOnTopN0000644000015301777760000000343512321005637033304 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: page width: 300 height: 300 color: "lightgray" objectName: "ROOT" Rectangle { id: label objectName: "RECT1" anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top height: 40 width: parent.width color: Qt.rgba(1, 0, 0, 0.4) MouseArea { objectName: "MA1" anchors.fill: parent z: 1 } } Rectangle { anchors.top: label.bottom anchors.topMargin: 20 anchors.horizontalCenter: parent.horizontalCenter height: 60 width: parent.width color: Qt.rgba(0, 0, 1, 0.4) objectName: "RECT2" Button { id: button objectName: "button" x: 20 y: 10 text: "I'm a button, I do nothing." } MouseArea { objectName: "MA2" anchors.fill: parent } InverseMouseArea { objectName: "IMA" anchors.fill: button onPressed: mouse.accepted = false } } } ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInWindow.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInWind0000644000015301777760000000332512321005637033315 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Window 2.0 import Ubuntu.Components 0.1 Item{ id: root property string log: "" width: units.gu(100) height: units.gu(100) Window { objectName: "isawindow" width: units.gu(50) height: units.gu(50) Item { id: clickArea anchors { left: parent.left right: parent.right top: parent.top } height: units.gu(10) Label { anchors.centerIn: parent text: "click me" } } Rectangle { id: rect color: "red" anchors { left: parent.left right: parent.right top: clickArea.bottom bottom: parent.bottom } } InverseMouseArea { objectName: "ima" id: ima anchors.fill: rect onClicked: { root.log = "IMA" rect.color = "green" } } } } ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaOnTop.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaOnTop.0000644000015301777760000000335712321005637033247 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: page width: 300 height: 300 color: "lightgray" objectName: "ROOT" Rectangle { id: label objectName: "RECT1" anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top height: 40 width: parent.width color: Qt.rgba(1, 0, 0, 0.4) MouseArea { objectName: "MA1" anchors.fill: parent z: 1 } } Rectangle { anchors.top: label.bottom anchors.topMargin: 20 anchors.horizontalCenter: parent.horizontalCenter height: 60 width: parent.width color: Qt.rgba(0, 0, 1, 0.4) objectName: "RECT2" Button { id: button objectName: "button" x: 20 y: 10 text: "I'm a button, I do nothing." } MouseArea { objectName: "MA2" anchors.fill: parent } InverseMouseArea { objectName: "IMA" anchors.fill: button } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/SensingAreaError.qml0000644000015301777760000000223612321005637032770 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root objectName: "root" width: units.gu(40) height: units.gu(40) property string log: "" MouseArea { anchors.fill: parent onClicked: root.log = "MA" } Rectangle { width: units.gu(10) height: units.gu(10) anchors.centerIn: parent color: "red" InverseMouseArea { anchors.fill: parent sensingArea: root onClicked: root.log = "IMA" } } } ././@LongLink0000000000000000000000000000015500000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInListView.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaInList0000644000015301777760000000330612321005637033326 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 MainView { id: root width: units.gu(40) height: units.gu(71) property InverseMouseArea ima: null Component { id: editor TextArea { } } Page { title: "Test" ListView { id: list objectName: "ListView" anchors.fill: parent model: 1 delegate: Empty { objectName: "Card" width: parent.width - units.gu(5) anchors.horizontalCenter: parent.horizontalCenter height: units.gu(50) Loader { anchors.fill: parent sourceComponent: editor } InverseMouseArea { id: imaItem objectName: "Test_IMA" anchors.fill: parent topmostItem: true Component.onCompleted: root.ima = imaItem } } } } } ././@LongLink0000000000000000000000000000016300000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaNormalEventStack.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaNormal0000644000015301777760000000217312321005637033355 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 300 height: 300 objectName: "ROOT" Rectangle { x: 10; y: 10 width: 100; height: 100 color: "blue" InverseMouseArea { anchors.fill: parent objectName: "IMA" } } Rectangle { x: 110; y: 10 width: 100; height: 100 color: "red" MouseArea { anchors.fill: parent objectName: "MA" } } } ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaSensingArea.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaSensin0000644000015301777760000000233512321005637033364 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 300 height: 300 MouseArea { objectName: "MA" anchors.fill: parent } Rectangle { id: blueRect width: 200 height: 200 anchors.centerIn: parent color: "blue" Rectangle { width: 100 height: 100 anchors.centerIn: parent color: "red" InverseMouseArea { objectName: "IMA" anchors.fill: parent sensingArea: blueRect } } } } ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaSignals.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaSignal0000644000015301777760000000166412321005637033346 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 300 height: 300 objectName: "ROOT" Rectangle { x: 10 y: 10 width: 100 height: 30 InverseMouseArea { anchors.fill: parent objectName: "IMA" } } } ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaTopmostItem.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaTopmos0000644000015301777760000000223212321005637033402 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 300 height: 300 objectName: "ROOT" Rectangle { x: 110; y: 10 width: 100; height: 100 color: "red" MouseArea { anchors.fill: parent objectName: "MA" } } Rectangle { x: 10; y: 10 width: 100; height: 100 color: "blue" InverseMouseArea { anchors.fill: parent objectName: "IMA" topmostItem: true } } } ././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaParentClipped.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/InverseMouseAreaParent0000644000015301777760000000273112321005637033356 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: root width: units.gu(40) height: units.gu(71) property InverseMouseArea ima: null Component { id: imaComponent InverseMouseArea { id: ima objectName: "Test_IMA" anchors.fill: parent topmostItem: true Component.onCompleted: root.ima = ima } } Component.onCompleted: loader.sourceComponent = imaComponent Page { title: "Test" Rectangle { objectName: "Card" width: parent.width - units.gu(5) height: units.gu(50) anchors.centerIn: parent color: "teal" clip: true Loader { id: loader anchors.fill: parent } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_inversemousearea/Defaults.qml0000644000015301777760000000137512321005637031331 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { InverseMouseArea { objectName: "testItem" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/add_qmlmakecheck.pri0000644000015301777760000000062112321005637026542 0ustar pbusernogroup00000000000000# Do not use CONFIG += testcase that would add a 'make check' because it also # adds a 'make install' that installs the test cases, which we do not want. # Instead add a 'make check' manually. check.target = check # Xvfb doesn't run on armhf/qemu !contains(QMAKE_HOST.arch,armv7l) { check.commands = "set -e;" for(TEST, TESTS) { check.commands += ../../unit/runtest.sh $${TARGET} $${TEST}; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_orientation/0000755000015301777760000000000012321006415026012 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_orientation/ManualAngle.qml0000644000015301777760000000176012321005637030722 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import QtQuick.Window 2.0 Item { width: 100 height: 100 OrientationHelper { objectName: "helper" orientationAngle: 90 } Window { id: window } Item { objectName: "checkpoint" property int contentOrientation: window.contentOrientation } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_orientation/tst_orientation.cpp0000644000015301777760000000626312321005637031757 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #include #include #include #include #include #include #include #include #include #include #include #include class tst_OrientationTest : public QObject { Q_OBJECT public: tst_OrientationTest() {} private: QString m_modulePath; QQuickView *createView(const QString &file, QSignalSpy **spy = 0) { QQuickView *view = new QQuickView(0); if (spy) { *spy = new QSignalSpy(view->engine(), SIGNAL(warnings(QList))); (*spy)->setParent(view); } view->engine()->addImportPath(m_modulePath); view->setSource(QUrl::fromLocalFile(file)); if (!view->rootObject()) { return 0; } view->show(); QTest::qWaitForWindowExposed(view); return view; } private Q_SLOTS: void initTestCase() { QDir modules ("../../../modules"); QVERIFY(modules.exists()); m_modulePath = modules.absolutePath(); } void cleanupTestCase() { } void test_defaults() { QSignalSpy *spy; QQuickView *view = createView("Defaults.qml", &spy); QVERIFY(view); QQuickItem *helper = view->rootObject()->findChild("helper"); QVERIFY(helper); QCOMPARE(helper->property("automaticOrientation").toBool(), true); // No warnings expected QCOMPARE(spy->count(), 0); delete view; } void test_manualAngle() { QSignalSpy *spy; QQuickView *view = createView("ManualAngle.qml", &spy); QVERIFY(view); QQuickItem *helper = view->rootObject()->findChild("helper"); QVERIFY(helper); // No warning about "window" being undefined must appear QSKIP("TypeError: Cannot set property 'contentOrientation' of null"); QCOMPARE(spy->count(), 0); QCOMPARE(helper->property("orientationAngle").toInt(), 90); // Verify expected values QQuickItem *checkpoint = view->rootObject()->findChild("checkpoint"); QVERIFY(checkpoint); // window.contentOrientation QCOMPARE(checkpoint->property("contentOrientation").toInt(), helper->property("orientationAngle").toInt()); delete view; } }; QTEST_MAIN(tst_OrientationTest) #include "tst_orientation.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_orientation/tst_orientation.pro0000644000015301777760000000024312321005637031765 0ustar pbusernogroup00000000000000include(../test-include.pri) DEFINES += SRCDIR=\\\"$$PWD/\\\" SOURCES += \ tst_orientation.cpp OTHER_FILES += \ Defaults.qml \ ManualOrientation.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_orientation/Defaults.qml0000644000015301777760000000143412321005637030303 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 100 height: 100 OrientationHelper { objectName: "helper" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/qmltest-include.pri0000644000015301777760000000020612321005637026416 0ustar pbusernogroup00000000000000include( ../unit/plugin_dependency.pri ) include( add_qmlmakecheck.pri) TEMPLATE = app QT += qml quick qmltest CONFIG += no_keywords ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/0000755000015301777760000000000012321006415026106 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/TestModule/0000755000015301777760000000000012321006415030173 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/TestModule/TestTheme/0000755000015301777760000000000012321006415032075 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000015500000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/TestModule/TestTheme/TestStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/TestModule/TestTheme/TestS0000644000015301777760000000124412321005637033070 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Item { } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/tst_theme_enginetest.cpp0000644000015301777760000001345712321005637033052 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include "uctheme.h" class tst_UCTheme : public QObject { Q_OBJECT private: QString m_xdgDataPath; private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void testInstance(); void testNameDefault(); void testNameSet(); void testCreateStyleComponent(); void testCreateStyleComponent_data(); void testThemesRelativePath(); void testThemesRelativePathWithParent(); void testThemesRelativePathWithParentXDGDATA(); void testThemesRelativePathWithParentNoVariablesSet(); void testThemesRelativePathWithParentOneXDGPathSet(); }; void tst_UCTheme::initTestCase() { m_xdgDataPath = QLatin1String(getenv("XDG_DATA_DIRS")); } void tst_UCTheme::cleanupTestCase() { qputenv("XDG_DATA_DIRS", m_xdgDataPath.toLocal8Bit()); } void tst_UCTheme::testInstance() { UCTheme::instance(); } void tst_UCTheme::testNameDefault() { UCTheme theme; QCOMPARE(theme.name(), QString("Ubuntu.Components.Themes.Ambiance")); } void tst_UCTheme::testNameSet() { UCTheme theme; theme.setName("MyBeautifulTheme"); QCOMPARE(theme.name(), QString("MyBeautifulTheme")); } void tst_UCTheme::testCreateStyleComponent() { QFETCH(QString, styleName); QFETCH(QString, parentName); QFETCH(bool, success); qputenv("UBUNTU_UI_TOOLKIT_THEMES_PATH", "."); UCTheme theme; theme.setName("TestModule.TestTheme"); QQmlEngine engine; QQmlComponent parentComponent(&engine, parentName); QObject* parent = parentComponent.create(); QQmlComponent* component = theme.createStyleComponent(styleName, parent); QCOMPARE(component != NULL, success); } void tst_UCTheme::testCreateStyleComponent_data() { QTest::addColumn("styleName"); QTest::addColumn("parentName"); QTest::addColumn("success"); QTest::newRow("Existing style") << "TestStyle.qml" << "Parent.qml" << true; QTest::newRow("Non existing style") << "NotExistingTestStyle.qml" << "Parent.qml" << false; QTest::newRow("No parent") << "TestStyle.qml" << "" << false; } void tst_UCTheme::testThemesRelativePath() { qputenv("UBUNTU_UI_TOOLKIT_THEMES_PATH", "../tst_theme_engine"); UCTheme theme; theme.setName("TestModule.TestTheme"); QQmlEngine engine; QQmlComponent parentComponent(&engine, "Parent.qml"); QObject* parent = parentComponent.create(); QQmlComponent* component = theme.createStyleComponent("TestStyle.qml", parent); QCOMPARE(component != NULL, true); QCOMPARE(component->status(), QQmlComponent::Ready); } void tst_UCTheme::testThemesRelativePathWithParent() { QSKIP("https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1248982"); qputenv("UBUNTU_UI_TOOLKIT_THEMES_PATH", "../../resources/themes:../../resources/themes/TestModule"); UCTheme theme; theme.setName("CustomTheme"); QQmlEngine engine; theme.registerToContext(engine.rootContext()); QQmlComponent parentComponent(&engine, "Parent.qml"); QObject* parent = parentComponent.create(); QQmlComponent* component = theme.createStyleComponent("TestStyle.qml", parent); QCOMPARE(component != NULL, true); QCOMPARE(component->status(), QQmlComponent::Ready); } void tst_UCTheme::testThemesRelativePathWithParentXDGDATA() { QSKIP("https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1248982"); qputenv("UBUNTU_UI_TOOLKIT_THEMES_PATH", ""); qputenv("XDG_DATA_DIRS", "../../resources/themes:../../resources/themes/TestModule"); UCTheme theme; theme.setName("CustomTheme"); QQmlEngine engine; theme.registerToContext(engine.rootContext()); QQmlComponent parentComponent(&engine, "Parent.qml"); QObject* parent = parentComponent.create(); QQmlComponent* component = theme.createStyleComponent("TestStyle.qml", parent); QCOMPARE(component != NULL, true); QCOMPARE(component->status(), QQmlComponent::Ready); } void tst_UCTheme::testThemesRelativePathWithParentNoVariablesSet() { qputenv("UBUNTU_UI_TOOLKIT_THEMES_PATH", ""); qputenv("XDG_DATA_DIRS", ""); UCTheme theme; QQmlEngine engine; QSignalSpy spy(&engine, SIGNAL(warnings(QList))); theme.registerToContext(engine.rootContext()); QQmlComponent parentComponent(&engine, "Parent.qml"); QObject* parent = parentComponent.create(); QQmlComponent* component = theme.createStyleComponent("TestStyle.qml", parent); // warning about TestStyle not defined in Ubuntu.Components.Themes.Ambiance should be shown QCOMPARE(spy.count(), 1); QCOMPARE(component == NULL, true); } void tst_UCTheme::testThemesRelativePathWithParentOneXDGPathSet() { qputenv("UBUNTU_UI_TOOLKIT_THEMES_PATH", ""); qputenv("XDG_DATA_DIRS", "../tst_theme_engine"); UCTheme theme; theme.setName("TestModule.TestTheme"); QQmlEngine engine; QQmlComponent parentComponent(&engine, "Parent.qml"); QObject* parent = parentComponent.create(); QQmlComponent* component = theme.createStyleComponent("TestStyle.qml", parent); QCOMPARE(component != NULL, true); QCOMPARE(component->status(), QQmlComponent::Ready);} QTEST_MAIN(tst_UCTheme) #include "tst_theme_enginetest.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/tst_theme_engine.pro0000644000015301777760000000014512321005637032156 0ustar pbusernogroup00000000000000include(../test-include.pri) SOURCES += tst_theme_enginetest.cpp OTHER_FILES += \ TestStyle.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_theme_engine/Parent.qml0000644000015301777760000000124412321005637030060 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Item { } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/test-include.pri0000644000015301777760000000024512321005637025707 0ustar pbusernogroup00000000000000include( ../unit/plugin_dependency.pri ) include( layout_dependency.pri ) include( add_makecheck.pri ) TEMPLATE = app QT += testlib qml quick CONFIG += no_keywords ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/add_makecheck.pri0000644000015301777760000000054412321005637026034 0ustar pbusernogroup00000000000000# Do not use CONFIG += testcase that would add a 'make check' because it also # adds a 'make install' that installs the test cases, which we do not want. # Instead add a 'make check' manually. # Xvfb doesn't run on armhf/qemu !contains(QMAKE_HOST.arch,armv7l) { check.target = check check.commands = ../../unit/runtest.sh $${TARGET} $${TARGET}; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_test/0000755000015301777760000000000012321006415024436 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_test/tst_test.pro0000644000015301777760000000022012321005637027030 0ustar pbusernogroup00000000000000TESTS += $$system(ls tst_*.qml) include(../qmltest-include.pri) TARGET = tst_test SOURCES += tst_test.cpp OTHER_FILES += $$system(ls *.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_test/tst_test.cpp0000644000015301777760000000130212321005637027014 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include QUICK_TEST_MAIN(test) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_test/tst_ubuntutestcase.qml0000644000015301777760000000317512321005637031134 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 Rectangle { id: root width: 800 height: 600 MouseArea { id: mouseArea objectName: "myMouseArea" anchors.fill: parent hoverEnabled: true property int testX : 0 property int testY : 0 property int steps : 0 onPositionChanged: { testX = mouseX; testY = mouseY; steps++; } } UbuntuTestCase { name: "TestTheUbuntuTestCase" when: windowShown function test_mouseMoveSlowly() { mouseMoveSlowly(root,0,0,800,600,10,100); compare(mouseArea.testX,800); compare(mouseArea.testY,600); compare(mouseArea.steps,10); } function test_findChild() { var child = findChild(root,"myMouseArea"); compare(child!==null,true, "When a child is found, it is returned"); compare(child.objectName,"myMouseArea"); child = findChild(root,"NoSuchChildHere"); compare(child===null,true,"When there is no child, function should return null"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/layout_dependency.pri0000644000015301777760000000061312321005637027021 0ustar pbusernogroup00000000000000COMPONENTS_PATH = ../../../modules/Ubuntu/Layouts INCLUDEPATH += $$COMPONENTS_PATH/plugin PRE_TARGETDEPS = $$COMPONENTS_PATH/libUbuntuLayouts.so LIBS += $$COMPONENTS_PATH/libUbuntuLayouts.so DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$_PRO_FILE_PWD_\\\"\" components.target = $$PRE_TARGETDEPS components.commands = cd $$COMPONENTS_PATH/plugin && $(QMAKE) && make QMAKE_EXTRA_TARGETS += components ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/0000755000015301777760000000000012321006415025157 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorFilledMargins.qml0000644000015301777760000000253712321005637031561 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { color: "red" objectName: "testItem" Layouts.item: "test" anchors.fill: parent anchors.margins: 10 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/OverlaidInItemLayout.qml0000644000015301777760000000322312321005637031750 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { id: layoutManager objectName: "layoutManager" anchors.fill: parent layouts: [ ConditionalLayout { name: "portrait" when: root.width < root.height ItemLayout { objectName: "layout" item: "red" x: 20 y: 30 width: 40 height: 30 Rectangle { objectName: "overlay" width: 10 height: 10 color: "green" z: 100 } } } ] Rectangle { objectName: "hostedItem" id: red width: 40 height: 30 color: "red" Layouts.item: "red" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorVerticalCenterOffset.qml0000644000015301777760000000266412321005637033123 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: 50 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorFilledReparenting.qml0000644000015301777760000000247712321005637032442 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { color: "red" objectName: "testItem" Layouts.item: "test" anchors.fill: parent } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/DefaultLayout.qml0000644000015301777760000000227712321005637030471 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { objectName: "defaultLayout" anchors.fill: parent Label { objectName: "item1" id: label1 Layouts.item: "item1" text: "item1" } Label { objectName: "item2" id: label2 anchors.bottom: label1.bottom Layouts.item: "item2" text: "item2" } Label { objectName: "item3" id: label3 anchors.bottom: label2.bottom Layouts.item: "item3" text: "item3" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorRight.qml0000644000015301777760000000263112321005637030111 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.right: parent.right anchors.rightMargin: 10 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/DialerCrash.qml0000644000015301777760000000261612321005637030065 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 import Ubuntu.Layouts 0.1 MainView { width: units.gu(40) height: units.gu(71) backgroundColor: "#A55263" property bool wide: true Layouts { objectName: "layoutManager" layouts: [ ConditionalLayout { name: "wideAspect" when: wide ItemLayout { item: "object1" } }, ConditionalLayout { name: "regularAspect" when: !wide ItemLayout { item: "object2" } } ] Dialer { Layouts.item: "object1" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/LargeLayout.qml0000644000015301777760000000177112321005637030135 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 ConditionalLayout { name: "large" when: layouts.width > units.gu(60) Row { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/SimpleLayouts.qml0000644000015301777760000000475512321005637030524 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(40) height: units.gu(30) property alias currentLayout: layouts.currentLayout Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ ConditionalLayout { name: "small" when: layouts.width <= units.gu(40) Column { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } }, ConditionalLayout { name: "medium" when: layouts.width > units.gu(40) && layouts.width <= units.gu(60) Flow { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } }, ConditionalLayout { name: "large" when: layouts.width > units.gu(60) Row { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } } ] // default layout DefaultLayout{ } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/NestedLayouts.qml0000644000015301777760000000411112321005637030477 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(40) height: units.gu(30) property string nestedLayout: "" Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ ConditionalLayout { name: "extra-large" when: layouts.width > units.gu(80) Item { anchors.fill: parent Item { id: header ItemLayout { item: "item3" } } Row { anchors.fill: parent anchors.topMargin: header.height ItemLayout { item: "item1" } ItemLayout { item: "item2" } } } }, ConditionalLayout { name: "simple" when: layouts.width <= units.gu(100) SimpleLayouts{ id: nested anchors.fill: parent onCurrentLayoutChanged: root.nestedLayout = nested.currentLayout } } ] // default layout DefaultLayout{ } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/CurrentLayoutChange.qml0000644000015301777760000000214012321005637031622 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 360 height: 360 Layouts { objectName: "layoutManager" id: layoutManager layouts: [ ConditionalLayout { name: "portrait" when: root.width < root.height }, ConditionalLayout { name: "landscape" when: root.width >= root.height } ] } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorHorizontalCenter.qml0000644000015301777760000000261312321005637032326 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.horizontalCenter: parent.horizontalCenter } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/LaidOutItemsOutsideOfLayout.qml0000644000015301777760000000247412321005637033271 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 360 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "portrait" when: root.width < root.height ItemLayout { item: "red" anchors.right: parent.right anchors.bottom: parent.bottom } } ] } Rectangle { objectName: "itemLaidOut" width: 40 height: 30 color: "red" Layouts.item: "red" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/tst_layouts.pro0000644000015301777760000000202312321005637030275 0ustar pbusernogroup00000000000000include(../test-include.pri) include(../../unit/qtprivate_dependency.pri) QT += gui SOURCES += \ tst_layouts.cpp OTHER_FILES += \ SimpleLayouts.qml \ NoLayouts.qml \ OverlappingCondition.qml \ SmallLayout.qml \ MediumLayout.qml \ LargeLayout.qml \ ExternalLayouts.qml \ NestedLayouts.qml \ DefaultLayout.qml \ ResizingContainers.qml \ SizedDefaultLayout.qml \ CurrentLayoutChange.qml \ PositioningOnLayoutChange.qml \ LaidOutItemsOutsideOfLayout.qml \ OverlaidInItemLayout.qml \ AnchorFilledReparenting.qml \ AnchorCenteredInDefault.qml \ AnchorFilledMargins.qml \ AnchorFilledSeparateMargins.qml \ AnchorVerticalCenter.qml \ AnchorVerticalCenterOffset.qml \ AnchorCenterWithOffset.qml \ AnchorHorizontalCenter.qml \ AnchorHorizontalCenterOffset.qml \ AnchorLeft.qml \ AnchorRight.qml \ AnchorTop.qml \ AnchorBottom.qml \ AnchorAll.qml \ ItemInstanceAsProperty.qml \ DialerCrash.qml \ ExcludedItemDeleted.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorLeft.qml0000644000015301777760000000262612321005637027732 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.left: parent.left anchors.leftMargin: 10 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/PositioningOnLayoutChange.qml0000644000015301777760000000275712321005637033015 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 360 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "portrait" when: root.width < root.height ItemLayout { item: "red" anchors.right: parent.right anchors.bottom: parent.bottom } }, ConditionalLayout { name: "landscape" when: root.width > root.height } ] Rectangle { anchors.fill: parent; color: 'yellow'} Rectangle { width: 40 height: 30 color: "red" Layouts.item: "red" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/NoLayouts.qml0000644000015301777760000000157512321005637027644 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(40) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/OverlappingCondition.qml0000644000015301777760000000366312321005637032044 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(40) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ ConditionalLayout { name: "small" when: layouts.width <= units.gu(40) Column { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } }, ConditionalLayout { name: "medium" when: layouts.width >= units.gu(40) && layouts.width <= units.gu(60) Flow { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } } ] DefaultLayout{ } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorTop.qml0000644000015301777760000000262312321005637027577 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.top: parent.top anchors.topMargin: 10 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorFilledSeparateMargins.qml0000644000015301777760000000271512321005637033244 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { color: "red" objectName: "testItem" Layouts.item: "test" anchors.fill: parent anchors.leftMargin: 10 anchors.topMargin: 20 anchors.rightMargin: 30 anchors.bottomMargin: 40 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/SizedDefaultLayout.qml0000644000015301777760000000301612321005637031460 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { objectName: "defaultLayout" anchors.fill: parent Button { objectName: "item1" id: label1 Layouts.item: "item1" text: "item1" anchors { left: parent.left right: parent.right } } Button { objectName: "item2" id: label2 anchors.bottom: label1.bottom Layouts.item: "item2" text: "item2" anchors { left: parent.left top: label1.bottom right: parent.right } } Button { objectName: "item3" id: label3 anchors.bottom: label2.bottom Layouts.item: "item3" text: "item3" anchors { left: parent.left top: label2.bottom right: parent.right } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorCenteredInDefault.qml0000644000015301777760000000256212321005637032364 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.centerIn: parent } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/tst_layouts.cpp0000644000015301777760000007620712321005637030276 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include #include #include #include "ullayouts.h" #include "ucunits.h" #include "uctestcase.h" #include #include #define QCOMPARE_RET(actual, expected) \ do {\ if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\ return false;\ } while (0) #define QVERIFY_RET(statement, resturns) \ do {\ if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\ return resturns;\ } while (0) class tst_Layouts : public QObject { Q_OBJECT private: QString m_modulePath; public: tst_Layouts() { } QQuickView * loadTest(const QString &file) { UbuntuTestCase* testCase = new UbuntuTestCase(file); return qobject_cast(testCase); } QQuickItem *testItem(QQuickItem *that, const QString &identifier) { if (that->property(identifier.toLocal8Bit()).isValid()) return that->property(identifier.toLocal8Bit()).value(); QList children = that->findChildren(identifier); return (children.count() > 0) ? children[0] : 0; } private Q_SLOTS: void initTestCase() { } void cleanupTestCase() { } void testCase_NoLayouts() { QScopedPointer testCase(new UbuntuTestCase("NoLayouts.qml")); ULLayouts *layouts = testCase->findItem("layouts"); QVERIFY(layouts->layoutList().isEmpty()); } void testCase_SimpleLayout() { QScopedPointer view(loadTest("SimpleLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy currentLayout(layouts, SIGNAL(currentLayoutChanged())); currentLayout.wait(300); QCOMPARE(layouts->currentLayout(), QString("small")); QQuickItem *item = testItem(root, "item1"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickColumn")); item = testItem(root, "item2"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickColumn")); item = testItem(root, "item3"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickColumn")); } void testCase_SimpleLayout_Medium() { QScopedPointer view(loadTest("SimpleLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy layoutChangeSpy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(UCUnits::instance().gu(55)); QCOMPARE(root->width(), UCUnits::instance().gu(55)); layoutChangeSpy.wait(100); QCOMPARE(layoutChangeSpy.count(), 1); QCOMPARE(layouts->currentLayout(), QString("medium")); QQuickItem *item = testItem(root, "item1"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickFlow")); item = testItem(root, "item2"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickFlow")); item = testItem(root, "item3"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickFlow")); } void testCase_SimpleLayout_Large() { QScopedPointer view(loadTest("SimpleLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy layoutChangeSpy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(UCUnits::instance().gu(65)); QCOMPARE(root->width(), UCUnits::instance().gu(65)); layoutChangeSpy.wait(100); QCOMPARE(layoutChangeSpy.count(), 1); QCOMPARE(layouts->currentLayout(), QString("large")); QQuickItem *item = testItem(root, "item1"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickRow")); item = testItem(root, "item2"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickRow")); item = testItem(root, "item3"); QVERIFY(item); QVERIFY(item->parentItem()->parentItem()->inherits("QQuickRow")); } void testCase_OverlappingCondition() { QScopedPointer view(loadTest("OverlappingCondition.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy currentLayout(layouts, SIGNAL(currentLayoutChanged())); currentLayout.wait(300); QCOMPARE(layouts->currentLayout(), QString("small")); } void testCase_ExternalLayouts() { QScopedPointer view(loadTest("ExternalLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy currentLayout(layouts, SIGNAL(currentLayoutChanged())); currentLayout.wait(300); QCOMPARE(layouts->currentLayout(), QString("small")); } void testCase_ExternalLayouts_Medium() { QScopedPointer view(loadTest("ExternalLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy layoutChangeSpy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(UCUnits::instance().gu(55)); layoutChangeSpy.wait(100); QCOMPARE(layoutChangeSpy.count(), 1); QCOMPARE(layouts->currentLayout(), QString("medium")); } void testCase_ExternalLayouts_Large() { QScopedPointer view(loadTest("ExternalLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy layoutChangeSpy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(UCUnits::instance().gu(65)); layoutChangeSpy.wait(100); QCOMPARE(layoutChangeSpy.count(), 1); QCOMPARE(layouts->currentLayout(), QString("large")); } void testCase_NestedLayouts() { QScopedPointer view(loadTest("NestedLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy currentLayout(layouts, SIGNAL(currentLayoutChanged())); currentLayout.wait(300); QCOMPARE(layouts->currentLayout(), QString("simple")); } void testCase_NestedLayouts_ExtraLarge() { QScopedPointer view(loadTest("NestedLayouts.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy layoutChangeSpy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(UCUnits::instance().gu(90)); layoutChangeSpy.wait(100); QCOMPARE(layoutChangeSpy.count(), 1); QCOMPARE(layouts->currentLayout(), QString("extra-large")); root->setWidth(UCUnits::instance().gu(50)); layoutChangeSpy.wait(100); QCOMPARE(layoutChangeSpy.count(), 2); QCOMPARE(root->property("nestedLayout").toString(), QString("medium")); } void testCase_ResizingContainers() { QScopedPointer view(loadTest("ResizingContainers.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); // fetch the current size of one item QQuickItem *item = testItem(root, "item1"); qreal width = item->width(); qreal height = item->height(); QQuickItem *item2 = testItem(root, "item2"); qreal width2 = item2->width(); qreal height2 = item2->height(); ULLayouts *layouts = qobject_cast(testItem(root, "layouts")); QVERIFY(layouts); QVERIFY(!layouts->layoutList().isEmpty()); QSignalSpy layoutChangeSpy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(UCUnits::instance().gu(50)); layoutChangeSpy.wait(100); QCOMPARE(layouts->currentLayout(), QString("small")); QCOMPARE(item->width(), UCUnits::instance().gu(10)); QCOMPARE(item->height(), UCUnits::instance().gu(10)); root->setWidth(UCUnits::instance().gu(60)); layoutChangeSpy.wait(100); QCOMPARE(layouts->currentLayout(), QString("large")); QCOMPARE(item->width(), UCUnits::instance().gu(22)); QCOMPARE(item->height(), UCUnits::instance().gu(22)); root->setWidth(UCUnits::instance().gu(80)); layoutChangeSpy.wait(100); QCOMPARE(layouts->currentLayout(), QString("xlarge")); QCOMPARE(item->width(), UCUnits::instance().gu(30)); QCOMPARE(item->height(), UCUnits::instance().gu(30)); QCOMPARE(item2->width(), UCUnits::instance().gu(40)); QCOMPARE(item2->height(), UCUnits::instance().gu(50)); root->setWidth(UCUnits::instance().gu(40)); layoutChangeSpy.wait(100); QCOMPARE(item->width(), width); QCOMPARE(item->height(), height); QCOMPARE(item2->width(), width2); QCOMPARE(item2->height(), height2); } void testCase_CurrentLayoutChange() { QScopedPointer view(loadTest("CurrentLayoutChange.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layoutManager")); QVERIFY(layouts); QSignalSpy spy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(root->height() - 10); spy.wait(100); QEXPECT_FAIL(0, "Layout change should not happen when component is not defined", Continue); QCOMPARE(spy.count(), 1); } void testCase_PositioningOnLayoutChange() { QScopedPointer view(loadTest("PositioningOnLayoutChange.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layoutManager")); QVERIFY(layouts); QSignalSpy spy(layouts, SIGNAL(currentLayoutChanged())); root->setWidth(root->height() + 10); spy.wait(100); QEXPECT_FAIL(0, "Layout change should not happen when component is not defined", Continue); QCOMPARE(spy.count(), 1); spy.clear(); root->setWidth(root->height() - 10); spy.wait(100); QCOMPARE(spy.count(), 1); } void testCase_LaidOutItemsOutsideOfLayout() { QScopedPointer view(loadTest("LaidOutItemsOutsideOfLayout.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *item = qobject_cast(testItem(root, "itemLaidOut")); QVERIFY(item); ULLayoutsAttached *marker = qobject_cast( qmlAttachedPropertiesObject(item, false)); QVERIFY(marker); QVERIFY(!marker->isValid()); } void testCase_OverlaidInItemLayout() { QScopedPointer view(loadTest("OverlaidInItemLayout.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); ULLayouts *layouts = qobject_cast(testItem(root, "layoutManager")); QVERIFY(layouts); QSignalSpy currentLayout(layouts, SIGNAL(currentLayoutChanged())); currentLayout.wait(300); QQuickItem *layout = qobject_cast(testItem(root, "layout")); QVERIFY(layout); QQuickItem *item = qobject_cast(testItem(root, "hostedItem")); QVERIFY(item); QCOMPARE(layout->childItems()[0], item); } void testCase_AnchorFilledReparenting() { QScopedPointer view(loadTest("AnchorFilledReparenting.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->fill(), layout); } void testCase_AnchorFilledMargins() { QScopedPointer view(loadTest("AnchorFilledMargins.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QCOMPARE(anchors->margins(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->fill(), layout); QCOMPARE(anchors->margins(), 10.0); } void testCase_AnchorFilledSeparateMargins() { QScopedPointer view(loadTest("AnchorFilledSeparateMargins.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QCOMPARE(anchors->margins(), 0.0); QCOMPARE(anchors->leftMargin(), 0.0); QCOMPARE(anchors->rightMargin(), 0.0); QCOMPARE(anchors->topMargin(), 0.0); QCOMPARE(anchors->bottomMargin(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->fill(), layout); QCOMPARE(anchors->leftMargin(), 10.0); QCOMPARE(anchors->topMargin(), 20.0); QCOMPARE(anchors->rightMargin(), 30.0); QCOMPARE(anchors->bottomMargin(), 40.0); } void testCase_AnchorCenteredInDefault() { QScopedPointer view(loadTest("AnchorCenteredInDefault.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->centerIn(), layout); } void testCase_AnchorVerticalCenter() { QScopedPointer view(loadTest("AnchorVerticalCenter.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->verticalCenter().item, layout); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->verticalCenter().item, layout); } void testCase_AnchorVerticalCenterOffset() { QScopedPointer view(loadTest("AnchorVerticalCenterOffset.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->verticalCenter().item, layout); QCOMPARE(anchors->verticalCenterOffset(), 50.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = qobject_cast(testItem(root, "testLayout")); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); // no need to check offset as it does not affect the fill root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->verticalCenter().item, layout); QCOMPARE(anchors->verticalCenterOffset(), 50.0); } void testCase_AnchorHorizontalCenter() { QScopedPointer view(loadTest("AnchorHorizontalCenter.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->horizontalCenter().item, layout); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->horizontalCenter().item, layout); } void testCase_AnchorHorizontalCenterOffset() { QScopedPointer view(loadTest("AnchorHorizontalCenterOffset.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->horizontalCenter().item, layout); QCOMPARE(anchors->horizontalCenterOffset(), 50.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); // no need to check offset as it does not affect the fill root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->horizontalCenter().item, layout); QCOMPARE(anchors->horizontalCenterOffset(), 50.0); } void testCase_AnchorCenterWithOffset() { QScopedPointer view(loadTest("AnchorCenterWithOffset.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->centerIn(), layout); QCOMPARE(anchors->verticalCenterOffset(), 50.0); QCOMPARE(anchors->horizontalCenterOffset(), 40.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); // no need to check offsets as it does not affect the fill root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->centerIn(), layout); QCOMPARE(anchors->verticalCenterOffset(), 50.0); QCOMPARE(anchors->horizontalCenterOffset(), 40.0); } void testCase_AnchorLeft() { QScopedPointer view(loadTest("AnchorLeft.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->left().item, layout); QCOMPARE(anchors->leftMargin(), 10.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QCOMPARE(anchors->leftMargin(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->left().item, layout); QCOMPARE(anchors->leftMargin(), 10.0); } void testCase_AnchorTop() { QScopedPointer view(loadTest("AnchorTop.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->top().item, layout); QCOMPARE(anchors->topMargin(), 10.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QCOMPARE(anchors->topMargin(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->top().item, layout); QCOMPARE(anchors->topMargin(), 10.0); } void testCase_AnchorRight() { QScopedPointer view(loadTest("AnchorRight.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->right().item, layout); QCOMPARE(anchors->rightMargin(), 10.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QCOMPARE(anchors->rightMargin(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->right().item, layout); QCOMPARE(anchors->rightMargin(), 10.0); } void testCase_AnchorBottom() { QScopedPointer view(loadTest("AnchorBottom.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->bottom().item, layout); QCOMPARE(anchors->bottomMargin(), 10.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QCOMPARE(anchors->bottomMargin(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->bottom().item, layout); QCOMPARE(anchors->bottomMargin(), 10.0); } void testCase_AnchorAll() { QScopedPointer view(loadTest("AnchorAll.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); QQuickItem *item = testItem(root, "testItem"); QVERIFY(item); QQuickAnchors *anchors = item->property("anchors").value(); QVERIFY(anchors); QCOMPARE(anchors->left().item, layout); QCOMPARE(anchors->top().item, layout); QCOMPARE(anchors->right().item, layout); QCOMPARE(anchors->bottom().item, layout); QVERIFY(!anchors->fill()); QCOMPARE(anchors->margins(), 20.0); root->setWidth(root->width() + 100); layoutChangeSpy.wait(100); QQuickItem *testLayout = testItem(root, "testLayout"); QVERIFY(testLayout); QCOMPARE(anchors->fill(), testLayout); QVERIFY(!anchors->left().item); QVERIFY(!anchors->top().item); QVERIFY(!anchors->right().item); QVERIFY(!anchors->bottom().item); QCOMPARE(anchors->margins(), 0.0); root->setWidth(root->width() - 100); layoutChangeSpy.wait(100); QCOMPARE(anchors->left().item, layout); QCOMPARE(anchors->top().item, layout); QCOMPARE(anchors->right().item, layout); QCOMPARE(anchors->bottom().item, layout); QVERIFY(!anchors->fill()); QCOMPARE(anchors->margins(), 20.0); } // the following tests guard bug #1280359 void testCase_ItemInstanceAsProperty() { QScopedPointer view(loadTest("ItemInstanceAsProperty.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); // invoke layout change view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "changeLayout"); layoutChangeSpy.wait(); QCOMPARE(layoutChangeSpy.count(), 1); } void testCase_DialerCrash() { QScopedPointer view(loadTest("DialerCrash.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); // invoke layout change view->rootObject()->setProperty("wide", false); layoutChangeSpy.wait(); QCOMPARE(layoutChangeSpy.count(), 1); } void testCase_ExcludedItemDeleted() { QScopedPointer view(loadTest("ExcludedItemDeleted.qml")); QVERIFY(view); QQuickItem *root = view->rootObject(); QVERIFY(root); QQuickItem *layout = testItem(root, "layoutManager"); QVERIFY(layout); QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged())); // invoke layout change view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "changeLayout"); layoutChangeSpy.wait(); QCOMPARE(layoutChangeSpy.count(), 1); } }; QTEST_MAIN(tst_Layouts) #include "tst_layouts.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/ExternalLayouts.qml0000644000015301777760000000205112321005637031040 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(40) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ SmallLayout{}, MediumLayout {}, LargeLayout {} ] // default layout DefaultLayout{ } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorVerticalCenter.qml0000644000015301777760000000260712321005637031751 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.verticalCenter: parent.verticalCenter } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/MediumLayout.qml0000644000015301777760000000203412321005637030314 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 ConditionalLayout { name: "medium" when: layouts.width > units.gu(40) && layouts.width <= units.gu(60) Flow { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorHorizontalCenterOffset.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorHorizontalCenterOffset.qm0000644000015301777760000000267412321005637033330 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 50.0 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorCenterWithOffset.qml0000644000015301777760000000271612321005637032263 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.centerIn: parent anchors.verticalCenterOffset: 50 anchors.horizontalCenterOffset: 40 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/ItemInstanceAsProperty.qml0000644000015301777760000000322112321005637032311 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { property bool wide: true width: units.gu(40) height: units.gu(71) function changeLayout() { loader.sourceComponent = undefined; wide = false } Layouts { objectName: "layoutManager" layouts: [ ConditionalLayout { name: "wideAspect" when: wide ItemLayout { item: "object1" } }, ConditionalLayout { name: "regularAspect" when: !wide ItemLayout { item: "object2" anchors.left: parent.left } } ] Item { Layouts.item: "object1" Loader { id: loader sourceComponent: ShaderEffectSource { sourceItem: Item { } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/ExcludedItemDeleted.qml0000644000015301777760000000337712321005637031554 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { property bool wide: true width: units.gu(40) height: units.gu(71) function changeLayout() { loader2.sourceComponent = undefined; wide = false } Layouts { objectName: "layoutManager" layouts: [ ConditionalLayout { name: "wideAspect" when: wide ItemLayout { item: "object1" } }, ConditionalLayout { name: "regularAspect" when: !wide ItemLayout { item: "object1" anchors.left: parent.left } } ] Column { Loader { Layouts.item: "object1" id: loader sourceComponent: ShaderEffectSource { sourceItem: Item { } } } Loader { id: loader2 sourceComponent: Item{} } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/ResizingContainers.qml0000644000015301777760000000636512321005637031531 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(40) height: units.gu(30) property alias currentLayout: layouts.currentLayout Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ ConditionalLayout { name: "xlarge" when: layouts.width >= units.gu(80) Column { anchors.fill: parent ItemLayout { item: "item1" width: units.gu(30) height: units.gu(30) } ItemLayout { item: "item3" width: units.gu(30) height: units.gu(30) } ItemLayout { item: "item2" width: units.gu(40) height: units.gu(50) } } }, ConditionalLayout { name: "large" when: layouts.width >= units.gu(60) Column { anchors.fill: parent ItemLayout { item: "item1" width: units.gu(22) height: units.gu(22) } ItemLayout { item: "item2" width: units.gu(22) height: units.gu(22) } ItemLayout { item: "item3" width: units.gu(22) height: units.gu(22) } } }, ConditionalLayout { name: "small" when: layouts.width > units.gu(40) Row { anchors.fill: parent ItemLayout { item: "item1" width: units.gu(10) height: units.gu(10) } ItemLayout { item: "item2" width: units.gu(10) height: units.gu(10) } ItemLayout { item: "item3" width: units.gu(10) height: units.gu(10) } } } ] // default layout SizedDefaultLayout{ } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorAll.qml0000644000015301777760000000301112321005637027535 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 20 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/SmallLayout.qml0000644000015301777760000000177512321005637030157 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 ConditionalLayout { name: "small" when: layouts.width <= units.gu(40) Column { anchors.fill: parent ItemLayout { item: "item1" } ItemLayout { item: "item2" } ItemLayout { item: "item3" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_layouts/AnchorBottom.qml0000644000015301777760000000263412321005637030303 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Layouts 0.1 Rectangle { id: root width: 300 height: 360 Layouts { objectName: "layoutManager" id: layoutManager anchors.fill: parent layouts: [ ConditionalLayout { name: "landscape" when: root.width > root.height ItemLayout { objectName: "testLayout" anchors.fill: parent item: "test" } } ] Rectangle { width: 100 height: 100 color: "red" objectName: "testItem" Layouts.item: "test" anchors.bottom: parent.bottom anchors.bottomMargin: 10 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/0000755000015301777760000000000012321006415026200 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterFlickable.qml0000644000015301777760000000201112321005637031734 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Flickable { width: units.gu(40) height: units.gu(40) clip: true objectName: "FilterOwner" Mouse.priority: Mouse.BeforeItem contentWidth: content.width contentHeight: content.height Rectangle { id: content width: units.gu(100) height: units.gu(100) color: "green" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInput.qml0000644000015301777760000000174312321005637033373 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(40) height: units.gu(71) TextInput { objectName: "FilterOwner" width: units.gu(30) height: units.gu(4) activeFocusOnPress: true // create InverseMouse filter attached InverseMouse.priority: Mouse.BeforeItem } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/PressAndHoldAndClicked.qml0000644000015301777760000000151712321005637033154 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { objectName: "FilterOwner" width: units.gu(10) height: units.gu(5) activeFocusOnPress: true Mouse.onPressAndHold: {} } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterTextInputAfter.qml0000644000015301777760000000157212321005637033021 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { objectName: "FilterOwner" width: units.gu(10) height: units.gu(5) activeFocusOnPress: true // create Mouse filter attached Mouse.priority: Mouse.AfterItem } ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterTextInputTolerance.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterTextInputTolerance.q0000644000015301777760000000165212321005637033342 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { objectName: "FilterOwner" width: units.gu(10) height: units.gu(5) activeFocusOnPress: true // create Mouse filter attached Mouse.priority: Mouse.BeforeItem Mouse.clickAndHoldThreshold: units.gu(0.5) } ././@LongLink0000000000000000000000000000016400000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardDblClickToTransparentMouseArea.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardDblClickToTranspare0000644000015301777760000000247612321005637033320 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) MouseArea { id: topArea objectName: "target" width: units.gu(40) height: units.gu(10) preventStealing: false onPressed: mouse.accepted = false onReleased: mouse.accepted = false onDoubleClicked: mouse.accepted = false TextInput { objectName: "FilterOwner" width: units.gu(30) height: units.gu(5) anchors.centerIn: parent selectByMouse: true text: "This is a test text" Mouse.forwardTo: [topArea] } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterFlickableAfter.qml0000644000015301777760000000221212321005637032721 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) Flickable { width: root.width height: units.gu(40) clip: true objectName: "FilterOwner" Mouse.priority: Mouse.AfterItem contentWidth: content.width contentHeight: content.height Rectangle { id: content width: units.gu(100) height: units.gu(100) color: "green" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/InverseAttachedToItem.qml0000644000015301777760000000137712321005637033123 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 100 height: 62 InverseMouse.enabled: true } ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardToTransparentMouseArea.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardToTransparentMouseA0000644000015301777760000000224712321005637033400 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) MouseArea { id: topArea objectName: "target" width: units.gu(40) height: units.gu(10) onPressed: mouse.accepted = false onReleased: mouse.accepted = false TextInput { objectName: "FilterOwner" width: units.gu(30) height: units.gu(5) anchors.centerIn: parent Mouse.forwardTo: [topArea] } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/tst_mousefilters.pro0000644000015301777760000000175112321005637032346 0ustar pbusernogroup00000000000000include(../test-include.pri) QT += quick-private SOURCES += tst_mousefilterstest.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" OTHER_FILES += \ FilterTextInput.qml \ PressAndHoldAcceptedEatsClick.qml \ PressAndHoldAndClicked.qml \ FilterInverseTextInput.qml \ FilterInverseTextInputOSKExcluded.qml \ AttachedToItem.qml \ InverseAttachedToItem.qml \ MouseFilterAttachedToNonItem.qml \ InverseMouseFilterAttachedToNonItem.qml \ ForwardedMouseEvents.qml \ ForwardToMouseArea.qml \ FilterTextInputAfter.qml \ FilterInverseTextInputAfter.qml \ ForwardedMouseEventsStopped.qml \ ForwardedEventsToTargetBlocked.qml \ ForwardToInverseMouseArea.qml \ FilterFlickable.qml \ FilterFlickableAfter.qml \ Hover.qml \ FilterTextInputTolerance.qml \ FilterInverseTextInputTolerance.qml \ ForwardedEventsStoppedInForwards.qml \ ForwardToTransparentMouseArea.qml \ ForwardDblClickToTransparentMouseArea.qml \ DoubleClicked.qml ././@LongLink0000000000000000000000000000015500000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedEventsToTargetBlocked.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedEventsToTargetBlo0000644000015301777760000000202712321005637033342 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) objectName: "target" Mouse.enabled: true TextInput { objectName: "FilterOwner" width: root.width height: units.gu(5) Mouse.forwardTo: [root] Mouse.priority: Mouse.AfterItem Mouse.onPressed: mouse.accepted = true } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/tst_mousefilterstest.cpp0000644000015301777760000011765112321005637033237 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include "ucmouse.h" #include "ucinversemouse.h" #include "ucunits.h" #include "quickutils.h" #include "inversemouseareatype.h" #include #include // keep in sync with QQuickMouseArea PressAndHoldDelay const int DefaultPressAndHoldDelay = 800; template T *attachedFilter(QQuickItem *item, const QString &objectName) { QQuickItem *testItem = item->objectName() == objectName ? item : item->findChild(objectName); if (testItem) { return qobject_cast(qmlAttachedPropertiesObject(testItem, false)); } return 0; } class tst_mouseFilterTest : public QObject { Q_OBJECT public: tst_mouseFilterTest() {} private: QString m_modulePath; bool insideClick; bool oskClick; QQuickView * loadTest(const QString &file, QSignalSpy **spy = 0) { QQuickView *view = new QQuickView; if (spy) { *spy = new QSignalSpy(view->engine(), SIGNAL(warnings(QList))); (*spy)->setParent(view); } view->engine()->addImportPath(m_modulePath); view->setSource(QUrl::fromLocalFile(file)); if (!view->rootObject()) { delete view; view = 0; } else { view->show(); QTest::qWaitForWindowExposed(view); } return view; } void mousePressAndHold(QWindow *view, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, const QPoint &point, int delay = DefaultPressAndHoldDelay + 200) { QTest::mousePress(view, button, modifiers, point); QTest::qWait(delay); } bool inputPanelPresent() { return !QuickUtils::instance().inputMethodProvider().isEmpty(); } QPoint guPoint(qreal guX, qreal guY) { return QPoint(UCUnits::instance().gu(guX), UCUnits::instance().gu(guY)); } void preventDblClick() { QTest::qWait(400); } protected Q_SLOTS: private Q_SLOTS: void initTestCase() { QString modules("../../../modules"); QVERIFY(QDir(modules).exists()); m_modulePath = QDir(modules).absolutePath(); } void cleanupTestCase() { } void testCase_pressedInsideTextInput() { QScopedPointer view(loadTest("FilterTextInput.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedInsideTextInputHandledAfter() { QScopedPointer view(loadTest("FilterTextInputAfter.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedOutsideTextInput() { QScopedPointer view(loadTest("FilterInverseTextInput.qml")); QVERIFY(view); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedOutsideTextInputAfter() { QSignalSpy *spy; QScopedPointer view(loadTest("FilterInverseTextInputAfter.qml", &spy)); QVERIFY(view); QCOMPARE(spy->count(), 1); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedInsideTextInputTolerance() { QScopedPointer view(loadTest("FilterTextInputTolerance.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::mouseMove(view.data(), guPoint(2.2, 2.2)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(2.2, 2.2)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedOutsideTextInputTolerance() { QScopedPointer view(loadTest("FilterInverseTextInputTolerance.qml")); QVERIFY(view); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::mouseMove(view.data(), guPoint(10.2, 10.2)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(10.2, 10.2)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedInsideTextInputOutOfTolerance() { QScopedPointer view(loadTest("FilterTextInputTolerance.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::mouseMove(view.data(), guPoint(2.7, 2.7)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(2.7, 2.7)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 0); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedOutsideTextInputOutOfTolerance() { QScopedPointer view(loadTest("FilterInverseTextInputTolerance.qml")); QVERIFY(view); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::mouseMove(view.data(), guPoint(10.6, 10.6)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(10.6, 10.6)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 0); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressedOverOSKExcluded() { QScopedPointer view(loadTest("FilterInverseTextInputOSKExcluded.qml")); QVERIFY(view); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); // focus TextInput QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); input->forceActiveFocus(); QCOMPARE(input->hasFocus(), true); // introduce small delay to suppress double clicks preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::waitForEvents(); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(10, 69)); QTest::waitForEvents(); if (!inputPanelPresent()) { QEXPECT_FAIL(0, "No OSK installed", Abort); } QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressAndMovedInsideTextInput() { QScopedPointer view(loadTest("FilterTextInput.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); // make sure we do not get double click because of the previous tests preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::mouseMove(view.data(), guPoint(2.7, 2.7)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(2.7, 2.7)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressAndMovedOutsideTextInputInTolerance() { QScopedPointer view(loadTest("FilterInverseTextInputTolerance.qml")); QVERIFY(view); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); // make sure we do not get double click because of the previous tests preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::mouseMove(view.data(), guPoint(10.5, 10.5)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(10.5, 10.5)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressAndMovedOutsideTextInputOutTolerance() { QScopedPointer view(loadTest("FilterInverseTextInputTolerance.qml")); QVERIFY(view); UCInverseMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); // make sure we do not get double click because of the previous tests preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(10, 10)); QTest::mouseMove(view.data(), guPoint(15, 15)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(15, 15)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 0); QCOMPARE(positionChanged.count(), 1); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_pressAndHoldDisableClick() { QScopedPointer view(loadTest("PressAndHoldAcceptedEatsClick.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); preventDblClick(); mousePressAndHold(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressAndHold.count(), 1); QCOMPARE(clicked.count(), 0); } void testCase_pressAndHoldAndClick() { QScopedPointer view(loadTest("PressAndHoldAndClicked.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); preventDblClick(); mousePressAndHold(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::qWait(DefaultPressAndHoldDelay + 200); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(view->rootObject()->hasFocus(), true); QCOMPARE(pressAndHold.count(), 1); QCOMPARE(clicked.count(), 1); } void testCase_doubleClicked() { QScopedPointer view(loadTest("DoubleClicked.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QQuickItem *input = view->rootObject(); QVERIFY(input); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy dblClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); preventDblClick(); QTest::mouseDClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QVariant selectedText = input->property("selectedText"); QCOMPARE(input->hasFocus(), true); QVERIFY(selectedText.isValid()); QVERIFY(!selectedText.toString().isEmpty()); // ther emust be one click, the second one should be suppressed // by the doubleClicked() signal being connected at least to signalSpy! QCOMPARE(clicked.count(), 1); QCOMPARE(dblClicked.count(), 1); } void testCase_mouseFilterAttachedToNonItem() { QSignalSpy *warningSpy; QScopedPointer view(loadTest("MouseFilterAttachedToNonItem.qml", &warningSpy)); QVERIFY(view); QCOMPARE(warningSpy->count(), 1); } void testCase_inverseMouseFilterAttachedToNonItem() { QSignalSpy *warningSpy; QScopedPointer view(loadTest("InverseMouseFilterAttachedToNonItem.qml", &warningSpy)); QVERIFY(view); QCOMPARE(warningSpy->count(), 1); } void testCase_forwardedEventsToItem() { QScopedPointer view(loadTest("ForwardedMouseEvents.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "target"); QVERIFY(filter); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_forwardedEventsToItemStopped() { QScopedPointer view(loadTest("ForwardedMouseEventsStopped.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "target"); QVERIFY(filter); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), false); QCOMPARE(pressed.count(), 0); QCOMPARE(released.count(), 0); QCOMPARE(clicked.count(), 0); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 0); QCOMPARE(exited.count(), 0); } void testCase_forwardedEventsToItemStoppedInForwards() { QScopedPointer view(loadTest("ForwardedEventsStoppedInForwards.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "target"); QVERIFY(filter); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_forwardedEventsToTargetBlocked() { QScopedPointer view(loadTest("ForwardedEventsToTargetBlocked.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "target"); QVERIFY(filter); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), true); QCOMPARE(pressed.count(), 0); QCOMPARE(released.count(), 0); QCOMPARE(clicked.count(), 0); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 0); QCOMPARE(exited.count(), 0); } void testCase_forwardedEventsToMouseArea() { QScopedPointer view(loadTest("ForwardToMouseArea.qml")); QVERIFY(view); QQuickItem *target = view->rootObject()->findChild("target"); QVERIFY(target); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(target, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(target, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(target, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(target, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(target, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(target, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(target, SIGNAL(entered())); QSignalSpy exited(target, SIGNAL(exited())); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), false); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_forwardedEventsToTransparentMouseArea() { QScopedPointer view(loadTest("ForwardToTransparentMouseArea.qml")); QVERIFY(view); QQuickItem *target = view->rootObject()->findChild("target"); QVERIFY(target); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(target, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(target, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(target, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(target, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(target, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(target, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(target, SIGNAL(entered())); QSignalSpy exited(target, SIGNAL(exited())); preventDblClick(); QTest::mouseClick(input->window(), Qt::LeftButton, 0, guPoint(10, 7)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } void testCase_forwardedDblClickToTransparentMouseArea() { QScopedPointer view(loadTest("ForwardDblClickToTransparentMouseArea.qml")); QVERIFY(view); QQuickItem *target = view->rootObject()->findChild("target"); QVERIFY(target); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy doubleClicked(target, SIGNAL(doubleClicked(QQuickMouseEvent*))); preventDblClick(); QTest::mouseDClick(input->window(), Qt::LeftButton, 0, guPoint(10, 7)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), true); QVariant selectedText = input->property("selectedText"); QVERIFY(selectedText.isValid()); QVERIFY(selectedText.toString().isEmpty()); QCOMPARE(doubleClicked.count(), 1); } void testCase_forwardedEventsToInverseMouseArea() { QScopedPointer view(loadTest("ForwardToInverseMouseArea.qml")); QVERIFY(view); QQuickItem *target = view->rootObject()->findChild("target"); QVERIFY(target); QQuickItem *input = view->rootObject()->findChild("FilterOwner"); QVERIFY(input); QSignalSpy pressed(target, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(target, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(target, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(target, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(target, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(target, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(target, SIGNAL(entered())); QSignalSpy exited(target, SIGNAL(exited())); preventDblClick(); QTest::mouseClick(view.data(), Qt::LeftButton, 0, guPoint(2, 2)); QTest::waitForEvents(); QCOMPARE(input->hasFocus(), true); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 0); QCOMPARE(clicked.count(), 0); QCOMPARE(positionChanged.count(), 0); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 0); } void testCase_filterFlickable() { QScopedPointer view(loadTest("FilterFlickable.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QQuickItem *flickable = view->rootObject(); QVERIFY(flickable); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); QSignalSpy flickStart(flickable, SIGNAL(movementStarted())); preventDblClick(); QTest::mousePress(flickable->window(), Qt::LeftButton, 0, guPoint(5, 5)); for (int i = 0; i < 30; i++) { QTest::mouseMove(flickable->window(), guPoint(5 + i, 5 + i)); } QTest::waitForEvents(); QTest::mouseRelease(flickable->window(), Qt::LeftButton, 0, guPoint(35, 35)); QTest::waitForEvents(); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 30); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); QCOMPARE(flickStart.count(), 1); } void testCase_filterFlickableAfter() { QScopedPointer view(loadTest("FilterFlickableAfter.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QQuickItem *flickable = view->rootObject()->findChild("FilterOwner"); QVERIFY(flickable); QSignalSpy pressed(filter, SIGNAL(pressed(QQuickMouseEvent*))); QSignalSpy released(filter, SIGNAL(released(QQuickMouseEvent*))); QSignalSpy clicked(filter, SIGNAL(clicked(QQuickMouseEvent*))); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy doubleClicked(filter, SIGNAL(doubleClicked(QQuickMouseEvent*))); QSignalSpy pressAndHold(filter, SIGNAL(pressAndHold(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); QSignalSpy flickStart(flickable, SIGNAL(movementStarted())); preventDblClick(); QTest::mousePress(flickable->window(), Qt::LeftButton, 0, guPoint(5, 5)); for (int i = 0; i < 30; i++) { QTest::mouseMove(flickable->window(), guPoint(5 + i, 5 + i)); } QTest::mouseRelease(flickable->window(), Qt::LeftButton, 0, guPoint(35, 35)); QTest::waitForEvents(); QCOMPARE(pressed.count(), 1); QCOMPARE(released.count(), 1); QCOMPARE(clicked.count(), 1); QCOMPARE(positionChanged.count(), 30); QCOMPARE(doubleClicked.count(), 0); QCOMPARE(pressAndHold.count(), 0); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); QCOMPARE(flickStart.count(), 1); } void testCase_hover() { QScopedPointer view(loadTest("FilterFlickableAfter.qml")); QVERIFY(view); UCMouse *filter = attachedFilter(view->rootObject(), "FilterOwner"); QVERIFY(filter); QSignalSpy positionChanged(filter, SIGNAL(positionChanged(QQuickMouseEvent*))); QSignalSpy entered(filter, SIGNAL(entered(QQuickMouseEvent*))); QSignalSpy exited(filter, SIGNAL(exited(QQuickMouseEvent*))); preventDblClick(); QTest::mousePress(view.data(), Qt::LeftButton, 0, guPoint(5, 5)); QTest::mouseMove(view.data(), guPoint(15, 5)); QTest::mouseMove(view.data(), guPoint(25, 5)); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, guPoint(35, 5)); QTest::waitForEvents(); QCOMPARE(positionChanged.count(), 3); QCOMPARE(entered.count(), 1); QCOMPARE(exited.count(), 1); } }; QTEST_MAIN(tst_mouseFilterTest) #include "tst_mousefilterstest.moc" ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedMouseEventsStopped.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedMouseEventsStoppe0000644000015301777760000000175712321005637033450 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) objectName: "target" Mouse.enabled: true TextInput { objectName: "FilterOwner" width: root.width height: units.gu(5) Mouse.forwardTo: [root] Mouse.onPressed: mouse.accepted = true } } ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInputAfter.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInputAfte0000644000015301777760000000174212321005637033402 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(40) height: units.gu(71) TextInput { objectName: "FilterOwner" width: units.gu(30) height: units.gu(4) activeFocusOnPress: true // create InverseMouse filter attached InverseMouse.priority: Mouse.AfterItem } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/Hover.qml0000644000015301777760000000200612321005637030001 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) MouseArea { id: other objectName: "FilterOwner" width: units.gu(30) height: units.gu(10) anchors.horizontalCenter: parent hoverEnabled: true // test hover Mouse.priority: Mouse.BeforeItem } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedMouseEvents.qml0000644000015301777760000000170012321005637033031 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) objectName: "target" Mouse.enabled: true TextInput { objectName: "FilterOwner" width: root.width height: units.gu(5) Mouse.forwardTo: [root] } } ././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInputOSKExcluded.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInputOSKE0000644000015301777760000000172612321005637033266 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(40) height: units.gu(71) TextInput { objectName: "FilterOwner" width: units.gu(30) height: units.gu(4) activeFocusOnPress: true // create InverseMouse filter attached InverseMouse.enabled: true } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardToMouseArea.qml0000644000015301777760000000177012321005637032436 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) MouseArea { id: other objectName: "target" anchors.fill: parent } TextInput { objectName: "FilterOwner" width: root.width height: units.gu(5) Mouse.forwardTo: [root, other] } } ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedEventsStoppedInForwards.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardedEventsStoppedInFo0000644000015301777760000000175412321005637033354 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) objectName: "target" Mouse.enabled: true Mouse.onPressed: mouse.accepted = true TextInput { objectName: "FilterOwner" width: root.width height: units.gu(5) Mouse.forwardTo: [root] } } ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/MouseFilterAttachedToNonItem.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/MouseFilterAttachedToNonIt0000644000015301777760000000136212321005637033301 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { QtObject { Mouse.enabled: true } } ././@LongLink0000000000000000000000000000016200000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/InverseMouseFilterAttachedToNonItem.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/InverseMouseFilterAttached0000644000015301777760000000137112321005637033362 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { QtObject { InverseMouse.enabled: true } } ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardToInverseMouseArea.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/ForwardToInverseMouseArea.0000644000015301777760000000245612321005637033262 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) Column { TextInput { objectName: "FilterOwner" width: root.width height: units.gu(5) Mouse.forwardTo: [root, other] } Rectangle { width: root.width height: units.gu(15) color: "blue" InverseMouseArea { id: other objectName: "target" anchors.fill: parent onPressed: mouse.accepted = false onReleased: mouse.accepted = false } } } } ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInputTolerance.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterInverseTextInputTole0000644000015301777760000000203512321005637033422 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(40) height: units.gu(71) TextInput { objectName: "FilterOwner" width: units.gu(30) height: units.gu(4) activeFocusOnPress: true // create InverseMouse filter attached InverseMouse.priority: Mouse.BeforeItem InverseMouse.clickAndHoldThreshold: units.gu(0.5) } } ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/PressAndHoldAcceptedEatsClick.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/PressAndHoldAcceptedEatsCl0000644000015301777760000000154412321005637033207 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { objectName: "FilterOwner" width: units.gu(10) height: units.gu(5) activeFocusOnPress: true Mouse.onPressAndHold: {mouse.accepted = true} } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/InverseHover.qml0000644000015301777760000000235012321005637031337 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: units.gu(40) height: units.gu(71) Rectangle { width: units.gu(30) height: units.gu(10) color: "blue" anchors.horizontalCenter: parent.horizontalCenter // use MouseArea and enable hover events only MouseArea { id: other anchors.fill: parent objectName: "FilterOwner" hoverEnabled: true acceptedButtons: Qt.NoButton // test hover InverseMouse.priority: Mouse.BeforeItem } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/DoubleClicked.qml0000644000015301777760000000171712321005637031417 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { objectName: "FilterOwner" width: units.gu(40) height: units.gu(5) text: "This is a test text"; selectByMouse: true mouseSelectionMode: TextInput.SelectWords // make sure we have the doubleClicked() handled Mouse.onDoubleClicked: {} } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/FilterTextInput.qml0000644000015301777760000000157312321005637032040 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { objectName: "FilterOwner" width: units.gu(10) height: units.gu(5) activeFocusOnPress: true // create Mouse filter attached Mouse.priority: Mouse.BeforeItem } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_mousefilters/AttachedToItem.qml0000644000015301777760000000137012321005637031560 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 100 height: 62 Mouse.enabled: true } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/unit_x11.pro0000644000015301777760000000026012321005637024762 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += tst_components tst_test tst_inversemousearea tst_recreateview tst_statesaver tst_theme_engine tst_orientation tst_layouts \ tst_mousefilters ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/0000755000015301777760000000000012321006415025640 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/GridViewItems.qml0000644000015301777760000000203612321005637031103 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 GridView { id: listView objectName: "grid" anchors.fill: parent model: 2 delegate: Rectangle { id: listItem objectName: "testItem" width: 20 height: 20 StateSaver.properties: "height" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SaveArrays.qml0000644000015301777760000000173512321005637030446 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { property var boolArray: [false, false] property var intArray: [1, 2] property var realArray: [10.1, 20.2] property var stringArray: ["false", "false"] id: testItem objectName: "testItem" StateSaver.properties: "boolArray, intArray, realArray, stringArray" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/tst_statesaver.pro0000644000015301777760000000127112321005637031443 0ustar pbusernogroup00000000000000include(../test-include.pri) DEFINES += SRCDIR=\\\"$$PWD/\\\" SOURCES += \ tst_statesaver.cpp OTHER_FILES += \ SaveArrays.qml \ SaveSupportedTypes.qml \ ValidUID.qml \ InvalidUID.qml \ ValidGroupProperty.qml \ InvalidGroupProperty.qml \ Dynamic.qml \ TwoDynamics.qml \ DisabledStateSaver.qml \ SaveObject.qml \ FirstComponent.qml \ SecondComponent.qml \ SameIdsInDifferentComponents.qml \ SavePropertyGroups.qml \ ComponentsWithStateSavers.qml \ CustomControl.qml \ ComponentsWithStateSaversNoId.qml \ NestedDynamics.qml \ RepeaterStates.qml \ ListViewItems.qml \ GridViewItems.qml \ NormalAppClose.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/NestedDynamics.qml0000644000015301777760000000163512321005637031277 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 Column { id: column Loader { id: outerLoader objectName: "outerLoader" StateSaver.properties: "source" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/FirstComponent.qml0000644000015301777760000000151212321005637031331 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: sameRoot Item { id: sameItem objectName: "firstComponent" StateSaver.properties: "objectName" } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ComponentsWithStateSavers.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ComponentsWithStateSavers.qm0000644000015301777760000000161612321005637033356 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: user width: 100 height: 100 CustomControl { id: component1 objectName: "control1" } CustomControl { id: component2 objectName: "control2" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/InvalidUID.qml0000644000015301777760000000146312321005637030314 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { Item { id: testItem objectName: "testItem" StateSaver.properties: "objectName" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ValidUID.qml0000644000015301777760000000150012321005637027755 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root Item { id: testItem objectName: "testItem" StateSaver.properties: "objectName" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/InvalidGroupProperty.qml0000644000015301777760000000157112321005637032534 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root Item { id: testItem property var group: QtObject { objectName: "testItem" StateSaver.properties: "objectName" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/Dynamic.qml0000644000015301777760000000146312321005637027750 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 Loader { id: loader source: "ValidUID.qml" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/RepeaterStates.qml0000644000015301777760000000211712321005637031314 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 Column { id: column objectName: "column" Repeater { id: repeater model: 4 Rectangle { id: rect width: root.width height: 20 objectName: "testItem" StateSaver.properties: "height" } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/DisabledStateSaver.qml0000644000015301777760000000154212321005637032073 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root Item { id: testItem objectName: "testItem" StateSaver.properties: "objectName" StateSaver.enabled: false } } ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SameIdsInDifferentComponents.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SameIdsInDifferentComponents0000644000015301777760000000160012321005637033276 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 Loader { id: loader objectName: "testItem" source: "FirstComponent.qml" StateSaver.properties: "source" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/NormalAppClose.qml0000644000015301777760000000221212321005637031234 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { property var boolArray: [false, false] property var intArray: [1, 2] property var realArray: [10.1, 20.2] property var stringArray: ["false", "false"] id: testItem objectName: "testItem" StateSaver.properties: "boolArray, intArray, realArray, stringArray" Timer { id: closeTimer interval: 1000 running: false onTriggered: Qt.quit(); } Component.onCompleted: closeTimer.running = true } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/CustomControl.qml0000644000015301777760000000145012321005637031173 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: control width: 100 height: 50 color: "red" StateSaver.properties: "color" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SaveObject.qml0000644000015301777760000000147612321005637030415 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { property Item object: Item { objectName: "testObject" } id: testItem StateSaver.properties: "object" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SaveSupportedTypes.qml0000644000015301777760000000336712321005637032222 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { property int intValue: 100 property bool boolValue: false property real realValue: 123.45 property double doubleValue: 32155.2355 property string string: "component string" property url url: Qt.resolvedUrl("SaveSupportedTypes.qml") property date date: new Date() property point point: Qt.point(10, 10) property rect rect: Qt.rect(0, 0, 20, 20) property size size: Qt.size(20, 30) property color color: "red" property font font: Qt.font({family: "Courrier New"}) property vector2d vector2d: Qt.vector2d(1, 2) property vector3d vector3d: Qt.vector3d(1, 2, 3) property vector4d vector4d: Qt.vector4d(1, 2, 3, 4) property quaternion quaternion: Qt.quaternion(0.5, 1, 2, 3) property matrix4x4 matrix4x4: Qt.matrix4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) id: testItem objectName: "testItem" StateSaver.properties: "intValue, boolValue, realValue, doubleValue, string, url,"+ "date, point, rect, size, time, color, font, vector2d, vector3d, vector4d, quaternion, matrix4x4" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SavePropertyGroups.qml0000644000015301777760000000161412321005637032225 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root property Rectangle propertyGroup: Rectangle { } width: 100 height: 100 objectName: "testItem" StateSaver.properties: "color, border.color, propertyGroup.color" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/tst_statesaver.cpp0000644000015301777760000005111312321005637031425 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include #include #include #include #include #include #include #include #include #include #include #include #include "quickutils.h" #include "ucapplication.h" #include #include #include #define protected public #include "ucstatesaver.h" #include "statesaverbackend_p.h" #undef protected class tst_StateSaverTest : public QObject { Q_OBJECT public: tst_StateSaverTest() {} private: QString m_modulePath; QQuickView *createView(const QString &file, QSignalSpy **spy = 0) { QQuickView *view = new QQuickView(0); if (spy) { *spy = new QSignalSpy(view->engine(), SIGNAL(warnings(QList))); (*spy)->setParent(view); } view->engine()->addImportPath(m_modulePath); view->setSource(QUrl::fromLocalFile(file)); if (!view->rootObject()) { return 0; } view->show(); QTest::qWaitForWindowExposed(view); // connect StateSaverBackend's initiateStateSaving() to view destroyed return view; } void resetView(QScopedPointer &view, const QString &file, QSignalSpy **spy = 0) { Q_EMIT StateSaverBackend::instance().initiateStateSaving(); view.reset(); view.reset(createView(file, spy)); } QString stateFile(const QString &appId) { return QString("%1/%2.state") .arg(QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0]) .arg(appId); } private Q_SLOTS: void initTestCase() { QCoreApplication::setApplicationName("tst_statesaver"); QCoreApplication::setOrganizationName(""); QDir modules ("../../../modules"); QVERIFY(modules.exists()); m_modulePath = modules.absolutePath(); // invoke initialization StateSaverBackend::instance(); } void cleanupTestCase() { StateSaverBackend::instance().reset(); } void test_SaveArrays() { QScopedPointer view(createView("SaveArrays.qml")); QVERIFY(view); QObject *testItem = view->rootObject(); QVERIFY(testItem); QVariantList boolValues; boolValues << true << true; QVariantList intValues; intValues << 100 << 200; QVariantList realValues; realValues << 123.45 << 678.9; QVariantList stringValues; stringValues << "one" << "two"; testItem->setProperty("boolArray", boolValues); testItem->setProperty("intArray", intValues); testItem->setProperty("realArray", realValues); testItem->setProperty("stringArray", stringValues); resetView(view, "SaveArrays.qml"); QVERIFY(view); testItem = view->rootObject(); QVERIFY(testItem); QVERIFY(testItem->property("boolArray") == boolValues); QVERIFY(testItem->property("intArray") == intValues); QVERIFY(testItem->property("realArray") == realValues); QVERIFY(testItem->property("stringArray") == stringValues); } void test_SaveStructures() { QScopedPointer view(createView("SaveSupportedTypes.qml")); QVERIFY(view); QObject *testItem = view->rootObject(); QVERIFY(testItem); QVariantHash values; values.insert("intValue", 1000); values.insert("boolValue", true); values.insert("realValue", 345.12); values.insert("doubleValue", 65535.33244); values.insert("string", "test string"); values.insert("url", QUrl::fromLocalFile("tst_statesaver.cpp")); values.insert("date", QDateTime::currentDateTime().addDays(5)); values.insert("point", QPoint(100, 100)); values.insert("rect", QRect(100, 100, 200, 200)); values.insert("size", QSize(345, 678)); values.insert("color", QColor("blue")); values.insert("font", QFont("Ubuntu")); values.insert("vector2d", QVector2D(100.0, 200.0)); values.insert("vector3d", QVector3D(100.0, 200.0, 300.0)); values.insert("vector4d", QVector4D(100.0, 200.0, 300.0, 400.0)); values.insert("quaternion", QQuaternion(1, 100.0, 200.0, 300.0)); values.insert("matrix4x4", QMatrix4x4(5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)); QHashIterator i(values); while (i.hasNext()) { i.next(); QVERIFY2(testItem->setProperty(i.key().toLocal8Bit().constData(), i.value()), QString("set %1").arg(i.key()).toLocal8Bit().constData()); } resetView(view, "SaveSupportedTypes.qml"); QVERIFY(view); testItem = view->rootObject(); QVERIFY(testItem); UCStateSaverAttached *stateSaver = qobject_cast(qmlAttachedPropertiesObject(testItem, false)); QVERIFY(stateSaver); QStringList properties = stateSaver->properties().split(','); Q_FOREACH(const QString &property, properties) { QVERIFY2(testItem->property(property.toLocal8Bit().constData()) == values.value(property), QString("verifying %1").arg(property).toLocal8Bit().constData()); } } void test_SavePropertyGroup() { QScopedPointer view(createView("SavePropertyGroups.qml")); QVERIFY(view); QObject *testItem = view->rootObject(); QVERIFY(testItem); QVERIFY(testItem->setProperty("color", QColor("red"))); // set property groups using QQmlProperty QQmlProperty borderColor(testItem, "border.color"); borderColor.write(QColor("green")); QQmlProperty propertyGroup(testItem, "propertyGroup.color"); propertyGroup.write(QColor("blue")); resetView(view, "SavePropertyGroups.qml"); QVERIFY(view); testItem = view->rootObject(); QVERIFY(testItem); QCOMPARE(testItem->property("color"), QVariant(QColor("red"))); // read property groups using QQmlProperty QQmlProperty verifyBorderColor(testItem, "border.color"); QCOMPARE(verifyBorderColor.read(), QVariant(QColor("green"))); QQmlProperty verifyPropertyGroup(testItem, "propertyGroup.color"); QCOMPARE(verifyPropertyGroup.read(), QVariant(QColor("blue"))); } void test_SaveObject() { QScopedPointer view(createView("SaveObject.qml")); QVERIFY(view); QObject *testItem = view->rootObject(); QVERIFY(testItem); QScopedPointer obj(new QQuickItem); obj->setObjectName("internal"); testItem->setProperty("object", QVariant::fromValue(obj.data())); resetView(view, "SaveObject.qml"); QVERIFY(view); testItem = view->rootObject(); QVERIFY(testItem); QVERIFY(testItem->property("object").value() != obj.data()); } void test_ValidUID() { QScopedPointer view(createView("ValidUID.qml")); QVERIFY(view); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("updated"); resetView(view, "ValidUID.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("updated"); QVERIFY(testItem); } void test_InvalidUID() { QSignalSpy *spy; QScopedPointer view(createView("InvalidUID.qml", &spy)); QVERIFY(view); QCOMPARE(spy->count(), 1); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("updated"); resetView(view, "InvalidUID.qml", &spy); QVERIFY(view); QCOMPARE(spy->count(), 1); testItem = view->rootObject()->findChild("updated"); QVERIFY(testItem == 0); } void test_ValidGroupProperty() { QScopedPointer view(createView("ValidGroupProperty.qml")); QVERIFY(view); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("group"); resetView(view, "ValidGroupProperty.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("group"); QVERIFY(testItem); } void test_InvalidGroupProperty() { QSignalSpy *spy; QScopedPointer view(createView("InvalidGroupProperty.qml", &spy)); QVERIFY(view); QCOMPARE(spy->count(), 1); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("group"); resetView(view, "InvalidGroupProperty.qml", &spy); QVERIFY(view); QCOMPARE(spy->count(), 1); testItem = view->rootObject()->findChild("group"); QVERIFY(testItem == 0); } void test_Dynamic() { QScopedPointer view(createView("Dynamic.qml")); QVERIFY(view); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("updated"); resetView(view, "Dynamic.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("updated"); QVERIFY(testItem); } void test_TwoDynamics() { QScopedPointer view(createView("TwoDynamics.qml")); QVERIFY(view); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("updated"); resetView(view, "TwoDynamics.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("updated"); QVERIFY(testItem); } void test_DisabledStateSaver() { QScopedPointer view(createView("DisabledStateSaver.qml")); QVERIFY(view); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("updated"); resetView(view, "DisabledStateSaver.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("updated"); QVERIFY(testItem == 0); } void test_SameIdsInDifferentComponents() { QScopedPointer view(createView("SameIdsInDifferentComponents.qml")); QVERIFY(view); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setProperty("source", "SecondComponent.qml"); // check if the SecondComponent state saver is enabled QObject *item = testItem->property("item").value(); QVERIFY(item); QObject *innerItem = item->findChild("secondComponent"); UCStateSaverAttached *stateSaver = qobject_cast(qmlAttachedPropertiesObject(innerItem, false)); QVERIFY(stateSaver); QVERIFY(stateSaver->enabled()); resetView(view, "SameIdsInDifferentComponents.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("secondComponent"); QVERIFY(testItem); } void test_ComponentsWithStateSavers() { QScopedPointer view(createView("ComponentsWithStateSavers.qml")); QVERIFY(view); QObject *control1 = view->rootObject()->findChild("control1"); QVERIFY(control1); QObject *control2 = view->rootObject()->findChild("control2"); QVERIFY(control2); UCStateSaverAttached *stateSaver1 = qobject_cast(qmlAttachedPropertiesObject(control1, false)); QVERIFY(stateSaver1); QVERIFY(stateSaver1->enabled()); UCStateSaverAttached *stateSaver2 = qobject_cast(qmlAttachedPropertiesObject(control2, false)); QVERIFY(stateSaver2); QVERIFY(stateSaver2->enabled()); QVERIFY(control1->setProperty("color", QColor("green"))); QVERIFY(control2->setProperty("color", QColor("blue"))); resetView(view, "ComponentsWithStateSavers.qml"); control1 = view->rootObject()->findChild("control1"); QVERIFY(control1); control2 = view->rootObject()->findChild("control2"); QVERIFY(control2); stateSaver1 = qobject_cast(qmlAttachedPropertiesObject(control1, false)); QVERIFY(stateSaver1); QVERIFY(stateSaver1->enabled()); stateSaver2 = qobject_cast(qmlAttachedPropertiesObject(control2, false)); QVERIFY(stateSaver2); QVERIFY(stateSaver2->enabled()); QVERIFY(view); QCOMPARE(control1->property("color"), QVariant(QColor("green"))); QCOMPARE(control2->property("color"), QVariant(QColor("blue"))); } void test_ComponentsWithStateSaversNoId() { QSignalSpy *spy; QScopedPointer view(createView("ComponentsWithStateSaversNoId.qml", &spy)); QVERIFY(view); QObject *control1 = view->rootObject()->findChild("control1"); QVERIFY(control1); QObject *control2 = view->rootObject()->findChild("control2"); QVERIFY(control2); UCStateSaverAttached *stateSaver1 = qobject_cast(qmlAttachedPropertiesObject(control1, false)); QVERIFY(stateSaver1); QVERIFY(stateSaver1->enabled() == false); QCOMPARE(spy->count(), 1); UCStateSaverAttached *stateSaver2 = qobject_cast(qmlAttachedPropertiesObject(control2, false)); QVERIFY(stateSaver2); QVERIFY(stateSaver2->enabled()); } void test_nestedDynamics() { QScopedPointer view(createView("NestedDynamics.qml")); QVERIFY(view); QObject *topLoader = view->rootObject()->findChild("outerLoader"); QVERIFY(topLoader); topLoader->setProperty("source", "Dynamic.qml"); QTest::waitForEvents(); QObject *testItem = view->rootObject()->findChild("testItem"); QVERIFY(testItem); testItem->setObjectName("updated"); resetView(view, "NestedDynamics.qml"); QVERIFY(view); testItem = view->rootObject()->findChild("updated"); QVERIFY(testItem); } void test_repeaterStates() { QScopedPointer view(createView("RepeaterStates.qml")); QVERIFY(view); QQuickItem *column = view->rootObject()->findChild("column"); QVERIFY(column); QList items = column->childItems(); QCOMPARE(items.count(), 5); // 4 Rectangles + 1 Repeater Q_FOREACH(QQuickItem *item, items) { if (QuickUtils::instance().className(item) == "QQuickRectangle") { item->setHeight(25); } } resetView(view, "RepeaterStates.qml"); QVERIFY(view); column = view->rootObject()->findChild("column"); QVERIFY(column); items = column->childItems(); QCOMPARE(items.count(), 5); // 4 Rectangles + 1 Repeater Q_FOREACH(QQuickItem *item, items) { if (QuickUtils::instance().className(item) == "QQuickRectangle") { QCOMPARE(item->height(), 25.0); } } } void test_ListViewItemStates() { QScopedPointer view(createView("ListViewItems.qml")); QVERIFY(view); QQuickItem *list = view->rootObject()->findChild("list"); QVERIFY(list); QQuickItem *contentItem = list->property("contentItem").value(); QVERIFY(contentItem); QList items = contentItem->childItems(); int testItemCount = 0; Q_FOREACH(QQuickItem *item, items) { if (item->objectName() == "testItem") { item->setHeight(25); testItemCount++; } } QCOMPARE(testItemCount, 2); resetView(view, "ListViewItems.qml"); QVERIFY(view); list = view->rootObject()->findChild("list"); QVERIFY(list); contentItem = list->property("contentItem").value(); QVERIFY(contentItem); items = contentItem->childItems(); Q_FOREACH(QQuickItem *item, items) { if (item->objectName() == "testItem") { QCOMPARE(item->height(), 25.0); } } } void test_GridViewItemStates() { QScopedPointer view(createView("GridViewItems.qml")); QVERIFY(view); QQuickItem *list = view->rootObject()->findChild("grid"); QVERIFY(list); QQuickItem *contentItem = list->property("contentItem").value(); QVERIFY(contentItem); QList items = contentItem->childItems(); int testItemCount = 0; Q_FOREACH(QQuickItem *item, items) { if (item->objectName() == "testItem") { item->setHeight(25); testItemCount++; } } QCOMPARE(testItemCount, 2); resetView(view, "GridViewItems.qml"); QVERIFY(view); list = view->rootObject()->findChild("grid"); QVERIFY(list); contentItem = list->property("contentItem").value(); QVERIFY(contentItem); items = contentItem->childItems(); Q_FOREACH(QQuickItem *item, items) { if (item->objectName() == "testItem") { QCOMPARE(item->height(), 25.0); } } } void test_normalAppClose() { QProcess testApp; QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("APP_ID", "NormalAppClose"); testApp.setProcessEnvironment(env); testApp.start("qmlscene", QStringList() << "-I" << "../../../modules" << "NormalAppClose.qml"); testApp.waitForFinished(); QString fileName = stateFile("NormalAppClose"); QVERIFY(!QFile(fileName).exists()); } void test_SigTerm() { QProcess testApp; QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("APP_ID", "SimpleApp"); testApp.setProcessEnvironment(env); testApp.start("qmlscene -I ../../../modules SimpleApp.qml"); testApp.waitForStarted(); // send SIGTERM signal to the process, use terminate() to do that. testApp.terminate(); testApp.waitForFinished(); QString fileName = stateFile("SimpleApp"); QVERIFY(!QFile(fileName).exists()); } void test_SigInt() { QProcess testApp; QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("APP_ID", "SimpleApp"); testApp.setProcessEnvironment(env); testApp.start("qmlscene -I ../../../modules SimpleApp.qml"); testApp.waitForStarted(); QTest::qWait(1000); // make sure we are not killing the parent QVERIFY(testApp.pid() != QCoreApplication::applicationPid()); // skip tests if the application PID is zero => the child app PID seems to be zero as well if (!testApp.pid()) { // kill child process testApp.close(); QSKIP("This test requires valid PID"); } // send SIGINT ::kill(testApp.pid(), SIGINT); testApp.waitForFinished(); QString fileName = stateFile("SimpleApp"); QVERIFY(QFile(fileName).exists()); // clean the file QFile::remove(fileName); } }; QTEST_MAIN(tst_StateSaverTest) #include "tst_statesaver.moc" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ValidGroupProperty.qml0000644000015301777760000000161712321005637032206 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root Item { id: testItem property var group: QtObject { id: group objectName: "testItem" StateSaver.properties: "objectName" } } } ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ComponentsWithStateSaversNoId.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ComponentsWithStateSaversNoI0000644000015301777760000000157312321005637033352 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: user width: 100 height: 100 CustomControl { objectName: "control1" } CustomControl { id: customControl2 objectName: "control2" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SecondComponent.qml0000644000015301777760000000151312321005637031456 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: sameRoot Item { id: sameItem objectName: "secondComponent" StateSaver.properties: "objectName" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/SimpleApp.qml0000644000015301777760000000173512321005637030260 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { property var boolArray: [false, false] property var intArray: [1, 2] property var realArray: [10.1, 20.2] property var stringArray: ["false", "false"] id: testItem objectName: "testItem" StateSaver.properties: "boolArray, intArray, realArray, stringArray" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/ListViewItems.qml0000644000015301777760000000205012321005637031125 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 ListView { id: listView objectName: "list" anchors.fill: parent model: 2 delegate: Rectangle { id: listItem objectName: "testItem" width: parent.width height: 20 StateSaver.properties: "height" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_statesaver/TwoDynamics.qml0000644000015301777760000000167712321005637030634 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 Column { id: column Loader { id: loader source: "ValidUID.qml" } Loader { id: loader2 source: "ValidUID.qml" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/0000755000015301777760000000000012321006415025644 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_optionselector.qml0000644000015301777760000001116412321005637032332 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Test 0.1 import Ubuntu.Unity.Action 1.1 as UnityActions MainView { width: 400 height: 400 Column { anchors { left: parent.left right: parent.right } OptionSelector { id: selector text: "TEST" delegate: selectorDelegate model: customModel expanded: true action: { enabled: true name: 'selector' text: 'Selector' parameterType: UnityActions.Action.Integer } } OptionSelectorDelegate { id: testDelegate text: "TEST" subText: "test" iconSource: "../../resources/optionselector/test.png" constrainImage: true } } Component { id: selectorDelegate OptionSelectorDelegate { text: name subText: description iconSource: image constrainImage: true } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "../../resources/optionselector/test.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "../../resources/optionselector/test.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "../../resources/optionselector/test.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "../../resources/optionselector/test.png" } } SignalSpy { id: clickedSignal target: selector signalName: "delegateClicked" } SignalSpy { id: triggeredSignal target: selector signalName: "triggered" } SignalSpy { id: expansionSignal target: selector signalName: "expansionCompleted" } UbuntuTestCase { name: "OptionSelectorAPI" when: windowShown function test_expanded() { var listContainer = findChild(selector, "listContainer"); selector.expanded = false; compare(listContainer.currentlyExpanded, false, "expanded should be true if list is an expanded one"); compare(listContainer.state, "collapsed", "state should be collapsed"); selector.expanded = true; compare(listContainer.currentlyExpanded, true, "expanded should be false if list is an expanded one"); compare(listContainer.state, "expanded", "state should be expanded"); } function test_text() { var newText = "Hello World!"; selector.text = newText; compare(selector.text, newText, "set/get"); } function test_selectedIndex() { compare(selector.selectedIndex, 0, "selectedIndex is 0 by default"); } function test_model() { selector.model = undefined; var newValues = ["value0","value1","value2","value3"]; selector.model = newValues; compare(selector.model, newValues, "set/get"); } function test_custom_model_delegate() { compare(selector.model, customModel, "Model wasn't set correctly."); compare(selector.delegate, selectorDelegate, "Delegate hasn't been set correctly"); } function test_image_constraint() { var image = findChild(testDelegate, "icon"); compare(image.height, testDelegate.height); } function test_signal() { skip('FIXME: This test doesn\'t pass in CI') mouseClick(selector, 100, 100, Qt.LeftButton); clickedSignal.wait(); expansionSignal.wait(); } function test_triggered() { skip('FIXME: This test doesn\'t pass in CI') mouseClick(selector, 100, 100, Qt.LeftButton); triggeredSignal.wait(); } } } ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_listitems_itemselector.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_listitems_itemselector.q0000644000015301777760000001015612321005637033524 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem import Ubuntu.Test 0.1 Item { width: 400 height: 400 Column { anchors { left: parent.left right: parent.right } ListItem.ItemSelector { id: selector text: "TEST" delegate: selectorDelegate model: customModel } OptionSelectorDelegate { id: testDelegate text: "TEST" subText: "test" iconSource: "../../resources/optionselector/test.png" constrainImage: true } } Column { anchors.left: parent.left anchors.right: parent.right ListItem.ItemSelector { id: expandedSelector text: i18n.tr("Return results from:") model: [i18n.tr("Phone only"), i18n.tr("Phone and Internet")] expanded: true } } Component { id: selectorDelegate OptionSelectorDelegate { text: name subText: description iconSource: image constrainImage: true } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "../../resources/optionselector/test.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "../../resources/optionselector/test.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "../../resources/optionselector/test.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "../../resources/optionselector/test.png" } } UbuntuTestCase { name: "ItemSelectorAPI" when: windowShown function test_expanded() { var listContainer = findChild(selector, "listContainer"); selector.expanded = false; compare(listContainer.currentlyExpanded, false, "expanded should be true if list is an expanded one"); compare(listContainer.state, "collapsed", "state should be collapsed"); selector.expanded = true; compare(listContainer.currentlyExpanded, true, "expanded should be false if list is an expanded one"); compare(listContainer.state, "expanded", "state should be expanded"); } function test_text() { var newText = "Hello World!"; selector.text = newText; compare(selector.text, newText, "set/get"); } function test_selectedIndex() { compare(selector.selectedIndex, 0, "selectedIndex is 0 by default"); } function test_model() { selector.model = undefined; var newValues = ["value0","value1","value2","value3"]; selector.model = newValues; compare(selector.model, newValues, "set/get"); } function test_custom_model_delegate() { compare(selector.model, customModel, "Model wasn't set correctly."); compare(selector.delegate, selectorDelegate, "Delegate hasn't been set correctly"); } function test_image_constraint() { var image = findChild(testDelegate, "icon"); compare(image.height, testDelegate.height); } function test_expandedSelector() { verify(expandedSelector.containerHeight > 0, "Expanded ItemSelector height negative"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_hide_chrome.qml0000644000015301777760000001043412321005637031526 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { width: units.gu(50) height: units.gu(80) MainView { id: mainView anchors.fill: parent Tabs { id: tabs Tab { id: tab1 title: "tab 1" page: Page { id: page1 Button { id: button anchors.centerIn: parent text: "click" } tools: ToolbarItems { ToolbarButton { id: toolbarButton text: "something" } } } } Tab { id: tab2 title: "tab 2" page: Page { id: page2 } } } } TestCase { name: "HideChrome" when: windowShown id: testCase function openToolbar() { var toolbar = mainView.__propagated.toolbar; toolbar.open(); compare(toolbar.opened, true, "Cannot open toolbar using open()"); wait(UbuntuAnimation.FastDuration); // wait for the open animation to finish return toolbar; } function setTabBarSelectionMode(newSelectionMode) { var tabBar = tabs.tabBar; var header = mainView.__propagated.header; compare(tabBar, header.contents, "TabBar is not the active header contents"); header.show(); tabBar.selectionMode = newSelectionMode; compare(tabBar.selectionMode, newSelectionMode, "Failed to set the tab bar selection mode"); return tabBar; } function test_tabBar_press_closes_toolbar_bug1223600() { testCase.setTabBarSelectionMode(false); var toolbar = testCase.openToolbar(); testCase.mousePress(tabs.tabBar); compare(toolbar.opened, false, "Activating TabBar did not close toolbar"); testCase.mouseRelease(tabs.tabBar); testCase.setTabBarSelectionMode(false); } function test_toolbar_press_closes_tabBar_bug1223606 () { var tabBar = testCase.setTabBarSelectionMode(true); var toolbar = testCase.openToolbar(); testCase.mouseClick(toolbarButton, toolbarButton.width/2, toolbarButton.height/2, Qt.LeftButton); compare(tabBar.selectionMode, false, "Clicking a toolbar button does not disable tab bar selection mode"); toolbar.open(); testCase.setTabBarSelectionMode(true); testCase.mousePress(toolbar, toolbar.width/2, toolbar.height/2, Qt.LeftButton); compare(tabBar.selectionMode, false, "Pressing the toolbar does not disable tab bar selection mode"); testCase.mouseRelease(toolbar, toolbar.width/2, toolbar.height/2, Qt.LeftButton); toolbar.close(); testCase.setTabBarSelectionMode(true); testCase.mousePress(mainView, mainView.width/2, mainView.height - toolbar.triggerSize/2, Qt.LeftButton); compare(tabBar.selectionMode, false, "Triggering the toolbar hint does not disable tab selection mode"); testCase.mouseRelease(mainView, mainView.width/2, mainView.height - toolbar.triggerSize/2, Qt.LeftButton); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_dialer.qml0000644000015301777760000001311012321005637030512 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Item { id: root width: 200 height: 200 Dialer { id: noHands } Dialer { id: oneHand DialerHand { id: hand } } Dialer { DialerHand { id: overlayHand Label { id: overlayItem text: overlayHand.value } } } SignalSpy { id: spy } TestCase { id: testCase name: "DialerAPI" when: windowShown function test_0_Dialer_minimumValue() { compare(noHands.minimumValue, 0.0, "noHands.minimumValue"); compare(oneHand.minimumValue, 0.0, "oneHand.minimumValue"); } function test_0_Dialer_maximumValue() { compare(noHands.maximumValue, 360.0, "noHands.maximumValue"); compare(oneHand.maximumValue, 360.0, "oneHand.maximumValue"); } function test_0_Dialer_size() { compare(noHands.size, units.gu(32), "noHands.size"); compare(oneHand.size, units.gu(32), "oneHand.size"); } function test_0_Dialer_handSpace() { compare(noHands.handSpace, units.gu(6.5), "noHands.handSpace"); compare(oneHand.handSpace, units.gu(6.5), "oneHand.handSpace"); } function test_0_Dialer_centerItem() { verify(noHands.centerItem !== undefined, "noHands.centerItem"); verify(oneHand.centerItem !== undefined, "oneHand.centerItem"); } function test_0_Dialer_centerContent() { verify(noHands.centerContent !== undefined, "noHands.centerContent"); verify(oneHand.centerContent !== undefined, "oneHand.centerContent"); } function test_0_Dialer_hands() { verify(noHands.hands !== undefined, "hoHands.hands is defined"); compare(noHands.hands.length, 0, "noHands.hands.length"); compare(oneHand.hands.length, 1, "noHands.hands.length"); compare(oneHand.hands[0], hand, "noHands.hands[0] == hand"); } function test_0_DialerHand_value() { compare(hand.value, 0.0, "hand.value"); } function test_0_DialerHand_hand_height() { verify(hand.hand.height !== 0.0, "hand.hand.height"); } function test_0_DialerHand_hand_width() { verify(hand.hand.width !== 0.0, "hand.hand.width"); } function test_0_DialerHand_hand_draggable() { compare(hand.hand.draggable, true, "hand.hand.draggable"); } function test_0_DialerHand_hand_visible() { compare(hand.hand.visible, true, "hand.hand.visible"); } function test_0_DialerHand_hand_toCenterItem() { compare(hand.hand.toCenterItem, false, "hand.hand.toCenterItem"); } function test_0_DialerHand_index() { compare(hand.index, 0, "hand.index"); } function test_0_DialerHand_dialer() { compare(hand.dialer, oneHand, "hand.dialer"); } function test_0_DialerHand_overlay() { verify(hand.overlay !== undefined, "hand.overlay"); } function test_DialerHand_valueChange() { spy.clear(); spy.signalName = "onHandUpdated"; spy.target = oneHand; hand.value = 100; compare(hand.value, 100, "hand.value changed"); tryCompare(spy, "count", 1); } function test_DialerHand_hand_toCenterItem_Change() { hand.hand.toCenterItem = true; compare(hand.hand.toCenterItem, true, "hand.hand.toCenterItem changed"); } function test_DialerHand_hand_draggable_Change() { hand.hand.draggable = false; compare(hand.hand.draggable, false, "hand.hand.draggable changed"); } function test_DialerHand_handSizeChange() { var prevHeight = hand.hand.height; hand.hand.height = units.gu(10); verify(hand.hand.height !== prevHeight, "hand.hand.height"); compare(hand.hand.height, units.gu(10), "hand.hand.height changed"); var prevWidth = hand.hand.width; hand.hand.width = units.gu(10); verify(hand.hand.width !== prevWidth, "hand.hand.width"); compare(hand.hand.width, units.gu(10), "hand.hand.width changed"); } function test_OverlayHand_visible() { overlayHand.hand.visible = false; compare(overlayItem.visible, true, "overLayItem.visible"); } function test_OverlayHand_rotation() { overlayHand.value = 50; compare(overlayItem.rotation, 0.0, "overLayItem.rotation"); } function test_OverlayHand_valueChange() { overlayHand.value = 70; compare(overlayItem.text, "70", "overLayItem.text"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_ubuntulistview.qml0000644000015301777760000001627512321005637032402 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 Item { width: units.gu(40) height: units.gu(60) ListModel { id: dummyModel Component.onCompleted: { for (var i = 0; i < 20; ++i) { dummyModel.append({idx: i}); } } } UbuntuListView { id: ubuntuListView anchors { left: parent.left; top: parent.top; right: parent.right } height: units.gu(20) clip: true model: dummyModel delegate: Expandable { id: expandable objectName: "expandable" + index expandedHeight: contentColumn.height onClicked: ubuntuListView.expandedIndex = index Column { id: contentColumn anchors { left: parent.left; right: parent.right; top: parent.top } Rectangle { anchors { left: parent.left; right: parent.right} id: collapsedRect color: index % 2 == 0 ? "khaki" : "blue" height: expandable.collapsedHeight } Rectangle { anchors { left: parent.left; right: parent.right } height: units.gu(40) color: "orange" } } } } UbuntuTestCase { name: "UbuntuListView" when: windowShown function initTestCase() { tryCompare(dummyModel, "count", 20); } function init() { waitForRendering(ubuntuListView); } function expandItem(item) { var index = ubuntuListView.indexAt(item.x, item.y); ubuntuListView.expandedIndex = index; var targetHeight = Math.min(item.expandedHeight, ubuntuListView.height - item.collapsedHeight); tryCompare(item, "height", targetHeight); waitForRendering(ubuntuListView) } function collapse() { if (ubuntuListView.expandedIndex == -1) { return; } var expandedItem = findChild(ubuntuListView, "expandable" + ubuntuListView.expandedIndex); ubuntuListView.expandedIndex = -1; tryCompare(expandedItem, "height", expandedItem.collapsedHeight); waitForRendering(ubuntuListView); } function test_expandedItem() { var item = findChild(ubuntuListView, "expandable1"); expandItem(item); // expandedItem needs to point to the expanded item compare(ubuntuListView.expandedIndex, 1); // item must be expanded now compare(item.expanded, true); collapse(); // expandedItem must be unset after collapsing compare(ubuntuListView.expandedIndex, -1); } function test_noScrollingNeeded() { var item = findChild(ubuntuListView, "expandable1"); fuzzyCompare(ubuntuListView.mapFromItem(item).y, item.collapsedHeight, .5); expandItem(item); waitForRendering(ubuntuListView); fuzzyCompare(ubuntuListView.mapFromItem(item).y, item.collapsedHeight, .5); } function test_scrollToTop() { ubuntuListView.height = units.gu(30); ubuntuListView.positionViewAtIndex(0, ListView.Beginning) var item = findChild(ubuntuListView, "expandable1"); fuzzyCompare(ubuntuListView.mapFromItem(item).y, item.collapsedHeight, 1); expandItem(item); fuzzyCompare(ubuntuListView.mapFromItem(item).y, 0, .5); } function test_scrollIntoView() { var item = findChild(ubuntuListView, "expandable9"); expandItem(item); waitForRendering(ubuntuListView); // The item must be scrolled upwards, leaving space for one other item at the bottom fuzzyCompare(ubuntuListView.mapFromItem(item).y, ubuntuListView.height - item.collapsedHeight - item.expandedHeight, 1); } function test_collapseByClickingOutside() { // expand item 0 var item = findChild(ubuntuListView, "expandable0"); expandItem(item); // click on item 1 var item1 = findChild(ubuntuListView, "expandable1"); mouseClick(item1, item1.width / 2, item1.height / 2); // make sure item1 is collapsed tryCompare(item, "expanded", false); } function test_dimOthers() { var item = findChild(ubuntuListView, "expandable1"); expandItem(item); for (var i = 0; i < ubuntuListView.contentItem.children.length; ++i) { var childItem = ubuntuListView.contentItem.children[i]; if (childItem.hasOwnProperty("expanded")) { compare(childItem.opacity, childItem.expanded ? 1 : .5) } } } function test_destroyAndRecreateExpanded() { var item = findChild(ubuntuListView, "expandable1"); expandItem(item); // scroll the list to the bottom ubuntuListView.currentIndex = 0; ubuntuListView.positionViewAtIndex(ubuntuListView.count -1, ListView.End); // make sure the item is eventually destroyed tryCompareFunction(function() { return findChild(ubuntuListView, "expandable1") == null;}, true) // scroll the list back up ubuntuListView.positionViewAtIndex(0, ListView.Beginning) // wait until the item is recreated. tryCompareFunction(function() { return findChild(ubuntuListView, "expandable1") != null; }, true); item = findChild(ubuntuListView, "expandable1"); compare(item.expanded, true); } function test_collapseOnClick() { var item = findChild(ubuntuListView, "expandable1"); item.collapseOnClick = true; expandItem(item); compare(ubuntuListView.expandedIndex, 1); mouseClick(item, item.width / 2, item.collapsedHeight / 2); tryCompare(ubuntuListView, "expandedIndex", -1); // restore stuff we've changed item.collapseOnClick = false; } function cleanup() { // Restore listview height ubuntuListView.height = units.gu(60); collapse(); // scroll the ListView back to top ubuntuListView.positionViewAtIndex(0, ListView.Beginning); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tabsmodel.h0000644000015301777760000000232012321005637027771 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef TABSMODEL_H #define TABSMODEL_H #include #include class TabsModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ rowCount NOTIFY countChanged); public: TabsModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex&, int) const; QHash roleNames() const; Q_INVOKABLE void append(const QString &title); Q_INVOKABLE QVariantMap get(int index); Q_SIGNALS: void countChanged(); private: QStringList m_list; }; #endif ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_toolbar.qml0000644000015301777760000001325112321005637030722 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { width: units.gu(50) height: units.gu(80) MainView { anchors.fill: parent id: mainView Page { id: page title: "test page" Label { anchors.centerIn: parent text: "testing the toolbar" } tools: ToolbarItems { id: toolbarItems ToolbarButton { id: toolbarButton text: "action1" } } } ToolbarItems { id: lockedTools ToolbarButton { text: "locked" } locked: true opened: true } } TestCase { name: "ToolbarAPI" when: windowShown function initTestCase() { compare(page.tools, toolbarItems, "Page tools are set initially"); compare(page.__propagated, mainView.__propagated, "propagated property is propagated from mainView to page") compare(mainView.__propagated.toolbar.tools, toolbarItems, "Toolbar tools are set to page tools initially"); compare(toolbarItems.opened, true, "Toolbar is opened initially"); compare(toolbarItems.locked, false, "Toolbar is initially not locked"); } function test_opened() { mainView.__propagated.toolbar.open() compare(mainView.__propagated.toolbar.opened, true, "Toolbar can be made opened"); mainView.__propagated.toolbar.close(); compare(mainView.__propagated.toolbar.opened, false, "Toolbar can be made closed"); page.tools.opened = true; compare(mainView.__propagated.toolbar.opened, true, "Toolbar can be made opened by setting page.tools.opened"); page.tools.opened = false; compare(mainView.__propagated.toolbar.opened, false, "Toolbar can be made closed by setting page.tools.opened to false"); } function test_hideTimeout_bug1249031() { compare(mainView.__propagated.toolbar.hideTimeout, 5000, "Toolbar hide timeout is initially 5 seconds."); mainView.__propagated.toolbar.open(); compare(mainView.__propagated.toolbar.opened, true, "Toolbar can be made opened"); wait(mainView.__propagated.toolbar.hideTimeout + 500); // add 500 ms margin compare(mainView.__propagated.toolbar.opened, false, "Toolbar automatically closes after timeout"); // now, wait in total more than hideTimeout, but less than 2*hideTimeout, // and have user interaction half-way to verify that the interaction // resets the timer and the toolbar is not closed. mainView.__propagated.toolbar.open(); wait(0.6*mainView.__propagated.toolbar.hideTimeout); mouseClick(toolbarButton, toolbarButton.width/2, toolbarButton.height/2); wait(0.6*mainView.__propagated.toolbar.hideTimeout); compare(mainView.__propagated.toolbar.opened, true, "Interacting with toolbar contents resets the hide timer"); // verify that the timer is still running by waiting a bit longer: wait(0.6*mainView.__propagated.toolbar.hideTimeout); compare(mainView.__propagated.toolbar.opened, false, "Interacting with the toolbar contents does not stop the timer") } function test_locked() { compare(mainView.__propagated.toolbar.tools.locked, false, "Toolbar initially not locked"); mainView.__propagated.toolbar.locked = true; compare(mainView.__propagated.toolbar.locked, true, "Toolbar can be locked"); mainView.__propagated.toolbar.locked = false; compare(mainView.__propagated.toolbar.locked, false, "Toolbar can be unlocked"); page.tools.locked = true; compare(mainView.__propagated.toolbar.locked, true, "Toolbar can be locked by setting page.tools.locked"); page.tools.locked = false; compare(mainView.__propagated.toolbar.locked, false, "Toolbar can be unlocked by setting page.tools.locked to false"); } function test_bug1192673() { toolbarItems.opened = false; mainView.__propagated.toolbar.open(); compare(toolbarItems.opened, true, "opening the toolbar updates toolbarItems.opened"); toolbarItems.opened = false; compare(mainView.__propagated.toolbar.opened, false, "setting toolbarActions.opened to false closes the toolbar"); } function test_dont_hide_locked_toolbar_bug1248759() { page.tools = lockedTools; compare(mainView.__propagated.toolbar.tools.locked, true, "Setting locked tools locks the toolbar"); wait(mainView.__propagated.toolbar.hideTimeout + 500); compare(mainView.__propagated.toolbar.opened, true, "Don't auto-hide locked toolbar after timeout"); // revert original tools for other tests: page.tools = toolbarItems; } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_picker.qml0000644000015301777760000002523512321005637030542 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Item { id: testSuite width: units.gu(40) height: units.gu(71) Flow { anchors.fill: parent Picker { objectName: "linear" id: linearShort circular: false model: objectModel delegate: PickerDelegate { Label {text: modelData} } } Picker { objectName: "linear" id: linearLong circular: false model: longerModel delegate: PickerDelegate { Label {text: modelData} } } Picker { objectName: "objectModelled" id: objectModelled model: objectModel selectedIndex: 2 delegate: PickerDelegate { Label {text: modelData} } } Picker { objectName: "simpleModelled" id: simpleModelled model: emptyModel selectedIndex: 2 delegate: PickerDelegate { Label {text: modelData} } } Picker { objectName: "picker" id: picker } Picker { id: linearDynPicker objectName: "linearDynPicker" model: dynamicModel circular: false delegate: PickerDelegate { Label {text: modelData} } } Picker { id: circularDynPicker objectName: "circularDynPicker" model: dynamicModel circular: true delegate: PickerDelegate { Label {text: modelData} } } } ListModel { id: emptyModel } ListModel { id: dynamicModel Component.onCompleted: reset() function reset() { clear(); for (var i = 0; i < 100; i++) { append({"label": "line" + i}); } } } ListModel { id: objectModel ListElement { label: "line1" } ListElement { label: "line2" } ListElement { label: "line3" } } ListModel { id: longerModel ListElement { label: "line1" } ListElement { label: "line2" } ListElement { label: "line3" } ListElement { label: "line4" } ListElement { label: "line5" } ListElement { label: "line6" } } SignalSpy { id: spy } UbuntuTestCase { id: testCase name: "PickerAPI" when: windowShown function waitPickerScrolling() { wait(600); } function getPickerList(item, linear) { return findChild(item, (linear) ? "Picker_Linear" : "Picker_WrapAround"); } function test_0_circular() { compare(picker.circular, true, "default circular"); } function test_0_model() { compare(picker.model, undefined, "default model"); } function test_0_delegate() { compare(picker.delegate, null, "default delegate"); } function test_0_selectedIndex() { compare(picker.selectedIndex, 0, "default selectedIndex"); } function test_1_runtimeModel() { picker.model = emptyModel; compare(picker.selectedIndex, 0, "selectedIndex gets 0"); } function test_1_selectedIndexForEmptyModel() { compare(simpleModelled.selectedIndex, 0, "empty modelled picker selectedIndex is 0"); } function test_1_selectedIndexForObjectModel() { compare(objectModelled.selectedIndex, 2, "model containing data, picker.selectedIndex"); } function test_2_updateModel() { picker.selectedIndex = 1; spy.clear(); spy.signalName = "onSelectedIndexChanged"; spy.target = picker; picker.model = []; tryCompare(spy, "count", 1); } function test_2_updateModel2() { objectModelled.selectedIndex = 1; spy.clear(); spy.signalName = "onSelectedIndexChanged"; spy.target = objectModelled; objectModelled.model = []; tryCompare(spy, "count", 1); } function test_4_clickMovesSelection_Long() { spy.clear(); spy.signalName = "onSelectedIndexChanged"; spy.target = linearLong; mouseClick(linearLong, units.gu(1), units.gu(1)); tryCompare(spy, "count", 0); mouseClick(linearLong, units.gu(1), units.gu(18)); tryCompare(spy, "count", 1); } function test_3_clickMovesSelection_Short() { spy.clear(); spy.signalName = "onSelectedIndexChanged"; spy.target = linearShort; mouseClick(linearShort, units.gu(1), units.gu(1)); tryCompare(spy, "count", 0); mouseClick(linearShort, units.gu(1), units.gu(18)); tryCompare(spy, "count", 1); } function test_5_clickMovesSelection_Long() { spy.clear(); spy.signalName = "onSelectedIndexChanged"; linearLong.circular = true; spy.target = linearLong; mouseClick(linearLong, units.gu(1), units.gu(1)); waitPickerScrolling(); tryCompare(spy, "count", 1); mouseClick(linearLong, units.gu(1), units.gu(18)); waitPickerScrolling(); tryCompare(spy, "count", 2); } function test_6_pickerCircularChange() { var expectedList = picker.circular ? "Picker_WrapAround" : "Picker_Linear"; verify(findChild(picker, expectedList) !== undefined, "Picker must use " + expectedList); picker.circular = !picker.circular; expectedList = picker.circular ? "Picker_WrapAround" : "Picker_Linear"; verify(findChild(picker, expectedList) !== undefined, "circular changed, Picker must use " + expectedList); } function test_7_modelCropping() { var selected = 50; linearDynPicker.selectedIndex = selected; circularDynPicker.selectedIndex = selected; waitPickerScrolling(); var linearList = getPickerList(linearDynPicker, true); var circularList = getPickerList(circularDynPicker, false); selected = 40; dynamicModel.remove(selected, dynamicModel.count - selected); waitPickerScrolling(); compare(linearList.count, selected, "bad removal from linearList") compare(linearDynPicker.selectedIndex, selected - 1, "bad index of linearList"); compare(circularList.count, selected , "bad removal from circularList") compare(circularDynPicker.selectedIndex, selected - 1, "bad index of circularList"); // remove from the middle selected = 10; dynamicModel.remove(selected, 10); waitPickerScrolling(); compare(linearList.count, 30, "bad removal from linearList") compare(linearDynPicker.selectedIndex, 29, "bad index of linearList"); compare(circularList.count, 30, "bad removal from circularList") compare(circularDynPicker.selectedIndex, 29, "bad index of circularList"); // move selection in front and remove from after linearDynPicker.selectedIndex = 10; circularDynPicker.selectedIndex = 10; dynamicModel.remove(20, 10); waitPickerScrolling(); compare(linearList.count, 20, "bad removal from linearList") compare(linearDynPicker.selectedIndex, 10, "bad index of linearList"); compare(circularList.count, 20, "bad removal from circularList") compare(circularDynPicker.selectedIndex, 10, "bad index of circularList"); // remove 6 items around selectedIndex dynamicModel.remove(5, 6); waitPickerScrolling(); compare(linearList.count, 14, "bad removal from linearList") compare(linearDynPicker.selectedIndex, 4, "bad index of linearList"); compare(circularList.count, 14, "bad removal from circularList") compare(circularDynPicker.selectedIndex, 4, "bad index of circularList"); } function test_8_modelReset() { var linearList = getPickerList(linearDynPicker, true); var circularList = getPickerList(circularDynPicker, false); dynamicModel.reset(); waitPickerScrolling(); compare(linearList.currentIndex, 0, "linear picker's itemList selection not reset"); compare(circularList.currentIndex, 0, "circular picker's itemList selection not reset"); compare(linearDynPicker.selectedIndex, 0, "linear picker's selection not reset"); compare(circularDynPicker.selectedIndex, 0, "circular picker's selection not reset"); } function test_9_modelClear() { var linearList = getPickerList(linearDynPicker, true); var circularList = getPickerList(circularDynPicker, false); dynamicModel.clear(); waitPickerScrolling(); compare(linearList.currentIndex, -1, "linear picker's itemList selection not reset"); expectFailContinue("", "PathView issue: https://bugreports.qt-project.org/browse/QTBUG-35400"); compare(circularList.currentIndex, -1, "circular picker's itemList selection not reset"); compare(linearDynPicker.selectedIndex, -1, "linear picker's selection not reset"); expectFailContinue("", "PathView issue: https://bugreports.qt-project.org/browse/QTBUG-35400"); compare(circularDynPicker.selectedIndex, -1, "circular picker's selection not reset"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tabsmodel.cpp0000644000015301777760000000271312321005637030332 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "tabsmodel.h" TabsModel::TabsModel() { } int TabsModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; return m_list.count(); } QVariant TabsModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { return m_list[index.row()]; } return QVariant(); } void TabsModel::append(const QString &title) { const int count = m_list.count(); beginInsertRows(QModelIndex(), count, count); m_list << title; endInsertRows(); Q_EMIT countChanged(); } QVariantMap TabsModel::get(int index) { QVariantMap res; res.insert("title", m_list[index]); return res; } QHash TabsModel::roleNames() const { QHash roles; roles[Qt::DisplayRole] = "title"; return roles; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_tabbar.qml0000644000015301777760000001637112321005735030520 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import TestObjects 0.1 Item { id: root width: units.gu(40) height: units.gu(71) TabBar { id: bar anchors.top: parent.top width: parent.width } TabBar { id: bar2 // anchor to bottom not to occlude the first TabBar anchors.bottom: parent.bottom width: parent.width model: invalidModel } ListView { anchors { fill: parent topMargin: bar.height } orientation: Qt.Horizontal currentIndex: bar.selectedIndex model: pages delegate: Rectangle { width: ListView.view.width height: ListView.view.height Label { anchors.centerIn: parent text: title fontSize: "x-large" } color: Qt.rgba(Math.random(0.5), Math.random(1), Math.random(0.5), 1) } } ListModel { id: pages ListElement { title: "Tab 1" } ListElement { title: "Tab 2" } ListElement { title: "Tab 3" } ListElement { title: "Tab 4" } ListElement { title: "Tab 5" } } ListModel { id: invalidModel ListElement { fruit: "Pear" } } ListModel { id: invalidModelTab ListElement { tab: "Pear" } } Item { id: myTab property string title: "Pear" } ListModel { id: validModelTab } ListModel { id: emptyModelWillBeInvalid } ListModel { id: emptyModel } TabsModel { id: pagesCpp } Label { id: textSizer text: "Tab 9" visible: false } TestCase { name: "TabBarAPI" when: windowShown // API test function test_0_tabsItem() { // deprecated } function test_0_model() { compare(bar.model, null, "model default is undefined"); } function test_0_selectionMode() { compare(bar.selectionMode, true, "default selectionMode"); } function test_0_selectedIndex() { compare(bar.selectedIndex, -1, "default selectedIndex"); } function test_0_alwaysSelectionMode() { compare(bar.alwaysSelectionMode, false, "default alwaysSelectionMode"); } function test_0_animate() { compare(bar.animate, true, "default animate"); } function test_1_modelSet() { bar.model = pages; compare(bar.model, pages); compare(bar.selectedIndex, 0, "selectedIndex defaults to 0 when model is defined"); } function test_2_tabSelection_data() { // sync textSizer with style settings textSizer.fontSize = bar.__styleInstance.headerFontSize; textSizer.font.weight = bar.__styleInstance.headerFontWeight; var tabWidth = units.gu(2) + textSizer.paintedWidth + bar.__styleInstance.headerTextLeftMargin + bar.__styleInstance.headerTextRightMargin; return [ {"position": tabWidth, "selectedIndex": 1}, {"position": tabWidth, "selectedIndex": 2}, {"position": tabWidth, "selectedIndex": 3}, {"position": tabWidth, "selectedIndex": 4}, {"position": tabWidth, "selectedIndex": 0}, {"position": tabWidth, "selectedIndex": 1}, {"position": tabWidth, "selectedIndex": 2}, {"position": tabWidth, "selectedIndex": 3}, {"position": tabWidth, "selectedIndex": 4}, {"position": 2 * tabWidth, "selectedIndex": 1}, {"position": 2 * tabWidth, "selectedIndex": 3}, {"position": 2 * tabWidth, "selectedIndex": 0}, ]; } function test_2_tabSelection(data) { bar.model = pages; compare(bar.model, pages); if (bar.selectionMode) { // wait till the TabBar goes off from selection mode, with an extra threshold wait(bar.__styleInstance.deactivateTime + 500); } // activate tab compare(bar.selectionMode, false, "TabBar is not yet in selection mode"); mouseClick(root, units.gu(2), units.gu(2)); wait(bar.__styleInstance.headerTextFadeDuration); // wait to show the selections compare(bar.selectionMode, true, "TabBar is in selection mode"); // select the next tab mouseClick(root, data.position, units.gu(2)); compare(bar.selectionMode, false, "TabBar is no longer in selection mode"); // wait till the selection mode goes off by waiting ~1 second wait(bar.__styleInstance.headerTextFadeDuration); compare(bar.selectedIndex, data.selectedIndex, "the next tab is selected"); } function test_invalidModel() { bar.model = invalidModel; compare(bar.model, null, "the model has to be null when setting an invalid model"); } function test_invalidModelTab() { bar.model = invalidModelTab; compare(bar.model, null, "the model has to be null when setting an invalid model"); } function test_invalidModelTab2() { compare(bar2.model, null, "the model has to be null when setting an invalid model"); } function test_validModelTab() { bar.model = validModelTab; compare(bar.model, validModelTab); validModelTab.append({tab: myTab}); compare(bar.model, validModelTab); } function test_invalidModelEmptyAtTheBeginning() { bar.model = emptyModelWillBeInvalid; compare(bar.model, emptyModelWillBeInvalid); emptyModelWillBeInvalid.append({fruit: "Pear"}); compare(bar.model, null, "the model has to be null when setting an invalid model"); } function test_addTabAfterShownQML() { bar.model = emptyModel; compare(bar.model, emptyModel); compare(bar.selectedIndex, -1); emptyModel.append({title:"Title 1"}); compare(bar.selectedIndex, 0); } function test_addTabAfterShownCpp() { bar.model = pagesCpp; compare(bar.model, pagesCpp); compare(bar.selectedIndex, -1); pagesCpp.append("Title 1"); compare(bar.selectedIndex, 0); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_textarea.qml0000644000015301777760000004004712321005637031100 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Item { width: 200; height: 200 property bool hasOSK: QuickUtils.inputMethodProvider !== "" TextArea { id: textArea SignalSpy { id: signalSpy target: parent } property int keyPressData property int keyReleaseData Keys.onPressed: keyPressData = event.key Keys.onReleased: keyReleaseData = event.key } TextArea { id: colorTest color: colorTest.text.length < 4 ? "#0000ff" : "#00ff00" } TextEdit { id: textEdit } ListItem.Empty { id: listItem height: 200 anchors.left: parent.left anchors.right: parent.right SignalSpy { id: listItemSpy signalName: "clicked" target: listItem } TextArea { id: input anchors.fill: parent Component.onCompleted: forceActiveFocus() } } Item { TextArea { id: t1 objectName: "t1" } TextArea { id: t2 objectName: "t2" } } TestCase { name: "TextAreaAPI" when: windowShown function test_1_activate() { textArea.forceActiveFocus(); compare(textArea.activeFocus, true, "TextArea is active"); } // TextEdit shared properties function test_0_activeFocusOnPress() { compare(textArea.activeFocusOnPress,textEdit.activeFocusOnPress,"TextArea.activeFocusOnPress is same as TextEdit.activeFocusOnPress") } function test_0_canPaste() { compare(textArea.canPaste,textEdit.canPaste,"TextArea.canPaste is same as TextEdit.canPaste") } function test_0_canRedo() { compare(textArea.canRedo,textEdit.canRedo,"TextArea.canRedo is same as TextEdit.canRedo") } function test_0_canUndo() { compare(textArea.canUndo,textEdit.canUndo,"TextArea.canUndo is same as TextEdit.canUndo") } function test_0_color() { compare(textArea.color,textEdit.color,"TextArea.color is same as TextEdit.canUndo") } function test_0_cursorDelegate() { compare((textArea.cursorDelegate!=null),true,"TextArea.cursorDelegate is not null") } function test_0_cursorPosition() { compare(textArea.cursorPosition,textEdit.cursorPosition,"TextArea.cursorPosition is same as TextEdit.cursorPosition") } function test_0_cursorRectangle() { compare(textArea.cursorRectangle,textEdit.cursorRectangle,"TextArea.cursorRectangle is same as TextEdit.cursorRectangle") } function test_0_cursorVisible() { compare(textArea.cursorVisible,textEdit.cursorVisible,"TextArea.cursorVisible is same as TextEdit.cursorVisible") } function test_0_effectiveHorizontalAlignment() { compare(textArea.effectiveHorizontalAlignment,textEdit.effectiveHorizontalAlignment,"TextArea.effectiveHorizontalAlignment is same as TextEdit.effectiveHorizontalAlignment") } function test_0_font() { compare(textArea.font,textEdit.font,"TextArea.font is same as TextEdit.font") } function test_0_horizontalAlignment() { compare(textArea.horizontalAlignment,textEdit.horizontalAlignment,"TextArea.horizontalAlignment is same as TextEdit.horizontalAlignment") } function test_0_inputMethodComposing() { compare(textArea.inputMethodComposing,textEdit.inputMethodComposing,"TextArea.inputMethodComposing is same as TextEdit.inputMethodComposing") } function test_0_inputMethodHints() { compare(textArea.inputMethodHints,textEdit.inputMethodHints,"TextArea.inputMethodHints is same as TextEdit.inputMethodHints") } function test_0_length() { compare(textArea.length,textEdit.length,"TextArea.length is same as TextEdit.length") } function test_0_lineCount() { compare(textArea.lineCount,textEdit.lineCount,"TextArea.lineCount is same as TextEdit.lineCount") } function test_1_mouseSelectionMode() { compare(textArea.mouseSelectionMode, TextEdit.SelectWords,"TextArea.mouseSelectionMode is SelectWords") } function test_0_persistentSelection() { compare(textArea.persistentSelection,textEdit.persistentSelection,"TextArea.persistentSelection is same as TextEdit.persistentSelection") } function test_0_readOnly() { compare(textArea.readOnly,textEdit.readOnly,"TextArea.readOnly is same as TextEdit.readOnly") } function test_0_renderType() { compare(textArea.renderType,textEdit.renderType,"TextArea.renderType is same as TextEdit.renderType") } function test_0_selectByMouse() { compare(textArea.selectByMouse,true,"TextArea.selectByMouse is true") } function test_0_selectedText() { compare(textArea.selectedText,textEdit.selectedText,"TextArea.selectedText is same as TextEdit.selectedText") } function test_0_selectedTextColor() { compare(textArea.selectedTextColor,textEdit.selectedTextColor,"TextArea.selectedTextColor is same as TextEdit.selectedTextColor") } function test_0_selectionColor() { compare(textArea.selectionColor,textEdit.selectionColor,"TextArea.selectionColor is same as TextEdit.selectionColor") } function test_0_selectionEnd() { compare(textArea.selectionEnd,textEdit.selectionEnd,"TextArea.selectionEnd is same as TextEdit.selectionEnd") } function test_0_selectionStart() { compare(textArea.selectionStart,textEdit.selectionStart,"TextArea.selectionStart is same as TextEdit.selectionStart") } function test_0_text() { compare(textArea.text,textEdit.text,"TextArea.text is same as TextEdit.text") } function test_0_textFormat() { compare(textArea.textFormat,textEdit.textFormat,"TextArea.textFormat is same as TextEdit.textFormat") } function test_0_verticalAlignment() { compare(textArea.verticalAlignment,textEdit.verticalAlignment,"TextArea.verticalAlignment is same as TextEdit.verticalAlignment") } function test_0_wrapMode() { compare(textArea.wrapMode,TextEdit.Wrap,"TextArea.wrapMode is TextEdit.Wrap") } // TextArea specific properties function test_1_highlighted() { compare(textArea.highlighted, textArea.focus, "highlighted is the same as focused"); } function test_1_contentHeight() { compare(textArea.contentHeight>0,true,"contentHeight over 0 units on default") var newValue = 200; textArea.contentHeight = newValue; compare(textArea.contentHeight,newValue,"set/get"); } function test_1_contentWidth() { compare(textArea.contentWidth,units.gu(30),"contentWidth is 30 units on default") var newValue = 200; textArea.contentWidth = newValue; compare(textArea.contentWidth,newValue,"set/get"); } function test_1_placeholderText() { compare(textArea.placeholderText,"","placeholderText is '' on default") var newValue = "Hello Placeholder"; textArea.placeholderText = newValue; compare(textArea.placeholderText,newValue,"set/get"); } function test_1_autoSize() { compare(textArea.autoSize,false,"TextArea.autoSize is set to false"); var newValue = true; textArea.autoSize = newValue; compare(textArea.autoSize, newValue,"set/get"); } function test_1_baseUrl() { expectFail("","TODO") compare(textArea.baseUrl,"tst_textarea.qml","baseUrl is QML file instantiating the TextArea item on default") } function test_1_displayText() { compare(textArea.displayText,"","displayText is '' on default") var newValue = "Hello Display Text"; try { textArea.displayText = newValue; compare(false,true,"Unable to set value as it is read-only"); } catch (e) { compare(true,true,"Unable to set value as it is read-only"); } } function test_1_popover() { compare(textArea.popover, undefined, "Uses default popover"); } function test_1_maximumLineCount() { compare(textArea.maximumLineCount,5,"maximumLineCount is 0 on default") var newValue = 10; textArea.maximumLineCount = newValue; compare(textArea.maximumLineCount,newValue,"set/get"); } function test_0_visible() { textArea.visible = false; compare(textArea.activeFocus, false, "TextArea is inactive"); } // functions function test_copy() { textArea.copy(); } function test_cut() { Clipboard.clear(); textArea.readOnly = false; textArea.text = "test text"; textArea.cursorPosition = textArea.text.indexOf("text"); textArea.selectWord(); textArea.cut(); compare(textArea.text, "test ", "Text cut properly"); compare(Clipboard.data.text, "text", "Clipboard contains cut text"); // we should have the "text" only ones var plainTextCount = 0; for (var i in Clipboard.data.formats) { if (Clipboard.data.formats[i] === "text/plain") plainTextCount++; } compare(plainTextCount, 1, "Clipboard is correct"); } function test_deselect() { textArea.deselect(); } function test_getFormattedText() { textArea.getFormattedText(0,0); } function test_getText() { textArea.getText(0,0); } function test_insert() { textArea.insert(0,"Hello"); } function test_isRightToLeft() { textArea.isRightToLeft(0,0); } function test_moveCursorSelection() { textArea.moveCursorSelection(0,0); } function test_paste() { textArea.readOnly = false; textArea.text = "test"; textArea.cursorPosition = textArea.text.length; textArea.paste(" text"); compare(textArea.text, "test text", "Data pasted"); } function test_positionAt() { textArea.positionAt(0,1); } function test_positionToRectangle() { textArea.positionToRectangle(0); } function test_redo() { textArea.redo(); } function test_remove() { textArea.remove(0,0); } function test_select() { textArea.select(0,0); } function test_selectAll() { textArea.selectAll(); } function test_selectWord() { textArea.selectWord(); } function test_undo() { textArea.undo(); } // signals function test_linkActivated() { signalSpy.signalName = "linkActivated"; compare(signalSpy.valid,true,"linkActivated signal exists") } // filters function test_keyPressAndReleaseFilter() { textArea.visible = true; textArea.forceActiveFocus(); textArea.readOnly = false; textArea.keyPressData = 0; textArea.keyReleaseData = 0; keyClick(Qt.Key_T, Qt.NoModifier, 100); compare(textArea.keyPressData, Qt.Key_T, "Key press filtered"); compare(textArea.keyReleaseData, Qt.Key_T, "Key release filtered"); } function test_TextAreaInListItem_EnterCaptured() { input.forceActiveFocus(); input.textFormat = TextEdit.PlainText; input.text = ""; keyClick(Qt.Key_T); keyClick(Qt.Key_E); keyClick(Qt.Key_S); keyClick(Qt.Key_T); keyClick(Qt.Key_Enter); compare(input.text, "test\n", "Keys"); } function test_TextAreaInListItem_EnterDoesNotProduceClick() { input.forceActiveFocus(); input.textFormat = TextEdit.PlainText; input.text = ""; listItemSpy.clear(); keyClick(Qt.Key_Enter); tryCompare(listItemSpy, "count", 0, 100); } function test_colorCollisionOnDelegate() { // fixes bug lp:1169601 colorTest.text = "abc"; compare(colorTest.color, "#0000ff", "Color when text length < 4"); colorTest.text = "abcd"; compare(colorTest.color, "#00ff00", "Color when text length >= 4"); } function test_OneActiveFocus() { t1.focus = true; compare(t1.activeFocus, true, "T1 has activeFocus"); compare(t2.activeFocus, false, "T1 has activeFocus"); t2.focus = true; compare(t1.activeFocus, false, "T1 has activeFocus"); compare(t2.activeFocus, true, "T1 has activeFocus"); } function test_OSK_ShownWhenNextTextAreaIsFocused() { if (!hasOSK) expectFail("", "OSK can be tested only when present"); t1.focus = true; compare(Qt.inputMethod.visible, true, "OSK is shown for the first TextArea"); t2.focus = true; compare(Qt.inputMethod.visible, true, "OSK is shown for the second TextArea"); } function test_RemoveOSKWhenFocusLost() { if (!hasOSK) expectFail("", "OSK can be tested only when present"); t1.focus = true; compare(Qt.inputMethod.visible, true, "OSK is shown when TextArea gains focus"); t1.focus = false; compare(Qt.inputMethod.visible, false, "OSK is hidden when TextArea looses focus"); } function test_ReEnabledInput() { textArea.forceActiveFocus(); textArea.enabled = false; compare(textArea.enabled, false, "textArea is disabled"); compare(textArea.focus, true, "textArea is focused"); compare(textArea.activeFocus, false, "textArea is not active focus"); compare(Qt.inputMethod.visible, false, "OSK removed"); textArea.enabled = true; compare(textArea.enabled, true, "textArea is enabled"); compare(textArea.focus, true, "textArea is focused"); compare(textArea.activeFocus, true, "textArea is active focus"); if (!hasOSK) expectFail("", "OSK can be tested only when present"); compare(Qt.inputMethod.visible, true, "OSK shown"); } // make it to b ethe last test case executed function test_zz_TextareaInListItem_RichTextEnterCaptured() { textArea.text = "a
b"; textArea.textFormat = TextEdit.RichText; input.forceActiveFocus(); input.textFormat = TextEdit.RichText; input.text = "ab"; input.cursorPosition = 1; keyClick(Qt.Key_Return); compare(input.text, textArea.text, "Formatted text split"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_datepicker.qml0000644000015301777760000006221712321005637031401 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Item { id: testSuite width: units.gu(40) height: units.gu(71) Component { id: testComponent DatePicker { width: testSuite.width } } Loader { id: pickerLoader asynchronous: false width: parent.width } UbuntuTestCase { name: "DatePickerAPI" when: windowShown readonly property DatePicker picker: pickerLoader.item function init() { pickerLoader.sourceComponent = testComponent; tryCompareFunction(function(){return pickerLoader.status}, Loader.Ready); waitPickerMoving(); } function cleanup() { pickerLoader.sourceComponent = undefined; } function waitPickerMoving() { waitForRendering(picker); tryCompareFunction(function(){return picker.moving}, false); } function getPickerLabel(picker, name) { var pickerItem = findChild(picker, name); var pickerCurrent = findChild(pickerItem, "Picker_ViewLoader"); return findChild(pickerCurrent.item.currentItem, "PickerRow_PickerLabel"); } function getPickerModel(picker, name) { var pickerItem = findInvisibleChild(picker, name); return pickerItem ? pickerItem.model : undefined; } function setHMS(date, h, m, s) { date.setHours(h); date.setMinutes(m); date.setSeconds(s); return date; } function test_0_mode() { compare(picker.mode, "Years|Months|Days", "default mode"); } function test_0_date() { var date = (new Date()).midnight(); compare(picker.date, date, "default mode"); compare(picker.year, date.getFullYear(), "default year"); compare(picker.month, date.getMonth(), "default month"); compare(picker.day, date.getDate(), "default day"); compare(picker.week, date.getWeek(), "default week"); compare(picker.hours, date.getHours(), "default hour"); compare(picker.minutes, date.getMinutes(), "default minute"); compare(picker.seconds, date.getSeconds(), "default second"); } function test_0_minimum_maximum() { var endDate = Date.prototype.midnight.call(new Date()); endDate.setFullYear(endDate.getFullYear() + 50); compare(picker.minimum, picker.date, "default minimum is same as date property"); compare(picker.maximum, endDate, "default maximum is a 50 years window"); } function test_0_locale() { compare(picker.locale, Qt.locale(), "default locale is the same as system locale"); } function test_1_changeModeYM() { var newMode = "Years|Months"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeMD() { var newMode = "Days|Months"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeYD() { var newMode = "Years|Days"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; // no rendering is expected, no need to wait var positioner = findChild(picker, "PickerRow_Positioner"); expectFailContinue("", "Invalid mode"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeY() { var newMode = "Years"; var pickerCount = 1 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeM() { var newMode = "Months"; var pickerCount = 1 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeD() { var newMode = "Days"; var pickerCount = 1 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeHMS() { var newMode = "Hours|Minutes|Seconds"; var pickerCount = 3 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeHM() { var newMode = "Hours|Minutes"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeMS() { var newMode = "Minutes|Seconds"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeHS() { var newMode = "Hours|Seconds"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); expectFailContinue("", "cannot set mode to Hours|Minutes"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeH() { var newMode = "Hours"; var pickerCount = 1 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeMinute() { var newMode = "Minutes"; var pickerCount = 1 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeS() { var newMode = "Seconds"; var pickerCount = 1 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeYMDHMS() { var newMode = "Years|Months|Days|Hours|Minutes|Seconds"; var pickerCount = 6 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); expectFailContinue("", "cannot combine date and time pickers"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeYH() { var newMode = "Years|Hours"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; waitPickerMoving(); var positioner = findChild(picker, "PickerRow_Positioner"); expectFailContinue("", "cannot combine date and time pickers"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeModeUnhandled() { var newMode = "Years|Whatever"; var pickerCount = 2 + 1; // +1 is the Repeater picker.mode = newMode; // no rendering is expected, no need to wait var positioner = findChild(picker, "PickerRow_Positioner"); expectFailContinue("", "unhandled mode flag should not pass"); compare(positioner.children.length, pickerCount, "invalid amount of pickers"); } function test_1_changeLocale() { var prevLocale = picker.locale; var locale = Qt.locale("hu_HU"); picker.minimum = new Date(2012, 11, 1); picker.date = new Date(2012, 11, 1); picker.locale = Qt.locale("hu_HU"); waitPickerMoving(); var label = getPickerLabel(picker, "PickerRow_MonthPicker"); compare(label.text, locale.monthName(picker.date.getMonth(), Locale.LongFormat), "locale for month wrong"); label = getPickerLabel(picker, "PickerRow_DayPicker"); var dayModel = getPickerModel(picker, "PickerRow_DayPicker"); compare(label.text, dayModel.text(picker.date.getDate() - 1, testSuite.width), "locale for day name wrong"); } function test_1_changeMinimumBeforeDate() { var date = new Date(picker.date); var originalDate = new Date(date); date.setFullYear(date.getFullYear() - 1); date.setDate(1); picker.minimum = date; // no rendering is expected, so no need to wait var year = getPickerLabel(picker, "PickerRow_YearPicker"); compare(year.text, originalDate.getFullYear().toString(), "year differs"); var month = getPickerLabel(picker, "PickerRow_MonthPicker"); compare(month.text, picker.locale.monthName(originalDate.getMonth(), Locale.LongFormat), "month differs"); var day = getPickerLabel(picker, "PickerRow_DayPicker"); var dayModel = getPickerModel(picker, "PickerRow_DayPicker"); compare(day.text, dayModel.text(originalDate.getDate() - 1), "day differs"); } function test_1_changeMaximumAfterDate() { var date = new Date(picker.date); var originalDate = new Date(date); date.setFullYear(date.getFullYear() + 1); date.setDate(1); picker.maximum = date; waitPickerMoving(); var year = getPickerLabel(picker, "PickerRow_YearPicker"); compare(year.text, originalDate.getFullYear().toString(), "year differs"); var month = getPickerLabel(picker, "PickerRow_MonthPicker"); compare(month.text, picker.locale.monthName(originalDate.getMonth(), Locale.LongFormat), "month differs"); var day = getPickerLabel(picker, "PickerRow_DayPicker"); var dayModel = getPickerModel(picker, "PickerRow_DayPicker"); compare(day.text, dayModel.text(originalDate.getDate() - 1), "day differs"); } // make infinite function test_1_changeMinimumInvalid() { picker.minimum = Date.prototype.getInvalidDate.call(); // no rendering is expected compare(picker.minimum, picker.date, "invalid minimum hasn't been adjusted to date"); } // make infinite function test_1_changeMaximumInvalid() { picker.maximum = Date.prototype.getInvalidDate.call(); waitPickerMoving(); // check if the year picker model is autoExtending var yearModel = getPickerModel(picker, "PickerRow_YearPicker"); compare(yearModel.autoExtend, true, "the year picker is not auto-extending one"); } function test_1_changeDate() { var date = new Date(); date.setFullYear(picker.date.getFullYear() + 2); date.setMonth(5); date.setDate(21); picker.date = date; picker.mode = "Years|Months|Days"; waitPickerMoving(); var yearLabel = getPickerLabel(picker, "PickerRow_YearPicker"); var monthLabel = getPickerLabel(picker, "PickerRow_MonthPicker"); var monthModel = getPickerModel(picker, "PickerRow_MonthPicker"); var dayLabel = getPickerLabel(picker, "PickerRow_DayPicker"); var dayModel = getPickerModel(picker, "PickerRow_DayPicker"); compare(yearLabel.text, date.getFullYear().toString(), "different year value"); compare(monthLabel.text, monthModel.text(date.getMonth()), "different month value"); compare(dayLabel.text, dayModel.text(date.getDate() - 1), "different day value"); } function test_1_changeDateToNextMonth() { picker.minimum = new Date(2013, 9, 1); picker.date = new Date(2013, 09, 31); picker.locale = Qt.locale("hu_HU") waitPickerMoving(); // click on the month picker to set the next month var monthPicker = findChild(picker, "PickerRow_MonthPicker"); var monthCurrent = findChild(monthPicker, "Picker_ViewLoader"); var my = monthPicker.y + (monthPicker.height / 2) + monthCurrent.item.currentItem.height; var mx = monthPicker.x + monthPicker.width / 2; mouseClick(picker, mx, my); waitPickerMoving(); var yearLabel = getPickerLabel(picker, "PickerRow_YearPicker"); var monthLabel = getPickerLabel(picker, "PickerRow_MonthPicker"); var monthModel = getPickerModel(picker, "PickerRow_MonthPicker"); var dayLabel = getPickerLabel(picker, "PickerRow_DayPicker"); var dayModel = getPickerModel(picker, "PickerRow_DayPicker"); compare(yearLabel.text, "2013", "different year value"); // November compare(monthLabel.text, monthModel.text(10), "different month value"); // the 30th compare(dayLabel.text, dayModel.text(29), "different day value"); // set it back my = monthPicker.y + (monthPicker.height / 2) - monthCurrent.item.currentItem.height; mouseClick(picker, mx, my); waitPickerMoving(); compare(yearLabel.text, "2013", "different year value"); // October monthLabel = getPickerLabel(picker, "PickerRow_MonthPicker"); compare(monthLabel.text, monthModel.text(9), "different month value"); // the 30th dayLabel = getPickerLabel(picker, "PickerRow_DayPicker"); compare(dayLabel.text, dayModel.text(29), "different day value"); } function test_2_disabledYear() { var date = new Date(2013, 4, 1); var minDate = new Date(2013, 0, 1); var maxDate = new Date(2013, 11, 31); picker.minimum = minDate; picker.maximum = maxDate; waitPickerMoving(); picker.date = date; waitPickerMoving(); var yearPicker = findChild(picker, "PickerRow_YearPicker"); compare(yearPicker.enabled, false, "year picker should be disabled"); } function test_2_disabledYearAndMonth() { var date = new Date(2013, 11, 1); var minDate = new Date(2013, 11, 1); var maxDate = new Date(2013, 11, 31); picker.minimum = minDate; picker.maximum = maxDate; picker.date = date; waitPickerMoving(); var yearPicker = findChild(picker, "PickerRow_YearPicker"); compare(yearPicker.enabled, false, "year picker should be disabled"); var monthPicker = findChild(picker, "PickerRow_MonthPicker"); compare(monthPicker.enabled, false, "month picker should be disabled"); } function test_2_linearDayPicker() { var date = new Date(2013, 11, 1); var minDate = new Date(2013, 11, 2); var maxDate = new Date(2013, 11, 31); picker.minimum = minDate; picker.maximum = maxDate; picker.date = date; var yearPicker = findChild(picker, "PickerRow_YearPicker"); compare(yearPicker.enabled, false, "year picker should be disabled"); var monthPicker = findChild(picker, "PickerRow_MonthPicker"); compare(monthPicker.enabled, false, "month picker should be disabled"); var dayPickerModel = getPickerModel(picker, "PickerRow_DayPicker"); expectFailContinue("", "day picker is always circular"); compare(dayPickerModel.circular, false, "day picker should be linear"); } function test_3_changeHours() { picker.mode = "Hours|Minutes|Seconds"; waitPickerMoving(); var date = new Date(picker.date); date.setHours((date.getHours() + 10) % 24); picker.date = date; waitPickerMoving(); var hoursLabel = getPickerLabel(picker, "PickerRow_HoursPicker"); verify(hoursLabel, "hour label undefined"); compare(hoursLabel.text, ("00" + date.getHours()).slice(-2), "hours differ"); var minutesLabel = getPickerLabel(picker, "PickerRow_MinutesPicker"); verify(minutesLabel, "minutes label undefined"); compare(minutesLabel.text, ("00" + date.getMinutes()).slice(-2), "minutes differ"); var secondsLabel = getPickerLabel(picker, "PickerRow_SecondsPicker"); verify(secondsLabel, "seconds label undefined"); compare(secondsLabel.text, ("00" + date.getSeconds()).slice(-2), "seconds differ"); } function test_3_changeMinutes() { picker.mode = "Hours|Minutes|Seconds"; var date = new Date(picker.date); date.setMinutes((date.getMinutes() + 40) % 60); picker.date = date; waitPickerMoving(); var hoursLabel = getPickerLabel(picker, "PickerRow_HoursPicker"); verify(hoursLabel, "hour label undefined"); compare(hoursLabel.text, ("00" + date.getHours()).slice(-2), "hours differ"); var minutesLabel = getPickerLabel(picker, "PickerRow_MinutesPicker"); verify(minutesLabel, "minutes label undefined"); compare(minutesLabel.text, ("00" + date.getMinutes()).slice(-2), "minutes differ"); var secondsLabel = getPickerLabel(picker, "PickerRow_SecondsPicker"); verify(secondsLabel, "seconds label undefined"); compare(secondsLabel.text, ("00" + date.getSeconds()).slice(-2), "seconds differ"); } function test_3_changeSeconds() { picker.mode = "Hours|Minutes|Seconds"; var date = new Date(picker.date); date.setSeconds((date.getSeconds() + 50) % 60); picker.date = date; waitPickerMoving(); var hoursLabel = getPickerLabel(picker, "PickerRow_HoursPicker"); verify(hoursLabel, "hour label undefined"); compare(hoursLabel.text, ("00" + date.getHours()).slice(-2), "hours differ"); var minutesLabel = getPickerLabel(picker, "PickerRow_MinutesPicker"); verify(minutesLabel, "minutes label undefined"); compare(minutesLabel.text, ("00" + date.getMinutes()).slice(-2), "minutes differ"); var secondsLabel = getPickerLabel(picker, "PickerRow_SecondsPicker"); verify(secondsLabel, "seconds label undefined"); compare(secondsLabel.text, ("00" + date.getSeconds()).slice(-2), "seconds differ"); } function test_4_changeMinimumBeforeDateHMS() { picker.mode = "Hours|Minutes|Seconds"; var date = new Date(picker.date); var originalDate = new Date(date); date.setFullYear(date.getFullYear() - 1); date.setDate(1); picker.minimum = date; waitPickerMoving(); var hoursLabel = getPickerLabel(picker, "PickerRow_HoursPicker"); verify(hoursLabel, "hour label undefined"); compare(hoursLabel.text, ("00" + originalDate.getHours()).slice(-2), "hours differ"); var minutesLabel = getPickerLabel(picker, "PickerRow_MinutesPicker"); verify(minutesLabel, "minutes label undefined"); compare(minutesLabel.text, ("00" + originalDate.getMinutes()).slice(-2), "minutes differ"); var secondsLabel = getPickerLabel(picker, "PickerRow_SecondsPicker"); verify(secondsLabel, "seconds label undefined"); compare(secondsLabel.text, ("00" + originalDate.getSeconds()).slice(-2), "seconds differ"); } function test_4_changeMaximumAfterDateHMS() { picker.mode = "Hours|Minutes|Seconds"; var date = new Date(picker.date); var originalDate = new Date(date); date.setFullYear(date.getFullYear() + 1); date.setDate(1); picker.maximum = date; waitPickerMoving(); var hoursLabel = getPickerLabel(picker, "PickerRow_HoursPicker"); verify(hoursLabel, "hour label undefined"); compare(hoursLabel.text, ("00" + originalDate.getHours()).slice(-2), "hours differ"); var minutesLabel = getPickerLabel(picker, "PickerRow_MinutesPicker"); verify(minutesLabel, "minutes label undefined"); compare(minutesLabel.text, ("00" + originalDate.getMinutes()).slice(-2), "minutes differ"); var secondsLabel = getPickerLabel(picker, "PickerRow_SecondsPicker"); verify(secondsLabel, "seconds label undefined"); compare(secondsLabel.text, ("00" + originalDate.getSeconds()).slice(-2), "seconds differ"); } function test_4_disabledHour() { picker.mode = "Hours|Minutes|Seconds"; var date = setHMS(new Date(), 12, 10, 45); var minDate = setHMS(new Date(), 12, 0, 0); var maxDate = setHMS(new Date(), 12, 59, 59); picker.minimum = minDate; picker.maximum = maxDate; waitPickerMoving(); picker.date = date; var hoursPicker = findChild(picker, "PickerRow_HoursPicker"); compare(hoursPicker.enabled, false, "hours picker should be disabled"); } function test_4_disabledHoursAndMinutes() { picker.mode = "Hours|Minutes|Seconds"; var date = setHMS(new Date(), 12, 10, 45); var minDate = setHMS(new Date(), 12, 10, 0); var maxDate = setHMS(new Date(), 12, 10, 59); picker.minimum = minDate; picker.maximum = maxDate; picker.date = date; waitPickerMoving(); var hoursPicker = findChild(picker, "PickerRow_HoursPicker"); compare(hoursPicker.enabled, false, "hours picker should be disabled"); var minutesPicker = findChild(picker, "PickerRow_MinutesPicker"); compare(minutesPicker.enabled, false, "minutes picker should be disabled"); } function test_4_linearSecondsPicker() { picker.mode = "Hours|Minutes|Seconds"; var date = setHMS(new Date(), 12, 10, 45); var minDate = setHMS(new Date(), 12, 10, 1); var maxDate = setHMS(new Date(), 12, 10, 59); picker.minimum = minDate; picker.maximum = maxDate; picker.date = date; waitPickerMoving(); var hoursPicker = findChild(picker, "PickerRow_HoursPicker"); compare(hoursPicker.enabled, false, "hours picker should be disabled"); var minutesPicker = findChild(picker, "PickerRow_MinutesPicker"); compare(minutesPicker.enabled, false, "minutes picker should be disabled"); var secondsPickerModel = getPickerModel(picker, "PickerRow_SecondsPicker"); compare(secondsPickerModel.circular, false, "day picker should be linear"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_panel.qml0000644000015301777760000002710412321005637030361 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { width: 200 height: 200 id: root Panel { id: panel anchors { bottom: parent.bottom left: parent.left right: parent.right } height: parent.height / 2 Rectangle { color: "pink" anchors.fill: parent } } TestCase { id: testCase name: "PanelAPI" when: windowShown function initTestCase() { compare(panel.align, Qt.AlignBottom, "Panel initially aligned at bottom"); compare(panel.opened, false, "Panel initially not opened"); compare(panel.locked, false, "Panel initially not locked"); compare(panel.hintSize, units.gu(2), "Default hintSize is 2 grid units"); compare(panel.triggerSize, units.gu(2), "Default triggerSize is 2 grid units"); } function test_align() { panel.align = Qt.AlignTop; compare(panel.align, Qt.AlignTop, "Can set align to top"); panel.align = Qt.AlignLeft; compare(panel.align, Qt.AlignLeft, "Can set align to left"); panel.align = Qt.AlignRight; compare(panel.align, Qt.AlignRight, "Can set align to right"); panel.align = Qt.AlignBottom; compare(panel.align, Qt.AlignBottom, "Can set align to bottom"); } function test_opened() { panel.open(); compare(panel.opened, true, "Can set opened"); panel.close(); compare(panel.opened, false, "Can unset opened"); } function test_locked() { panel.locked = true; compare(panel.locked, true, "Can set locked"); panel.locked = false; compare(panel.locked, false, "Can unset locked"); } function test_hintSize() { panel.hintSize = units.gu(1); compare(panel.hintSize, units.gu(1), "Can set hintSize"); panel.hintSize = units.gu(2); } function test_triggerSize() { panel.triggerSize = units.gu(5); compare(panel.triggerSize, units.gu(5), "Can set triggerSize"); panel.triggerSize = units.gu(2); } function test_swipeBottomPanel() { // swipe bottom-aligned panel in and out swipeTests.slowMouseMove = false; swipeTests.swipeUpDown(); swipeTests.slowMouseMove = true; swipeTests.swipeUpDown(); swipeTests.slowMouseMove = false; } function test_swipeLeftPanel() { // swipe a left-aligned panel in and out panel.align = Qt.AlignLeft; swipeTests.slowMouseMove = false; swipeTests.swipeRightLeft(); swipeTests.slowMouseMove = true; swipeTests.swipeRightLeft(); swipeTests.slowMouseMove = false; panel.align = Qt.AlignBottom; } function test_swipeRightPanel() { // swipe right-aligned panel in and out panel.align = Qt.AlignRight; swipeTests.slowMouseMove = false; swipeTests.swipeLeftRight(); swipeTests.slowMouseMove = true; swipeTests.swipeLeftRight(); swipeTests.slowMouseMove = false; panel.align = Qt.AlignBottom; } function test_swipeLeadingPanel() { // swipe leading-aligned panel in and out panel.align = Qt.AlignLeading; swipeTests.swipeRightLeft(); panel.LayoutMirroring.enabled = true; panel.LayoutMirroring.childrenInherit = true; swipeTests.slowMouseMove = false; swipeTests.swipeLeftRight(); swipeTests.slowMouseMove = true; swipeTests.swipeLeftRight(); swipeTests.slowMouseMove = false; panel.LayoutMirroring.enabled = false; panel.align = Qt.AlignBottom; } function test_swipeTrailingPanel() { // swipe trailing-aligned panel in and out panel.align = Qt.AlignTrailing; swipeTests.swipeLeftRight(); panel.LayoutMirroring.enabled = true; panel.LayoutMirroring.childrenInherit = true; swipeTests.slowMouseMove = false; swipeTests.swipeRightLeft(); swipeTests.slowMouseMove = true; swipeTests.swipeRightLeft(); swipeTests.slowMouseMove = false; panel.LayoutMirroring.enabled = false; panel.align = Qt.AlignBottom; } function test_swipeTopPanel() { // swipe top-aligned panel in and out panel.anchors.top = root.top; panel.anchors.bottom = undefined; panel.align = Qt.AlignTop; swipeTests.slowMouseMove = false; swipeTests.swipeDownUp(); swipeTests.slowMouseMove = true; swipeTests.swipeDownUp(); swipeTests.slowMouseMove = false; // revert to original state panel.anchors.bottom = root.bottom; panel.anchors.top = undefined; panel.align = Qt.AlignBottom; } function test_clickToDeactivate() { panel.open(); compare(panel.opened && panel.align === Qt.AlignBottom, true, "Panel is opened and bottom-aligned"); mouseClick(root, root.width / 2, 5, Qt.LeftButton); compare(panel.opened, false, "Panel is deactivated by clicking in the view outside of the panel"); } function test_hideTimeout_bug1249031() { compare(panel.hideTimeout, -1, "Panel hide timeout is initially negative (no timeout)"); panel.hideTimeout = 2000; panel.open(); compare(panel.opened, true, "Panel can be made opened"); wait(panel.hideTimeout + 500); // add 500 ms margin compare(panel.opened, false, "Panel automatically closes after timeout"); // now, wait in total more than hideTimeout, but less than 2*hideTimeout, // and have user interaction half-way to verify that the interaction // resets the timer and the panel is not closed. panel.open(); wait(0.6*panel.hideTimeout); mouseClick(panel, panel.width/2, panel.height/2); wait(0.6*panel.hideTimeout); compare(panel.opened, true, "Interacting with panel contents resets the hide timer"); // verify that the timer is still running by waiting a bit longer: wait(0.6*panel.hideTimeout); compare(panel.opened, false, "Interacting with the panel contents does not stop the timer") panel.hideTimeout = -1; } QtObject { id: swipeTests // waiting time in ms after move, to simulate slow drag vs fast swipe property int moveDelay: slowMouseMove ? 400 : 0 property bool slowMouseMove: false function swipeUpDown() { testCase.compare(panel.opened, false, "Panel initially not opened") var x = root.width / 2; var y = root.height - 1; var dx = 0; var dy = -panel.height / 2; testCase.mousePress(root, x, y, Qt.LeftButton); testCase.mouseMove(root, x + dx, y + dy, moveDelay); testCase.mouseRelease(root, x + dx, y + dy, Qt.LeftButton); testCase.compare(panel.opened, true, "Panel activated by swiping up (delay: "+moveDelay+")") x = panel.width / 2; y = 10; testCase.mousePress(panel, x, y, Qt.LeftButton); testCase.mouseMove(panel, x - dx, y - dy, moveDelay); testCase.mouseRelease(panel, x - dx, y - dy, Qt.LeftButton); testCase.compare(panel.opened, false, "Panel deactivated by swiping down (delay: "+moveDelay+")") } function swipeRightLeft() { testCase.compare(panel.opened, false, "Panel initially not opened") var x = 1; var y = 3 * root.height / 4; var dx = panel.width / 2; var dy = 0; testCase.mousePress(root, x, y, Qt.LeftButton); testCase.mouseMove(root, x + dx, y + dy, moveDelay); testCase.mouseRelease(root, x + dx, y + dy, Qt.Leftbutton); testCase.compare(panel.opened, true, "Left-aligned panel activated by swiping to the right (delay: "+moveDelay+")"); x = 3 * panel.width / 4; y = panel.height / 2; testCase.mousePress(panel, x, y, Qt.LeftButton); testCase.mouseMove(root, x - dx, y - dy, moveDelay); testCase.mouseRelease(panel, x - dx, y - dy, Qt.LeftButton); testCase.compare(panel.opened, false, "Left-aligned panel deactivated by swiping to the left (delay: "+moveDelay+""); } function swipeLeftRight() { testCase.compare(panel.opened, false, "Panel initially not opened") var x = root.width - 1; var y = 3 * root.height / 4; var dx = -panel.width / 2; var dy = 0; testCase.mousePress(root, x, y, Qt.LeftButton); testCase.mouseMove(root, x + dx, y + dy, moveDelay); testCase.mouseRelease(root, x + dx, y + dy, Qt.Leftbutton); testCase.compare(panel.opened, true, "Right-aligned panel activated by swiping to the left (delay: "+moveDelay+""); x = 1; y = panel.height / 2; testCase.mousePress(panel, x, y, Qt.LeftButton); testCase.mouseMove(panel, -dx, -dy, moveDelay); testCase.mouseRelease(panel, x - dx, y - dy, Qt.LeftButton); testCase.compare(panel.opened, false, "Right-aligned panel deactivating by swiping to the right (delay: "+moveDelay+""); } function swipeDownUp() { testCase.compare(panel.opened, false, "Panel initially not opened") var x = root.width / 2; var y = 1; var dx = 0; var dy = panel.height / 2; testCase.mousePress(root, x, y, Qt.LeftButton); testCase.mouseMove(root, x + dx, y + dy, moveDelay); testCase.mouseRelease(root, x + dx, y + dy, Qt.LeftButton); testCase.compare(panel.opened, true, "Top-aligned panel activated by swiping down (delay: "+moveDelay+""); x = panel.width / 2; y = panel.height - 1; testCase.mousePress(panel, x, y, Qt.LeftButton); testCase.mouseMove(panel, x - dx, y - dy, moveDelay); testCase.mouseRelease(panel, x - dx, y - dy, Qt.LeftButton); testCase.compare(panel.opened, false, "Top-aligned panel deactivated by swiping up (delay: "+moveDelay+""); } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_components.cpp0000644000015301777760000000157612321005637031445 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include "tabsmodel.h" class Register { public: Register() { qmlRegisterType("TestObjects", 0, 1, "TabsModel"); } }; Register r; QUICK_TEST_MAIN(components) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_alarms.qml0000644000015301777760000001606512321005637030545 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 Item { id: root width: 100 height: 100 Alarm { id: testAlarm } AlarmModel { id: testModel } ListView { id: roleTest model: testModel delegate: Item { objectName: "roleItem" property var roleModel: model property bool roleEnabled: model.enabled property string roleMessage: message property var roleDate: date property int roleType: type property int roleDaysOfWeek: daysOfWeek property url roleSound: sound } } UbuntuTestCase { id: testCase name: "AlarmAPI" when: windowShown function clean() { var i = 0; while (i < testModel.count) { var alarm = testModel.get(i); if (alarm.message === "test") { alarm.cancel(); wait(100); i = 0; } else { i++; } } } function initTestCase() { clean(); } function cleanupTestCase() { clean(); } function test_createOneTimeFail() { testAlarm.reset(); testAlarm.date = new Date(); testAlarm.save(); compare(testAlarm.error, Alarm.EarlyDate, 'alarm date must be greater than the current time'); } function test_createOneTimePass() { testAlarm.reset(); testAlarm.message = "test" var dt = new Date(); dt.setMinutes(dt.getMinutes() + 10); testAlarm.date = dt; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, 'alarm date must be greater than the current time'); } function test_repeating_AutoDetect() { testAlarm.reset(); testAlarm.message = "test" testAlarm.date = new Date(); testAlarm.type = Alarm.AutoDetect; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, 'repating AutoDetect alarm'); } function test_repeating_Daily() { testAlarm.reset(); testAlarm.message = "test" testAlarm.date = new Date(); testAlarm.type = Alarm.Daily; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, 'repating Daily alarm'); } function test_repeating_givenDay() { testAlarm.reset(); testAlarm.message = "test" testAlarm.date = new Date(); testAlarm.type = Alarm.Repeating; testAlarm.daysOfWeek = Alarm.Monday; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, 'repating on a given day alarm'); } function test_repeating_moreDays() { testAlarm.reset(); testAlarm.message = "test" testAlarm.date = new Date(); testAlarm.type = Alarm.Monday | Alarm.Friday; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, 'repating on multiple days alarm'); } function test_setAlarmObject_WrongRecurence() { testAlarm.reset(); testAlarm.message = "test"; var dt = new Date(); dt.setMinutes(dt.getMinutes() + 10); testAlarm.date = dt; testAlarm.type = Alarm.OneTime; testAlarm.daysOfWeek = Alarm.Monday | Alarm.Tuesday; testAlarm.save(); compare(testAlarm.error, Alarm.OneTimeOnMoreDays, 'repating on multiple days alarm'); } function test_cancel_Fail() { testAlarm.reset(); testAlarm.cancel(); compare(testAlarm.error, Alarm.InvalidEvent, "cannot cancel an unregistered alarm"); } function test_cancel_Pass() { testAlarm.reset(); testAlarm.message = "test"; testAlarm.type = Alarm.OneTime; var dt = new Date(); dt.setMinutes(dt.getMinutes() + 10); testAlarm.date = dt; testAlarm.save(); wait(100); testAlarm.cancel(); wait(100); compare(testAlarm.error, Alarm.NoError, "alarm canceled"); } function test_updateAlarm_sameType() { testAlarm.reset(); testAlarm.message = "test"; testAlarm.type = Alarm.OneTime; var dt = new Date(); dt.setMinutes(dt.getMinutes() + 10); testAlarm.date = dt; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, "fist alarm added"); dt.setDate(dt.getDate() + 2); testAlarm.date = dt; compare(testAlarm.error, Alarm.NoError, "updated alarm"); } function test_updateAlarm_differentType() { testAlarm.reset(); testAlarm.message = "test"; testAlarm.type = Alarm.OneTime; var dt = new Date(); dt.setMinutes(dt.getMinutes() + 10); testAlarm.date = dt; testAlarm.save(); compare(testAlarm.error, Alarm.NoError, "fist alarm added"); testAlarm.type = Alarm.Repeating; compare(testAlarm.error, Alarm.NoError, "updated alarm"); } function test_modelRoles() { clean(); testAlarm.reset(); testAlarm.message = "test"; var dt = new Date(); dt.setMinutes(dt.getMinutes() + 10); testAlarm.date = dt; testAlarm.type = Alarm.Repeating; testAlarm.daysOfWeek = Alarm.Monday; testAlarm.save(); wait(100); verify(testModel.count > 0, "alarm added"); var item = findChild(roleTest, "roleItem"); verify(item, "has children"); verify(item.roleModel !== undefined, "model is defined"); verify(item.roleEnabled !== undefined, "enabled is defined"); verify(item.roleMessage !== undefined, "message is defined"); verify(item.roleDate !== undefined, "date is defined"); verify(item.roleType !== undefined, "type is defined"); verify(item.roleDaysOfWeek !== undefined, "daysOfWeek is defined"); verify(item.roleSound !== undefined, "sound is defined"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_expandable.qml0000644000015301777760000001036712321005637031370 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 Item { width: units.gu(40) height: units.gu(60) ExpandablesColumn { id: expandablesColumn anchors { left: parent.left; top: parent.top; right: parent.right } height: units.gu(60) Expandable { id: expandable expandedHeight: contentColumn.height onClicked: expanded = !expanded Column { id: contentColumn anchors { left: parent.left; right: parent.right; top: parent.top } Rectangle { anchors { left: parent.left; right: parent.right} id: collapsedRect color: "khaki" height: expandable.collapsedHeight } Rectangle { anchors { left: parent.left; right: parent.right } height: units.gu(40) color: "orange" } } } } UbuntuTestCase { name: "Expandable" when: windowShown function test_expanding_collapsing() { waitForRendering(expandable); // expand it and make sure it eventually reaches the expandedHeight expandable.expanded = true; tryCompare(expandable, "height", contentColumn.height); // Item's flickable must not be interactive when the full expandedHeight fits var flickable = findInvisibleChild(expandable, "__expandableContentFlickable"); compare(flickable.interactive, false); // collapse it and make sure it eventually reaches the collapsedHeight expandable.expanded = false; tryCompare(expandable, "height", expandable.collapsedHeight); } function test_maxExpandingHeight() { // resize the column to something smaller expandablesColumn.height = units.gu(30); // Item's flickable must not be interactive when collapsed var flickable = findInvisibleChild(expandable, "__expandableContentFlickable"); compare(flickable.interactive, false); expandable.expanded = true; tryCompare(expandable, "height", expandablesColumn.height - expandable.collapsedHeight); // Now that we're expanded and don't fit into the parent, flicking must be enabled compare(flickable.interactive, true); } function test_restoreCollapsingFlickable() { // resize the column to something smaller expandablesColumn.height = units.gu(30); expandable.expanded = true; tryCompare(expandable, "height", expandablesColumn.height - expandable.collapsedHeight); var flickable = findInvisibleChild(expandable, "__expandableContentFlickable"); flickable.flick(0, -units.gu(500)) tryCompare(flickable, "flicking", false); // contentY should be off the grid now verify(flickable.contentY != 0); // Now collapse and make sure that the contentY ends up again at 0 expandable.expanded = false; tryCompare(expandable, "height", expandable.collapsedHeight); compare(flickable.contentY, 0); } function cleanup() { // Restore listview height expandablesColumn.height = units.gu(60); // restore collapsed state expandable.expanded = false; tryCompare(expandable, "height", expandable.collapsedHeight); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_header.qml0000644000015301777760000000537312321005637030516 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { width: units.gu(50) height: units.gu(80) id: root property real listViewHeaderHeight: units.gu(5) MainView { id: mainViewHeader anchors.fill: parent Page { id: page title: "listview" ListView { anchors.fill: parent id: listView header: Rectangle { color: "red" width: parent.width height: root.listViewHeaderHeight } model: 500 delegate: Label { text: "number " +index } } } Item { // Wrapping the Page inside this Item should not // affect the header alignment, see bug #1261907. anchors.fill: parent id: wrappingItem Page { id: wrappedPage title: "listview" ListView { anchors.fill: parent id: wrappedListView header: Rectangle { color: "red" width: parent.width height: root.listViewHeaderHeight } model: 500 delegate: Label { text: "number " +index } } } } } TestCase { name: "HeaderAlignment" when: windowShown function test_ListViewHeaderAlignment_bug1202277() { compare(listView.contentY, -root.listViewHeaderHeight - mainViewHeader.__propagated.header.height, "ListView header is aligned with the MainView header"); } function test_WrappedListViewHeaderAlignment_bug1261907() { compare(wrappedListView.contentY, -root.listViewHeaderHeight - mainViewHeader.__propagated.header.height, "ListView header inside wrapped Page is aligned with the MainView header"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_expandablescolumn.qml0000644000015301777760000001232012321005637032760 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 Item { width: units.gu(40) height: units.gu(60) ExpandablesColumn { id: expandablesColumn anchors { left: parent.left; top: parent.top; right: parent.right } height: units.gu(60) clip: true Repeater { id: repeater model: 20 delegate: Expandable { id: expandable objectName: "expandable" + index expandedHeight: contentColumn.height onClicked: expanded = !expanded Column { id: contentColumn anchors { left: parent.left; right: parent.right; top: parent.top } Rectangle { anchors { left: parent.left; right: parent.right} id: collapsedRect color: index % 2 == 0 ? "khaki" : "blue" height: expandable.collapsedHeight } Rectangle { anchors { left: parent.left; right: parent.right } height: units.gu(40) color: "orange" } } } } } UbuntuTestCase { name: "ExpandablesColumn" when: windowShown function init() { waitForRendering(expandablesColumn); } function expandItem(item) { item.expanded = true; var targetHeight = Math.min(item.expandedHeight, expandablesColumn.height - item.collapsedHeight); tryCompare(item, "height", targetHeight); } function collapse() { var expandedItem = expandablesColumn.expandedItem; if (expandedItem != undefined) { expandedItem.expanded = false; tryCompare(expandedItem, "height", expandedItem.collapsedHeight); } } function test_expandedItem() { var item = findChild(expandablesColumn, "expandable1"); expandItem(item); // expandedItem needs to point to the expanded item compare(expandablesColumn.expandedItem, item); collapse(); // expandedItem must be unset after collapsing compare(expandablesColumn.expandedItem, undefined); } function test_noScrollingNeeded() { var item = findChild(expandablesColumn, "expandable1"); compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight); expandItem(item); compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight); } function test_scrollToTop() { expandablesColumn.height = units.gu(30); var item = findChild(expandablesColumn, "expandable1"); compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight); expandItem(item); compare(expandablesColumn.mapFromItem(item).y, 0); } function test_scrollIntoView() { var item = findChild(expandablesColumn, "expandable9"); expandItem(item); // The item must be scrolled upwards, leaving space for one other item at the bottom compare(expandablesColumn.mapFromItem(item).y, expandablesColumn.height - item.collapsedHeight - item.expandedHeight); } function test_collapseByClickingOutside() { // expand item 0 var item = findChild(expandablesColumn, "expandable0"); expandItem(item); // click on item 1 var item1 = findChild(expandablesColumn, "expandable1"); mouseClick(item1, item1.width / 2, item1.height / 2); // make sure item1 is collapsed tryCompare(item, "expanded", false); } function test_dimOthers() { var item = findChild(expandablesColumn, "expandable1"); expandItem(item); for (var i = 0; i < repeater.count; ++i) { var isCurrent = (repeater.itemAt(i) === expandablesColumn.expandedItem) compare(repeater.itemAt(i).opacity, isCurrent ? 1 : .5) } } function cleanup() { // Restore listview height expandablesColumn.height = units.gu(60); collapse(); // scroll the column back to top expandablesColumn.flick(0, units.gu(500)); tryCompare(expandablesColumn, "flicking", false); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_components.pro0000644000015301777760000000030112321005637031444 0ustar pbusernogroup00000000000000TESTS += $$system(ls tst_*.qml) include(../qmltest-include.pri) TARGET = tst_components SOURCES += tst_components.cpp tabsmodel.cpp HEADERS += tabsmodel.h OTHER_FILES += $$system(ls *.qml) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_listitems_standard.qml0000644000015301777760000001123612321005637033156 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Item { width: 400 height: 400 Rectangle { id: testItem } AbstractButton { id: testControl visible: false } ListItem.Standard { id: listItemStandard anchors.fill: parent } TestCase { name: "ListItemsStandardAPI" when: windowShown function test_fallbackIconSource() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076762") compare(listItemStandard.fallbackIconSource,undefined,"fallbackIconSource is not set by default") } function test_control() { listItemStandard.control = testControl compare(listItemStandard.control,testControl,"set/get") listItemStandard.control = null compare(listItemStandard.control, null, "unset") } function test_clicked() { compare(listItemClickedSpy.valid, true, "clicked signal exists") compare(controlClickedSpy.valid, true, "control has clicked signal") var listItemClickedCount = listItemClickedSpy.count var controlClickedCount = controlClickedSpy.count mouseMove(listItemStandard, 10, 10) mouseClick(listItemStandard, 10, 10, Qt.LeftButton) listItemClickedCount++; compare(listItemClickedSpy.count, listItemClickedCount, "List item clicked triggered") listItemStandard.control = testControl; mouseMove(listItemStandard, 10, 10) mouseClick(listItemStandard, 10, 10, Qt.LeftButton) compare(listItemStandard.control, testControl, "control can be set") controlClickedCount++; compare(controlClickedSpy.count, controlClickedCount, "Control clicked triggered") compare(listItemClickedSpy.count, listItemClickedCount, "List item clicked not triggered when there is a control") listItemStandard.control = null; } function test_bug1166982_disabled_control_clicked() { var listItemClickedCount = listItemClickedSpy.count var controlClickedCount = controlClickedSpy.count listItemStandard.control = testControl testControl.enabled = false mouseMove(listItemStandard, 10, 10) mouseClick(listItemStandard, 10, 10, Qt.LeftButton) compare(listItemClickedSpy.count, listItemClickedCount, "List item clicked not triggered with disabled control") compare(controlClickedSpy.count, controlClickedCount, "Control clicked not triggered with disabled control") testControl.enabled = true listItemStandard.control = null } function test_icon() { compare(listItemStandard.icon,undefined,"icon is not set by default") // test with item listItemStandard.icon = testItem compare(listItemStandard.icon,testItem,"set/get from Item") // test with url var newIcon = "../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png" listItemStandard.icon = newIcon compare(listItemStandard.icon,newIcon,"set/get from url") } function test_iconFrame() { compare(listItemStandard.iconFrame,true,"iconFrame is true by default") } function test_progression() { compare(listItemStandard.progression,false,"progression is false by default") } function test_text() { compare(listItemStandard.text,"","text is '' by default") var newText = "Hello World!" listItemStandard.text = newText compare(listItemStandard.text,newText,"set/get") } SignalSpy { id: listItemClickedSpy target: listItemStandard signalName: "clicked" } SignalSpy { id: controlClickedSpy target: testControl signalName: "clicked" } } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_textarea_in_flickable.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_textarea_in_flickable.qm0000644000015301777760000000506112321005637033403 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: root width: 200; height: 200 property bool hasOSK: QuickUtils.inputMethodProvider !== "" Flickable { id: flickable anchors.fill: parent contentWidth: inFlickable.width contentHeight: inFlickable.height clip: true TextArea { id: inFlickable width: flickable.width autoSize: true maximumLineCount: 0 text: "1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1" } } SignalSpy { id: flickableSpy target: flickable signalName: "movingChanged" } TestCase { name: "TextAreaInFlickableAPI" when: windowShown // simulates a flick event between \b from and \b to points both relative to the item // with a given speed function flick(item, from, to, speed) { var pointCount = 5; if (from === undefined) qtest_fail("source point not defined", 2); if (to === undefined) qtest_fail("destination point not defined", 2); if (speed === undefined) speed = -1; else speed /= pointCount; var dx = to.x - from.x; var dy = to.y - from.y; mousePress(item, from.x, from.y); for (var i = 0; i < pointCount; i++) { mouseMove(item, from.x + (i + 1) * dx / pointCount, from.y + (i + 1) * dy / pointCount, speed); } mouseRelease(item, to.x, to.y); // empty event queues wait(500); } function test_DoNotStealFlickEvents() { mouseClick(inFlickable, 10, 10); flick(inFlickable, Qt.point(50, 20), Qt.point(50, 0), 100); tryCompare(flickableSpy, "count", 2, 200); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_pickerpanel.qml0000644000015301777760000002557012321005637031564 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Test 0.1 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Item { id: testSuite width: units.gu(40) height: units.gu(71) Flow { anchors { fill: parent // give a margin so we can dismiss panels topMargin: units.gu(4) } Button { id: defaultMode text: "defaultMode" property date buttonDate: new Date() property Item panel onClicked: panel = PickerPanel.openDatePicker(defaultMode, "buttonDate") } Button { id: modeSet text: "modeSet" property string mode property date buttonDate: new Date() property Item panel onClicked: panel = PickerPanel.openDatePicker(modeSet, "buttonDate", mode) } } SignalSpy { id: closeSpy signalName: "closed" } UbuntuTestCase { name: "PickerPanelAPI" when: windowShown function initTestCase() { waitForRendering(testSuite); } function test_0_clickOndefaultMode() { mouseClick(defaultMode, units.gu(1), units.gu(1)); verify(defaultMode.panel !== null, "the picker is not opened"); verify(defaultMode.panel.picker !== null, "the DatePicker is not defined"); compare(defaultMode.panel.pickerMode, "Years|Months|Days", "the mode from the picker is not the default"); compare(defaultMode.panel.date, defaultMode.buttonDate, "the date from the picker differs from the button's"); compare(defaultMode.panel.caller, defaultMode, "wrong caller"); compare(defaultMode.panel.callerProperty, "buttonDate", "wrong callerProperty"); verify(defaultMode.panel.hasOwnProperty("closed"), "the object has no closed signal"); // dismiss closeSpy.clear(); closeSpy.target = defaultMode.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_1_modeSet_YM() { modeSet.mode = "Years|Months" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); compare(picker.children.length, 3, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_1_modeSet_YD() { modeSet.mode = "Years|Days" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); expectFailContinue("", "this mode is invalid"); compare(picker.children.length, 2, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_1_modeSet_HMS() { modeSet.mode = "Hours|Minutes|Seconds" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); compare(picker.children.length, 4, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_1_modeSet_HS() { modeSet.mode = "Hours|Seconds" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); expectFailContinue("", "this mode is invalid"); compare(picker.children.length, 2, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } // forced panel tests // these should be executed as last ones function test_2_clickOndefaultMode() { // force panel - this is private specific!!! var privates = findChild(PickerPanel, "PickerPanel_Internals"); privates.isPhone = true; mouseClick(defaultMode, units.gu(1), units.gu(1)); verify(defaultMode.panel !== null, "the picker is not opened"); verify(defaultMode.panel.picker !== null, "the DatePicker is not defined"); compare(defaultMode.panel.pickerMode, "Years|Months|Days", "the mode from the picker is not the default"); compare(defaultMode.panel.date, defaultMode.buttonDate, "the date from the picker differs from the button's"); compare(defaultMode.panel.caller, defaultMode, "wrong caller"); compare(defaultMode.panel.callerProperty, "buttonDate", "wrong callerProperty"); verify(defaultMode.panel.hasOwnProperty("closed"), "the object has no closed signal"); // dismiss closeSpy.clear(); closeSpy.target = defaultMode.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_3_modeSet_YM() { modeSet.mode = "Years|Months" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); compare(picker.children.length, 3, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_3_modeSet_YD() { modeSet.mode = "Years|Days" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); expectFailContinue("", "this mode is invalid"); compare(picker.children.length, 2, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_3_modeSet_HMS() { modeSet.mode = "Hours|Minutes|Seconds" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); compare(picker.children.length, 4, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } function test_3_modeSet_HS() { modeSet.mode = "Hours|Seconds" ; mouseClick(modeSet, units.gu(1), units.gu(1)); verify(modeSet.panel !== null, "the picker is opened"); compare(modeSet.panel.date, modeSet.buttonDate, "the date from the picker differs from the button's"); compare(modeSet.panel.pickerMode, modeSet.mode, "the mode from the picker differs from the button's"); // check the number of pickers var picker = findChild(modeSet.panel.picker, "PickerRow_Positioner"); expectFailContinue("", "this mode is invalid"); compare(picker.children.length, 2, "there is not enough pickers in the panel"); // dismiss closeSpy.clear(); closeSpy.target = modeSet.panel; mouseClick(testSuite, units.gu(1), units.gu(1)); closeSpy.wait(); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_tabs.qml0000644000015301777760000004013312321005637030210 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 Item { id: testCase width: units.gu(50) height: units.gu(80) Tabs { id: emptyTabs } MainView { id: mainView anchors.fill: parent Tabs { id: tabs Tab { id: tab1 title: "tab 1" page: Page { id: page1 Button { id: button anchors.centerIn: parent text: "click" } } } Tab { id: tab2 title: "tab 2" page: Page { id: page2 } } Tab { id: tab3 title: "tab 3" page: Page { id: page3 } } Tab { id: tabFlick1 title: "flick" page: Page { Flickable { id: flickable1 anchors.fill: parent } } } Tab { id: tabFlick2 title: "flick 2" page: Page { Flickable { id: flickable2 anchors.fill: parent } } } Tab { id: tabFlickLoader title: "load" page: Loader { id: loader sourceComponent: tabs.selectedTabIndex != 5 ? null : pageComponent } } Tab { id: tabNoFlickLoader title: "loadNoFlick" page: Loader { id: loaderNoFlick anchors { left: parent.left right: parent.right bottom: parent.bottom } // height compes from the loaded Page sourceComponent: tabs.selectedTabIndex === 6 ? pageComponentNoFlick : null } } } Component { id: pageComponent Page { title: "Loaded page" property Flickable flick: loadedFlickable Flickable { id: loadedFlickable anchors.fill: parent contentHeight: 1000 } } } Component { id: pageComponentNoFlick Page { title: "Loaded page without flickable" } } } ListModel { id: inputModel Component.onCompleted: { append({ "name": "tab 1" }); insert(0, { "name": "tab 0" }); append({ "name": "tab 3" }); insert(2, { "name": "tab 2" }); } } Tabs { id: tabsWithRepeater Repeater { objectName: "tabsRepeater" id: tabsRepeater model: inputModel Tab { title: name } } } Tabs { id: repeaterTabs Repeater { objectName: "repeater" id: repeater Tab { title: modelData } } } Tabs { id: twoRepeaters Repeater { objectName: "firstRepeater" id: firstRepeater model: inputModel Tab { title: name } } Repeater { objectName: "secondRepeater" id: secondRepeater model: testCase.listModel Tab { title: modelData } } } property var listModel: ["tab #0", "tab #1", "tab #2", "tab #3"]; Tabs { id: twinRepeaters ListModel { id: twinModel Component.onCompleted: { append({ "name": "twintab 1" }); insert(0, { "name": "twintab 0" }); append({ "name": "twintab 3" }); insert(2, { "name": "twintab 2" }); } } Repeater { objectName: "tabsRepeater" id: twinRepeater1 model: twinModel Tab { title: name } } Repeater { objectName: "tabsRepeater" id: twinRepeater2 model: twinModel Tab { title: name } } } TestCase { name: "TabsAPI" when: windowShown /* The following testcases are all related to bug #1253804 */ function test_tabOrder_bug1253804() { var tabsModel = tabsWithRepeater.tabBar.model; compare(tabsRepeater.count, inputModel.count, "Incorrect number of tabs in Tabs"); compare(tabsModel.count, tabsRepeater.count, "Incorrect number of tabs in TabBar"); for (var i=0; i < tabsModel.count; i++) { compare(tabsModel.get(i).title, inputModel.get(i).name, "Tab titles don't match for index "+i); } //shufle inputModel.move(1, 2, 1); inputModel.move(3, 0, 1); inputModel.move(1, 3, 1); // wait few miliseconds wait(50); for (i=0; i < tabsModel.count; i++) { compare(tabsModel.get(i).title, inputModel.get(i).name, "Tab titles after shuffling don't match for index "+i); } // set it to null tabsRepeater.model = null; compare(tabsWithRepeater.tabBar.model.count, 0, "There are still tabs left after repeater model is reset"); } function test_repeaterTabs() { repeater.model = inputModel; var tabsModel = repeaterTabs.tabBar.model; compare(repeater.count, inputModel.count, "Incorrect number of tabs in Tabs"); compare(tabsModel.count, repeater.count, "Incorrect number of tabs in TabBar"); for (var i=0; i < tabsModel.count; i++) { compare(tabsModel.get(i).title, inputModel.get(i).name, "Tab titles don't match for index "+i); } // clear repeaterTabs repeater.model = null; compare(repeaterTabs.tabBar.model.count, 0, "There are still tabs left after repeater model is reset"); } function test_repeaterTabs_arrayAsModel() { repeater.model = testCase.listModel; var tabsModel = repeaterTabs.tabBar.model; compare(repeater.count, testCase.listModel.length, "Incorrect number of tabs in Tabs"); compare(tabsModel.count, repeater.count, "Incorrect number of tabs in TabBar"); for (var i=0; i < tabsModel.count; i++) { compare(tabsModel.get(i).title, testCase.listModel[i], "Tab titles don't match for index "+i); } // shuffling elements in an array is not detectable in Repeater var x = testCase.listModel[1]; testCase.listModel[1] = testCase.listModel[0]; testCase.listModel[0] = x; expectFailContinue("", "Array changes are not detected by repeaters"); compare(tabsModel.get(0).title, testCase.listModel[0], "Tab titles don't match for index 0"); expectFailContinue("", "Array changes are not detected by repeaters"); compare(tabsModel.get(1).title, testCase.listModel[1], "Tab titles don't match for index 0"); // clear repeaterTabs repeater.model = null; compare(repeaterTabs.tabBar.model.count, 0, "There are still tabs left after repeater model is reset"); } function test_twoRepeaters() { var tabsModel = twoRepeaters.tabBar.model; var secondRepeaterModel = secondRepeater.model; compare(tabsModel.count, firstRepeater.count + secondRepeater.count, "Incorrect number of tabs in TabBar"); for (var i = 0; i < firstRepeater.count; i++) { compare(tabsModel.get(i).title, inputModel.get(i).name, "Tab titles don't match for index "+i); } for (i = firstRepeater.count; i < firstRepeater.count + secondRepeater.count; i++) { compare(tabsModel.get(i).title, secondRepeaterModel[i - firstRepeater.count], "Tab titles don't match for index "+i); } } function test_twinRepeaters() { var tabsModel = twinRepeaters.tabBar.model; compare(twinRepeater1.count, twinModel.count, "Incorrect number of tabs in the first repeater"); compare(twinRepeater2.count, twinModel.count, "Incorrect number of tabs in the second repeater"); compare(tabsModel.count, twinRepeater1.count + twinRepeater2.count, "Incorrect number of tabs in TabBar"); for (var j = 0; j < 2; j++) { for (var i = 0; i < twinModel.count; i++) { var index = j * twinModel.count + i; compare(tabsModel.get(index).title, twinModel.get(i).name, "Tab titles don't match for Tabs index " + index); } } //shuffle twinModel.move(1, 2, 1); twinModel.move(3, 0, 1); twinModel.move(1, 3, 1); // wait few miliseconds till Tabs update is realized wait(50); /* FIXME for (var j = 0; j < 2; j++) { for (var i = 0; i < twinModel.count; i++) { var index = j * twinModel.count + i; compare(tabsModel.get(index).title, twinModel.get(i).name, "Tab titles don't match for Tabs index " + index); } } */ // set it to null twinRepeater1.model = null; twinRepeater2.model = null; compare(twinRepeaters.tabBar.model.count, 0, "There are still tabs left after repeater model is reset"); } function test_emptyTabs() { compare(emptyTabs.selectedTabIndex, -1, "The default value for selectedTabIndex is -1 when there are no tabs"); compare(emptyTabs.selectedTab, null, "The default selected tab is null when there are no tabs"); compare(emptyTabs.currentPage, null, "The default currentPage is null when there are no tabs"); } /* FIXME function test_tabsDefaults() { compare(tabs.selectedTabIndex, 0, "The default selectedTabIndex is 0 when Tabs has contents"); compare(tabs.selectedTab, tab1, "The default selectedTab is the first tab"); compare(tabs.currentPage, page1, "The default currentPage is the page of the first tab"); compare(mainView.__propagated.toolbar.tools, page1.tools, "The default tools are the tools of the first tab"); compare(mainView.__propagated.header.contents, tabs.tabBar, "Tabs updates the Header contents"); } */ function test_tabsSetSelectedTab() { var tabArray = [tab1, tab2, tab3]; var pageArray = [page1, page2, page3]; for (var i=0; i < 3; i++) { tabs.selectedTabIndex = i; compare(tabs.selectedTabIndex, i, "Can set selectedTabIndex"); compare(tabs.selectedTab, tabArray[i], "Can update selectedTab by setting selectedTabIndex"); compare(tabs.currentPage, pageArray[i], "Can update currentPage by setting selectedTabIndex"); compare(mainView.__propagated.toolbar.tools, pageArray[i].tools, "Activating a Tab updates the tools of the Toolbar"); for (var j=0; j < 3; j++) { compare(pageArray[j].active, j===i, "Only the page of the selected tab is active"); } } } function test_flickable() { // ensure that the flickable of the header is set to the flickable of the selected tab. tabs.selectedTabIndex = 3; compare(mainView.__propagated.header.flickable, flickable1, "Header flickable correctly initialized"); tabs.selectedTabIndex = 4; compare(mainView.__propagated.header.flickable, flickable2, "Header flickable correctly updated"); tabs.selectedTabIndex = 0; } function test_pageLoader() { tabs.selectedTabIndex = 0; compare(loader.item, null, "Page not loaded when tab is not selected"); tabs.selectedTabIndex = 5; compare(tabs.currentPage, loader, "Selected loader for current page"); compare(loader.item.title, "Loaded page", "Loaded item is a page"); tabs.selectedTabIndex = 0; compare(loader.item, null, "Loaded page was properly unloaded"); } function test_bug1088740() { tabs.selectedTabIndex = 5; compare(mainView.__propagated.header.flickable, loader.item.flick, "Header flickable correctly updated with Loader"); compare(loader.item.flick.contentHeight, 1000, "Header flickable is correct flickable"); tabs.selectedTabIndex = 0; } function test_pageHeightLoaderNoFlick_bug1259917() { tabs.selectedTabIndex = 6; compare(tabs.selectedTab, tabNoFlickLoader, "Tab 6 was selected."); compare(mainView.__propagated.header.flickable, null, "Loaded page without flickable."); compare(loaderNoFlick.item.height, mainView.height - mainView.__propagated.header.height, "Correct height for loaded Page without flickable."); } function test_index() { compare(tab1.index, 0, "tab1 is at 0"); compare(tab2.index, 1, "tab2 is at 1"); compare(tab3.index, 2, "tab3 is at 2"); compare(tabFlick1.index, 3, "tabFlick1 is at 3"); compare(tabFlick2.index, 4, "tabFlick2 is at 4"); compare(tabFlickLoader.index, 5, "tabFlickLoader is at 5"); compare(tabNoFlickLoader.index, 6, "tabNoFlickLoader is at 6"); } function test_deactivateByTimeout() { tabs.tabBar.selectionMode = true; compare(tabs.tabBar.selectionMode, true, "Tab bar can be put into selection mode"); compare(tabs.tabBar.__styleInstance.deactivateTime > 0, true, "There is a positive deactivate time"); wait(tabs.tabBar.__styleInstance.deactivateTime + 500); // add 500 ms margin /* FIXME compare(tabs.tabBar.selectionMode, false, "Tab bar automatically leaves selection mode after a timeout."); */ } function test_deactivateByAppInteraction() { tabs.tabBar.selectionMode = true; compare(tabs.tabBar.selectionMode, true, "Tab bar can be put into selection mode"); mouseClick(button, units.gu(1), units.gu(1), Qt.LeftButton); compare(tabs.tabBar.selectionMode, false, "Tab bar deactivated by interacting with the page contents"); } function test_tabBar_pressed() { compare(tabs.tabBar.pressed, false, "Before user interaction, pressed is false"); mousePress(tabs.tabBar, tabs.tabBar.width/2, tabs.tabBar.height/2); compare(tabs.tabBar.pressed, true, "Pressing the tab bar makes pressed true"); mouseRelease(tabs.tabBar, tabs.tabBar.width/2, tabs.tabBar.height/2); compare(tabs.tabBar.pressed, false, "After releasing, pressed is false"); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/unit_x11/tst_components/tst_textfield.qml0000644000015301777760000004320612321005637031253 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 import Ubuntu.Unity.Action 1.1 as UnityActions Item { id: textItem width: 200; height: 200 property bool hasOSK: QuickUtils.inputMethodProvider !== "" function reset() { colorTest.focus = false; textField.focus = false; t1.focus = false; t2.focus = false; } TextField { id: colorTest color: colorTest.text.length < 4 ? "#0000ff" : "#00ff00" } TextField { id: textField SignalSpy { id: signalSpy target: parent } property int keyPressData property int keyReleaseData Keys.onPressed: keyPressData = event.key Keys.onReleased: keyReleaseData = event.key action: Action { enabled: true name: 'spam' text: 'Spam' } } Item { TextField { id: t1 } TextField { id: t2 } } TextField { id: enabledTextField enabled: true } TextField { id: disabledTextField enabled: false } TestCase { name: "TextFieldAPI" when: windowShown function initTestCase() { textField.forceActiveFocus(); compare(textField.focus, true, "TextField is focused"); // clear clipboard Clipboard.clear(); } function test_0_popover() { compare(textField.popover, undefined, "No poppover defined by default."); } function test_0_highlighted() { compare(textField.highlighted, textField.focus, "highlighted is the same as focused"); } function test_0_acceptableInput() { compare(textField.acceptableInput,true,"acceptableInput true by default") } function test_0_activeFocusOnPress() { compare(textField.activeFocusOnPress, true,"activeFocusOnPress true by default") } function test_0_autoScroll() { compare(textField.autoScroll, true,"autoScroll true by default") } function test_0_canPaste() { compare(textField.canPaste, false,"calPaste false when clipboard is empty") } function test_0_canRedo() { compare(textField.canRedo, false,"calRedo false when no data was entered") } function test_0_canUndo() { compare(textField.canUndo, false,"calUndo false when no data entered") } function test_0_contentWidth() { compare(textField.contentWidth, 0,"contentWidth by default") } function test_0_contentHeight() { // line size is the font pixel size + 3 dp var lineSize = textField.font.pixelSize + units.dp(3) compare(textField.contentHeight, lineSize,"contentHeight by default") } function test_0_cursorDelegate() { verify(textField.cursorDelegate, "cursorDelegate set by default") } function test_0_cursorPosition() { compare(textField.cursorPosition, 0, "cursorPosition 0 by default") } function test_0_cursorRectangle() { compare(textField.cursorRectangle, Qt.rect(0, 0, 0, 0), "cursorRectangle 0 by default") } function test_0_cursorVisible() { compare(textField.cursorVisible, true, "cursorVisible true by default") } function test_0_customSoftwareInputPanel() { compare(textField.customSoftwareInputPanel,null,"customSoftwareInputPanel is null by default") } function test_0_displayText() { compare(textField.displayText, "", "displayText empty by default") } function test_0_echoMode() { compare(textField.echoMode, TextInput.Normal,"echoMode is TextInput.Normal by default") } function test_0_errorHighlight() { compare(textField.errorHighlight, false,"errorHighlight is false by default") textField.errorHighlight = true compare(textField.errorHighlight,true,"set/get") } function test_0_font() { verify((textField.font),"font is set") } function test_0_alignments() { compare(textField.horizontalAlignment, TextInput.AlignLeft, "horizontalAlignmen is Left by default") compare(textField.effectiveHorizontalAlignment, TextInput.AlignLeft, "effectiveHorizontalAlignmen is Left by default") compare(textField.verticalAlignment, TextInput.AlignTop, "verticalAlignmen is Top by default") } function test_hasClearButton() { compare(textField.hasClearButton, true, "hasClearButton is false by default") textField.hasClearButton = false compare(textField.hasClearButton, false, "set/get") } function test_0_inputMask() { compare(textField.inputMask, "", "inputMask is undefined by default") } function test_0_inputMethodComposing() { compare(textField.inputMethodComposing, false, "inputMethodComposing is false by default") } function test_0_inputMethodHints() { compare(textField.inputMethodHints, Qt.ImhNone, "inputMethodHints is Qt.ImhNone by default") } function test_0_length() { compare(textField.length, 0, "length is 0 by default") } function test_0_maximumLength() { compare(textField.maximumLength, 32767, "maximumLength is 32767 by default") } function test_0_mouseSelectionMode() { compare(textField.mouseSelectionMode, TextInput.SelectCharacters, "mouseSelectionMode default") } function test_0_passwordCharacter() { compare(textField.passwordCharacter, "\u2022", "passwordCharacter default") } function test_0_persistentSelection() { compare(textField.persistentSelection, false, "persistentSelection default") } function test_0_renderType() { compare(textField.renderType, Text.QtRendering, "renderType default") } function test_0_selectByMouse() { compare(textField.selectByMouse, true, "selectByMouse default") } function test_0_placeholderText() { compare(textField.placeholderText, "", "placeholderText is '' by default") } function test_0_primaryItem() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076768") compare(textField.primaryItem, undefined, "primaryItem is undefined by default") } function test_0_readOnly() { compare(textField.readOnly, false, "readOnly is false by default") textField.readOnly = true compare(textField.readOnly, true, "set/get") } function test_0_secondaryItem() { expectFail("","https://bugs.launchpad.net/tavastia/+bug/1076768") compare(textField.secondaryItem, undefined, "secondaryItem is undefined by default") } function test_0_selectedText() { compare(textField.selectedText, "", "selectedText is '' by default") } function test_0_selectionEnd() { compare(textField.selectionEnd, 0, "selectionEnd is 0 by default") } function test_0_selectionStart() { compare(textField.selectionStart, 0, "selectionStart is 0 by default") } function test_0_text() { compare(textField.text, "", "text is '' by default") var newText = "Hello World!" textField.text = newText compare(textField.text, newText, "set/get") } function test_0_validator() { compare(textField.validator, null, "validator is null by default") textField.validator = regExpValidator compare(textField.validator, regExpValidator, "set/get") } function test_validator_and_acceptableInput_with_invalid_value() { textField.validator = null compare(textField.acceptableInput,true,"acceptableInput should be true") textField.validator = regExpValidator textField.text = "012345" compare(textField.acceptableInput,false,"with validator failure the acceptableInput should be false") } function test_0_accepted() { signalSpy.signalName = "accepted"; compare(signalSpy.valid,true,"accepted signal exists") } function test_0_visible() { textField.visible = false; compare(textField.visible, false, "TextField is inactive"); } function test_keyPressAndReleaseFilter() { textField.visible = true; textField.forceActiveFocus(); textField.readOnly = false; textField.keyPressData = 0; textField.keyReleaseData = 0; keyClick(Qt.Key_Control, Qt.NoModifier, 200); compare(textField.keyPressData, Qt.Key_Control, "Key press filtered"); compare(textField.keyReleaseData, Qt.Key_Control, "Key release filtered"); } function test_1_undo_redo() { textField.readOnly = false; textField.text = ""; textField.focus = true; keyClick(Qt.Key_T); keyClick(Qt.Key_E); keyClick(Qt.Key_S); keyClick(Qt.Key_T); compare(textField.text, "test", "new text"); if (!textField.canUndo) expectFail("", "undo is not allowed in this input"); textField.undo(); compare(textField.text, "", "undone"); textField.redo(); compare(textField.text, "test", "redone"); } function test_1_getText() { textField.text = "this is a longer text"; compare(textField.getText(0, 10), "this is a ", "getText(0, 10)"); compare(textField.getText(10, 0), "this is a ", "getText(10, 0)"); compare(textField.getText(0), "", "getText(0)"); compare(textField.getText(4, 0), "this", "getText(4, 0)"); } function test_1_removeText() { textField.text = "this is a longer text"; textField.remove(0, 10); compare(textField.text, "longer text", "remove(0, 10)"); textField.text = "this is a longer text"; textField.remove(10, 0); compare(textField.text, "longer text", "remove(0, 10)"); textField.text = "this is a longer text"; textField.remove(0); compare(textField.text, "this is a longer text", "remove(0)"); textField.text = "this is a longer text"; textField.remove(4, 0); compare(textField.text, " is a longer text", "remove(4, 0)"); textField.text = "this is a longer text"; textField.select(0, 4); textField.remove(); compare(textField.text, "this is a longer text", "select(0, 4) && remove()"); } function test_1_moveCursorSelection() { textField.text = "this is a longer text"; textField.cursorPosition = 5; textField.moveCursorSelection(9, TextInput.SelectCharacters); compare(textField.selectedText, "is a", "moveCursorSelection from 5 to 9, selecting the text"); } function test_1_isRightToLeft() { textField.text = "this is a longer text"; compare(textField.isRightToLeft(0), false, "isRightToLeft(0)"); compare(textField.isRightToLeft(0, 0), false, "isRightToLeft(0, 0)"); compare(textField.isRightToLeft(5, 10), false, "isRightToLeft(5, 10)"); } function test_cut() { Clipboard.clear(); textField.readOnly = false; textField.text = "test text"; textField.cursorPosition = textField.text.indexOf("text"); textField.selectWord(); textField.cut(); compare(textField.text, "test ", "Text cut properly"); compare(Clipboard.data.text, "text", "Clipboard has the text cut"); // we should have the "text" only ones var plainTextCount = 0; for (var i in Clipboard.data.formats) { if (Clipboard.data.formats[i] === "text/plain") plainTextCount++; } compare(plainTextCount, 1, "Clipboard is correct"); } function test_paste() { textField.readOnly = false; textField.text = "test"; textField.cursorPosition = textField.text.length; textField.paste(" text"); compare(textField.text, "test text", "Data pasted"); } function test_colorCollisionOnDelegate() { // fixes bug lp:1169601 colorTest.text = "abc"; compare(colorTest.color, "#0000ff", "Color when text length < 4"); colorTest.text = "abcd"; compare(colorTest.color, "#00ff00", "Color when text length >= 4"); } function test_OneActiveFocus() { t1.focus = true; compare(t1.activeFocus, true, "T1 has activeFocus"); compare(t2.activeFocus, false, "T1 has activeFocus"); t2.focus = true; compare(t1.activeFocus, false, "T1 has activeFocus"); compare(t2.activeFocus, true, "T1 has activeFocus"); } // need to make the very first test case, otherwise OSK detection fails on phablet function test_zz_OSK_ShownWhenNextTextFieldIsFocused() { if (!hasOSK) expectFail("", "OSK can be tested only when present"); t1.focus = true; compare(Qt.inputMethod.visible, true, "OSK is shown for the first TextField"); t2.focus = true; compare(Qt.inputMethod.visible, true, "OSK is shown for the second TextField"); } function test_zz_RemoveOSKWhenFocusLost() { if (!hasOSK) expectFail("", "OSK can be tested only when present"); t1.focus = true; compare(Qt.inputMethod.visible, true, "OSK is shown when TextField gains focus"); t1.focus = false; compare(Qt.inputMethod.visible, false, "OSK is hidden when TextField looses focus"); } function test_zz_ReEnabledInput() { textField.forceActiveFocus(); textField.enabled = false; compare(textField.enabled, false, "textField is disabled"); compare(textField.focus, true, "textField is focused"); compare(textField.activeFocus, false, "textField is not active focus"); compare(Qt.inputMethod.visible, false, "OSK removed"); textField.enabled = true; compare(textField.enabled, true, "textField is enabled"); compare(textField.focus, true, "textField is focused"); compare(textField.activeFocus, true, "textField is active focus"); if (!hasOSK) expectFail("", "OSK can be tested only when present"); compare(Qt.inputMethod.visible, true, "OSK shown"); } function test_zz_Trigger() { signalSpy.signalName = 'accepted' textField.enabled = true textField.text = 'eggs' textField.accepted() signalSpy.wait() } function test_zz_ActionInputMethodHints() { // Preset digit only for numbers textField.inputMethodHints = Qt.ImhNone textField.action.parameterType = UnityActions.Action.Integer compare(textField.inputMethodHints, Qt.ImhDigitsOnly) textField.inputMethodHints = Qt.ImhNone textField.action.parameterType = UnityActions.Action.Real compare(textField.inputMethodHints, Qt.ImhDigitsOnly) // No preset for strings textField.inputMethodHints = Qt.ImhNone textField.action.parameterType = UnityActions.Action.String compare(textField.inputMethodHints, Qt.ImhNone) // Never interfere with a manual setting textField.inputMethodHints = Qt.ImhDate textField.action.parameterType = UnityActions.Action.Integer compare(textField.inputMethodHints, Qt.ImhDate) } RegExpValidator { id: regExpValidator regExp: /[a-z]*/ } function test_click_enabled_textfield_must_give_focus() { textField.forceActiveFocus(); compare( enabledTextField.focus, false, 'enabledTextField is not focused'); mouseClick( enabledTextField, enabledTextField.width/2, enabledTextField.height/2) compare( enabledTextField.focus, true, 'enabledTextField is focused') } function test_click_disabled_textfield_must_not_give_focus() { mouseClick( disabledTextField, disabledTextField.width/2, disabledTextField.height/2) compare( textField.focus, false, 'disabledTextField is not focused'); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/qmlapicheck.py0000755000015301777760000001617512321005637023772 0ustar pbusernogroup00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Copyright 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # Author: Christian Dywan import sys import fileinput import os if len(sys.argv) < 2 or '-h' in sys.argv or '--help' in sys.argv: basename = os.path.basename(sys.argv[0]) print ( 'Usage:\n env BUILTINS=foo,bar %s FILENAME [FILENAME2..N]\n\n' ' Generate a QML API file\n' 'Example:\n' ' env BUILTINS=QQuick,QQml,U1db:: ' '%s modules/Ubuntu/Components/qmldir plugins.qmltypes' ' > components.api.new\n' '\n' ' It is recommended to pass qmldir files over a list of qml files\n' ' because then internal components are discarded and errors in that\n' ' list can be found.\n' ' For testing one can pass qml files also directly or serve them\n' ' via standard input.\n' ' The variable BUILTINS is a comma-separated list of prefixes for\n' ' API that appears in qmltypes files but not part of the same\n' ' package.\n' '\n' 'Use the following command to see changes in the API:\n' ' diff -Fqml -u components.api{,.new}\n' % (basename, basename)) sys.exit(1) builtins = os.getenv('BUILTINS', '').split(',') inputfiles = [] for line in fileinput.input(): if fileinput.filename()[-6:] == 'qmldir': if line[:8] == 'internal': # Internal components are not part of public API continue pieces = line.strip().split(' ') if len(pieces) > 2: filename = pieces[2] # We only work with QML if filename[-3:] == 'qml': # Filenames are relative to the qmldir # Foo 1.0 Foo.qml folder = os.path.dirname(fileinput.filename()) inputfiles.append(folder + '/' + filename) else: inputfiles.append(fileinput.filename()) fileinput.nextfile() inputfiles.sort() hook = fileinput.hook_encoded('utf-8') for line in fileinput.input(inputfiles, openhook=hook): # New file if fileinput.isfirstline(): in_block = 0 in_comment = in_builtin_type = False block_meta = {} annotated_properties = {} if fileinput.filename()[-3:] == 'qml': filetype = 'qml' keywords = ['signal', 'property', 'function'] elif fileinput.filename()[-8:] == 'qmltypes': filetype = 'qmltypes' keywords = ['Signal', 'Property', 'Method', 'prototype', 'exports'] else: print('Unknown filetype %s' % fileinput.filename()) sys.exit(1) print('%s' % fileinput.filename()) line = line.split('//')[0] # alias properties only define their type through qdoc comments if '\\qmlproperty' in line: words = line.strip().split(' ') name = words[2] # Strip namespace if '::' in name: name = name.split('::')[1] type = words[1] annotated_properties[name] = type elif '\\internal' in line: # internal without type always relates to the next declared property annotated_properties['internal'] = 'internal' if '/*' in line and not '*/' in line: in_comment = True continue if '*/' in line: in_comment = False line = line.split('*/')[1] if in_comment: continue if '{' in line and '}' in line: if filetype == 'qmltypes' and not in_builtin_type: print(' ' + line.strip()) continue # End of function/ signal/ Item block if '}' in line: in_block -= 1 block_meta = {} if in_block == 1 and in_builtin_type: in_builtin_type = False continue # Only root "Item {" is inspected for QML, otherwise all children if in_block == 1 or filetype == 'qmltypes': # Left hand side specifies a keyword, a type and a variable name declaration = line.split(':')[0] words = declaration.strip().split(' ') # Skip types with prefixes considered builtin if filetype == 'qmltypes' and words[0] == 'name': found_builtin_type = False for builtin in builtins: if '"' + builtin in line: found_builtin_type = True break if found_builtin_type: in_builtin_type = True continue if 'prototype' in block_meta: print(' ' + block_meta['prototype'].strip()) print(' ' + line.strip()) continue block_meta[words[0]] = line # Omit prototype if it comes before the name since we may skip it if not 'name' in block_meta and words[0] == 'prototype': continue # Don't consider the qml variable name as a keyword if filetype == 'qml': words.pop() if filetype == 'qmltypes' and in_block > 1: keywords.append('name') keywords.append('Parameter') for word in words: if word in keywords: if filetype == 'qml': signature = declaration.split('{')[0].strip() if 'alias' in line: no_mods = signature for mod in ['readonly', 'default']: no_mods = no_mods.replace(mod, '') name = no_mods.strip().split(' ')[2] if 'internal' in annotated_properties: if not name in annotated_properties: annotated_properties[name] = 'internal' del annotated_properties['internal'] if not name in annotated_properties: print(' %s' % (signature)) print('Error: Missing \\qmlproperty for %s' % name) sys.exit(1) real_type = annotated_properties[name] signature = signature.replace('alias', real_type) elif filetype == 'qmltypes': signature = line.strip() if not in_builtin_type: print(' %s' % (signature)) break # Start of function/ signal/ Item block if '{' in line: in_block += 1 block_meta = {} # The parent type can affect API if in_block == 1 and filetype == 'qml': print(line.split('{')[0].strip()) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/0000755000015301777760000000000012321006415023127 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/layouts/0000755000015301777760000000000012321006415024627 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/pickers/0000755000015301777760000000000012321006415024567 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/pickers/PickerTest.qml0000644000015301777760000001322412321005637027366 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 MainView { width: units.gu(40) height: units.gu(71) Column{ Row { ListModel { id: pickerModel Component.onCompleted: reset(100); function reset(num) { clear(); for (var i = 0; i < num; i++) { append({"label": "Item #"+i}); } } } Picker { objectName: "Circular" id: circularPicker height: units.gu(40) model: pickerModel delegate: PickerDelegate { property string text: modelData ? modelData : "" Label { anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: modelData ? modelData : "" } } onSelectedIndexChanged: print("circular index="+selectedIndex) onMovingChanged: print("MOVING?", moving) } Picker { objectName: "Linear" id: linearPicker height: units.gu(40) model: pickerModel circular: false delegate: PickerDelegate { property string text: modelData ? modelData : "" Label { anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: modelData ? modelData : "" } } onSelectedIndexChanged: print("linear index="+selectedIndex) onMovingChanged: print("MOVING?", moving) } Picker { height: units.gu(40) model: pickerModel live: true delegate: PickerDelegate { Label { anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: modelData } } onSelectedIndexChanged: print("circular index="+selectedIndex) onMovingChanged: print("MOVING?", moving) } Picker { height: units.gu(40) model: pickerModel circular: false live: true delegate: PickerDelegate { Label { anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: modelData } } onSelectedIndexChanged: print("linear index="+selectedIndex) onMovingChanged: print("MOVING?", moving) } } Flow { spacing: units.gu(1) width: parent.width Button { text: "move & crop from 50" onClicked: { linearPicker.selectedIndex = 50; circularPicker.selectedIndex = 50; pickerModel.remove(50, 50); print("circular: selectedIndex="+circularPicker.selectedIndex) print("linear: selectedIndex="+linearPicker.selectedIndex) } } Button { text: "crop from 50" onClicked: { pickerModel.remove(50, 50); print("circular: selectedIndex="+circularPicker.selectedIndex) print("linear: selectedIndex="+linearPicker.selectedIndex) } } Button { text: "reset" onClicked: { pickerModel.reset(100); print("circular: selectedIndex="+circularPicker.selectedIndex) print("linear: selectedIndex="+linearPicker.selectedIndex) } } Button { text: "move to 20" onClicked: { circularPicker.selectedIndex = 20; linearPicker.selectedIndex = 20; } } Button { text: "clear" onClicked: { pickerModel.clear(); print("circular: selectedIndex="+circularPicker.selectedIndex) print("linear: selectedIndex="+linearPicker.selectedIndex) } } Button { text: "append" onClicked: { pickerModel.append({"label": "Item #"+pickerModel.count}); } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/pickers/PanelTest.qml0000644000015301777760000000267312321005637027216 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 MainView { width: units.gu(40) height: units.gu(71) Column { Button { id: datePickerButton property date date: new Date() text: "Date picker: " + Qt.formatDate(date, "yyyy/MMMM/dd dddd") onClicked: { var picker = PickerPanel.openDatePicker(datePickerButton, "date", "Years|Months|Days") picker.picker.locale = Qt.locale("hu_HU") } } Button { id: timePickerButton property date date: new Date() text: "Time picker: " + Qt.formatTime(date, "hh:mm:ss") onClicked: PickerPanel.openDatePicker(timePickerButton, "date", "Hours|Minutes|Seconds") } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/pickers/DatePickerTest.qml0000644000015301777760000001416512321005637030171 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 MainView { width: units.gu(40) height: units.gu(71) Page { title: "DatePicker test" Column { anchors.fill: parent DatePicker { id: picker locale: Qt.locale("en_UK") date: new Date() onDateChanged: print("CHANGED DATE=" + Qt.formatDateTime(date, "yyyy/MM/dd, hh:mm:ss")) onMovingChanged: print("MOVING?", moving) } Slider { value: 0.0//units.gu(36) live: true height: units.gu(2) minimumValue: 0.0 maximumValue: parent.width onValueChanged: picker.width = value } Flow { width: parent.width spacing: units.gu(1) Button { text: "HU" width: units.gu(5) height: units.gu(2) onClicked: picker.locale = Qt.locale("hu_HU") } Button { text: "DE" width: units.gu(5) height: units.gu(2) onClicked: picker.locale = Qt.locale("de_DE") } Button { text: "EN(US)" width: units.gu(9) height: units.gu(2) onClicked: picker.locale = Qt.locale("en_US") } Button { text: "FI" width: units.gu(5) height: units.gu(2) onClicked: { picker.locale = Qt.locale("fi_FI") picker.width = units.gu(37); } } Button { text: "infinite" height: units.gu(2) onClicked: picker.maximum = picker.maximum.getInvalidDate() } Button { text: "Jan-Mar" height: units.gu(2) onClicked: { var date = new Date(); date.setMonth(0); picker.minimum = date; date.setMonth(2); picker.maximum = date; picker.date = new Date(date); } } Button { text: "Change minimum" height: units.gu(2) onClicked: { picker.minimum = new Date(2012, 11, 1); } } Button { text: "minimum & date" height: units.gu(2) onClicked: { picker.minimum = new Date(2013, 11, 1); picker.date = new Date(2014, 11, 5); } } Button { text: "today" height: units.gu(2) onClicked: picker.date = new Date() } Repeater { model: ["Years|Months|Days", "Years|Months", "Months|Days", "Years", "Months", "Days", "Hours|Minutes|Seconds", "Hours|Minutes", "Minutes|Seconds", "Hours", "Minutes", "Seconds", "Years|Months|Days|Hours|Minutes"] Button { text: "model: " + modelData height: units.gu(2) onClicked: picker.mode = modelData } } Button { text: "disable hours" height: units.gu(2) onClicked: { picker.mode = "Hours|Minutes|Seconds"; var min = new Date(); min.setHours(23); min.setMinutes(0); min.setSeconds(0); var max = new Date(); max.setHours(23); max.setMinutes(59); max.setSeconds(59); picker.minimum = min; picker.maximum = max; } } Button { text: "disable hours and minutes" height: units.gu(2) onClicked: { picker.mode = "Hours|Minutes|Seconds"; var min = new Date(); min.setHours(23); min.setMinutes(10); min.setSeconds(0); var max = new Date(); max.setHours(23); max.setMinutes(10); max.setSeconds(59); picker.minimum = min; picker.maximum = max; } } Button { text: "second range" height: units.gu(2) onClicked: { picker.mode = "Hours|Minutes|Seconds"; var min = new Date(); min.setHours(23); min.setMinutes(10); min.setSeconds(20); var max = new Date(); max.setHours(23); max.setMinutes(10); max.setSeconds(59); picker.minimum = min; picker.maximum = max; } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/0000755000015301777760000000000012321006415025266 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/TabView.qml0000644000015301777760000000421112321005637027345 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: view width: 800 height: 600 ListModel { id: pages ListElement { title: "Tab 1" } ListElement { title: "Tab 2" } ListElement { title: "Tab 3" } ListElement { title: "Tab 4" } ListElement { title: "Tab 5" } } Header { id: header contents: TabBar { id: tabBar model: pages anchors { top: parent.top left: parent.left right: parent.right } } } Component { id: tabComponent Rectangle { width: ListView.view.width height: ListView.view.height Label { anchors.centerIn: parent text: title fontSize: "x-large" } color: Qt.rgba(Math.random(0.5), Math.random(1), Math.random(0.5), 1) MouseArea { anchors.fill: parent onClicked: tabBar.selectedIndex = index } } } ListView { id: list anchors { top: header.bottom left: parent.left right: parent.right bottom: parent.bottom } orientation: Qt.Horizontal model: pages delegate: tabComponent currentIndex: tabBar.selectedIndex } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/RepeaterTabs.qml0000644000015301777760000000457012321005637030375 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: root width: units.gu(40) height: units.gu(71) ListModel { id: inputModel Component.onCompleted: { append({ "name": "tab 1" }); insert(0, { "name": "tab 0" }); append({ "name": "tab 3" }); insert(2, { "name": "tab 2" }); } } property var listModel: ["tab #0", "tab #1", "tab #2", "tab #3"]; Tabs { id: tabsWithRepeater Repeater { objectName: "first_repeater" id: tabsRepeater model: inputModel Tab { title: name page: Page { Label { anchors.centerIn: parent text: title fontSize: "large" } tools: ToolbarItems { ToolbarButton { text: "shufle" onTriggered: { inputModel.move(1, 2, 1); inputModel.move(3, 0, 1); inputModel.move(1, 3, 1); } } ToolbarButton { text: "reset" onTriggered: tabsRepeater.model = null; } } } } } Repeater { objectName: "second_repeater" id: secondRepeater model: root.listModel Tab { title: "second" + modelData page: Page { Label { text: title } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/StackWithTabs.qml0000644000015301777760000000545612321005637030533 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: mainView width: units.gu(38) height: units.gu(50) PageStack { id: pageStack Component.onCompleted: push(tabs) Tabs { id: tabs Tab { title: "Tab 1" page: Page { Button { anchors.centerIn: parent onClicked: pageStack.push(page3) text: "Press" } } } Tab { title: "Tab 2" page: Page { Column { anchors { centerIn: parent } width: childrenRect.width height: childrenRect.height spacing: units.gu(1) Label { text: "Tab bar always in selection mode?" } Switch { id: alwaysSelectionModeSwitch Binding { target: tabs.tabBar property: "alwaysSelectionMode" value: alwaysSelectionModeSwitch.checked } } Label { text: "Animate tab bar." } Switch { id: animateSwitch checked: true Binding { target: tabs.tabBar property: "animate" value: animateSwitch.checked } } } } } } Page { id: page3 visible: false title: "Page on stack" Label { anchors.centerIn: parent text: "Press back to return to the tabs" } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/call_icon@8.png0000644000015301777760000000267112321005637030122 0ustar pbusernogroup00000000000000PNG  IHDR;mGtEXtSoftwareAdobe ImageReadyqe<fiTXtXML:com.adobe.xmp =IDATxbLLJa n@l@7w6//`G1ZADXdP$C899͐EYYYH2D_EE$CDDE># 8:ؿ M!"W`nnEIɩI2x?˗/@6;BB+4߂8g#LMgE3oP܉$C@P%!xxxѣ{891 惼\+FFF IN~~@@ NG@  aff~*b!P幹:qq IIpdgPPPv4h(CIHHtlظI$ˋ@ **(.A6HJJ'1!GX :]E,rBϟ?#Ο #gϞsվ |!Hqp b&PL"}phIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/PageStack.qml0000644000015301777760000000521712321005637027655 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Rectangle { color: "white" width: units.gu(50) height: units.gu(70) MainView { id: mainView width: units.gu(38) height: units.gu(50) anchors.centerIn: parent PageStack { id: pageStack Component.onCompleted: push(page0) Page { id: page0 title: i18n.tr("Root page") visible: false Column { anchors.fill: parent ListItem.Standard { text: i18n.tr("Page one") onClicked: pageStack.push(page1) progression: true } ListItem.Standard { text: i18n.tr("External page") onClicked: pageStack.push(Qt.resolvedUrl("MyCustomPage.qml")) progression: true } } } Page { id: page1 title: i18n.tr("First page") visible: false Column { anchors.fill: parent ListItem.Standard { text: i18n.tr("Root page (again)") onClicked: pageStack.push(page0) progression: true } ListItem.Standard { text: i18n.tr("Red rectangle") onClicked: pageStack.push(page2, {color: "red"}) progression: true } } tools: ToolbarItems { ToolbarButton { text: "oh" } } } Page { title: "Rectangle" id: page2 visible: false property alias color: rectangle.color Rectangle { id: rectangle anchors { fill: parent margins: units.gu(5) } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/MyCustomPage.qml0000644000015301777760000000265412321005637030372 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Page { title: i18n.tr("My custom page") Flickable { anchors.fill: parent contentHeight: height + units.gu(10) Label { anchors { top: parent.top topMargin: units.gu(16) horizontalCenter: parent.horizontalCenter } text: i18n.tr("This is an external page\nwith a locked toolbar.") color: "#757373" } } tools: ToolbarItems { ToolbarButton { text: "action 1" iconSource: Qt.resolvedUrl("call_icon.png") } ToolbarButton { text: "action 2" iconSource: Qt.resolvedUrl("call_icon.png") } opened: true locked: true } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/Tabs.qml0000644000015301777760000000726412321005712026702 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: 800 height: 600 Tabs { id: tabs selectedTabIndex: 0 Item { // does this mess up stuff? nope. } Tab { id: simpleTab title: i18n.tr("Simple page #" + index) page: Page { Row { anchors.centerIn: parent spacing: units.gu(1) width: childrenRect.width height: childrenRect.height Button { text: "tab bar on" enabled: !tabs.tabBar.selectionMode onClicked: tabs.tabBar.selectionMode = true; } Button { text: "tab bar off" enabled: tabs.tabBar.selectionMode onClicked: tabs.tabBar.selectionMode = false; } } tools: ToolbarItems { ToolbarButton { text: "action" iconSource: "call_icon.png" onTriggered: print("action triggered") } } } } Repeater { model: 3 Tab { id: tab title: "Extra #" + tab.index page: Page { Column { anchors.centerIn: parent width: units.gu(40) Label { anchors { left: parent.left right: parent.right } text: "Extra tab number "+index } Button { anchors { left: parent.left right: parent.right } text: "Previous" onClicked: if (tabs.selectedTabIndex > 0) tabs.selectedTabIndex-- } } } } } Tab { id: externalTab title: i18n.tr("External #" + index) page: Loader { parent: externalTab anchors.fill: parent source: (tabs.selectedTab === externalTab) ? Qt.resolvedUrl("MyCustomPage.qml") : "" } } Tab { title: i18n.tr("List view #" + index) page: Page { ListView { clip: true anchors.fill: parent model: 20 delegate: ListItem.Standard { iconSource: Qt.resolvedUrl("call_icon.png") text: "Item "+modelData } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/navigation/SimpleTabs.qml0000644000015301777760000000321212321005637030047 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: 800 height: 600 Tabs { id: tabs selectedTabIndex: 1 Tab { title: i18n.tr("One") page: Page { Label { anchors.centerIn: parent text: i18n.tr("First page") } tools: ToolbarItems { ToolbarButton { text: "1111" iconSource: "call_icon.png" } } } } Tab { title: i18n.tr("Two") page: Page { Label { anchors.centerIn: parent text: i18n.tr("Second page") } tools: ToolbarItems { ToolbarButton { text: "2222" iconSource: "call_icon.png" } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/popover/0000755000015301777760000000000012321006415024621 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/popover/PopoverTest.qml0000644000015301777760000000351612321005637027640 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: units.gu(80) height: units.gu(34) Component { id: popover Popover { Column { anchors { left: parent.left top: parent.top right: parent.right } ListItem.Standard { text: "Do something" } ListItem.Standard { text: "Do something else" } ListItem.Subtitled { text: "Title"; subText: "Subtitle"; showDivider: false} } } } Button { id: referenceButton visible: false } Grid { id: grid anchors.fill: parent columns: 6 rows: 8 spacing: units.gu(6) anchors.leftMargin: -referenceButton.width/2.0 anchors.topMargin: -referenceButton.height/2.0 Repeater { model: grid.columns * grid.rows delegate: Button { id: button text: "open" onClicked: PopupUtils.open(popover, button) } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/statesaver/0000755000015301777760000000000012321006415025310 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/statesaver/StateSaver.qml0000644000015301777760000000317712321005637030121 0ustar pbusernogroup00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: app width: units.gu(40) height: units.gu(71) applicationName: "StateSaver" StateSaver.properties: "width, height" Page { id: page title: "StateSaver test" Rectangle { id: rect anchors.fill: parent color: "red" StateSaver.properties: "color" Column { anchors.centerIn: parent Button { text: app.StateSaver.enabled ? "Disable" : "Enable" + " StateSaver" onClicked: { app.StateSaver.enabled = !app.StateSaver.enabled } } Button { text: "Random color" onClicked: { rect.color = Qt.rgba(Math.random(1.0) * 1, Math.random(1.0) * 1, Math.random(1.0) * 1, 1) } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/optionselector/0000755000015301777760000000000012321006415026200 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/optionselector/test.png0000644000015301777760000002243312321005637027676 0ustar pbusernogroup00000000000000PNG  IHDRHc"bKGD pHYs  tIME7'ܓ^ IDATx]ydUy@(* $#%hAĈVeJ-K%njR".)7*AKDfy{'{{~=ornݯ{wm{8scYs(xs{xk= h_ocp`Ъjzn%3ěJ7~Oʳbϊ6LHx|\@r^@uYtk",au8ifl|6Pu1&keȮ EX$Q8 owLNc*aC^, *_npqVf*>rz[0)MxKPGR$n&H[ ~ HɐUKurp=1(X(^1w5!A( Ц,G !xpI@M8&kq]. ,Z Zeo%_uiњ2r} }yEzubY,TV  .>sxњB=>M!S쥅%Nop6!< dQ,. sk11Y]5fvb7`(mCX'%( f]drцɴy/E>>9@Xǝ#' rfqL 5=vIA)aߤ"k6w:^sMt:h͝ޗ49"@[7>^7fb.|Hpn醿nsDbU ycđ~2B+p}!|q6}f#u5~pj cB1`6.BG/ :~cO=.1eElqi+Zq<<1ʧ3iA& 9L!F_1D=*wm-7{S\[IMC 15dHj `gFHvX0v V koFA׈y;G:{8xi,Ol^Ekdq %Qy KA~ ZB85לph3 p`j-kIpgb@a.~E! ZIDJ6L8}(OdeW4苟A/["6|Z\5Cxrg!=`T܏:JX3f `.Vќ xWs5zSVtJMFڱY2fG,Yhͭu"GW>A!@8E^hY) V+ζ`+\k[k /3quQ9#N9CǸXŸ́8@{B7!.tl{D'J2õ'z~ < RIPEC=l@\)2:j9GjE\ϓ5*ꀚTg Ǣm2ļOT?Dz/?!.- -. QSm^OeJGB\ֶ-!THW U^qy){Y) ʑP 5(n61 Q(eT2,; ^篯zX])͒1H<,^@lA&C%c );dprG0sѬ絉5;+$gg8闂6WDcϳrd%"e`j9m 8&aT s@v42Y&jq@f\ @\.qH{Θn5z0h;W2e','i4ZaTŠ9kMAmNN+;*oL#xO5Kܲ6 !D){ I GՐnGT ;١()#7_t2a4gy5y>!B^s [1fmͯYH{$ڤO3H-a,ׯ^(DK(uC]؜ŔE,-r#l<M(ZMw -VhGe \JHTl hpa{5a0hy*-'jdF9!fNh8&8eagǻKQ[AuTd5>qRB'؛|@׌Q*Bn+ #[U8x[;!9OPwD1ĄQ3})XbD_ւf;%&p؄:@ڃD8²ܯE(0 .A/Lr#CtFcW`z9n Ü#w&V.ލ]я8"ܰsY597"*52wq?ZbιiMJGIB2&~*'ȘRpaa0.%?.f% p $* .RPGz! 5nX'-#[?s;QsD Ѡ9e%x(`zV}hD=IeFuɗd\{/(kC RCK4N"?DEUNdQ;1zR:rFN'~)c aO`LNHtp$$Dsq%hb a\,jxA7! ٰO0'L]zμڠ}Te¿'n!|".N,Nhh-fXAI9;F'La滖Z5t\!8{d8 (9"d =+Sn²CR By'[]]%u.LG3ڶ=G b0U#C˒0Bw}`= S\wA:90W1ĉVp K'}(}MQ.iCU3YD2n8}ڶ)|H\J.ĭؗ2|TV?&E7n1LY;=,KMUQ1;_6x$ںH\V̹er!zhȆSkԮ)D/Oq#2ו1YpYιI^M7̡@j7'u} 64=n&I)lgåι hVњ\W5qӜ {_c@DU;h;/ ;:H 5ֲ1ǮR}n2&Ӊfp v$ ;vXVFZ{?/0 \ hQZt3f:ҩ=Y4dQs݊"èif?O2fM"[ajej"F fUi Y+<Duwez5G6A.us1⦅!U$C;h(RUʮ Dhf0w<.w$BPjϺǬ(Qv".&@@Kڗ\elF<`|Y5͐SKҤă->w)1bϒ &ɧ4F+!t21*7>^97{ZARgŢ+IC^'Q딴~uvG~EKIgϾWoA;v.Lv&C s( n1ˉуOgy.#.W9aZ \_B9^c}ճ# ^$;FDdCb 0vX}<"p,2ҍLcX@+9m=rxDӔwA4 { ;|qh 詉"68 /AAI,ZV̘I TiL3wSsD+X䷑f@-/Z7xͼ )Tt4#4kjMP^̣Oɠx^o 5V7ћ` 5:UDA(9â$ ,=&WT+!;R՚r)?As>(BU–>Z+] X&jܾ$=LD9Q6rz/|,;Z֠,\-oC'Q\chV {Z\ r/Krk>dfhr*ajod00AȮ2.Cn%a"B\v$L,i%7厘ZQ54Q?gn:4b5CCfQNƷqzJD%hw%Lj3lUl佬'bkcЖQ2B AkVH W(E© g\m$xa_($.FÚO7DaE~vbŠbe?,v QSLƦmGҮ<{I\Q47kLj&;Xj% A:6 |>8 m-[i20VpDZfBHdlz|vU2l2pQ`{0qNiZku[Pu:R$[=6uMOlcUplUz48~}- AbK0z~f$1UIZ|]mA9K!@NB`슜~Z#(~蜼Df !"᳿GhP犻Fn_dX}酮 u4\ J6Y輀E+^`$g8 4>ވbs}Z4q0͞hh񕡶Qsl h3ެxo-Y{L`!{E%v–2J}dsQ _KwUM5Re_)^@pEmoGkE|9ĕxj !U+hMiHu+ hDYb΢HuEB GC \dR¯}ͷk=_?7nMF#v68Gn|ͼGwHl꡴s xt MzpT\+~80\' 0/.GzÌ(W5x2 gyh&,ni1asth6FviU sf;iJ+Ц_d8D#SZRt|7bA3vda. t%s#1UWCm|s<G-΢gɢ21v5((\Be&@#BTʢ`,k ÈqZH`i6>@b Sh^o|8YGm1VРR<݋&AV4=9ʶZ꠲KQr]ڵ@$.uA.ڮrZΑCkgRˡX[\ o%Db p v"}'G};Pp6c$v{zeW*&8qݪ 4ΠSRI1(Jf~'DBÅP^B/t"Aj5Jeƙk+0$2\"zt^hDTq7ZmIꚐW3کt.Z;"XH?wִUd?2 YMi^_`CAmtݴyשE]^CYZeg/B,@mH]EyXР<+xb;4|{bU!N 66ͮ- nsڇ_lw1N:=T!gt)pdNѯhY(dqc!lgr ) {B.Ne!10JxjDwe&ZZ+3Lj>V,cDF`CHBٲ!lq;A.EsrrK?$J[^q%u./ n)P3j~*=ʲ!;x IQZ.KH1ڡ(A&osnJjygJ;Fd\ (zQa^h⢄uT UG!Nml Z#0gw:+V0nj+(g$Z%'t T9 RUGjS 'Yx;[Yt*J9VfEPIF*d$qFsempj WNc(7#\0݃dsC%2GhǐԊ#1$h[ϸIDAT&rPwmqEly9$)6wUnIN~X%IOE؆JzzEŸ5|OtD'ŷuэ['͹"HPZ?'Œ>FM.# kỵ]@߻q = u][ ={6 HLUk@jwp{O;K̴ S+&IW:5&f) ծ]OakV.ë, 8pf."JI6"=Fv4W'z.z&fDf D̋r -]J^40@u[ҥ|X(Խc]~9hJˏs/{_z!.cY$q5\DfE;B'J63|ubvHcLKtc(8,d0&"Nbk8p$.Yj QhZ877#꿪9=̳v `^j eGd;f.yYlc,YǚL "O".-u;w\s.Vz٤8瞈8T29lE"'kgAq/5,0UgsTA.(لN9G9FHIrʾBY\Di's Hr"25]ָD0#6HiTW͸y׋ȸ{?/刦UbIwNpC[ myYA\>/&Yj_[|qBmȚp!<⽟ q͉ q} )5[g؊x*突Vc߉6ٵf3jmA3$2̰q[{?CD_:# d2q!%0sHg&TJKIﯓ cqxZ ? F/l/Oؐ<IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/filters/0000755000015301777760000000000012321006415024577 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/filters/MouseFilters.qml0000644000015301777760000000317612321005637027747 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(40) height: units.gu(71) Column { anchors.fill: parent spacing: units.gu(1) Rectangle { width: parent.width height: units.gu(5) TextInput { activeFocusOnPress: true anchors.fill: parent anchors.margins: units.gu(0.5) MouseArea { anchors.fill: parent preventStealing: false propagateComposedEvents: true onPressed: mouse.accepted = false onReleased: print("released") } } } Button { text: "Button" Mouse.onPressed: print("Button pressed") } Rectangle { width: parent.width height: units.gu(5) color: "green" Mouse.onPressed: print("Rectangle pressed") } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/toolbar/0000755000015301777760000000000012321006415024571 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/toolbar/panels.qml0000644000015301777760000001031012321005637026566 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { color: "grey" width: units.gu(80) height: units.gu(80) LayoutMirroring.enabled: true LayoutMirroring.childrenInherit: true Rectangle { width: units.gu(50) height: units.gu(50) color: "lightgrey" anchors.centerIn: parent Label { text: "Panels everywhere!" anchors.centerIn: parent } Panel { align: Qt.AlignLeft anchors { left: parent.left bottom: parent.bottom top: parent.top } width: units.gu(20) Rectangle { anchors.fill: parent color: "black" opacity: 1.0 } Column { width: parent.width height: childrenRect.height anchors.verticalCenter: parent.verticalCenter Slider { width: parent.width / 1.2 anchors.horizontalCenter: parent.horizontalCenter value: 50 } Button { width: parent.width text: "click me!!" onClicked: print("click!") } } } Panel { align: Qt.AlignRight anchors { right: parent.right verticalCenter: parent.verticalCenter } height: units.gu(20) width: units.gu(10) Rectangle { anchors.fill: parent color: "yellow" } } Panel { id: bottomLeftPanel align: Qt.AlignBottom anchors { bottom: parent.bottom left: parent.left right: rightPanel.left } height: toolbar.height StyledItem { id: toolbar anchors { left: parent.left right: parent.right bottom: parent.bottom } height: units.gu(8) property bool opened: bottomLeftPanel.opened property bool animating: bottomLeftPanel.animating style: Theme.createStyleComponent("ToolbarStyle.qml", toolbar) Label { anchors.centerIn: parent text: "This looks like a standard toolbar" } } } Panel { id: rightPanel align: Qt.AlignBottom anchors { bottom: parent.bottom right: parent.right top: parent.top } width: units.gu(15) Rectangle { color: "pink" anchors.fill: parent } } Panel { align: Qt.AlignTop anchors { top: parent.top right: parent.right } width: units.gu(20) height: units.gu(20) Rectangle { color: "red" anchors.fill: parent } } Panel { align: Qt.AlignTop anchors { top: parent.top left: parent.left } width: units.gu(20) height: units.gu(20) Rectangle { color: "orange" anchors.fill: parent } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/toolbar/toolbar.qml0000644000015301777760000000432212321005637026754 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(80) Action { id: action1 text: "action 1" onTriggered: print("one!") iconSource: Qt.resolvedUrl("../../../examples/ubuntu-ui-toolkit-gallery/call_icon.png") } Page { title: "test page" Label { anchors.centerIn: parent text: "Hello, world" } tools: ToolbarItems { Button { // normal-styled button. anchors.verticalCenter: parent.verticalCenter width: units.gu(10) text: "yeah" onClicked: print("upa") } ToolbarButton { iconSource: Qt.resolvedUrl("../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png") text: "oh" onTriggered: print("lala") enabled: false } ToolbarButton { action: action1 } ToolbarButton { action: Action { onTriggered: print("two!") iconSource: Qt.resolvedUrl("../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png") text: "Second action" } text: "action 2" } back: ToolbarButton { text: "cancel" iconSource: Qt.resolvedUrl("../../../modules/Ubuntu/Components/artwork/back.png") anchors.verticalCenter: parent.verticalCenter } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/toolbar/oldToolbarWithActions.qml0000644000015301777760000000224212321005637031567 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(80) Action { id: action1 text: "action 1" onTriggered: print("one!") } Action { id: action2 text: "action 2" onTriggered: print("two!") } Page { title: "test page" Label { anchors.centerIn: parent text: "Hello, world" } tools: ToolbarActions { actions: [action1, action2] } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/toolbar/LockedToolbar.qml0000644000015301777760000000243612321005637030042 0ustar pbusernogroup00000000000000/* * Copyright (C) 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(80) id: mainView Page { id: page title: "test page" Label { anchors.centerIn: parent text: "testing the toolbar" } tools: ToolbarItems { id: toolbarItems ToolbarButton { text: "action1" } } } ToolbarItems { id: lockedTools ToolbarButton { text: "locked" } locked: true opened: true } Component.onCompleted: { page.tools = lockedTools; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/urihandler/0000755000015301777760000000000012321006415025264 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/urihandler/UriHandlerTest.qml0000644000015301777760000000242412321005637030703 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Loïc Molinari */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: mainView width: 700 height: 100 Rectangle { id: background anchors.fill: parent color: "black" } Text { id: uri anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pixelSize: 20 font.bold: true font.family: "Ubuntu" color: "white" text: "Uri: \"\"" } Connections { target: UriHandler onOpened: uri.text = "Uri: \"" + uris + "\"" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/alarm/0000755000015301777760000000000012321006415024223 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/alarm/Alarms.qml0000644000015301777760000001315512321005637026167 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 import Ubuntu.Components.Popups 0.1 MainView { id: mainView width: units.gu(40) height: units.gu(71) objectName: "mainView" AlarmModel{ id: alarmModel } Alarm { id: alarm onStatusChanged: { print("operation " + operation + ", status= " + status + ", error=" + error); if (status !== Alarm.Ready) return; if ((operation > Alarm.NoOperation) && (operation < Alarm.Reseting)) { reset(); } } } Column { id: layout anchors { left: parent.left top: parent.top right: parent.right } height: childrenRect.height Standard { text: "Label" control: TextField { id: message objectName: "alarm_message" text: alarm.message } } Standard { text: "Date" control: TextField { id: date objectName: "alarm_date" text: alarm.date.toString() } } Standard { text: "Enabled" control: Switch { id: enabled objectName: "alarm_enabled" checked: alarm.enabled onCheckedChanged: { if (checked != alarm.enabled) { alarm.enabled = checked; } } } } ValueSelector { id: recurence text: "Recurence" values: ["OneTime", "Daily", "Weekly"] selectedIndex: { if (alarm.type == Alarm.OneTime) return 0; else if (alarm.type == Alarm.Repeating) { if (alarm.daysOfWeek === Alarm.Daily) return 1; else return 2; } } onSelectedIndexChanged: { switch (selectedIndex) { case 0: alarm.type = Alarm.OneTime; break; case 1: alarm.type = Alarm.Repeating; alarm.daysOfWeek = Alarm.Daily; break; case 2: alarm.type = Alarm.Repeating; break; } } } MultiValue { id: days text: "Occurence" values: getValues() visible: recurence.selectedIndex == 2 onClicked: { PopupUtils.open(Qt.resolvedUrl("AlarmDays.qml"), days, {"alarm": alarm}); } function getValues() { var v = []; if (alarm.daysOfWeek & Alarm.Monday) v.push("Monday"); if (alarm.daysOfWeek & Alarm.Tuesday) v.push("Tuesday"); if (alarm.daysOfWeek & Alarm.Wednesday) v.push("Wednesday"); if (alarm.daysOfWeek & Alarm.Thursday) v.push("Thursday"); if (alarm.daysOfWeek & Alarm.Friday) v.push("Friday"); if (alarm.daysOfWeek & Alarm.Saturday) v.push("Saturday"); if (alarm.daysOfWeek & Alarm.Sunday) v.push("Sunday"); return v; } } Standard { text: "Save result="+alarm.error control: Button { text: "Save" onClicked: { alarm.message = message.text; alarm.date = new Date(date.text); alarm.save(); } } } Standard { text: "Alarm count: " + alarmModel.count control: Button { text: "Reset" onClicked: { alarm.reset(); } } } ThinDivider{} } ListView { id: alarmList anchors { fill: parent topMargin: layout.height } clip: true model: alarmModel delegate: Standard { text: message removable: true control: Switch { checked: model.enabled onCheckedChanged: { if (checked != model.enabled) { model.enabled = checked; model.save(); } } } onItemRemoved: { var data = alarmModel.get(index); data.cancel(); } onClicked: { var data = alarmModel.get(index); alarm.message = data.message; alarm.date = data.date; alarm.type = data.type; alarm.daysOfWeek = data.daysOfWeek; alarm.enabled = data.enabled; } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/alarm/AlarmDays.qml0000644000015301777760000000437312321005637026627 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 import Ubuntu.Components.ListItems 0.1 Dialog { id:root property var alarm title: "Choose days" Button { text: "Done" onClicked: PopupUtils.close(root); } ListModel { id: daysModel ListElement { day: "Monday" flag: Alarm.Monday } ListElement { day: "Tuesday" flag: Alarm.Tuesday } ListElement { day: "Wednesday" flag: Alarm.Wednesday } ListElement { day: "Thursday" flag: Alarm.Thursday } ListElement { day: "Friday" flag: Alarm.Friday } ListElement { day: "Saturday" flag: Alarm.Saturday } ListElement { day: "Sunday" flag: Alarm.Sunday } } Column { anchors { left: contents.left top: contents.top right: contents.right } height: childrenRect.height Repeater { model: daysModel Standard { text: day control: CheckBox { checked: (alarm.daysOfWeek & flag) == flag onCheckedChanged: { if (checked) { alarm.daysOfWeek |= flag; } else { alarm.daysOfWeek &= ~flag; } } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/0000755000015301777760000000000012321006415024414 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/CustomTheme/0000755000015301777760000000000012321006415026651 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/CustomTheme/TestStyle.qml0000644000015301777760000000140512321005637031331 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import TestTheme 1.0 as Parent Parent.TestStyle { Component.onCompleted: console.log("CUSTOMTHEME") } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/CustomTheme/parent_theme0000644000015301777760000000001212321005637031245 0ustar pbusernogroup00000000000000TestTheme ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/TestModule/0000755000015301777760000000000012321006415026501 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/TestModule/TestTheme/0000755000015301777760000000000012321006415030403 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/TestModule/TestTheme/TestStyle.qml0000644000015301777760000000140212321005637033060 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 Item { Component.onCompleted: console.log("PARENT") } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/TestModule/TestTheme/parent_theme0000644000015301777760000000004212321005637033002 0ustar pbusernogroup00000000000000Ubuntu.Components.Themes.Ambiance ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/resources/themes/TestModule/TestTheme/qmldir0000644000015301777760000000005412321005637031622 0ustar pbusernogroup00000000000000module TestTheme TestStyle 1.0 TestStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/xvfb.sh0000755000015301777760000000201012321005637022417 0ustar pbusernogroup00000000000000#!/bin/sh # # Copyright 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # Author: Christian Dywan echo Running $@ in virtual frame buffer... xvfb-run -a -s "-screen 0 1280x1024x24" -e xvfb.err "$@" 2>test.err RETVAL=$? if [ $RETVAL -eq 0 ]; then echo $@ finished successfully... else echo $@ in virtual frame buffer failed... cat test.err >&2 echo Tail of xvfb-run output: tail xvfb.err >&2 exit $RETVAL fi ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/tests/qmlapicheck.sh0000755000015301777760000000376312321005637023753 0ustar pbusernogroup00000000000000#!/usr/bin/env sh # # Copyright 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ################################################################################ QML="modules/Ubuntu/*/qmldir modules/Ubuntu/Components/Colors/UbuntuColors.qml modules/Ubuntu/Components/*/qmldir modules/Ubuntu/Components/Pickers/PickerPanel.qml" CPP="Ubuntu.Components Ubuntu.Layouts Ubuntu.PerformanceMetrics" echo Dumping QML API of C++ components echo '' > plugins.qmltypes for i in $CPP; do # Silence spam on stderr due to fonts # https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1256999 # https://bugreports.qt-project.org/browse/QTBUG-36243 qmlplugindump $i 0.1 modules 2>/dev/null >> plugins.qmltypes done STATUS=$? test $STATUS = 0 || ERRORS=1 test $STATUS = 0 || echo Error: qmldump failed echo Running QML API check for $QML # Palette gets included in Qt 5.2 qmlplugindump even though it's qml BUILTINS=QQuick,QQml,U1db::,Palette python3 tests/qmlapicheck.py $QML plugins.qmltypes > components.api.new STATUS=$? test $STATUS = 0 || ERRORS=1 test $STATUS = 0 || echo Error: qmlapicheck.py failed echo Verifying the diff between existing and generated API diff -Fqml -u components.api components.api.new STATUS=$? test $STATUS = 0 || ERRORS=1 test $STATUS = 0 || echo Error: diff mismatched if [ "x$ERRORS" != "x1" ]; then echo API is all fine. exit 0 else echo API test failed with errors. Did you forget to update components.api? exit 1 fi ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/0000755000015301777760000000000012321006415022624 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/all-modules.qdoc0000644000015301777760000000135712321005637025725 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \page all-modules.html \title All Modules \nextpage {Ubuntu User Interface Toolkit} */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-components-pickers.qdoc0000644000015301777760000000132212321005637030642 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \qmlmodule Ubuntu.Components.Pickers 0.1 \title Pickers */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/documentation.pri0000644000015301777760000000043112321005637026214 0ustar pbusernogroup00000000000000install_docs.files = $$PWD/html install_docs.path = /usr/share/ubuntu-ui-toolkit/doc install_docs.depends = docs install_qch.files = $$PWD/ubuntuuserinterfacetoolkit.qch install_qch.path = /usr/share/qt5/doc/qch/ install_qch.depends = docs INSTALLS += install_qch install_docs ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-appdev-site-footer.qdocconf0000644000015301777760000000753012321005637031411 0ustar pbusernogroup00000000000000HTML.footer = \ "\n" \ "
\n" \ "\n" \ "\n" \ "\n" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-ui-toolkit-online-indexes.qdocconf0000644000015301777760000000063212321005637032707 0ustar pbusernogroup00000000000000include(ubuntu-ui-toolkit-online.qdocconf) indexes = \ /usr/share/qt5/doc/qtqml/qtqml.index \ /usr/share/qt5/doc/qtquick/qtquick.index \ /usr/share/qt5/doc/qtwebkit/qtwebkit.index \ /usr/share/qt5/doc/qtsvg/qtsvg.index \ /usr/share/qt5/doc/qtscript/qtscript.index \ /usr/share/qt5/doc/qtmultimedia/qtmultimedia.index \ /usr/share/doc/unity-action/qml/unity-action-qml-api.index \ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-ui-toolkit-offline.qdocconf0000644000015301777760000000175112321005637031413 0ustar pbusernogroup00000000000000include(ubuntu-ui-toolkit-common.qdocconf) HTML.nobreadcrumbs = "true" HTML.stylesheets = \ $SRC/css/breadcrumbs.js \ $SRC/css/reset.css \ $SRC/css/qtquick.css \ $SRC/css/base.css \ $SRC/css/scratch.css HTML.headerstyles = \ "\n" \ "\n" \ "\n" \ "\n" HTML.postheader = \ "
\n" \ "
\n" HTML.footer = \ "
\n" \ "
\n" \ "
\n" \ "
\n" \ " \n" \ "

© 2013 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.

\n" \ "
\n" \ "
\n" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-components-listitems.qdoc0000644000015301777760000000132712321005637031224 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \qmlmodule Ubuntu.Components.ListItems 0.1 \title List Items */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/0000755000015301777760000000000012321006415024471 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/0000755000015301777760000000000012321006415026171 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/SimpleLayout.qml0000644000015301777760000001416312321005637031345 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(30) height: units.gu(30) //! [0] Layouts { id: layouts anchors.fill: parent layouts: [ //![column] ConditionalLayout { name: "column" when: layouts.width > units.gu(50) && layouts.width <= units.gu(70) Column { anchors.fill: parent ItemLayout { item: "red" height: parent.height / 3 anchors { left: parent.left right: parent.right } } ItemLayout { item: "green" height: parent.height / 3 anchors { left: parent.left right: parent.right } } ItemLayout { item: "blue" height: parent.height / 3 anchors { left: parent.left right: parent.right } } } }, //![column] //![row] ConditionalLayout { name: "row" when: layouts.width > units.gu(70) && layouts.width <= units.gu(90) Row { anchors.fill: parent ItemLayout { item: "blue" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "red" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "green" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } } }, //![row] //![hiding-element] ConditionalLayout { name: "hiding-element" when: layouts.width > units.gu(90) && layouts.width < units.gu(100) Row { anchors.fill: parent ItemLayout { item: "red" width: parent.width / 2 height: units.gu(20) } ItemLayout { item: "green" width: parent.width / 2 height: units.gu(20) } } }, //![hiding-element] //![showing-more] ConditionalLayout { name: "showing-more" when: layouts.width >= units.gu(100) Flow { anchors.fill: parent ItemLayout { item: "red" width: units.gu(50) height: units.gu(20) } ItemLayout { item: "green" width: units.gu(50) height: units.gu(20) } ItemLayout { item: "blue" width: units.gu(50) height: units.gu(20) } Button { text: "Flow item" width: units.gu(50) height: units.gu(20) } } } //![showing-more] ] //![default layout] Button { id: redButton text: "Item #1" color: "red" Layouts.item: "red" anchors { left: parent.left top: parent.top bottom: parent.bottom } width: units.gu(15) } Button { id: greenButton text: "Item #2" color: "green" Layouts.item: "green" anchors { top: parent.top left: redButton.right right: parent.right } height: units.gu(10) } Button { id: nolayout text: "Non-laid out" color: "brown" anchors { top: greenButton.bottom left: redButton.right right: parent.right bottom: blueButton.top } } Button { id: blueButton text: "Item #3" color: "blue" Layouts.item: "blue" anchors{ left: redButton.right right: parent.right bottom: parent.bottom } height: units.gu(10) } //![default layout] } //! [0] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/layout2.qml0000644000015301777760000000601712321005637030314 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![0] import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(30) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ //![row layout] ConditionalLayout { name: "row" when: layouts.width > units.gu(50) Row { anchors.fill: parent ItemLayout { item: "blue" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "red" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "green" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } } } //![row layout] ] //![default layout] Button { id: redButton text: "Item #1" color: "red" Layouts.item: "red" anchors { left: parent.left top: parent.top bottom: parent.bottom } width: units.gu(15) } Button { id: greenButton text: "Item #2" color: "green" Layouts.item: "green" anchors { top: parent.top left: redButton.right right: parent.right } height: units.gu(10) } Button { id: blueButton text: "Item #3" color: "blue" Layouts.item: "blue" anchors{ left: redButton.right right: parent.right bottom: parent.bottom } height: units.gu(10) } //![default layout] } } //![0] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/layout6.qml0000644000015301777760000000677412321005637030332 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![0] import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(30) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ //![flow layout] ConditionalLayout { name: "flow" when: layouts.width > units.gu(70) Flow { anchors.fill: parent ItemLayout { item: "red" width: units.gu(20) height: units.gu(20) } ItemLayout { item: "green" width: units.gu(20) height: units.gu(20) } ItemLayout { item: "blue" width: units.gu(20) height: units.gu(20) } Button { text: "Flow item" width: units.gu(20) height: units.gu(20) } } } //![flow layout] , //![row layout] ConditionalLayout { name: "row" when: layouts.width > units.gu(50) Row { anchors.fill: parent ItemLayout { item: "red" width: parent.width / 2 height: units.gu(20) } ItemLayout { item: "green" width: parent.width / 2 height: units.gu(20) } } } //![row layout] ] //![default layout] Button { id: redButton text: "Item #1" color: "red" Layouts.item: "red" anchors { left: parent.left top: parent.top bottom: parent.bottom } width: units.gu(15) } Button { id: greenButton text: "Item #2" color: "green" Layouts.item: "green" anchors { top: parent.top left: redButton.right right: parent.right } height: units.gu(10) } Button { id: blueButton text: "Item #3" color: "blue" Layouts.item: "blue" anchors{ left: redButton.right right: parent.right bottom: parent.bottom } height: units.gu(10) } //![default layout] } } //![0] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/layout1.qml0000644000015301777760000000601712321005637030313 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![0] import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(30) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ //![row layout] ConditionalLayout { name: "row" when: layouts.width > units.gu(50) Row { anchors.fill: parent ItemLayout { item: "red" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "green" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "blue" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } } } //![row layout] ] //![default layout] Button { id: redButton text: "Item #1" color: "red" Layouts.item: "red" anchors { left: parent.left top: parent.top bottom: parent.bottom } width: units.gu(15) } Button { id: greenButton text: "Item #2" color: "green" Layouts.item: "green" anchors { top: parent.top left: redButton.right right: parent.right } height: units.gu(10) } Button { id: blueButton text: "Item #3" color: "blue" Layouts.item: "blue" anchors{ left: redButton.right right: parent.right bottom: parent.bottom } height: units.gu(10) } //![default layout] } } //![0] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/layout7.qml0000644000015301777760000001022612321005637030316 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![0] import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(30) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ //![flow layout] ConditionalLayout { name: "flow" when: layouts.width > units.gu(70) Flow { anchors.fill: parent ItemLayout { item: "red" width: units.gu(20) height: units.gu(20) } ItemLayout { item: "green" width: units.gu(20) height: units.gu(20) } ItemLayout { item: "blue" width: units.gu(20) height: units.gu(20) } Button { text: "Flow item" width: units.gu(20) height: units.gu(20) } } } //![flow layout] , //![overlay layout] ConditionalLayout { name: "row" when: layouts.width > units.gu(50) Row { anchors.fill: parent ItemLayout { item: "red" width: parent.width / 2 height: units.gu(20) Rectangle { anchors{ left: parent.left right: parent.right bottom: parent.bottom margins: units.dp(3) } radius: units.dp(1) height: units.gu(8) color: "#bbbbbb88" Label { anchors.centerIn: parent text: "Overlay item" } } } ItemLayout { item: "green" width: parent.width / 2 height: units.gu(20) } } } //![overlay layout] ] //![default layout] Button { id: redButton text: "Item #1" color: "red" Layouts.item: "red" anchors { left: parent.left top: parent.top bottom: parent.bottom } width: units.gu(15) } Button { id: greenButton text: "Item #2" color: "green" Layouts.item: "green" anchors { top: parent.top left: redButton.right right: parent.right } height: units.gu(10) } Button { id: blueButton text: "Item #3" color: "blue" Layouts.item: "blue" anchors{ left: redButton.right right: parent.right bottom: parent.bottom } height: units.gu(10) } //![default layout] } } //![0] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/layouts/layout3.qml0000644000015301777760000000565612321005637030325 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![0] import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Layouts 0.1 Item { id: root width: units.gu(30) height: units.gu(30) Layouts { objectName: "layouts" id: layouts anchors.fill: parent layouts: [ //![row layout] ConditionalLayout { name: "row" when: layouts.width > units.gu(50) Row { anchors.fill: parent ItemLayout { item: "blue" width: units.gu(10) height: parent.height - units.gu(10) } ItemLayout { item: "red" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } ItemLayout { item: "green" width: parent.width / 3 anchors { top: parent.top bottom: parent.bottom } } } } //![row layout] ] //![default layout] Button { id: redButton text: "Item #1" color: "red" Layouts.item: "red" anchors { left: parent.left top: parent.top bottom: parent.bottom } width: units.gu(15) } Button { id: greenButton text: "Item #2" color: "green" Layouts.item: "green" anchors { top: parent.top left: redButton.right right: parent.right } height: units.gu(10) } Button { id: blueButton text: "Item #3" color: "blue" Layouts.item: "blue" anchors{ left: redButton.right right: parent.right bottom: parent.bottom } height: units.gu(10) } //![default layout] } } //![0] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/statesaver/0000755000015301777760000000000012321006415026652 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/statesaver/PropertyGroupSaver.qml0000644000015301777760000000300312321005637033230 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![property-group-saver] import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(40) height: units.gu(71) color: "green" StateSaver.properties: "border.color, border.width, innerRect.color" property Rectangle innerRect: Rectangle { width: units.gu(20) height: units.gu(40) parent: root z: 0 anchors.centerIn: root } Button { text: "Change" anchors.centerIn: parent z: 1 onClicked: { root.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); root.border.width = units.gu(2) * Math.random(1) root.border.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); innerRect.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); } } } //![property-group-saver] ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/statesaver/MultiplePropertySaver.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/statesaver/MultiplePropertySaver.qm0000644000015301777760000000232212321005637033556 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![group-saver] import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(40) height: units.gu(71) color: "green" StateSaver.properties: "color, border.color, border.width" Button { text: "Change" anchors.centerIn: parent onClicked: { root.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); root.border.width = units.gu(2) * Math.random(1) root.border.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); } } } //![group-saver] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/statesaver/PropertyGroupSaver2.qml0000644000015301777760000000313512321005637033320 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![property-group-saver] import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(40) height: units.gu(71) color: "green" StateSaver.properties: "border.color, border.width" //![alt-group-saver] property Rectangle innerRect: Rectangle { id: inner width: units.gu(20) height: units.gu(40) parent: root z: 0 anchors.centerIn: root StateSaver.properties: "color" } //![alt-group-saver] Button { text: "Change" anchors.centerIn: parent z: 1 onClicked: { root.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); root.border.width = units.gu(2) * Math.random(1) root.border.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); innerRect.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); } } } //![property-group-saver] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/snippets/statesaver/ColorChanger.qml0000644000015301777760000000204212321005637031736 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //![color-saver] import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(40) height: units.gu(71) color: "green" StateSaver.properties: "color" Button { text: "Change color" anchors.centerIn: parent onClicked: { root.color = Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1); } } } //![color-saver] ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/resolution-independence.qdoc0000644000015301777760000001320112321005637030320 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \page resolution-independence.html resolution-independence \title Resolution Independence \nextpage {Ubuntu User Interface Toolkit} The objective of resolution independence is to make it easy for graphical user interfaces in Ubuntu to scale to all the form factors that Ubuntu targets: phones, tablets, laptops and desktops. The approach taken combines simplicity for the designers and developers with visual fidelity, quality and usability. \part Measurement Units A new measurement unit is defined called the grid unit, abbreviated \b{\e gu}. 1 grid unit translates to a given number of pixels depending on the type of screen that the user interface is displayed on. For example, on a laptop computer 1 grid unit will typically translate to 8 pixels. The number of pixels per grid unit is chosen in order to preserve the perceived visual size of UI elements and therefore depends on the density of the display and the distance the user is to the screen. We also ensure that 1 grid unit is always an integer number of pixel. Examples: \table \header \li Device \li Conversion \row \li Most laptops \li 1 gu = 8 px \row \li Retina laptops \li 1 gu = 16 px \row \li Phone with 4 inch screen at HD resolution (around 720x1,280 pixels) \li 1 gu = 18 px \row \li Tablet with 10 inch screen at HD resolution (around 720x1,280 pixels) \li 1 gu = 10 px \endtable The grid unit defines a visual rhythm in Ubuntu and should be used for all measurements. Sizes of elements, spacing, margins, etc. should all use multiples of 1 gu. It is available from QML as a method of the global object \b units, instance of \l Units. Example Usage: \code import Ubuntu.Components 0.1 Item { width: units.gu(2) height: units.gu(5) } \endcode Exceptionally, in order to accommodate for the rare cases where measurements of less than 1 gu are needed another unit is available: the density independent pixel, abbreviated \b{\e dp}. 1 dp typically translates to 1 pixel on laptops and low density mobile phones and tablets. Example Usage: \code import Ubuntu.Components 0.1 Rectangle { height: units.dp(1) } \endcode \part Bitmaps Vector graphics, fonts and programmatically drawn elements will usually scale well to the different devices. On the other hand, bitmaps will typically require a bit more care. The size of a bitmap needs to be adequate to render well on a given device. The toolkit allows to design multiple versions of a bitmap and choose the appropriate one dynamically depending on the device the application is being run on. In order to know for what target device a given version of a bitmap was produced, we define a file naming convention based on the number of pixel per grid unit of the device. Example: If the target device the bitmap is produced for has 10 pixels per grid unit, then the file name of the bitmap should be suffixed with @10: \e my_bitmap.png should be renamed to \e my_bitmap@10.png. In order to support the highest possible resolution devices on the market, we recommend to always design bitmaps for a device that would have 30 pixels per grid unit (@30 suffix). The system will perform a high quality downscaling of the bitmap when needed on lower resolution screens. Example: If the destination size of the bitmap is 10 gu * 10 gu and the developer targets a device that has 18 pixels per grid unit (1 gu = 18 px), the bitmap should still be created as if 1 gu = 30 px which results in a 300 px * 300 px bitmap. When testing on the device the bitmap will be downscaled by a factor of 30 / 18 = 1.66667. \part Fonts It is critical for the font sizes to be consistent across Ubuntu and to have a rhythm defining them. Instead of setting the font size in pixels or points, it is imperative to define the font size in terms of literals: \table \row \li \b x-large \row \li \b large \row \li \b medium \row \li \b small \row \li \b x-small \endtable Example Usage: \code import Ubuntu.Components 0.1 Label { fontSize: "small" } \endcode For reference when designing, these sizes correspond to the following pixel measurements: \table \header \li Font Size \li Desktop \li Smart Phone with 4" HD screen \li Tablet with 10" HD screen \row \li \b{\e x-large} \li 34 px \li 76 px \li 42 px \row \li \b{\e large} \li 20 px \li 45 px \li 25 px \row \li \b{\e medium} \li 14 px \li 31 px \li 18 px \row \li \b{\e small} \li 12 px \li 27 px \li 15 px \row \li \b{\e x-small} \li 10 px \li 22 px \li 12 px \endtable */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-components.qdoc0000644000015301777760000000137412321005637027213 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \qmlmodule Ubuntu.Components 0.1 \title Basic QML Types \nextpage {Ubuntu User Interface Toolkit} */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-ui-toolkit-qtcreator.qdocconf0000644000015301777760000000040212321005637031765 0ustar pbusernogroup00000000000000include(ubuntu-ui-toolkit-offline.qdocconf) outputdir = offline qhp.projects = UbuntuUserInterfaceToolkit qhp.UbuntuUserInterfaceToolkit.namespace = com.canonical.ubuntuuitoolkit.0.1 qhp.UbuntuUserInterfaceToolkit.virtualFolder = UbuntuUserInterfaceToolkit ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-layouts.qdoc0000644000015301777760000003364512321005637026534 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \page ubuntu-layouts.html \title Layouts - Introduction \nextpage Layouts - Terminology QML has the following basic layout primitives: \list \li \l {https://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-column.html}{Column} - arrange children in a column \li \l {https://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-row.html}{Row} - arrange children in a row \li \l {https://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-grid.html}{Grid} - arrange children in a grid of x columns and y rows \li \l {https://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-flow.html}{Flow} - arrange children side-by-side with wrapping \endlist \raw HTML
\endraw Unfortunately in a design that needs to work in many different form factors these aren't very flexible on their own as: \list 1 \li not designed to alter size of children - so no form of stretching supported by default. \li as a result no way to have contents fill the container (without calculating the width/height of the children manually). \endlist \raw HTML
\endraw As a result, most applications need to do calculations to size the children correctly in these primitives to fill the whole container. Qt offers advice to developers on multi-layouts in QML. In summary they recommend: \e {Application top level page definitions, and reusable component definitions, should use one QML layout definition for the layout structure. This single definition should include the layout design for separate Device Orientations and container Aspect Ratios.} UIs layouts should be constructed to share as many components as possible. Then on display mode change these shared components can be reparented, reducing number of components to unload/reload and also helping to save state. Using a Loader to switch the QML for different display modes is slower, and will involve loss of state. Instead the above advice is to use AnchorChanges & PropertyChanges to specify all layouts in one QML document, so switching display mode is dynamic - but admittedly is a painful for all display modes and states that an application may want to support. \l {http://doc-snapshot.qt-project.org/qt5-stable/qtquicklayouts/qmlmodule-qtquick-layouts1-qtquick-layouts-1-0.html} {QtQuick Controls} introduces the \l {http://doc-snapshot.qt-project.org/qt5-stable/qtquicklayouts/qml-qtquick-layouts1-columnlayout.html} {ColumnLayout}, \l {http://doc-snapshot.qt-project.org/qt5-stable/qtquicklayouts/qml-qtquick-layouts1-rowlayout.html}{RowLayout} and \l {http://doc-snapshot.qt-project.org/qt5-stable/qtquicklayouts/qml-qtquick-layouts1-gridlayout.html}{GridLayout} components as well as the \l{http://doc-snapshot.qt-project.org/qt5-stable/qtquicklayouts/qml-qtquick-layouts1-layout.html}{Layout} attached properties, which brings additional layouting possibilities to Qt Quick. In addition to these, UI toolkit had introduced the Ubuntu.Layouts module to help developers define different layouts for different orientations and form factors, all being possible to be done within the same code base. This tutorial gives an introduction to layout factoring abilities offered by Ubuntu UI toolkit. It tries to cover few possible layout scenarios, however will not cover advanced scenarios application developers may need. Tutorial chapters: \list 1 \li \l {Layouts - Terminology}{Terminology} \li \l {Layouts - The first conditional layout}{The first conditional layout} \li \l {Layouts - Changing the order}{Changing the order} \li \l {Layouts - Lay out a single item differently from others}{Lay out a single item differently from others} \li \l {Layouts - Hiding elements, showing more}{Hiding elements, showing more} \li \l {Layouts - Overlay items in an item host}{Overlay items in an item host} \li \l {Layouts - Defining more layouts for different form factors}{Defining more layouts for different form factors} \endlist So, let's take them step-by-step... */ /*! \page ubuntu-layouts1.html \title Layouts - Terminology \nextpage Layouts - The first conditional layout First let's introduce the terminology we are going to use across this tutorial. \section3 Layout Block, Container and Item holder A layout block is a component embedding several layout definitions and items to be laid out. It is typically defined by the \l Layouts component. Each layout defined in the block is compound of containers, which can host laid out items hosted by item holders. An item holder is a pseudo-item which can host only one item, where the item is anchored to the item holder's edges, therefore the item holder has control over the componet's size, scale and rotation. To understand this let's take the following layout structure: \image sample-layout.png In this layout all three buttons are laid out in the same container, but green button was required to take the height of the window, whereas the red and blue buttons were required to have the same width and height. Illustrating the layout on the image with code: \qml Layouts { // <-- layout block id: layouts layouts: [ // [...] ConditionalLayout { // <-- layout name: "composit" Row { // <-- layout container // [...] ItemLayout { // <-- item holder item: "item2" // [...] } ItemLayout { // <-- item holder item: "item1" // [...] } ItemLayout { // <-- item holder item: "item3" // [...] } } } ] // the items to lay outitem3 Button { Layouts.item: "item1" // [...] } Button { Layouts.item: "item2" // [...] } Button { Layouts.item: "item3" // [...] } } \endqml A container can be any item, however it is preferable to use positioners or QtQuick layout elements whenever possible. As next step let's create some layouts. */ /*! \page ubuntu-layouts2.html \title Layouts - The first conditional layout \nextpage Layouts - Changing the order As first let's create the following default layout, with anchored buttons to each other. \image default-layout.png Defined by the following code: \snippet layouts/layout1.qml default layout \section1 Walkthrough \section2 Import First of all, in order to use the layouting abilities, you need to import Ubuntu.Layouts. \code import Ubuntu.Layouts 0.1 \endcode This layout will have the red button anchored to the parent's left, top and bottom, having a width of 15 grid units. The green and blue buttons are anchored left to the red button, righ to their parent, top and bottom to the parent top respectively to the parent bottom and both having a height of 10 grid units. This layout looks good in small form factors, however as the width, height and grid unit changes, this layout will start to look cumbersome. Every component we wan to lay out must be marked. This "marking" is done by attaching the Layouts.item property to erach item participating in the layouting. Therefore we mark each button with a unique name, "red", "green" and "blue". \section2 Define the conditional layout Let's define a column layout for the case when the layout block width passes 50 GU, and move the items into a \l{http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-row.html}{Row} container in the following order: "red", "green" and "blue". We also need to specify the size these components will have, so let's set the width to one third of the container's width and top and bottom anchored to the row's top and bottom. \snippet layouts/layout1.qml row layout Note the way the container is defined. Items are laid out using ItemLayout host items. The items will be laid out in the order the ItemLayout hosts are declared. Beside this ItemLayout also drives the size, scale, rotation, availability (enabled) visibility and opacity of the hosted item. The conditional layout is given a name so it can be identified when the layout is set through Layouts.curentLayout property. This, beside debugging abilities, gives additional possibilities to configure properties that are not directly updated by the layouting. Combining this with the default layout we will see the following layout when width exceeds 50 GU: \image layout1.png \snippet layouts/layout1.qml 0 */ /*! \page ubuntu-layouts3.html \title Layouts - Changing the order \nextpage Layouts - Lay out a single item differently from others So far we have seen how to define the default layout, a conditional layout and how to place items into those. As mentioned in the ConditionalLayout documentation, items hosted by the container are laid out based on the order they are hosted by the ItemLayout. So let's change the order the buttons are laid out so that we have blue, red and green order. \snippet layouts/layout2.qml row layout The layout after resizing the window width to exceed 50 GU will look as follows: \image layout2.png Note that when resizing the window width to < 50 GU, you will get all your components back to their original (default) positions and anchors. */ /*! \page ubuntu-layouts4.html \title Layouts - Lay out a single item differently from others \nextpage Layouts - Hiding elements, showing more As mentioned, ItemLayout has control over the size, anchors and visibility of the hosted element. Therefore we can have the blue button with a different size than the other two. Let's have the blue button's width set to 10 GUs and its height to 10 GUs less than the positioner's height. The code will look as follows: \snippet layouts/layout3.qml row layout \image layout3.png */ /*! \page ubuntu-layouts5.html \title Layouts - Hiding elements, showing more \nextpage Layouts - Overlay items in an item host Till this point we know how to define a layout block, what is the default layout, how to create layout, how to define the container and how to define the hosted elements and how to define item hosts to lay out individual items. There can be situations when for certain layouts we don't want to transfer all the components of a default layout. More, there can be situations when we want to show more components when we have more space to our disposal. Perhaps we want to provide more functionality when the phone is turned from portrait to landscape (typical use case is a Calculator application which on portrait is a simple calculator but on landscape provides scientific calculator functions). In the following we will define two layouts where we cover both use cases. \section1 Hiding components Let's create a layout where we only show the red and green buttons. This can be achieved by specifying only those components to be hosted by the container. \snippet layouts/layout6.qml row layout The layout when the block width exceeds 50 GU will look like this: \image layout6.png \section1 Showing more content Another use case is to show extra content in a different layout/form factor. These components can simply be declared inside the layout itself, assuming that those are not going to be used in any other layout. If yes, those must also be declared in the default layout in order to preserve their state, or other modalities to transfer the component state must be used. Let's create a layout which will be activated when the layout block width exceeds 70 GU. \snippet layouts/layout6.qml flow layout \image layout6-2.png */ /*! \page ubuntu-layouts6.html \title Layouts - Overlay items in an item host \nextpage Layouts - Defining more layouts for different form factors There is one more thing you can do with ItemLayout container, which is to define overlay items for certain hosted items on certain layouts. If an ItemLayout has child elements defined, the hosted item will be stacked as topmost element, so all the child elements declared in ItemLayout will be rendered as overlay on top of the hosted item. \image layout7.png \snippet layouts/layout7.qml overlay layout */ /*! \page ubuntu-layouts7.html \title Layouts - Defining more layouts for different form factors As mentioned, with Layouts we can achieve to have a single code base supporting different form factors. The following example illustrates how to support different layouts with the same code base. \section1 Default layout \image simple-layout1.png \snippet layouts/SimpleLayout.qml default layout \section1 Conditional layouts \section2 Column layout \image simple-layout2.png \snippet layouts/SimpleLayout.qml column \section2 Row layout \image simple-layout3.png \snippet layouts/SimpleLayout.qml row \section2 Layout hiding element \image simple-layout4.png \snippet layouts/SimpleLayout.qml hiding-element \section2 Layout showing more \image simple-layout5.png \snippet layouts/SimpleLayout.qml showing-more \section1 The entire code \snippet layouts/SimpleLayout.qml 0 \section1 That's it You're ready to go. You can find the layouting components under \l Layouting. For further questions please visit \b #ubuntu-app-devel irc channel on freenode. */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-appdev-site-header.qdocconf0000644000015301777760000000352412321005724031337 0ustar pbusernogroup00000000000000HTML.postheader = \ "
\n" \ "
\n" \ " \n" \ "
\n" \ "
\n" \ "
\n" \ " \n" \ " \"Ubuntu\n" \ "

Developer

\n" \ "
\n" \ "
\n" \ " \n" \ "
\n" \ "
\n" \ "
\n" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/0000755000015301777760000000000012321006415024071 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/sample-layout.png0000644000015301777760000002676112321005637027414 0ustar pbusernogroup00000000000000PNG  IHDR &sBIT|dtEXtSoftwaregnome-screenshot> IDATx{|UKNH@i#B76ZG9v:ՖնSK3vfSZuRTmX[q@d'.c@$PI_/$kg=k|ye9*z8V^$˲dYnɕe7Ҟuf96551:a:|V|#m Ў=!_Qv-2؎5uH-޳~t؎t#o7ދcf pb;=~m u~d  9lhm3n1Uvnu2?9?TWr~yCy7oeYmKk[3OW]]F^{{6o*۶3vH ڶ}yc=5n\81Fd" c,;QyZw{h?vz'˖ؕa3n\$ɕtL42L}a04}q,#u{71_1|?TH1+!vy#YvތCB1{6L4v\َ#Ƕ="_ N+twcF~X(YMZ6efV!\^[:̎}-Jr]w@~b3fhʔ&OP]];ֶW;vh˖-J&r=<2#Ab&͚ujT*˩c^ym߾]DBJxrrr6_LhewR<~nZ~馺:;1H [_>wI(H&dٶd۲lG-nK$#)/Uϟ6E׫r++JZqr(T܁_s`-R:k}qvymE*:OΓmKQ y/?c JJlGn"'ۄvJX J,[tZUԃTPT>FlS&-IF~_~T2qd)RJ+r*sѲ%ieN(1[c uIcFLIRkOI{gޣ)TRcVL?JrW~hʔ&R)ʊ QT>ͮ*5MiҞݭJ8 ~Fe3J;/~NA z \R* wq|)џ_ToOH ۻSnY]UsjrmJ^{VTfsNkC߸`(,ν\7:1%:^{Z!Xj:/tͥkĤw~t6QZ/}}MTjۤ'~]%lѪS4y\R$߫jure)R>ЛN%QlZ11SQKvB6]x捯ƎՒԘ*tw꼉i=;/v&7MV>W*!eu`<E&kgNyF PMM*z2_}_U>)Mٲs=wߨ.)E^R ӴJyi[gi+ɔ[ UO^>$ %'ݠC_[?[_F}t/K ք #&ԫ@Wq~J7 %uֿI+?[+(i[fbPrLxZn77GJF'6P6ACeΒ( 5-e)"I҂IW?+gG[#zZ%IQjj&( ˫DJb쇤CץDžaLUU&5I& dT*j#N0 *3TD%j5K*Yg~Zٽw@'uǮE?&q/]]pWtݬ1Us(8dc"j%InEVMQ-{/mTϷ`'US%>7ܬ{_ 5iէҒ-ոispj/ǩ;MK8JXCyrV$E{4U'g-h},"oD6,;e,57?}Su}&S"cd$E~_;^OˣJ;5A gM Zn%RQ%'~[zIR2ɱMҬ:Uɉ̀`+ˑv=_]g]/G93kUǏo;.QT*iZ$IMz痿wonjm}L kۥug儡tv"튌lm(0)O  C~Eo^Ԍ4w\oe iv|OAƔ!X;o^m|^){oPeUnHQT~YX 2Fo }}OH;ځJB2 Ka (nwU 4#/Տ?yk[~#Y!zMOoqԵI] OR}ЎTq6lѦ;x$J(*mjoPuumG}`(eY*o,ۿҎ] QU\]QAVڱu?dU5V9oNVwƗFTIFȿߪG~0CoFt}rvjmgLԭRN25 +۔UzSYj&tڲ^qx }U(RD[O,,/IU*}x-ӦSkPuLS>I{%*ٲ庮ݣL&0 eYl;mA _몵UNym[驧~=5(2}7 ۮ]o{g|]}%^wjo:lӦ=[ZGisr7+٦=&5JR֖=>ز*-[|'{/<7_OUE=|ʳJz斏7E?m=J;/GʸCÐ"NGZke+ JjJROKߜڰcN C)) d{ =3Zs͖&o_'LP2GQmKNTmOQ(Gcw]UUYN-^|ǮLK(O(nO>/۲ӣmJgCYJ$;ȭҥK'*ho Fmmm%6=OiyΚk_g ּO)ܮ_?C˯{Nz7֝/I5׎6K)Gͺ坺z婚YɳBvo֮ȕ_kuSE?R;&`5gn {JrWQ ݪ1~߲_]OvU"#TRE:}#pCl[Qh+/q]%lk'2F3g,.,o|6mIҫ*ɒX6AD*K*2WVEh}@r ]%ȤvJCNT $TU  PJfRJWO>PЛ-[^U*Ykb)TX K(vd((*fٶR%PQIGk`(cDBTOu]M&C)6PyeYyWV1VAUrbQ7[l{Ӟ\v%DZH$#:NXԦM/Qtrc[*oߡ(y^eı3[tJ I&(1_#GUK^UZ^H&w@tGz eM$&nI$9tzatvF/UQ*L&[npiE:S\_v+uJi<k[Vw(*[Q*e2&RPP[9%)y O,ɨoT׶,%I~I۶m׸q5d3J&$˨T*;׭;H&r=wuڰ! zᅜl)j^_\B!R8l[rKlф fHj¬MkܬA=g۲mͽ{~zu[J}{<`+MIRQRRW-XW-JWJM6am۴{~=֯W[T.GJg#I%)iW&#{b]u&^ym=v_;#Q3]ZUW+'jڴGݮo?mj1-2u7uySVtC* :w1j-GܻNx=Zrv6G%I s}͵mԳ=!LFzr.XR &ugΪU<ז(gMK\z"oL^̛+<2?Y\EQuGrsU7(/UTCή-nvibVjɜ%Zz5_0:qo0+%Mtp֗RM.,_nש1(huj:|_mmx4_thՑO02-s.':mqiZ-ZkhiQ]kPgx8[cwx\U[e.{ ۚomJx4]*<~d|]VJ"z/F5+uNe w]*cUx/K&[#/(GN&{>`hE}?cjSkA^s /tߚǶ4-;҂I'/;5˶~xx]wRg jN[W!ժZzKVn)U:,eκIN2%s9\U^(^U m曕>G3n۵QK+-vhKZW/9s&hR]QJA[K%Gճ￯^NygUWI___9kz_.8\]hADm5gu:jrK'hNPwhKΖ!`ǑlĈ9ur^p Vn5}~;F&w<'g{RfZ}p학p3T+?QdɜHQIyYRԢΩwC]իK4=м~;'R4#GB[25?TZ<9oXM7=~~WZ?xUrUN|cI_Kqp vjIjP(h^,d #);)JɁ;s?ueN_w/ϗɵ*[ U^ވ5FiE:}=:_6-{zKo)cJ#n}@'fd7#Yrm.ۚ{o,$ښ]w$$UWtͿ?lz.Ǭ>pu899 N9]=_&m[2_ͤcI FĊ'̱0vY-d5-SxjL$EsH_ |S TU4R4k{* /+ʪ]JJ|?UoL-MV)[iP?$u V>FV4Z<z.oRC3kI7jy4no?řw^Io7JxFU|]WQ94o{qJWg?땸zUxyuo}I/='W2RtE꠵H֡(3dT;[I_l=|'MxƠ]T__ G{?^[' =zmmyi@!g#s` }) Uou~IN=ҋ/CϼڪVzygGxQ#ϯI%?ǖE X$SIk#mdշ\MMmڹ~zgKQTTgHպRߒZU&JlꨬKkSRX<І4JD~I(m[0,(iY*-ْ2BMdv[֦q'};1cHU/ڵmCEv moHC0`H*I5:w9(ise@=[RX*K[:dK}:X$Hݻ: \Ǒr_X [sl;e' wIDAT .#" %`ls\ *slYc㰎-b c X`[} [Ār_qy c7 X@@,r_Hv)g`lv]rYI]׵F'`r_1ɑc0X&[`,vÕHtAjrƦ.&'.8n6t<`,:\l?^HD4~/Q VΒM.1%piO*9N0=p'%laS80 acy>opzX567oK[BfrEHwDVm O˗RLGƂT*F+Vxng/` fRIG9]pFʕr֬Qb,Hh͚J%_>Pg'UMʕ֬q`"la\W+NpJgd{NͲŏE`I&Qxɲ,-sr;VHhP+Wz6ovmIT402Odeˤ3t4os؇lc`Rr,5K vYŽ\NPH&dzGmYlVNmTJ ǧR,q5kхKPQ`ERtEXr]fjkR꤆K55G&8VMA?4)(`t8q֚ChR01@@,l [@@,l [@@,l [@@,l [@@,l [@@,l [@@,l [@@,l [vku׻3$I҇]9ΉI'-T3&=xͺ(UޚP7^6~pZ>^͗}Xq" QJ 3UoGƙWʜӵdL;$[ o\k6ʛ/;fv=~ZL?S &tX=V)Km~wN AN][wx5u>'P:O+uW%I;Ƕu˭]];W_hQd_~H]pt-k?~Fx@?=ڞZ߿tnڙ?wg|Z7?S: AfJި:&9WH΍*Zy)Ur ӳ]I]T]/G-uRSsj͚8Qm*)YHsI?ЩSZ}ry>iquHSZ :wt957o= QA RMT拔]k}T_]<_'5TN]oUWj:$e&B?J^]z]`t '?eցzr;._^n 8ƪ=:eZ~y=80uF[;eQJ}k¦ԪשO 0&qڥ|2jW69I맨~:A.W֫RMf׍;uG^ IDATx{]e}ϳڷ{.$$!!$@4$(Vہ^*UZjTrԢr BM0 L&̾sX{&$ ~k=;׌u֋Q>Ncj9??}7߂h>Sr{a#}h_ǎ_}w;Wgtڽn2wj(QcGf;mG_{_1r#=Gxd5~/f:18x˩¸qMUDDDduuuf:lj̢S8o؄?Î""""uz ZKd#loZ1C[oc=GՎ0@ujskhll^Ul #|'C5xKZGk6C0$""kqjq]R)/-X[[whQ. >tDejrdݱH2x(O\cX8e<3i)\,'7n/f[__Z(ZvV`E8. WyTBRPW}T*YK0~|aQ8OmC?SFf,IDlݺGyMq=3֧&Os˃|wfO}9o)0%g!g}=nߒr_0⑕(aH& b1^w q C?@x^ ǩ!ryΤ78>icp]絾oZ M\0n~0eJlԮhhDb6NmruMicNnimmځ_a 5{9?Ngg'eC1?>ohNŭXph&q2)ǻqiV[͍ ,a7b~ؚٜ['~0E4`h;}\~)̞&rz(q~dVȏnGs(WsG?SܘYʭo&]a(ӼqO=s03 dA/Qrjd振cUw?=(Z6A/gMq&S*Ðhʠ*EEMfS&R0r9ngps}˰v~_>ǚ:Ms*km)T„i=i:)`&M7qx07I8kg9LSS,O_,aO'Ƨ(E6beŗQ ho_6ސB83ynxL5r›fVc%J?% ~5^-G/6VUOt! Ce Q68aRy~C\:o; ( a|RRV+wK70 _W/4lVQ*vigPCjM*3fsrg;7qi^gcxs^_{{׸4/K]dm8Iey37GC%H-CU~+dh;nqq+!~o^q,'}O~&y9 /Si6wk yjTNcX=N7ulAZQ-?gћL~ q*G6κC o> 2]p8uf0.tu'.9o K.⢥'0㔷S㿼FCVk1\ϱ'{;-!V)'3v\v}"""ʨ0qYWx7" ѐnU_2U{||f5pLLM}}>Nq񮭓ʼn?8ډڱ8EQګ}LBv b8D^f 'Z73ޘӐz-qWh ~,VN]0]&15;/ uP#ߐ&\{͏sR h}=ŎO%""clW3ETGsx.W'bv6o_Ds 6wvjk@:Uylݺ|>G8'f<ϣN|xF| AEvKG98Nr{|F79Υv~FMX[VGÎ?mp#DDdlz)-t_gq*mڇȄ[9& ! 84O-] پ ȤShcpCf>Yk ţ.ۻꢮfx;Ah?D\שM9@Q J8?0?̐t 7Rw{pdr[9Lh1:q!_'s 7OjfrxݧeuܰYv\jHu\}Ή"eByT]_bo@SL""2Otj[M~׵`KGx)zM;)gRqWQ1wb(ҋG:qP;̜y4ƉGvn'>^߻1` /2`p\|؈JJ%"O]SOؖv(U 0Yr_R12Ŋ7MC$ (2,|J`2G6S[c-~էR k/I\,AŧsqHgd=6>2bW;"""cZ>3AJNpeC/ 2!Djw3ƀT;T92)JU^5TvAdǦMC:GnNRaikk%'vB?dÆDQD*Mq\4` X\s;T]ळ4v{x_PTd2n"Kr%|Ꝉ åOrY2P0ģ.1q;N 6R((f`mD\OL:K*`lҙ _e 466/d2` KZOOO/Lt*O]:."""Y|)j/8>QE18K*"'\lǧgSC'xLmu\ܔGKav|{R?M-W@9繤)0" z}b |>>kIDDD^?A4j1!vZp;:C#+v㨵5 xu5{j'\2iL*542_FWw^߳+7Ea𣩆gDDD`i%""""o'"""rzL""""4$"""2+WRZsQYVb\Ɔ!*v98uqYBԄ df̠0w.ٳ)̞W_.}>Vd妕<9n[V"eLDV.8K6-003;m.'fvlsqxCgKu+" 0t* K>]6K/ȴiMK׳宻N+%Ftqge1KMm7wq3wb #.pҪą X̟E6r 7̔vUKA?˗yZ^|pˣp7n۱㬂$[~,gCk-=ꨩ׶My7\f)XHH9@b>OLz7̔իiV.ҡX;}:p7_Z 5)(FEzz{8{4t VcmU^ Y+ԯZEZUV U,_S`U*lJxǦ,V|r6nKX bօXTa΄ֱn).'u@-tt@v,%reC.,0AG?Z(7:;UF qED 3r\1uDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDSDs\>**̈Hr)̈H)̈HBy$2>"f'7͋3w_Ly|_ci _ zo쁵Y=@[{ w$p!.Uel㲺'~ڙz2G}1{Q/?* `65ݾcT{<ZNxLXpLd6`zvfwOO`ǙAI:K晌wZo18^sԙTz7Pš6X]X={Oywv$Xw I8nq[<~"΂6 .23gHYCfLyg[zv,>b0w#G4?&Z4lUт #D,pWtď- 4T?~<Հ}';:rl³DT߇p_~ 9hF܎QD[1/l,b FU㦝D^Zp17/_wuIodF]A崧fsQoL+>C]n39E)?q/1+u'A}{Caf?+|*~"{4Ƅ_L+qC}n48 - .!3s=2MҐ2̻c;Œ)Xj/N)pܲܮ+=:d䵘N*7 X̏?M݊NG/=]Hu4ŐI7/q܏ns9HL!Zs'0k. *\2 sͼxg8qh˿}L`i<}"G/>o]8Y;w??=.:CyKpVrsO&?ku{-w?-nN>|;لԝrӮdq:IgRwR2@܈؉-{8B=ќgWXG#V-ȗ%2L~9[cݓ`%,UT1'cƵ=}:s3a":W d14lZԿw,?ᓫ/0i `qG8i++WB9w=-Ä}LY>]=Z,*T|He;պi߈*\J}^CS܀T3:q?Svì γ]ʁ>ɐT9Pv#O^f[쇰o1:gy6p0u۶Rֳ ?҇f۫?CLPjYzbD!!3\IJk\<;Pgih kί,yzySaK9n!ύĿ9-锥n..dU2'6c&͞߃k?K0[Wm9~g$X w7Ig&/n#}?U A~!K[)d&q\*[ ,;\L!UGCX{޷N1;&7>3h6n|wqw§?[L[OsJ?D#3:vpU`(3<_@mqDߎ-_Nv0ݱ ~hr|@4BN< .onMBeso:r0?}Y5|~=?~n+l.צFfm#b]NtQ8/t6} kLo^EEs?BE-Wcvw-ؑke,{ {'6] )t1>ՄH]wnSiSX@6cpфCCyC&5BuCGw1% 7cIGR^&e94a&_;M2P ˀ @°uPk;S۲m'3æP "DaPhȷD/=w˵0)ZDGI< TkҶBh!gBn |QTCVv)ed: wLv'٣ʥ݊z;\F\>J>V ;_a}nx.0 ]^HZPd}L6a[;ΰZa`6,Tʻn㏐;=׋lD)uΧR;.>%ZzTq^>*K~$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$Œ$( snju'D{;9 XwCs  #@!="8R_Qǫ`"Õ@-L ÓL 0uIXwI\Nej%4u91IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/default-layout.png0000644000015301777760000002451212321005637027547 0ustar pbusernogroup00000000000000PNG  IHDR 58sBIT|dtEXtSoftwaregnome-screenshot> IDATxyu׷d̑ ! @B `B BW?((."?ڕuAkA.G@`$L&3gzLHBHfR<Iuշ5~RBS…#ֽJQP/\xlMUVJ?z \RǞ쭖uY֯&:HjudAA^=ԫ\Ueu@Ӄ,d)z|A l˵\5jzM{ (xu"C=KwY{lyƛFdeJk4 Oyyـ'!ZZZٸi3aA>a|F u-[c B6L:aF~2:@aZ. OŸDqrϡ( L@)a{,G͈i,m0p]}TXmYPşZOA@5F1tib&(#Bc::؇r, 4Ѿ#͹3 nu} \rJ)-[?@sq4}ܠs{bZ<'LE>} :۱%|ر\7YP`ɋ#p{>UJy.p|~Q,#ϩ=ÀlWv/xض͢E'Pzx7eXNt>L7,._2p JK,ު~!Gn°lR1@rtvAxbǓH( ]9:.+I1uTI, 0\Krİ-y.˫]4vhʺLHmRg;J:60M ;x>ʄrlM dw~ɏy,?Wz6W|TfWAi}i~_η 5| |쌹/U7ݷsۓ;#Y鏳tXGP ~Kn}lN" qxIZa}[|Nux.;r>7>T3md [\zeQTuvNY kfOXۚmVT~;" ;?q\Ep_ck^}? &~*>qQyxz]f7 ʡt{8g|]?m7u}Ll>Wa9Sm4Е u@yʷ>PV{v#. >zZiIU%| LX|9]o ?#Hbsf"}Ag:1/}`1(N(Mm|}'1St>́O*Pȇ{nɒpP ЁO2P(VF6ݭnٯ bI\pZP`_õ[}ܗ'w׾-`^m"=-nP6+{z^mcq@ŠSNُ&Y{ȯe;p^ fM^xmC L*'>329m>+&riOws0Az)F*MPc(ju?}-KٵpT{ L,'Y}k9 ƐFysa7#'_t{us=wGw} G0u2 2\M.~Z#ەC[)s^ܭ|9vP\7ˣTq `JAc|5ppwz@ۆ_<$am_w<,Z: ǿ?}2TX|GheG!c W*׷Nj1E={ ]k0L6tn~ \t>3b&sN1%m`(3y⨵aRZ AWWWG2(ŐAP슗~z_,Gɴ v28/I>eX??(atE ~}(Ēk}N%>t S ;9/~ƍh+tSc```YMM;I&R\7e؈mZ-SO=;s< =XFC.4%W.NJ{y}ٰk1sf;d{3M]&c|3;oy_¼O]˯.v cOORf}Ugn``5}Z{vlnK25 {Ή&}p.vx.y,cJkW Fs찕4o|.^>:[]-PR5̙34a+ݕb(EgWM$%?=S8VFJ>ΜWMI£`TEoQ6pf_2Sgpˮvbkcc*N߾g-?}D] 䨴lkVĭ.kÜd6mlٱ$t?W+g[=VjщkDZ&`PvpMe'iLC ưlڕ bIl;OhB?8 }Fy0- ǎa@k&N<e= ¹iCV0;l%/Z7e_ZMc(pqЙ#SS!,kٜC,'KW~Qcӵ- >~iC2ab.>);-ڧs:2h[9b #{8좄/6\ng^̇AɳYwĊoa0rl|_**%wcW0Mqr <6FMMD8I֭۶h$8o5&%k]7NӳAX["QbѻMIr7ٞoQX txrpc,b1\erC|;Dc,R##0xݳy,7EI"N̶{r[[C֭HRJq2: ˑ褳3C̉c;vUOR8[`˖&J@+PB@gvc۸%Zۯ8xԢזma.APm>W易ps]/<'\abe z>sbw:6 2\2 ^yur JE"3ozZTCÄ>o&1$f=-b8[2mRݗBoBܽI !} D1lb8bxx)2֑]ڵ7mmjdr9~7 e8f*=j H͜IbTRSbIGuX}keS&2Mdrrn? Pa)FF1b3djTL4ߓU?-[عj-wIf NF1)gxCv!Ę3c7-[XUپN:ÃkT2o6 n3I2z=ss.*k--:oiߓ+\uvZWǎM{%d[r-=3褮Mn=%K/An}1ի__OdZgմΚşu7ю M}V3vP r%֔_Oa}z-! mkwnSP y3%8BPoi!#Qcc3CZ+q0ā:y7Þ @qjkAmsdp+ cK\nH#ˑFU Ba("B/SA-VDx9M r#-=~ 6^2  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"$BDY C(>&0<>;,&U=p􄫹k8xXzW?Ϭϲ(1|2|k&"Ib"#k\&~MNPe5ɷoAeqLU[PY'_ QOt^/}C\}e!+b7Z1y)V~a0I h6㭝h#Mn&uoQoO夣äX6=ȣ-véd|I6L1!]U4mte h'NCid1駡4h]Èzs~*f䷰9)K[~ ]v zZ&z% .ްs}%k.瞳ΤҦǬ>ȧQĜ4=+b# MY$bXn_\˚3d_?M,?An=Bf~=/_a)҉U/#'bm=ȧVgNQ1{p+/ ÛeI0yS@0i ~v)^< L 6^ll">r{(e47b*Mke_ ׏ M0KZd19$YX-1s rdrY72cV-w)ϙQ%>JL9KY{HV$ڋ8ɧ8(]kz#h#zuer̀mTߟ_K;k9f\#/n{FAgZb(v4- R1LK~=8']I)qq'?Q_ȍ2߼7g|]|9T55*7c+b5#~v/k,܎0?{/k x޺5hl6:ӃMN+*GMA^NJSnSK,5_|ܞeį:l^l4QxQ}PGglI($&v,7)IT2&fSm!W煕M²l iptl1ʈP>]7 F. (}l1b[^Y)/-.qi -X٧+[Ϧ3B%-C9|y~yrg:A'; c# q3MCΑ8Y!OBdIsd!"@ΑKZd!ҵ" [d!g%B2,4eYÞ v 2,D< OBDiI,aϔ'!i`;"dY !2y~wG CX2td *˰dHޕPDC̊OC]q93UI RPWA$V| c 6]eP3jLmR$GicQjwXUic#h"f|"!q3΢qX|b@|DQ3sW|rNz#PI|rV]Ɍ$2,ѩ,ٺg=۟gcF:ΡI;#fn\揝ςLs;IXv2Zr-V2 97G 4L e㤜e2Vx9J{V#L:G r,DH  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"$BDY d!"@,D Oɟ^w"puEn= j\_o5ߐj=_u=e" #1ĉe+`G3v1 /WP^PW`2E-v!\^3̅v3\n?Q%20SO}Aib>p_0rA6̆QsPl)h̠O6ٻ·нBwxytQ%kgA2@W`|?q!Um[P}8[PZ*%J ~vOmgU xN=cAr~@|al{EC~]l̹$̣ˏAR J-'1Dw KoRJ_Hr՘8e'NAy̭1q@=0^lB/J FC>zAkS>1!ަ2ȤG4~; ^ۈ l:@u!6pe}/>F^LL#ލ?ۼU%5wm(+y f/cm-Iu/`LPB;j:…889o@ǟ]N!:^k(_7]RD0iā;n!(C=| ?wY AGدL:7>G?>58^O*>H[iM[\WAb>佁ub\pb} w#S0\]ME}PWCDwϯ9rB}vQ [YهzA[|nuy,p-u#]k!I  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"$BDY d!"@,DHk+ u2[e 6ijrd|rPR"7HLF0!̙)NM0d7IDATujJ[dYj'wš5I`Lz;gj(şyd9s ;s͸q @|Dhiq|s'cѺ 9*:;=Zٴi\2yDxVVI=Yh]A}}իw0kV+ ]G<חJ#CuK#&L (Qd2%ll#BC ć/[ BC*[ !{_IP( u }l%GJ?5K >d!"@,DH  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"$2&f;=r|98&ߴ;>@V/懚XHM6PvϷmЕ䶚tL{vt&Opm9ʔ&m+fݱO4VƦ"{hZg8 C ҵ@)3G1e(}ف<_N3cHN[G|=&DŴ%y [\/WCifT}7Kq}B)uXQLbsJ?̫[p} rh^&ANrv*L9V(P٤0cZyz~myn+ԌӘ/G^9I}_i;cj`MŮ{Z]ߖ7ZĖfϫ <8OIZ ;NZ Otql,n| dbˤv)TlZɝ\Qj]*\3&Y\tU`m7;@ ?f#Y )7ж77e)KUQKk}9:r0Du6k^P]кŤr9RÆJҵC [tv@*0yOw X gO Hhҕs&Uq~EoqMIn^xCo O§R]֔q 9babY {KmvrȭI2vI/LSs{>E* r-Nx࡫Q6gQW^1v;?>_[hT ?iVx_wZuz_b8Zoꪄ 4AAQQte@;>S<%>cF@aACkq^${0c'Pdb&a(\,ML)rno}F 9gfV0tuu3EXlR+LYdSs2ٮyEo*y[@CWi ܟ# d!"@,DH  A"$BDY d!"@,DH  A"$BDY d!"@,DH  A"¯5$ϑenaѵ%_oUʲ9βc96-DX9b>Aqj]q8sFWwt-3ʺLHJ6lG$@&9=#-#Ã[ rm-i[l$7iBm-izt4=jk c48*iӘ6͠Jޤgڴe؋-"LJbE/fbE40x[E4@1Ό+W._Ntwr̕+qf` +M/wIPWOtZ|ʕ&3fK=8d < 17nDuv,0L}4j\?siӊG,Y3M:;4ɤ}U̟ Lf~ADZEO^ ZZP~k+:ArhiaqT*YVCy9կg+ε4Ilr9EkO&4A/-p` [*(+3MˡRNVq9!sb?C)IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/simple-layout4.png0000644000015301777760000002332612321005637027502 0ustar pbusernogroup00000000000000PNG  IHDR sBIT|dtEXtSoftwaregnome-screenshot> IDATxyw}wU9=,˷-˗|ȇl1%.g8/e!N` Y`cBnbs8cƇS1?g$Ki$9眥H$I : c1!{`^l/Ӯtk}}aᅲ }m0lɍ?㧓&'14z7ɿ= כ?Wgz@m8+{e'ĵqT[c=͟,Pe8{z/Nj}T {zv e:z;/f~1zO/f?k~ǿ}zWI^k q$OV=Fa@P,#쳗2} E$Ild#a;luL7$Ik/$I$.B g^h(˲4Kv/Ȳ kh7-?Xoj0d5Eaw&$ILPHN,IV$xBQ,&+˲v2,%$!MS,#0(#}C,OS "0CcZMx$Itw,HӨ7xQ9o 0ʺQϟR)S(vAg&h4,\y?ӧe 6m'W#P.( lvtZ-&uԑL>n?O}{Zr2{J$ijWIB+n򡳎0Fct; oXOǕ?YIӺA7,?Ybt ;TA@S,83S=il4x0ё}iQ,Y:SuG[:9ˆBLow0Ke4NI:"R@L2BJ*=]6YghއPJ9ȈuGbݚSE4G ƴ]U+Q}1aDZ\}ԑ$I҄&=ej\6Ƭlxp#M6,ꯍoeesѦ&QT NZ̛7@Radd:+i:>;˰s3cV7u)E%8aΜ9tj:pͷj.B8~z 87KObhV=~P0 \t|NѻYx9:qyؚԛ1}8yNܗIG.x5}RYxW|ۏU}xpXO@sӃoo@+ޘ:.:~s@y%+5|:J]RFJ3QZ-I=VUZH[1 qu\Q>yj`T۴q*7% $s%IcHg옕ni\֬^C1V000z]gl׋/չ[ hk֬^;'A\,}ȡxaTl8񌣘W&qPya]lN{w$Ibgw^q$[׳Y%FFS,ebNgh-4qѯ~жMgz\:iӏ`3FZ<]W_:w.%I&ҙw HC+Yx4sr>~KN;lm/8m۷ kU$i"&tj4wI E}#& ZfO3&IZ ]:PI<^{q?kc?ZMw;6v?$o2/#YgVk?1~QZDx&ɯ>~2]M_jޫфYϾ(\~}wci\' G8C _I}ԹfH$oܐؕ! =1/;D|=朓8!Lk4N;K{AwLxsY:ofvtuv}?;ޞn].wvj-\̡{m(U}hQ~XZ(CnS"J6AkMsi\wwsw-y^sfl~([oөw% N4#tr[$i&Ff햎 I2cl5߾+:$c}W=CF햐]gtN[H 3ֿ=::JgGGul[7̓Ꮀ%4%MOl4ɟ,}Ccvll84oLQ-<pmi\ =,m kldN-;h<`u`}IFn#!È9!JIlC[yEg'oXێ"aPag50 ٲeZ]" ! w2>  d:'n֩vl;V+ 6!馕l`1sc*߆->FeZ6I*UU+Wo,0i>m&k8\ Q["Yyn~u4{Ӳ !A7;:9$Ie&IR*m0'lTtUËz 8g,WF;G%nآT"$P(qj*I)aEnapB)F=i ?ٝ{|VLfu =>,]]FcJgjv.l pƼsC/^^; Xr%F5g)&VFj$/zwT oo"TP2uFzIP#Do(*m@R,;}YF܌i4%jՈV#kAR2F8&UG$I{lvբX*.޽6mVN yMF9Zzh;P*4< i/Yk{X`Κ5kRԞfGf>j͝TN'<ēiJX촰H` )U+`׹񌈮ꎯbW*wh6,P*c"]=Ghl{ Ҟ^J%j{1N0}֑$ID&_GѠ\.WFYbyu# 1=a4V[F<Z\,g߀u:a'xn{jT* $R:Cۇ\P,  c|; J2qǟZwr YAFdxh[Q*(I=,M(InsfQ(8&c4!M30 #"bq™㱀e֏f+&[NKIFDB +ufܢ:#L0P(IJjὴb)w$Is\_f Hju'g|f: ȂrX&+Щ5v}Iӈr)\,,WKIR;{ڒ$Ih#Y{&>l$I~L6$IH$IڻF"I$ibn>Fﻏ{#7 dI3PyYO 05xT/9o|#> H҄>SZnz&zAzlq(!4 xj?qSxْ_ʡx}K  [iY#Kun?k[5P[߬ ܶ6Z z[aVl]#?~mmy[n!w9lj ڒtP*px2[ykku})t1!dՌj{w[ƾ +yjYf$d` h\w[GrݽבdIA(+f<V<-I8d:VmI:؅5:)dGoyxTC4 V;_Wam6r,I>C$MB3ivnr,Ij$$iZI;_vLX$I46S"I:%Y;_vNX$I4v$Ҭ)$Ieؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$Irbؖ$IrFQ4c$Is(2lK$Iy0lK$I9`ؖ$Iqg%I|H $I lK$Iyg[$Iʉ=ے$IRN\O$Iʉa[$Iʉ=ے$IRN .'I$å$Iس-I$ĞmI$)'-I$6I$)']0lK$Iϴ`϶$IN϶lK$Iϴ(rmI$) )I$u%Iζ$I$Irٖ$Ir$I(*x$Io$Ir:ے$IRN ے$IRNq?I$Wp?I$).'I$$ S=I$ʰ-I$İ-I$İ)?Si/OZl IEF}5i̺M@.I_F$i9j5ɫz_/>KzRO[\uXP3 }[տѷ>;9t4+s؉p.KȞAq*UT#G WؤZk^A2P{'IS/ 9zz?%Sv<㈺O`錀'lfpܼ%L}MEWrغ&oY|_sGkJ.EGt>W j H^|y-Ÿ@5;vYp"':OGD<|%{~DO[/O#;,KzbdNz dIìSH6\O=4SI|$F O"3/ 7s= ,Y'sJa.l|+ E?Ym̯F[:ry'sh~V2=sJʕ +E ۥZ RǞ`a?N`]Y=9m<*'3IO~ '8$Äk?!_x-F߾On I?2H샡~W~T?30}GId=%x3G8vP~Ƿ~&HA$f6>3/姃/Xr(6dvxx7~kysoI}6)SnF{?6)[|S#jK})AP8|;\x}4[;3}&F#i:<FөE"h}}$+?Juշux':^Cts9ktx?$˱1$|#Sv" AQַgƟI:HAƺӿc\xZ潝O:w'2ξ|nq9;vlwYr?|.'|򺣏xw>w|r+9ss c7yqG7gkOtH{e%Iw|Jwm#/&Gݽcݳ ' ꄿvwdK3=!{$9gpw<^zKxٰi39n[glX Vfs8@:r/wm{>@pNǩ2c(m΄tq_[g7_ޚ챜lDJ/YDzh.)]va gGG 9ϧ.\4E(To },7'I-=Qt^u1;"py,a8(EqbTmOYx$'Wl\Iz\F|sٲꓼWE=o~~pKxʍRRSΰBl%XJ&].>z3{t_c"+X0{~kȼF&HR Q)!bݶ Xg_3qG߆`Y>_pƬsytpWk勹~$j)=l#a$KGv±d_Pa5WѼ*ٴ' g3Lt牶O3OҟC pV릷z8jwEt)?qrW7]fX_xGz6Y>U+kV= ?.}3S032=~jM!g5uQPF~By٫(7o$?0]KiL]3 ˂Ť(摞4&^76M &%IiO} ­"+|?KBʪ_?oy|?B/A,k:;cgv"dmM qrW?u|%I4Eo7k{kT@Ҁ؅5iIc ;]g&Dnێs i7e[@nWEZޱЩfMS?r aMPAjD5f֦śP3~e LfFud=+a0ъ;(HL1kPOw QT5iY{ԯ&.fu IDATxy|UsKVE (ZpZV+Zm]lc.vjk7c[.ZjݚUDQQPIl7Y?MIDH8< 9{~=G M^?,bxZZR(EB)z"`~.c*oTGߒ%T X幺 \oQ,W T5Ⱥ= /Nu@Y>Ru.׃:pΗko?۫;p 6l@;o-]˺_-Ww{YY(**$SkkcF.G͟Kaᨡb/ac#Ơ!A4 cԨz]Zi{[Tv]9Gϯ9Qs i0#fԨizض㺸 i*,$`YPZ{ضx5F>tiMjca&a v&xas#&ns5cIg8mrs3x:yq6Np˲AulL6˄ 3R imme+65~zB VʵloQ!RUUɓ(,* 'Lλƍ  ` 0{ؙ 3R;-=+] cjtAA|VZy٬MYcQ=<y(@& W>[2.`Y&pܢEyaa.mm<ضM0"kl4 >z!ٺg}m1-sxY۴uM+?V_sw4) a3w]kO{ضØ%mΝ_ sӸiv,+עzq]B'xH&l.YP(b't>kcY #ߢ;.ir' Jr qNm(W*ag5'_ v Dt,3O䷯Ō#'3t[)Nus_U޵k ˖2ULs6Biq=|i(dM68s_'xɡ,j2Wsӊ47HU/Hx"οp%?[5|vJ|swB.c yL]W?x3'rvc::[ؕ\j7^؜5w?.4oNǶ*Eس{[\/?mVJQWNw`mCaO.9AmϧsvP(_^4q0'Lg,@f˟L0l@ap8wֶ"£d M/8d"_Y~üИƜ0 *WjXiljSO-h fێ;#yVXD$麰r<jymbZY DdTj[ZTPWN:P:ӝ ׭@˲غu XuQ09waG?˲hnn&`Z[Ǡql\9q&<#h пMטD "׊@4Bw0a r5,"Q[& b{\a?F_ǝi`1 Mm&sIERLl N]'ө/q0@7W\kk(+Ȳq&8p H$;J P`(mgٰa#F%cB! &ҕ좽`(H0v8hzobQ -kG]aX8mxi Ca&@@Tk_AYƵ9q5&f"hPz.Y|w:7me\s]ЎM2a͵B|ݻu_vA)ӴD"}Loj(2!tO#`}f}=dRB# &B pz'MMVbMM4un$= .ه,rǶn-?2[WCZt#ׯzm!f.bfrL?Y7\wr#A-'Ӆ\]9Ҿn-?nsA$Ⱦsme d!|@,H > A$BY d!|@,H > A$BY d!|@,H > AQxw~v9O,,.{*S] 9OĄkxk9)PDqړh- KXq5 S^2b#5/⛵3z"d1(/9z최m==|˞YNwgPu,<B@B=2e͹; sX:y&^z!iB qØtqarc,g|4aFxvř( Znhlw /)G15p }yv4M zf|h'77Syy3 1{%\f3$>3Oi cJw J`5?y,gjSӏþ:_]̣Ocˢ?9/'sMc_%⿦b?hd&W&&ۛXtNwI4RPlt67/D, IPfΐʧY!"ʥuV&yn[NPuwЫ4+92%0mv_Qaѵ+tXFHۤeh\7Mմ3os/Cz NjN5 4M9G`g&# qpLC8> B# Bk-lI8# q˟#<3Ӕyd!z2%<> BL? %-=S8%]BdKyd!|@,.'3;p駑2df¯,Ò駑"d +M? uEC][ Ň b?98R cC P276NTvt-U*] HGE,b؅PWE|HfcEyD^5etRPWGD0҉KY6{ӫ #eX,x7.M/qew ub2fWf̯Omym>"l=f6K&siMvҴHf4p=w*01A8&S)$l) Q/'ޱg%AA2$G;i߸V]]8 낖yaA) $ UTĨj)SOLhdBHGxV?0Vd)E0ZOOkZx=KvVU!+wMp6eB<_W&a /PD[[ 2Qq03"VxSsˇ^h\l}=!%g)E+ jlLG`Ӥ mi! "HG7Ĕ n2 HG7*JG϶ b?9sK9@K}KKG~ڿV,H > A$BY d!|@,H > A$BY d!|@,H > A$Sv-wR"{*˨ ʚy#;q O<ɜTsO;O/ǒkH=z-naՌr~Ott&s︎fD=RDշ߾ ʈ=ZwobϾ˜ F qs|H 0zD~="2Jd<aF@63f%E'^„'cbCFU/o-}~+-~Ƹr!|ѹ*[x2`˛+r˫/ЄCr ap? ]70ÈN'|c J#P<hfSo\ ެ ԛ,I#u9ԝcZlKӚي rN#7:ZӽZeU;BL+ϳem{eS([C4n~OBWw.~y:70߹k q34駾׾բƢ׊Eac=[vؕ> wVQt1l:H6B=#‡'Ɔ2GgDAe˟+}<3vqO^˂+l@Lir^ZPsH'x9.W_o"|j*"T',y_nB /`)R"~ڷXp).MqnHbV iCOgü~kX@䰆ou 2+p= Փ.A^;a܋D27|~z6o秏yxݘ?_hBt!H] K0'bQF#pIDATR_Nj+$uo|vsHgL|jTف{x3/#nWq"c__Bmoo/߬AA%LE?`Ic*j'$<#FdCbs%OݼVXG^q7OO_¡^O7ڨ5׿{/y\M{=|1nw*q>EP5~&^Q|f ̍! 㵭 j xZ;;Xs_ be_Ƹj isRdNͪbv %|i5xфbgsqW^ #Ldь= T #)*XǦ?$.5zX2.acIl"2o<9#.1 (r]<:th4< }{ ̅GDBw\%fS7/Oe#O^و0[tYl:H(>TՅa*췞b叓mʑ8lr7oՓ5)(St RE1$ٮ=;I L֎>{$:ߣ OA5lBYk$Tr6aɍqiƨ{#mZƫm>c޿7Tyƴ+X_ܸ'6x ;%Klr}~珛Ӗ2w/of 8鿻QUlPQhdu5e"[s(q%m: )hꬍ6 eþkPUsq/A'FՌ7ZU+pjJ(|2^o=ױn*)D=q'~D׻xWpzC{ PVnJ*ʣ46ObgPT*/N96te1J*D:U1"c0 wl|˾@B`+B}>>6@8J=G~gɌ;g>X33O4Q6wHIɰoՃ?!w}|%Y-yﺎ3~w%h3<5蹋BO (7WR~{XrHc.>|e޸'W>p!Z)tSo\S4Ȟ{vr? nlKes;8Y4Fewͮe׾G˘ur2o 4Z|5e\=^ݺ /gZC>^k;W.yV~6NKBIc_a dB6Mɉ +Ԗ1oTՖ^F؂L*ʝ{G5Å3V02 aM>e#-<4iA/aaL3c 6PA Nwsۨ`eoXA} F4\Wbn #vrfp;~ReAV2];DJ"xI'y ց鷯QB6v= ðElH6i +ҀφehȤw\8g.uCg><%۴q9T{nz'e#MO\;H7rk3p`Z5ӵ۩)utN4nvFo9b$BY d!|@,H > A$BY d!|@,H > A$BY d!|@,HGFMGc+A5\|8zy0Pzy0OzybC][ L$f>[ ъ <O)yD(4PiPWC|BNHGʹs)=#ꪈ Q:{6s~C93}X2uгb1F}4q[6uaYTy$bΟO˪U&MpS&HȘ1R2cfQ8iF aB֒7 vvf2d::q2<< 0 0 P@4J( .-%ﰾytXaV٬_غ$LN{Fr<<"6MJKLbƌ5555+A!6lHq[VV@0>\"TC̿@ kb,*3;6HGV_z3EC.D.6֯LGhO?. :3 Khh|ffldiD˰fM7ZX AM(b?Q$QM@<"45@x!>t 2GVJGtZѯzyfb9qb9ub9@c+A$BY d!|@,H > A$BY d!|@,H > A$BY d!|@,(cb;mr_X6'%_N35xkqέ۸ XÏvrRaEV54V5Ō؁㞓 JkMTb+wgȊ6Gd6de=Qx1<~'KWsOɝĐc,e[,\k_U6KO21`C!YMa62T4[n=6K;=%L=YSJo'L(c7VerTOwZR 9m5|!ιWh=0/^ a'vxcJLҳӜ}vzxڢ~)jp ^{ \{h&պYC{ZZ$od)?OyIZ ;&DZ>Y\dWLA0-"խP#hvq%P%6EIon0#>ȝ(?y_$9p~xH,Q&اo`R<{M>l&~IWL::WPzM+_UmжͲWa %Z!`YrG<1%FVy$xģDì>Gչ"(w-5?DDoqs'e9D hmν,͡!ikz0/+"2Ƙ1n A$BY d!|@,H > A$BY d!|@,H > A$B@p ɳo|ZXOt-e[,,mNľܱ94-PٷB>A&պ` "G׿zkPEGf<^8^E,Z`BM8< o+>pcB͢E ˖a/]N$bD{ReNA-3Y&C]= ҥ6˖L;] $hnY+0׭Cuu,0rjl;s|!hQ2ŋ]^|VЬ[gե@042{b\?ߤc͞<}ڊJq$:CˀذL qBpP~=pX1{ɚOԴB:hksI&5uLSa+ Ma"(/W$;~{KֺSIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/layout6.png0000644000015301777760000002211712321005637026212 0ustar pbusernogroup00000000000000PNG  IHDR vWsBIT|dtEXtSoftwaregnome-screenshot> IDATxy\U]zI:[wlHHMDtu^qyeyǕQ_Qu^eQ gFP@ ;NbB6uNҝcy~sOUWկro9K#""r4\qp|Y>6rzee/ [frjRf?{o==hۚ! ueb{sFPf0_w^Rfe;geK>aej)s2X ̾ S~Hot. uGr 0& OPn}DظejW^~ |Tf= Yn#::`Xd1F jd׮.oxuk!t֒E4nDtuMqG9bL}ؤ#<<X#%*GT/#nȋ? 1!#* ΢BzxllAG1jiӦ1qb;c5]رc;/ Ȅ!~z< pjqLR3Oe( "]]Yv-6m"x^]#RJH۩=mzs46FTCTcCϝ;B&4q]p]ףXCm ]" =$II4q]ϫ ŽGEAOOEr?~i:|=۷Ed0BDt|? n,@DD^$==CKMJLxyəgLJY9\ҙ~'8IȄ."<ߡX,Tq\|!.In''x_D Ճ_46⋹㎟S#B#}pȎ9pI!|쬙;TJޠ 'L䊇ׇHSj.ØR_\音q8Kq⻵94MV*'P+ X쬁z/R2 I(K~dCQM 8.a.GcρZT{mppBS `ez"6d4=R}ezK/ӐshC\B̓#"rF28 yƙ>.:l/En]B^ȐzPhҶwy>Q3qb;lW֥i:?[_DE1\ٶ I &P=Gއ.(7:-R*py%sbkof?_[8.pIdq1l|~ŴsJ[yp{;7$*W7i`*tm|o~fV&iCyo-X̬g6GMGl-'|6fn`uW/<,„lLycsܾ$qJ[{R$I! i$}rM/Os=ESפl|C^f|R! 2Lfނn5;f9>`DNH3x&I^n< sWq3$Y)8c萾RJbR&X21IBsG5r9/jb W3r5>Y&M{ m!3Xt|ODo>@=OBŐz7i09aZ|?5ZɆݼ0&@&LH-M(TI}vIoh-LV{Q*_ z`ݴJrQ+P3wuanzcnU|c˩W <}.\13dY\KJ8cRIsq>/:cr4=`o{ooyn0>t lLw;gi~>vz{Z>g9ɸQi> <@5 ">9\#_P_`Hqrck[>͛ʜt'qml ta3qXzf/LE{[]dBW1޴L?L;YR,kCknR_cjCqry*J)^\8I{w0[z)iZ;+CRF`8^m!A`T I5b?*9=?կexӹ?-SkINkpj+oc["K{s&&gx^?""pu=㥤IlO̗W 17S- ='8)u+qkWڰׇd5-Zؽ^iZ~^C=P~\t:1 8,M/MHڗ modsyӵi3&j6s*쬱\{B(+nFzSi -D#׹E|u\e@CfU;>xYd:c^=c پ}|$IpMg:Ogg'[O!կ>qDz|?8S>mf3\U)E`GjYu5̉>is]U|>q:;D⇏-jw}Hwr?<6r[?MoOTy3k!0Rϳ)y_cq"rF<' M4ҞKc`( IaJ!O = ڛܹ1cȄAw:x7{~i&ٹ]hh(381̟ևjeiZJCo_; o M!CkD;+No!}˘СǐK&U,;YbθVښ cw}\oucJSgJ!ׯ3]p3FNBqz>_ľ}>P=&PgًM/ xOD=\3& ,t;H9'jISCT)'0m3d2.ibXY<' 23POj 3fLqk==/{:`֭[8sx&RRk $:\u;BrO0%eJ ,RX14s+IL%gWsq Bl>/e Q5RMHw B9C\(q㺄ِIݫ &VaVC;N(c0d' |pMݜI M\J>nԃ*IkioP[2]?V_{ؼy a`=J5k}\hb;U'6mz4M >x8o.a.K¾})GCcnqr 4Z| h<~!}ooӦ#"r LcQPdy ~Dғ+x4*А˒ Lpr\ǩVٴ ncjG a9@~6]=}=wOڜN(:n[yjXApA8@1Tn}[0Fc"#`լذs4z ٺkVlUE<B[*O1<LF+D[zwRG_.g-0ok+vx9,iW70S&.dTi#; `֯7?}'Ms7,9-{1s$'zP] 'SH^21C?yp)H!</yQ$K:%y.71$2-LF:2ft%s0OxN*_GV6R*s˦y8^ ujI4U7ljNc~TƇ.vmX3j N:d=ߖ⡻M=84&WILiVug/}1q\!xn&aϲ>8|B//~(1^ g[(Iܵ>1x ?D?Nz`4OuTNJ:@#+|!_|!4pP;L~@/Ȝ]lK0~{J{xpٶm{IJ_7{)$Ϥ.2Aʖn>{d]oxTn|kp,ХrVϸTF(eqP g_čډ?au&7|r.%އ0o{z87Ӱx9 ']F~v ϥa侼uo ig_?"{)4; ;/#|sԱ)!1l]񍅜yǪ-4L|/_Z0[Ӿs)Knx=וӗnX|\κ 3F>݅s{o''V\./wJglQE }8^B/$LB'Iį{%i,;`9SOFwI*~fl)'cwIqb;cfsOS^NĶ;aJm}ufS !i3< A0 =OcN" k~Zk3ŏloNN㎅l&^vU =lAo2Yp\J} MxϾt4pΠz7!h'Vp;>"9Wc&=7q*_$}dBoxᐲN"WM;ӲU>0jQrlvj ƭ˦_m׀Q:ʜj 1az.g._}Iu L@3xOMQIR|/ml+?K~R:o}kMq+_iqg)~c(屻_ ] KqG[ 8f'c1sNTǿk^4ӐôΛ|+o&5k~F~{Gcdk1m9=_)7-M_w{ 4#_ vqG_#;_K[O&k\~#Ɵ.~#c7|elBmVz=b  & m-fʟO&eo$dF}$88}+o5@ZeWi:~)p\RYu%`"驣q|vZ)9>'Ɋ$ q'?}E\6[/o{Z~~ cٹ@C >Wеkm8mC{)ޗޗ*=(!|%۞}ĕ.r*C!M{3gSC^Vi>T=+5$Iy?aaH/*!S⤬yF4EDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5rE"#M9.N=~߷UnqwkS ^H"#m7A Cm9'IDATn5l7AqBjcDW&nqN'4z4ֈbı'!20:7I=fD;}a94 ;{6 +…64]h)"Ǖ 7P|9f2ljDQk++w}\r%VM9.d,&/c@=¹svK/4iȁ3g4\~9Ͻ/~?3[fZnKg\svj|9ر$\>yIqz{q6[.cfœy&d-mn9̻9ȦGx1Vn_־il"v<ӛm!&.bɤ%?{`ՁS%8,…31_ v$]]bS.Cbڝ9&p ')`8ce5e'_ƢIX-[M_(Hc;%rlxd,@KeTv i=6|=NSCr:O[cmm"rЙKEDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !F!$""(DDXkB""bBHDDQ5 !ny Μ8{^/IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/layout6-2.png0000644000015301777760000003206112321005637026350 0ustar pbusernogroup00000000000000PNG  IHDR  sBIT|dtEXtSoftwaregnome-screenshot> IDATxy\U]jN'Ngl6CA>*n㣣2>8EbD k4 dtw魺kQ՝t!7[7׫S*{uZjgy""""2v,²p,"gTcsskVd{5 `->˽FVWKDp0xUn?=Z=x@e#chwmKryO~?'=fn5_+cvqk?Ja&V{y6Rٽc٥gj0Ve]7uy~ʈF/;tnhxrF[n#eak[`8ӨP\DDDDƊ.֭߈mەxRWW;סn6mފ}'DDDDdp3N6ُ9 1&Ą[1˲U~*3*-k`5}z 8]=?oSmm8x dc:1tcL%1!a] y9`ٕ>cMqpl{׏QCT3bf7sq̨1-_`}W/Oo/׶L&p]w:O\fƌLLCx좣c;[~z8ṋ,sRJe=(ftuu+yf8c8N%>cW3i̟Vö'O}1Gy]uFC6_9{& 1ae`XCKħ{mX<>X8gƍ#B $ }lq*wbyXlGy8Yg-q"a8|=۷wOP<8>'qNr{xOqK{m""""@oo~NU&|&'ջI}>ȋ>[1 C$ .|"WIm)cl.x?p] 'W3vSrpP=▅9z2f9T \wlܾJ.C,'N߽[==L,9{jP30Ѳ,|#s晧qʜ0 )J7`P/X,ƢEs`1\(WAײx\6m /$>o1q Q X6Tk (+e\ `E=r?Pq)+xҾD:E6TFvHRdS. %3"8qqS 2 2ۮ'sh& 4exRtq/PhO7ߺLjfeywMI0%6DڦXy|KMfRm vʊm#v)z2£R 6%R}=@[1?n&1\]IhJVz8gB ضKLjDP *mG -ɅaHs$l%f(+ =٣1<ò*5er3[[`9;b r܉I9vصwl&)Yqj˧W8FN|_?_<[xr/fAw;/&dʕ̗\= buz=O|'m8 ga-Ǿa68qXkZ>wօ$ɍ 7?) XOr8 N+]AmL];y'E.N彗4e^7Q`UO?0q?ͫgsқNG mw^M_ 䳧bUJQqt񷈈(i >ksj<<8n~b%:s! =;v,78V8lY+V<ח>&|<CʨdD986Ig)l68e$21k:av=4NhX?tυ ?-w>Zęq3J;~68K81 f]뭟Lm1ň[/0LC'`["""cBSն6-HŶyc ww_>2326>e igRO1Ԗes9gk00߱P((cRmUp[f' C°rwRTՌaXNb; r0^ :uOƆ/ҥ27/?yJ;LXiU|9:x?ж˔ϰw 0w m"8E_ȧ '$ *|k{}}u/^z*&̹ v ,ss1l++vj۶좦&S9%kc; ˲SpZ0  }?c nmv6)=$y>r=Y[i_АP&HȆx_硟`Nj⌓'pB$MO[ ڪϑ%$w<"OX>lz\\DDd̈~Uux*mҩ4Y:yvmUS'.yf y~ϸĬ2O_Q}M1ظQڐ"""cES~`c9)MiN281QAǎch!,׍cG' Ǔ*8Xi1 0ae4qGg]Y 'p;l7uhuLe9cG LAг?F ȷ5tq(1EC߫,1NS!֢N3xl[!u^/_h#geyc1znU^' ^LuԌ]mW^Yc l'4Yfbٕ]멼^XYҶXꫀX6Aτ eJ~"iիOEGܦ["Ir "DEP*/p2չO$I_e$y=J倠6XL<OX< !Ⱦ 8n$lꨯ'fq/:[شmwA\I@p`p+Dؽ@5>꯼ W\AjT6ulggog֕W|.Ng9V:Ր}&']o wl;Y2/~ɴr 6W^YWL`Mz{{Yn6lxokPk r@ HvwcOqo7>u#k5Ѡ>|DnȚ51ætw2}!`˖-r9jjjm}köm$X^bUM?^e\b5W1Fl9, c 5WSZWw5&;22L̰w5+֯`ŊW`L}k˜ WװbENl&JvdܴŦʻƍy2eXTF8u̖cUލ!O(#"OqcqacYx|%8<ٷ$JkR&#υ־Vhu@{@qIZ[ 晉D"AxDnw2\*}Cȳn}s]wFF8MxH$))hA+E(jnb[`Tp\>m\v#d*Z"\֝dh߫ )r|_QFݟ?Qup#2J@_e&Cd+*Qxd!Є‰z寑eHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$Gvg """"s(8Ⱦ)8H$` """"FEDDD$ʩjvq}GDsEDDD$-#""""(8H$(""""ZGDDDDr<""""8H$(""""hGDEDDD$JptEDDD98H9ZQDDDD^hG@LjH$ZQDDDD":""""HW#""""xDDDD$ quq.HD(""""Tr<""""(D8.h7BDDDD:(8H$ """rج{|9̯W#?8z7ta=+>v)a|҄)~daKvnĿ>wH7PʬJt%9R5iM» q۾ʳ|GX5|h%+.RGHg*p| 'NJ_۾>U^{ IKkievv2#F9`}/sM7q7O`=tތo{򚽛yB_w9 &; V:Cޱ#5Yi3`cBhmeK(Sopp0$ilE]M>Ŀ_@r;̢Գ26 0̚bK}Wg J7S-c s}>Ig69y,5=> tmΥ=_Fr LLf͚5smł /7W]xj l t,=%Vs0 ^YZydK$8*rc f|_ YN+ϼk|sL'Ìt%~u-y,f'zYAw{LO0ɓ9.5pbc7C: yn`)I:-937v;-:sD1VȜEe&lsydee q%efuY3L9f7.:NKcklV=`ZkW2}9VÌi>' [lQ-D?:c'GJjI}|MmMiWekac\ ?ń8@Gv4\߾BY'mܰ .lEJ2nJ3u1Ӳ/li>WNkVuYi&<6ʦ% 39ff1GfpJ>0X8/lx ۚA_?7eL}#ބa0Ӧb܉I)_ Ugې2⭗`4& &7(L"e?z?I7Mh_yrro}yIG;rj_b3ٟ_kVAqli TtKSm?>~s׬2͟K/49g[X$9WEGb\*EJ:Ǚ^.c8. }6L-p^vue١&`Wl~~8gIyHe,޶bHd n&g,5S پʥ]m=?rPK]:go{)dζg2Ky-N"`y|dOgwVG:M7Wm 9jn^*P =?cs.=ͧƂﺙZ֤]t>2q#zG羅e^fp\33IWb=H&ת)`( \{6[Zw}.!/e=t-~^ L7cOz=PٰЂ& "쾙r=+gy gqcOg_ 7nk<V~|lSnU,{К=g=  O%?ٷw=E\[,f#6_s>S,+%>"rOs7,ܙbEIDAT ,!t>pw}w {qlS ?݋,ys͓ q\agn?|ɳJ˳\#!ꁿ/sv Ci)_v ]Ca݃1ӹlL&I4-h+S[Y2qI4V-'\?Y:%6+~x2-;pn1PRh1s?>1wo?!/_ɚy8FRs#0ǟGаg$e/[WcM_Hz,fjCc&4jOzn3s!a{m2cqj5s/g%\ɝgco۷L5~hu Ucoݔ7/#5ם%78~mˊ,[VfCy]g-1J l&9ao2 Gx.FLy˟[Cw?%4\q-aaKefw2K0ޭKM?E6iэ>-)S}6rG$ZKൽrGO6gCc+2޵/K/Gcm&wlj&5 }^r@#?HܕYkalBr=76g5 0'\ 0v.-OԒ~spW_E~H܍WgQv5S7_Z@}˗~K{⽏V_f'W\Sw+7!E],'MY-ĞWԝ׮vn;Qwn.ݘ佟H1έ7Ɓ4ߺskÛE\9\ę9 $vK%9jv>W=&o룬m' '2&ލ+ymug-ܸ OPv,?QX %jقpef7c0`q;簋欅X~vhTg,c''b緰.cWэ{?k%CP̋ۦpv,c3l/y_#_.IyJ&foqZ<~]=]:_wx񅀣;<"?ˣcUY69t W!tx;03nw6 sx酐tΟ9 仿h \nv`[7|= 7U? x̐qNj{#B<#뢧l(NefeWsO7}~U09bܩV=KI̟]˾z&WZJmJG ̝@ߋv=ǎNc8bGo[(?ʯ9}-GS|05C֞Cݷ"f\9z_n{#M0Lʈh}[|[WrmŶ2'k^Ks{OXOY1C;DH0K ϥA\s8>ۇt'N!]-b1Ώ<I#Eiw]|m\[Wf|^;Gz~Br[|)ݦsfln.i/ls@-7g; ޣ\L|w׾d^t9wɃ?Xƿeqs5X=a߽s'WF-(%Zʜi'7rn?Yz/z+o}wg-pN=).ؖ5z vcqۏ̒~[G-"kX1LcЃ{8HXڱ Bu[21,W`Pf˫R; J%Xj]>uLq[#Y1C)sen;SLL(Z,W#~Z$jz)+?سYv0&JCm'H{ !>Lr&^`ֆnaC2a!RM6.s kæ.mH%!(IEze3lҞM\C²(z;,]d&Lhm6l LmL:!.^NRУTdr`n醴eI:q5'k8RޒE2&|xKnl6S& um\׮RuٽmYx~g?#mZ7 q-ػO =ߵa] =x͋M%ʑxW4}[ -q(xC_t#vYqaiiQM(B٢Yv\A3mX$΄ 쳆u,tՖC&c93ओ,N=8a||]]x|>O?}}})eYK&!NfI|Aum?2ow >`zz0mmىU,tuayLa$^rmd+ũ$P_؈ [C[b'EHW|9O+ T}sl۲IƒdYRu$$z{=6Cg']]X4!ocaېLZduuɤ-rؾy,A@c$%˪ܑȶm!cYSY=Gi+rPrDnKzP9rʡ=uP KDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$GDQDDDD"QpHEDDD$Οx!""""s?^8IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/layout2.png0000644000015301777760000002534312321005637026212 0ustar pbusernogroup00000000000000PNG  IHDR sBIT|dtEXtSoftwaregnome-screenshot> IDATxy\UϹU$;f#!$BLQ2ǟ228>20<3 PQA $@BNVݵNwtIz=T~,q \y"""o1T6xC<<N--Cv4d=2|9LY8–fɑeFM͈?+<ġ9ԳߨCmQFSÖ5h˃~<aqC58C~36y7l1{mu-lwmHό(+uͪA%ϡێ\Cn;~oaJowaޏ#UHoӠa,SA^zecpx駟Ƅ EDDdm8S /~%""@ggwM'^DDXs]oQ__`AD6Fϱa3_oKeԿngFku08!x^QD6†!ahNk\rrZ["k6C0$""kq. ƩLX0V'm4r<u#}Aɐvǻ>""Z>bOjan)awعJ:aeP~@\fLBc$&Lh}sg+[n%L%J=+L (ʴpI'0a|.^|EvA*d׭@<*/%x9 fֲMoBA%"̪3NQml%"eI/\ E(88qi͗WϱH&$ ^È0p0_׊R8!g? S!ryL%]ʩqyq}?$uW>z#]c`Gw͉k٘l_'T*~n=uWKx!6\fY6TOcD"ʕs*sTQQ.8Mg8P+D"U+ye!Q.-P5LQKؐB@;^t|ʡd8\ r|oKːr,~HoUP,YCDHo'j2nuoxdeAײh=)k!|.h2wvWfogAcv`M}.-a\LʸLB:ՕQ oT9~@&SC˴n'& frl/"_ùrX" y e1 bSMwšu9kOgjCKOu2̕R͌t2=pJslΗ[_Qp1r N s/|?}Rf6nGq(&giLOaKևv0DI^rJDjHnc?Y=9CM.vZ2kY૿iϖΤ9]&]q< bjT aRC4wTkDQDKTv"a!CZZ)+zoV/+|ǘʱOkaW1Y>q͹7H4E"gԳ'1l$.U% 4q;>)nx>S˹0@N{9äI ~_ŷUoaeD~euKF k|k,J冧DQ='a-:$sX0W-)r{SorIŔ=nđCH>lp>|tv?r&L7QOQ2=! ʪ($R.*G?~N]0 [SSY($R.Q(/ !5rt1sTXw&y_l%?_A;t?m?S7?_•'%Yb:/~:S K5s{nKX.l;×NIQWvªj[㮗C _$u?~whRo—,Κ(՟yrLE"r~DuB Z˖/G6ޕY'`_cHG@O).3ư~<ʕ JDrĨBsJos*U-g ])Of@Y~ni1gp /ƙ&pM/l&찐¸O;p?>K~{y|WwfJ=~`+^}K- @ 7yr'Lz03lc7 DEG)9JF=[OD*\8Z]3{n=!_(VJ9"Vq8O "[=*PݶX,aLuQs FZZEQTETFfY ! q,a9:.o ˿K.⢵'3ӖÿSnl1ϱ{݃袞8# Xu2(ud-y%F=܇8" ݈(^^ M=|trNNs̫K/K8}Imm288V h1===r**XjDQTwUoaC>=9Ѿ4קy%^W~aPet\sl]ydj3/]lb^[WL㑭K>GǸg/uh==ŎO~hd"zY82Pck1܎g'6 վUvvro@2Qyݻl6C8Thoo'z#Sv {_CD(c%ᴭNggΙd&1}yyqǒO|3Sbn>)!y=x ez=߻'t8͕_x[>ZY_w[)7GÎ?mp"Dp_ZvyKteZ2!A{91 !8$O-]rAIJ1;𭌶z1nبKIgG5590 B˒%Nu2EU_c }}ۻL(~>4C27HeS0@oj1LӋY9gw)L{O>}dS߸v֝u \[`>C7߼[;לœ &${ mK}^ĆÕc QeVqM&Gp](h{:,E%6 nʒHTE\&"N@ |[K&#=opI?G:NG,GDWuK%Rqey"L=Z''rx1HP!~LT"1J/1RSfǎr9rY48XQ,ۛ'LH&0C2l߾:,T c){&JL$ryyu̪3N7i^q<}($,cpD"A;vn!rAe{7jcC~@!ʊ@q~wݵ;`Æ,0 H. ,]^{%l%K.l^:3*og]wqD6U#3rlg&\v/̌l߷~}w>}'vmJ4DJlYL]eK/7\ʌJ::|ne77Kk4mLoolݺ~t9zoi4X#4Ao/׳{Vn}p#pc7j[I*rk=[Jw(̙ӯmnӰ]2dka,˔xLۼzkbdJ|.Y<͏f36mŖ |YxG*~ׯ/iS-fQˑͲiS-חxݴj12"dv&J׳4Գ B-94l޶m.| (9_öm!.ۨb Tm@N3rxNl!7ҴҦ#hES2:.󋈎yi&?(~lqki")|c]Arm_Si3/c/b{k;xyf58?]y6UwlfZ?}U!ei^D^>=,=#ݥ 4o\6wUv&$?iO^L167U>7һ1o3ϘwvLנm|(js+(,i0ѩ9 7PA72`sEg]:A+~D罃c\?4o+fMUe&{ņJ[|.̜˯W[L弔L)̞d =~$Y39aSJuo 矋Ųw'vﭗP[_u5w\i7Խ[9N.mg[P7/%j(җs>y3Wnf-枋.܀ocH%¯qo۱ab&Cƾ}#fxI̛7UI„~HNe9gi#>Np5I,XYˣ)˓W52Fm8}ay'_Y9aE-x|IP>nxZs\~ucȑl̢d-3vYvgOo.洕dW^J\uSϢfZRUGsWfy*S6n}a*K֭m0 j3D6i)NNn:jL<ǂ=a1Qgkh,9SpffvNynjj7Q_̂B[i3A<Փr;m^5n3'N̾g3, Nmu||?=^s}KY2D>N3[^ppR#Hm5 >I %m8^0T7 gBh[|rh[nN5|.;ߞ?l> /Z^zC& [#""Hw"L_ R7g}ҕ @{4. n܏˒''Cg-0mfKVFEADKV3qK2's%|B&۹dG|JN ~p$>8=G[K$Z]{'By .{63]~"L:g1j5[ iIDAT#lYUɇD ;֝͘{ͥU;pNxf;gp.Řy|_:)dS_]' o3K ,w{sv~ \&M_̾fC{7Pm35|1i+VBS"rus燔Kqs\)`I~hi),7~-ŞFK3xCo|^pv5Z K?Yu*Ɲimô,'<[7h4xg'\iؚlID'տ=}'Gl;Nk?46`~~-^M=mj\j sQswObݙFr'd«o3=[;s?aO֗o[i3sO$psSiiLߧTO5Pܐeښ,_}_-pc}DMM_Ln<A4r4- ݖ]@C)3 ? '~_woJ|7@$w)?rfWȮ:]z}A7H!CGm*G.v?N0hf7퇮 u\rHm/~>|]*0߾W|-]ϭQaL󏿃7߀ڡĈph34MGmrJ]7m,^7e:bKs|wu>q>v5w]΁t eRрCCq˚Ɛ)PYɱd,P^[`cYRP',',)!X.w87SYѸkxWe\(XmئfDT߅,(#APT柢F"N`x~NRJ @jAeMʢva1 ҮK) ei.dJP.XZMjM% դ2N HSj}°4I8N3t8ǏT8IEP,K6.oփj#CoCa0x mrP<\},vy^= |g}L6a_+ΰ6C2,CGD/\aJ>a}{p +2l)CLgҡ3QyGE% C9+ED5M!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[ )-ĖBJDDbK!%""RHHl)DD$R""[151] 98rxNR )T`Hw58bR)RP"U1@29uL$$1Hzs˹Z9r..G\:2TLp9^&ȨD'21X@ r$&f&Ր>\7 5#ӧL'p]a8U \Ogz%4j3rxu^7 pȚC,pp, lnq lnYSМU#k6`RW'XʒNGZ1t:b* WcW"JǻZcQ:]լ>a5f"ȡ4fb p߹k\zKWWDkKAcry>W\bEĔz.VL4Uuu睇s$W`rSthͷR fddpW,W?wbիLfMOO[lq5h%pBҥ],p{$W&q5sYc O|w=͖-]}'DO`ԥ,ӧ΂ݾO=CwenKGΐ|R,ZЎku !344Ӗ PW7rnс) ;;RJqIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/layout7.png0000644000015301777760000002534312321005637026217 0ustar pbusernogroup00000000000000PNG  IHDR vsBIT|dtEXtSoftwaregnome-screenshot> IDATxyxGoWw[-_o9|pĉ,@X, Dz@v`02dIef #$vrBNرG-Yj߫nɲ%[r-aԦDQ̜\z[~z.^{ےϫ' _r}/lKq CTW\ $|3\/#>=4˹֟1hK ȁ0M!B>uB]joߋo35IS0d+627 Ωc8S㎻^E8T*c>+V3TK R78.^؄JB%JI;O>0ĵ0`B& 6ϧR Xj( "ECJ8PzrMJy19q 5c#"20Qd `@ȎJP5|RnjR(q3; Tq&gC=˼8I(Phsf'۷n#p(aƌF=pw.!zmۆgv2R8ys|{ĔwlGS4.sYtqmxaqZgT-]--z-}Ŝ2#Fφ_}ՉO:`譼ghj_ I wW,gn!,m'PM?y.IGkDֱgwo%h0T'쯞F؍p'Z %#V |OnbMO/=ş.Ì|LES ܲx$qJGgJ$I! +}4]-IBg z=^v;!"kN6wm>ȡBK4 I>uY{Ԉ)Yv\ 5V`C"< ^7I[i}Əpݓȑ$;O+9@{S& TR2 ]ոI6Zw|qY;SM(%8jǪi+KX@g4 7y+!LG)2mR_[3;& ,GZɗ.^?_uL/i_7i0X MYiBX$ k8vISlj4X,^uT*$qwBSy~-@K%❯<[_hi;iE]rӆi~{!˯<ևfw+zA/:jQϽANOPidH{sbsZƷ{w2K]Ľlk 4깥%ÍVzh>S]R[(i( D1=OJwLjK[S[9+f7= 'omM툰øQyW/.{N~[xhswީ3v.% k˘@'o7xz'ͤͱ{gf7< &Ql/& YOʖs'"Gqc:>WK =?{27?;ʢ`q8+S2P1]t<ݠJBj뽹@e4NphK 4%MWijq'$Е^0& $a2x~\ | { t)ξ}:7pcE-~&c[f)̴Ygd%&3z\qaD0&8.UY⦤I7\__}\ȉ8/ݲP-pgc:Cwwp0009srC?85꩟{wo4M7]2dq41˽CqHwc;KѴ Ny%)@SsB|R<}:nHgu >r^3'3|1Mȯ>tGoG7x{qwyP=6!b(n ]ts4IId>lQǸ֥Yq0pQcLz a'P1XsrX{|phד.%C=$(>xpk) ^thODD/Dc8_T.""21EDD^.~aL 룼z5ի)?$v )IUl@z0W9Fq]65ᶶtvR\I'|:;KmJWwOlxy'w˽MtkE2i?vb]K4>7}7Oܮ.t" 4e=g=)Ҵ"2؂⧫O=x7VyjR00@nɛV"-kְj*vƍ4z݉F.0eVV=vNp2Pƾ`mB~B[%rlh= K΃-[FywkN(kNHp`w{OꄶGXa]&"njj\Ϸ*0ȶSj}cFvq9R[7]yODD2Oa'""S؉H)DD$v""y ;t9MG!Kқĵs[\:>G' .gމ;i2ٮv=h!=41squ=Ef*׿x'rhN;Ojk9c9pKK8{aSw/0f.gRe;KaֿOn>.pBt^S1$bOx]8$@qɫ_A23ƹ6d2ӖΞ qnw$/$`M\ v.k|?%خ04`L{-Nf6.ɐqb(<=OKxh?{'OWO;S2=pu~-fҹ\:$ړwOTBTϦOa/]B7 \8~= ~R>n~98C\}(qYɻVGcHK=I|Nh/z_C<, =mP0gTqyS,=D Or"2Γ[׳9-{!szq^xqؾs;S4Ji`n) xG{aRq;sd˚/PapOMrƷљ--ʷw'V'1'R HpŰ|z=9o "!C'VcW~ 9oITh wa|r"G\7o9a;y{~=ukg+_#9m-0c%K泸G+E)M%fM^ڵ͘]_}yr\o:Og?R:n|Xgw8Ƨǵ7ۨ~v2ɭx Enҷx/a1?M57X _|B{]Izd}QbWQoU<-Vq~3gu#|?2q ͗g`-#_a{&IF}LĩSضm5;e`廽ў"\Nio:~5 NKwyؘ|͛.-' Á餥m&*MN-a+;qy} V!j֘v*u}jr7n55Y~8Sy"~b=&B{;EplVmr3ٍ=Q'GRFYCR\7okT} 's8¡}ʡv'|Y=êVz6RS>U};}; $bϫBo{̆XomFF{}hE+$Iu?dIڰ\HeD8jnhXDD2Oa'""S؉H)DD$v""y ;ɼvdD7A䘦dNDD2Oa'""S؉H)DD$v""y ;"h \V}RJtʼs$ xlw>.kvx"x(kEL1̝CK9m}X*겤tHϮyt6cZXsa[ B;1~1ORjGX,S1~쳹C>dƨpЧL1/T6T]{'`՞=&egӗsD=o]zS;C91NgM5ŎB v{Ӝ+Kܰǒ8Z:3?qD\;l`mx2W4f~Qch )W\Ĝ=_>6$pR< Z˜80˃1ĉXZHMSI 59؝ 9 ohO}!ʹ\ytbk]#c,^[V-X ז1<5"cUp-q-1Dawb!33ۓz[kKw2v}""G+P* p)`Y,Šʅ-U 7\j1'\%%L}xD> :1M8Bo[ve ƍ|_ k̪xhg+yMKęU˝z[ }#vX{Ǹ-"2vc<_8T,nBӨ料-krS?W a)8oWֲa m9. MRK 'fﮡg,9?8?]FESBLc;㆜QK |cmWJ:,xNJV/)f|8bG!Ga7n5o?5ƒw(u%ؽڐ:qm!-l۾!Ts4z˾u86""Ka2(q'ט&EDa |P̠6vAcS؉H)DD$v""y ;#' "nj]Ld[D)-n1#҄6FX2eD7AQ޳uD7E$fgxbvʕ+H mHE^<羗\D7I$nWrJ<`R«& CN1H.$j ^Fn͍<N$[Z.{ W/KYag<`JSI.~+c><3-yG:}:v"gb>܊8ZyYaɌ% IDATxyuW-[Y:B:$$! !ۈ2wu2θ::uDsOA!3* E` {,ts;%.:#N=tuuO}Uu,P+!""2R{˲,*_-\,hYqq9X^d 6Z#h͐mmPc?1 SӰ 1[ Xôqkmz9vãczjq6,`%2!s6_ePϘc\idߨ gCwcF#(wq_i3?36Ga ZmÐ+u`vb倱\2/c„؅mY~RjǺ.y8=Gr,""r"]~2jkk0#dCd"LT<>1XWCy먴cw DZ, ۶GDDN^mm .!2&} Cӷv qHƘr1!Q] qH$p02)kb;mp > II9c]qO>Bmd̮fjU<;:xloL*uA}P9bٳ>ILPG{{ػ;v<܄[>R_%;wu&P]UE.0[neϞ=$=Sރ!=-^ʂ|AN(dDfZTWW1((|&{6_\((Dmmc͹"s>z|D"eW3qbaQ`.Sjk6>^"1>cr*NB ϡC<ȣ|Ω0Ƨ,>g7}oHQ8jyr'6Dte HkS_\g9n$ A\uZ"˕qZJXE*ӟ>Hnۮ!pUk `z~kꪫO~J), DZOv=?7#@DTuBCd&/qmcD*Lن["K%V_ c=AewIJ,'Xb)?/qLEE.2l=H$Xjy_?/.`"JzIj&$˓# YERhi3.Ǫ ,uʯvTդIPǏÎTڬED@w'04U)2g5FvHT#C4dbz;:8SPgA}UI| Uu\3ZK8LH*'3Т({{2!tJ?`ȟa5ρp͉NCEs.s];~W,9k k-\4iu)l ];7Я;} .h@~?O؊I6nk.缆";w&z,/{oy2&'?*n(9z+oz -J}wGYoʦLMb~66x|cpd] 0#k!' ;/m͇ϟƂtͼgLR6Aw'MNyl% "5N#!^GQ8}H r?/]A<>U^֌kwPzrJ)'TM:E"ikYt\)[ճ^f_धruv}۞>Rn5̷ <|4&z#B1 ߿r[&{(6g|jm= ?5&۞(E,|Y4Vj,Fɉgmj8_ g<P)bDdhZXDa)E,RG_//y:q_{ Nv(dF6M峿lRX^Z0 f2 dYJQ}AkH ]h(\[%n}E[/gѲn.J _onq8Ol%pƘ1v X۸[y@NCX^x`'ɀRc3-2Op;R 9Gmu_\xmX{qy硓Dd(#Lg QAΩyE|ѧxŜtֲHE~JT9w(˲,6nͰ^bYk)ȔoU~s0&pf/ 3<~sp;yv?\4uoHfp"3(`hkYW7~ˬ'2壖|O*m "Ufӏ("w (,c)Oʇ>A€Rп.pH'?׽\^]UD}785X3zq1%u=O=,CpdMqŲ_"2x `w8׉Q ]^\}1_F?5 l+\rm۴wP]-6===x N,J?c+;(*t[AX"k?bMԺ,!%Rw$Nv\_d\$Y"LngߛotZ_8naZ+O_%[n91AOŎÇDu9t l0 ێvd/,s]p!)_C AEMmrle#?yռmn-kv.xđkju.>WrKlg+z4hk VsOh' 7~Qq]Q]o K*ح-jq"Ddh#" BCKpõ5>3,((јo%8Ĝ0/" r 9u=ک4(UN}"\(F!&*wN&S~p8ve<E壚|۲P+l(g};W]8L:Pͤ/ʃoײbO[g@s3=<_!Ϸp۾7r勘Y1yZ-g5qք +$;-CO>guSE:V?& Zr[u~L}+vtZ >RM!%(/' ~DE̙3;%<1`6QhغK$m:L,|ud?Ekkl Ŷm ۱^(KeZ=BW /"J!IX W4xd+sa@̦Hӓz3вIx.deOV~ ;M;O,Ky\ LHQ52dM!J] ϣ i !D[[`;ʂ.r7߼3Pܱ!\P!frlfqf {9%K&M:5Į]3'Zv`? F+VM~3M/+]OP lyhμmVTdkCH\E  X̛u WODw~Fl7ǹ1αmσ@/) D]O/L,jCP%4X_@em ;xKf}eӦ¾/ᚑQT- #I].x?FvD@OPɏ{{q6g[ жj 8mio9ILt5&:]zl_OjX;}A3fYq^N\[u?-eKަ${:[v9kX.4kãu?SxV~vr%^]f%۝'D8ILҮ9. t?B 6-!o`;|D~+I\F$|zj;i";IepkgKdX]<4ݱyw)_049>1鷼e{-| q_9s5[W_^>ĄݼXXtwgAK];?̏{Ky[ٿ#\pJ>; yb OƖFʎf`q穈\*k*c"=<Ӊ9anŪ3lv `^;SÌgCG&Wsuf?e\bVe9|h[j&3qkdm&4e2>ϠΙI.7K"uD G$ϳ{!/(BwGO>Ps=śoUu9d"|B R7s?:/Iuxg=݁7dbCɪƳ*Dyz";xswI23q;$$HY__''4^ 9IDAT|;Б1%p0Gn m{{ ο$}(OOm\' 4E)'Bwt''`l&8Ս)|[lm5 q~?{g<#%_s#6 *4D6Y-2 /-8s`݄ L&8hԓ__Xߌ݇w]A oדx_~!9f̥LdX͆?n8ÅKex9/OD -/=v;w7Lnn{ u~yᷟ枞:X5t Q#q)ĪLԷHǟPwFo~C1~^2qf@dwEG0D$6-^EbK&qQԝ~ 6܇xS׸s}<{iHh,ƒ=`LDaoLq1inl8U YNrof=zk@Fw|`Տu-iZyE7֥\*A?r Xڱ-B4)uPw~!G"V Jr=HgzDP Rn64{4.e,;I ( '1i$=A&`9LN$CstWvU"V~_GƁRP.3(pG= Q~˨1QA[ƞ!'0-=E:Lb0qsCՃC$H,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" V̼hZw""C\:N[Zw""CI$_,;7eDDfTU9c]iKNDdh6ĉVrZ*NDDf ƺӎ̘1Ul l±`S zuU F*XʰzubK9% zp5ԘWScnpXP ŅłW{LfMcOow~!5yfȒ%K;,XBKaI,,q;pUv(,::Br9C`"q8]^/UUuuÄ 0uEMEDX܁ yj2)TDDFJ@H,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B#""PH,0"" B3lFeXW!mh8 ,Td$XW!m(`F|o(r,&Ǻ 9EmC3ƦM<m6Bq'r\x!K/e+^7z0Jp,̝*ho*;:0P(„ڡ,rL"aRPS=e Δ)Gw,fPʙ+iͷwU被EDabN9;YK::YMul"K} IDATx{]U}{ۜ3LL!{K*R4>xCEEx)V*JQy4rJAHeL2ۙ9}Yd2!WfY{I曵`)bŊS+߂1c(n0ZqZ) yehC^4GخͰm{m7#s?'f@W8av=B[3һfȷx}_R#iWjsfП{0y+9l#)`_GtJlߚ=L3l_Whibvw_j$Jmо^hen]#lv++wb#|sS5߬0=ÇmWK/cc sXN;jZDDd wuv)֩-vX%""2DGG';v9ḈXr]Na„MLZKd#lT=>c+n)](n ۙa ۏwu08Έ3aB &6} Ck\xAZ[%k6C0$""kq. )]6֖/~p\qW~ާDIw_ZKZ/p&Oj2)fsl] -$ <QEfΜɴiMOkW ۶m#żH#.L (4551{Qɐf_dΝ$qpR"Њ q.^؃'<[]9Z(Xwҙ h$QQ"`lk !xߋO,U80È( p-M86>Xl>p+ihB m͏>[TAm""@ww#.p|R}Cm74en3ڊLD27Q,H~@*UEӴ&m% F2t7p~?xh/E'?=oԏߒ5S8\yәZS{!7=kLe*6wʯ[ј, z8krp04\.GjGE}Jc(hj,aHSS#|M=-C})k&v>i7 ;|R I3Xt  ,zly-8ǿK/m8l87> }\55vZL1ib\Dh#_W|mhـ0Vw%>vd9uOqyh 4r(Nb,VL˵|ckD·W"KDFGyxqCH^lpJ-*r\:lCtLQw;Q2=" ($NS,J{輸va*-lN)OCՍQ|\qn=P؛?|dN_6~[,_oN (ǹfYptܧ_$"gtn5i \ _y'AMغ[޵s!SVo6Kߺ Ol{hx~Kfٙ3p„3ϣqQDFÑ/(/r~DSsEF޵b1 ]nk AE}Swq+Vҿm"c'r uiV>(sC,32,K<& ne~|$1\ [av UX}׳r-r~( S^ ᖫGQDQ(ʣ#?Y--}'rnÀbp\%,}/p%m|E\z!3Oy+:e?1:lpg){6pI/B3%X9~\|OkuSlγҨի0Qd3̭/f 8UAuu488WƢ1~J 2:;XrDQT|tG>AXǐv?bCXHcz.8*֭ؠ*?g/榿>tW{]4d7* |*ЉlWc||>zL'o0%~^H{qSAhcj|((Ҕ UرQoTֲ!ɔ~{^ک4D6dƟ_̊>\9Lgj ];C_K*ׯڳq\M fHzsC;U#fB{'p)0CKJ@Ӂ"2jOx-ˆZz~8^.=ib~Qĉ'}ӛf=C</8OP`˖hjj$J Y}<^ 85x{?6~P,,tscDaDC>W뵰O6>̳EDAxtScB\#J XpdGHGqDK"G8a~q12}RJߧW}JI{Oks7W=%(""2^Ӕh}qn6۴Rض ~l(dž!DGd8uqILؤI$f$hy̛W] +Ovs;v﮻hNI0 H./ֳ DDon/Bt{i%K2&_z)3oog﷾E-0Zk9yfnFŴʁձaBZDDdx@$[Zػ~=噾Bs3՛7+DDd\0@Z7o ݾlVa%""YہڳXV%""2$r`yZd!""G)X6zDDDFԗQ۫űEDDdd*Ve)"""#+gT)p,KY9JxU(}TTTTTTTTTTTTTTTTTTTTT{f]Iί. #GFDKuj4=r9m WXrIYX/*}{(sQ#u<`N{3ىf*w?@/Va((2xu "c< 99܍{J7-#pQlO~z'; Zf<³DTݍq_I)n qDK1hb"/Xu]ǿÏR{ߓK/̤7{+$g:w`,/cUS=K»;dWOB;`35P*i'vH1ɉ\Q`n%h)˨[MoYKղ5N>~k]޻SV^qn"s͙O>9Iw gٕyizR%}uxݛ_K s-8{Fgy ,!Io{a*KJ/nߌp1Q݀QynӸ;3wf?PM42M8 -xrPEFP3h | 1 [aڇyE~E$6g~U 'WAU>_ͶMI~?aT5,:DVX;`ͬiم ]Jmfew<;Vgp.ŘMy  >kX"ei9Iؚ)D{v>A0[UmM4{kwE w׈ǘZOo#~?㿇y}q]GװXg:fS|h#=["O į/~9ǟg< O(oe!t a( nS#v\gq:9Du<:r6Du1zk4S{X#2:$\(_+nb؆F P@4!9Q,Zt!""AaHE}X""R]DD*i%""ղviхZt!""AaHEP`HE(88c]oYRPDD'yDbI$JǸ3p31EDDd$}UaMH4Ո #8 ]DDƙuatXcZ`ac#@9bVaW$J&Ǵ0>Q2]تU@9 [f fL 55k[G|B<(ݔ_pds΁'>4̘֭-""w4 '`.qO; w[?$xKbgƞwcyŽl6!a8V#""#-=$L7:LCfЌ!duilڻgw<˶m'ϒQHd^DD^;8K2$0)33Y4cy̋ͣ:U߾?v_ŝOK߷"Pڀ͐E%Sp˸M2~Pvط[h-:pїf=|W(ֆ7~zZl܎i""rs,-oZ^mlތ)DDd|14okʁ{;Yhd޽(֞= ^9(VߩE""28匢S ?/bXbDDDFҗQ@cZH2(""S_F9(""V_FimTTTTTTTTTTTTTTTTTTTTTs+]Ҭ:&7^_\w+ioZLy]~='K&j3B6|Y?Y9vos,Ig1щh>;I;ʅxdzt, ];)Pf晝lɗ޾Y=>=?cFLDkj3,&0?ۻdfkf`_85LUU=/5ǽىn6m{ۻˉ7p|U \Ƣ.0i߿2ЛVc^}js*scwX"[v>X,7mez :Vf36wr}lYjkfXzәy=pՖ}+ Bj Xy?D/*U9?V)&Rs{h G숌 , 꼕˿}C[N鵜dȚ S3?^GvծW|d-Df>lWkXbaoegr{~p P?\{|+ #X"HO93Ryc*k^Lqb')A<՝z\Z.~Ӻ䴆P͉&ֺV Qyl{9_JdN>epE*KdR4ps=![۷ 0ʓ "^)"0nbH+Kp\CN*aR +rorQz޳^S?.ygÅ=AhE*Ky~cqs.8}R>=;dSw}9qF+ ./mڅ͕GQsdҖ?gh{y]вv9ut!W dSS?¾{ukדUQ͒ y{䛻oq/̾T--/MO#7q,(dS4VMa1oϋ_N6xF Lʽt E<X=jSDH4%n24LKu<_s8r S,エ5w>l{]wnbZDFt]0O?!bԤNTQfOXHya+apq[ WN-$H0Z O>8a&!2 IDATۆ-7՝?4’cAא! ^in}r>,ag`3G5h@zov~ 8F%""S_F9i1"""#( %ƴecZH2$2cZH2vLʖ3r`Mk1IDDd0׺Lk4Ǵ(Ӎ̟2(֪VrJnrL tU'ʁi!떮cͬ5kƴ@x kfau,lZVəɜ$O~[{ƴh96ciNpK.e647qI/iK]?N<|; OGl1Kو0 `DDu\㐌%3ԦjIzIu4dI:w3iSgm _M6G%FxDDuqu ɤC&2iR3,Za޼yTW;v}yg;7FI@p9`w3#""[}7G@.=,Ypeu\zdfHjoַr-=LZ DDDFA#==l۶SiÆ֯ii9kh%""czZZ_ŋ;<_ss͛V""2NMys5X۷dU(DDd0dUl^ztg )""2$UN-+gT9y}O}cZȈ2,EDDdd}z[}r3A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%""A%gVmKGL^37>ڕD\~OY}ts~mݩzlmiң]c=@=|I;ʅRR3.[:Ko;BbOy&p/;Sf/.@d<&b"=ylcr&5sO<`bo9餐,AO%s>64/Ar#dչ<2󸀓D?d ]wUFň}T7NW8'GdP`>s a ?g]oy&Մ|oܽn"WЁ9n}.۠/|ѡ7mt%_19t"#}j{nSk,51;~,+vqߴ s֦-07y*)A ږE;w+?rܿԱpD^Zϟox/'_r{Y~$毨 /g,Sϵq!~bhp9j6t{|IV^n7 W\}tNȸFgԻ⅐5k][zKuۅ`WvB :7Ƀ'XNLV EVrkqm)wGbuLC4%(2x%Eę'1!xҖhLbJ3{Uǝlq{Ʒe].'ygJ;ǹ8P_\-Xr 7 ^WLJ6C1^¬o 9 4{ PX1J#,9|}\L;'Wnn}7:>`],D_ < ԆtC_]W՛,&Dž8__5ܵ|D*_||vZDFɄ%*}Kč!}U!S&@Þ}U%p7aG_2fI9ޡ 1%a y`=a <)!O/tȏCul6h%ǠA#k5L6mm0z}),r |/0_ ={]ӈJ5, , , , , , , , , , , , , , , , , , , , , ,q/3cYȈ2H$X""2>ei-"""#( qDze0q"@4刈 '*gT9O Ʋ"!\7`X$""2DccuU1V$!XҲjU (…q֭sYƧƎi"""555k|֭sYLЃMYVř<9sB|~ڲuKOt!Yi ',]jXN;e|ai2iXclyY!7ttd|Ek)O&cuI&]ꠡPSs`uJ ?o:`9IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/simple-layout5.png0000644000015301777760000003423312321005637027502 0ustar pbusernogroup00000000000000PNG  IHDR)bjsBIT|dtEXtSoftwaregnome-screenshot> IDATxy]uaY23w&LBVBbPK{~.'ן_[Z[T_kiUkjUPԺ@Q"Aа$$a'Yvq'{!'|}? Q{ $ImA1Axrхp2k Włq5Gfb_6zzۺ`l| ׵O_Dk|G:;<~'~II?0<{Љq_[6v 8&s0=?sPaaed\xL=$I$)kWk׭' VHyޅ=XK$I3X_n6lD J$IғE!.IȲ,H,m{hYZg&?D=|?f=Y{EH$I:v&M PH,Ii44$8(1! dY֊"YF4 i)i0("ֺ̓FqFQ9 ?RfJF9:$IxdYFd4 j/]8gOa^w'+mla]w>=K\"C`thRי7ogϢg*'wkW;vlzYnbFL7BЪlRՙ5k JtV* ׷~7R*X Z) A%Q+2Y|J'~x *T$I,2Y)ziŐ]z&*%44%KS00$#zkP(ֱzAP˙2$II4m1QԚsg\IѠX(4h4/^'gq7E8GH -|;K~n|nkB&I$='6+R&Ksbڲ#^,[k&M5$T,qWu-鞶 €J/*[h& @4(+X*04Ԫlu•W^w] ':>y>˘,mC)\7blfN*gVn22XYG#6H$)7RWLX>P?ijGw;SY7‡\z 3ʭ2͡~.Ʒ1I3e欙$ 6{G?7 kHӔYfw I¬Y3V[9+~zh4ֹ̞ŦMR>gE(L==$zBf@V^>uH@6g[Gm:+i0X:~5gzSII9_g6IRfRcz#71rEd?sLU%M'9 5ZZ4e)F~z~٤R4H$5:0;4I8 )KN]/^·q;W~ Iv s:H+WP^~PR8':.ItYA^?#I'3Yu]+z: |?{)<ϭ.>lwo%xos u 9Dw=L󠝼,%4G?-[,_4 T]M^6^фV,}yLJvFt|ktpޥ'>IQԋE܄L$IO/]ޞ5 ow6xgo_t6g;iwlPN{GJѭL U~zS_t{-#,#h4suk}4ZRfhNwlXƈ9ȣz <(u<.X8v4;$Dl\ճo~n;yA_xR)AFZ:Sū?q^gfKJuN|۫gU8@xxF8WGggGkZS2<>o}3ttI>G-?>PPJw6@5 c^8ꉈ'I$I0ݽҔb;8sZk@{[; շضS;yUϣu-YsupTۛ 턄qh#I % S(<$n1[nŇuO~vkh6i8.LhaLyyżq$.qHb[aWj_usgǜ>GK~>;>q 4/{_k5u!*uQ'g| MYL!s_=rC_x<;K$IOqOj&bGfW9AHڬ3-޽kP휚$PLI"X9Qq;w3u*b5DI4RZmʲ$M(]}E{{Ci&{QNjMJa04<̎;hh'M}~dR~䣴5輙5پ#djϾєǔbapt5$ٸu3Oaf$٭_~6L[9x߹gqJW(x_~>j^u9,\$ nY4&7i>ZrT/I$=e_KQ&)ݍn>DWػq{6wR-uP(Γz$M9y{GN7d C$"ca'2,OF|uu0,G(xb *HZݽ~wfvCu;ʴE*# 2VeATctmGdڤ@L#M{rTR(ƔKbFA^FX(Ѭ5\EqYmmbz$IPޘ}R&b!us^)tt׬ѻ0AaFb>IFi4BIƚ53k֌֖JcO`ӦDQHXlzƃ>ĬY3hkk]ԿEI 7>F ѩfOvHLȚ5Ɉhl}Pho{e{h6ikwd= EE:~=n4f=$ISk[jJ%AG"/ mSa@pʑ6lTho+S*f(Iz:7>FRA\&B,Z280 bB@@{G[ X*hٰa#&uQT*A@Qb~"BF<%[ɒ$I&.XvYO|w1FFA&iFaDPP(qbO0ʲzAh֠NˆS aȞަxo=YBѤhNj!qQ(H$m'6rki6FtDŽc"I$0dbӽר7 (ikko   5kB׭4(#Jޑ)I g&vtk($I7^kǤNc{nH$If$I4xӽ$I$hxRӽ$I$ß`pjFVf{[GcvAj,I %Iǝ0$"rR0u*yumQYCFXݻ՛Vs{Yc3Xڨ if!I'0ˆrL\aje*zqgh"ZDg[\y{֤Ȇ lFv}+wMSmuǸ$@Ԁ~`sG2d+^A'an|宯pbyĴ:ܛ]A:qOЛM $}*0j*ݾj?o]V&wL~B+InP$I=Y^ooJV>WLoKf@$FY[Foͫof+sVs:\# ,sjVj* !+$e5kXn՘echz (1@ _ `Q4gX?fVHټQo$DQ7of8GX4n1l)$Ir-%I$J;"I$)G" $I'Qp^$IR~p^$IRxI$IbH$I+9$I݂X$IR$I\X7B$IgH$I+I$IbHmq3&Jݐ4?uv+g7tT,N_d}> $'~=ЂV1m+_O~B3xU_K9"5zzu%{X}ݬzﳬͷo:S[V&;cY}[LȞv%xldKl$ؽ_˩]s9in$ie,`J?f,x LOwe7R'dzsYlj\zķ& y/ro1intsk/xne!lͭgGE6}[DkZȞu&9"[#*ŽE$im=:Nm)N~hssgܿU` ^g ^G>}/$i|OiAH2r??ʕzE,6Z]̙r&,海YEoaXnt涷c1Ta^WϞ>]7B{wW! ӟxZ_ieHщg˨} #i{+KOy=׾׶ɯzHwo ؑr2_"hsH?^׽7pyd&nA@V_32t\-s7i4FcHO2>pddl_ve+3O+—3i}er{?^uk@kkǒ֏dtw̟'.Se8y/_ Y/yݴ59efJ.v8_ PژF}d3;HtsN<>CYK8}5żv5s޵+XşGe~K9/܏=jɡwo7\΍7p?^rWp=sF7qD^'8GRtιg C3Iyyk^t6z:6hB᯶]8g$]<Մd&M$^7rt/LtTut9}3VlrI?wWuK=Ưn<ǩScjYă|o䐥s^| ? qRRtL'7~%+|R{YR-]6jםIv蹎=g nO\3}\$*&t.=<;ݵpU)Ÿ8XHFt6>|2:>7V^⓼f޸t|'_}(F^ß2pTVCN,JdMd z#kD׿탇Iop#sH.JjDvNxO?.I:4YXÃ3q^o3?I}#6SOʯ{S͎?d#GrEd?t\qMN(AfY瓜Cup7J惡lB҅ 7ɒ_(ty[SpUo`3#bzI3ڶop֩\sɻyiOB;] 9w?|O>dzkrџں}|G?N_v^Qe&F| ?:G /~ #[0r7׿*?0-T_5 ҃ff i3K>~YE6?|jByͿ{W4|_^gp-&gdفS,> :w5|:tst4R|w~o{t'쎧%r%K_Ȗlt"M\XR*{ dgv{zN*DWWG9h٠$Ac( L< q 4PqȦ],A_qj̙¦Cǡ@9H* tu̠~了T*PnbshchQTM*AX-HN?D4mOH°D)<햎/3t7AyIc!IDATa ' i#Z2ڑﹴW Tc+kPm|7C8ֽ #ic`q`$,wOk|5FnX@N$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IU$In$xcg I҉%cb?$MP=Z!T:ꍑ$XRR ԏuK$IǓR2$O 0e Sڀ p$i<26eb2g($GY@3`tAE$$ilQ1kΘBpb3z$I'd ŋY|bftHgF xr!@areH0I--ɖ-|9/g(GW,;y/l P\Ҩ)vAQo$uuѸrkd KBvԳ:=zuIҡ]\>r]z-Kf-ޛ9/'6;hZ!CJ3Td$,] OtDn,?u9*Ӹ|؝ܵ.^PcX7_t u:?i>Kg.s Y<}oK-\Hv啰kAJG68HVB^NhAA Qw7Q 'LNu@r\f,Yȕ^ɮ.*}#} 6YJH҉, # \(S)Vn\t]cW230d)WW^X &T)IOHr$ !J%b8 ,ZԤO:#GHR;TPRDdYFe$IO (r$#2qD~o/a7޸|ewߝ24LJ@ľ8KNl{D $@ 解c3WN'000ڵkyGX,RT" ý$ķC4Ml޼ܹs?>cӟ'>1DolY$Ih3jjUm?oM{{ʚ5kذaL> $I@OOI000# $iI׏z[$I'zo(I!8֮Htfs|Iq$Qo$c!I:ZB?$M}$h u$I$iI$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$I+I$IbH$IXkY{?IiW(E:qǺғ.᳟gxwCW_ COgKR^>~ku'|]ׯ}0s07o+L)5BV6z:(I@C)ۃB}2j?Qo=7{ wd.:eY3TV3CJ憴5YzqB했:0wQEAw&7D kɟՈx?gd=S'TOk+μTj3ZT姷=imt<1脓)/3-d[nj,jp,(D[%~6 (dyVsI755ohp, Y}[ 83eԌlJ&Gܱ9c)M}nʮ#րnGa_8̨H48 vR.=s\eN֭yMS>:2ƴ[7l9dfu@G<΂'Pgucc#*2g9HCţ;:fs'SVlĶ4v?y=v(Y{(8h$ ):Dsk|cu2`׺Ef|ʤGc gtZ'X;b>%"d#1b3aއB)\quk&8+>n+8#}OC~Y<VLA/M/G!=)3}9tƧn쮧œ w Dr5u:G6Yߔdt.WNΈ_*v6G;Lƭ.U6IW>GĶG:觋,i=BFI ^*Eb@2G=S9{a ? h Gqw_g, @0tΜ5Ě?Bxڙ.q'S[SⅣqN:l|x3ÍC71_pA6-AGRtBv>}mPٗww1 |'ä ƟhAw Kۙ~fE t'sJGy='#H!_?]ܸ)~$Iq0}љtϏҗxk7-7@Oo\2k-S03=;gnxr&Ђ~^aqyҏ>4p*Ń7z.o91Aȁ I%/*6m9m&.r)# 2tu[@u= 'Mΐ}= 3ʐ2iaA!- ڄ (ƾ$!'枔ytcu9s_HG$I aLt#YڠVryZnj]Qp40 =5Ix& q6@-N)xf`FQT4I}udifa+e fFd)OKM8Bu#st;X:F|(쿗J8Ⱦõ -;r"IO $:Rr[@|#ڻrŏpχ $(5ГсuaL!<qࣤkR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRR$I$!E$IRQE4AaAfH3;B8$MLI҄;Jv2)B%I4#(z[$I'b^HJHN,JDP8͐$gwSG9Gʔ)1YHYB9s GQC53iX$Ǻ9D$IY8d ;I̘xqH{{%Icr˗X,\vʗ$)˖e,_^`T*c$IqR0y1K:zn+n-Cuue\~ykXHi6l۶$I Ð6MFWWטchݐk"Ӧ%\~yw]we]14IzfȘ??aҀχ /X8{#n" 344DtA$=A@tttNR}\[]Z_.,]paƕWfj@__`F$v:t"0l J@wwD1y2LwǨ@@ cpa)R6Xl8U^=uW|˺Y%q1F}O=yf!JZyNUgeVo?&u]? wuk7*Y[R[R[R[$y՗rHIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/images/layout1.png0000644000015301777760000002542712321005637026214 0ustar pbusernogroup00000000000000PNG  IHDR sBIT|dtEXtSoftwaregnome-screenshot> IDATxy|]e=]ҤBAAJi eGA@y!3 :tq.è#* :"220`ّ[M&w9ޤiA}^}e<7{\˱0T ~dɉaeaYTZXr`6775Zi֨Ͷ#}]Ƹ=>UuW(EqKj(ӶlnN[{^]7CG<3` '(ny1N@快-N_3F~Ќmv{xfF}h/|h3*5yt;꫼Ncx Li󃯺.eWiLg3k֬ò-lrm 't"u+ZDD䐵}{7k_Ym\|"jvDDD^{ذq3X;HDDDuc.>Djkk0c8Cd"LT[1˲+5|_ v(fc b86eanٝ\ D0}0$ P 98xIDƘr<1!Q] 9q<,<b32Dc(v|JANrv}DDd4n1D|"o=E- ̨frU-6_=e.UILBa˶l\sl-xP_Ky|9 uaDFDQm8N=]ZqK1y$hrm ymɧIs{˹#E 몍L$})w\>r߳t[n1F!C$g}k`]JXE*9ヌ q]ۮXq8H$=`׎rk8쳹뮻)> q}hk׫ȁD%X|nbwKera J(Q_*e*AeY%Xd?õcQQ*9SmPNy,[x?/8#J&Ty&$˓#JXERhITg\^a@T I ~@TڬEDi@'0%3iRNeLxd-!NSvC9""18 ySSIf>sC۾}*ϡ*I7Mⷝ%ZZIR 2#7DH344uK 'A455QVʁ F}guсkFs.ky٘r6v|ϒ&qƇ˙SRзn%}'/aas[x- aV>8)H?χрEo>։IyϿ@9=o<U`ɺ O9TslAi^`K!+7c0!KyD=nM6A/NLs<S ÐrVr,"m3 innP(3Yg>_|Dzǚ1C |?rY%pN'k)[ w CpғYKϰdomK.O-{:(А` ~/W= :jJ͑Za&͕:Ɇ,>F$}yrJ(:ERin9=,,0䰔E?"M3-k;.QǭsOfKԷ( May6lRR*G%v] 0 ɔ'!& fJ;3( אLX7JjNg5%*m ˎz}kp5$Ou9#]<̠5&®$ ` ]q5tऩ:">&ij| v e:񟟽[օL:s\#8/\ﯩ/UzfO9 5kOC9RJ$_9}rPe2NCuoj '={,`nE۵c_"C-ʨdKղ,~=%'L9D|}UZ9ig<(>ïB"!z-:'Ldñzxyv8Tm'2#ˁ'2Vf~\m "U8cіDQDNT,+ڱXSCw8ӎ`kb7iw-7|+;-y8/s?\-U>a`g>F'1 VgrE 5rr=""Řj \'" ˭RyG$v||vGxؖ\2ֶmo了:[m3`ZQ4ϲl*'V1ؕP}Una\wh1m5leMVN⹧\001IDJSWpࢫoIO䖇^b3 _,Ȋߵ%[ Ry*[ᖻYx53}\C9u,"Ϫ"ǃ̝XȤ3|̣i-uodVu>g1Ɏ`m /l۶l6MXVmGCKGGZNym' "3Tzn7hs#j9O" ^NVmZ\W?wro_:lo'&5t|\.[]. mrgTWr|Y%|sU4#_wy9"몟VD-c BMhN064vocVB""+srUUq]]i0d+m 't>iTn`F!&*&wӽ};LX# BñؕnrWj[];Ǝ^M!lj"_*FfOvmqcl(4^2ض5TNd 3ge[)/* -0k֬,lLD1_')eO̪ ̯LJX$)Ҏ_ LQrENle0 I|`[6^%_)BӰٴ!(=f6Tk ߩZ'T!T / n!D.eXip.! X䥗VT^RY9h0r}l܎$r唊EVz&te'U.'C6nDExW&s.6t`"Y 􎟍I v"EMbhrmmteǞ(ojM$p=n$dw}uMXȡ%NJE$尢acy:,קڎlV~ڇR؂I(`+~-&&erөJU3}mqG?WS 4 vh0x5(d{ͅs9Mc\v_{--mm#QEbHv:)yhC|/k%&k`V^;ܲ^ /魧es&IdP@ʟWq-8ӦM-QZZVᗽbQ~o` f),<5|/ʨU){9` `K{ M+6&?rlᇩ~%4}Evo1k;k~zkbt.g,K׾@WP'}}`s̘xne`:;\̑V-{.~M[+o"uk)3n>|t#sK4$}>|3ma;o`NnH󮗹qd'Us.s+HXL:,)؛rQs@WPߵC,K8kguHæi'2M7/`3ox|=a܈L9^ Āز G,irS"_PǥzY?83$[N9[XuGL 7SvrD!jWeDS"?܋rcI4;8h6|VM/=]MP}^ OR5'p֌"ZfOo<}3l\ 4)9l; Lm9S'5=k`s0XӨ<7MgM38Z5R)} ~UL+#J9W<ZeP;yLpYt2%b|æ, }]+Uqh:ˎ *֡Uu~dEka(v9Q ] W#/$(u'~zv4 N,aYMD|%U^ǚr!}Ibl|1L򷷐]t۰u%|BOqrk,Wm:o<ͭI643s Ddl(4^W|7t O;ONjHDWsRk8⢟33|Cuh`_',O`\ ˁVCl~ۿֺ~ߗ\r^=Ңw\ ѡm<#˽6v5tarW|M|ɝwr<7ƶX?% Ctd7hL촏sN܁|qڒA'/$z EK$yg^z"/H Zy/Of)d~' X?d.".wm|V2ރgj%;]xq/;b~^7zq̾|zW܄?Odg_I'g r?>E?|<⍼''0=x䈣 qݧo_Of˚O\!l.>}kjNiѳ'pV|662oI'/hg> FN:a.Lhq_N`;t‘-cδ^f$.Sh6lc>V_eq NO-K pv>Eo&{hÆ*}jp\)jv7= ^zyڱk<3,\zQt$j>>4x7ѓw^d 3SgJ^򫙘}LҭG2wbhuD:b1p} .O&G-H \t~@qCܝck|?kl&F8fadCk6?uYiSoHlf_7?׿CvW:%z%Da&H'.;?aB>Ȗ.x9DG7Cl7D8Q(ׄC#8%p0ßmFoH IDAT_'IO' $\$!-gcSx;nC_?Sw ۺ-Qy:"GQ}/t ? 4|0`_=RV{p,S 4rBXl^kShap]VfSf`uDst<{?'_2Ic=y>[0q~o$V\`o\CۿckN[>͜ieiOk82~"Z2MjeݓΫ}G- b5x~eR7ßEnj UShJgrul^PdtCM}H߁}u-L8ga{4j}n~P1yX,E+|W.!i2x"~De;|ףq 쟼GGvRK?{%$~=wbeaR2ﻭT {GE;9(<ަfyUX?~ޟ 5L8梳ӳ"[sI]}[v+Ϟ pӋ 10b%S% ߀Yigd֘p|kn+_/C:aɢ]CSD`e״ Փ"&d ᰵ$|y 2XU<gHbz)=C_E8| u!S a}z#Stoߺ{8 mi[{G+c.e%v;zǢQ k8.6r1a#{Ng)19P v{hQ*$E>?w]F7}[F)c``vPܷfcCUhdѽѥ{n g1N}E)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1(8EDDbPpĠA)""SDD$H N"""1V~~dY8sk!c;XgQiX{0"mt2%_nY98c6D`WCƹt"m)O29,8I$f]dm2U'j0*m`E;ۦ`BƹƪFWUUӬ`FƵQ?[ft%%]98N%p4Q=Y, 5 M7tYвlޡ8S9sfd2KiBgNÜ]4a~|., NB̩/,[FJԊLJ⋙\5,|ڃ]%gjg{\5/N1ujp$L*lar]pajkzzpڰŃ\My? ^H: BX߳RSǽ)5S1#Y::4${p> ^|Y\(!|9ĉg>yqk( yX p$,0.( [GYٶ:_Ehƒ\{y=p,TG7dzeK[JK] eLZ}I8#>=fӆ6וL?<,-Nr3u/n4o{vۋٲo*1P(„IeX. */ /*! \qmlmodule Ubuntu.Components.Popups 0.1 \title Popovers, Sheets and Dialogs */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/overview.qdoc0000644000015301777760000000535712321005637025361 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \page overview-ubuntu-sdk.html overview \title Ubuntu User Interface Toolkit \part General Topics \list \li \l{ubuntu-layouts.html}{Layouts} describes a flexible layouting engine to ease the development of responsive user interfaces. \li \l {Resolution Independence} describes the facilities that should be used when setting the size of UI elements (widgets, fonts, etc.) in order for them to behave well on a variety of devices. \li \l{Automatic State Saving} provides automatic property saving for components. \endlist \part Basic QML Types Available through: \code import Ubuntu.Components 0.1 \endcode \annotatedlist ubuntu \part List Items Available through: \code import Ubuntu.Components.ListItems 0.1 \endcode \annotatedlist ubuntu-listitems \part Pickers Available through: \code import Ubuntu.Components.Pickers 0.1 \endcode \annotatedlist ubuntu-pickers \part Popovers, Sheets and Dialogs Available through: \code import Ubuntu.Components.Popups 0.1 \endcode \annotatedlist ubuntu-popups \part Layouting Available through: \code import Ubuntu.Layouts 0.1 \endcode \annotatedlist ubuntu-layouts \part Theming Elements Available through: \code import Ubuntu.Components 0.1 \endcode \annotatedlist theming \part Resolution Independence Items Available through: \code import Ubuntu.Components 0.1 \endcode \annotatedlist resolution-independence \part Parsing Command-Line Arguments Available through: \code import Ubuntu.Components 0.1 \endcode \annotatedlist ubuntu-commandline \part Services Available through: \code import Ubuntu.Components 0.1 \endcode \annotatedlist ubuntu-services \part Performance Metrics Available through: \code import Ubuntu.PerformanceMetrics 0.1 \endcode \annotatedlist ubuntu-performance-metrics */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/html/0000755000015301777760000000000012321006415023570 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/css/0000755000015301777760000000000012321006415023414 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/css/breadcrumbs.js0000644000015301777760000000141612321005637026252 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ $(document).ready(function(){ var ul = $("ul.breadcrumb"); var li = ul.children("li:has(a)").remove(); ul.prepend(li); }); ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/css/qtquick.css0000644000015301777760000003316012321005637025617 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ @media screen { /* basic elements */ html { color: #000000; background: #FFFFFF; } table { border-collapse: collapse; border-spacing: 0; } fieldset, img { border: 0; max-width:100%; } address, caption, cite, code, dfn, em, strong, th, var, optgroup { font-style: inherit; font-weight: inherit; } del, ins { text-decoration: none; } ol li { list-style: decimal; } ul li { list-style: none; } caption, th { text-align: left; } h1.title { font-weight: bold; font-size: 150%; } h0 { font-weight: bold; font-size: 130%; } h1, h2, h3, h4, h5, h6 { font-size: 100%; } q:before, q:after { content: ''; } abbr, acronym { border: 0; font-variant: normal; } sup, sub { vertical-align: baseline; } tt, .qmlreadonly span, .qmldefault span { word-spacing:0.5em; } legend { color: #000000; } strong { font-weight: bold; } em { font-style: italic; } body { margin: 0 1.5em 0 1.5em; font-family: ubuntu; line-height: normal } a { color: #00732F; text-decoration: none; } hr { background-color: #E6E6E6; border: 1px solid #E6E6E6; height: 1px; width: 100%; text-align: left; margin: 1.5em 0 1.5em 0; } pre { border: 1px solid #DDDDDD; -moz-border-radius: 0.7em 0.7em 0.7em 0.7em; -webkit-border-radius: 0.7em 0.7em 0.7em 0.7em; border-radius: 0.7em 0.7em 0.7em 0.7em; padding: 1em 1em 1em 1em; overflow-x: auto; } table, pre { -moz-border-radius: 0.7em 0.7em 0.7em 0.7em; -webkit-border-radius: 0.7em 0.7em 0.7em 0.7em; border-radius: 0.7em 0.7em 0.7em 0.7em; background-color: #F6F6F6; border: 1px solid #E6E6E6; border-collapse: separate; margin-bottom: 2.5em; } pre { font-size: 90%; display: block; overflow:hidden; } thead { margin-top: 0.5em; font-weight: bold } th { padding: 0.5em 1.5em 0.5em 1em; background-color: #E1E1E1; border-left: 1px solid #E6E6E6; } td { padding: 0.25em 1.5em 0.25em 1em; } td.rightAlign { padding: 0.25em 0.5em 0.25em 1em; } table tr.odd { border-left: 1px solid #E6E6E6; background-color: #F6F6F6; color: black; } table tr.even { border-left: 1px solid #E6E6E6; background-color: #ffffff; color: #202020; } div.float-left { float: left; margin-right: 2em } div.float-right { float: right; margin-left: 2em } span.comment { color: #008B00; } span.string, span.char { color: #000084; } span.number { color: #a46200; } span.operator { color: #202020; } span.keyword { color: #840000; } span.name { color: black } span.type { font-weight: bold } span.type a:visited { color: #0F5300; } span.preprocessor { color: #404040 } /* end basic elements */ /* font style elements */ .heading { font-weight: bold; font-size: 125%; } .subtitle { font-size: 110% } .small-subtitle { font-size: 100% } .red { color:red; } /* end font style elements */ /* global settings*/ .header, .footer { display: block; clear: both; overflow: hidden; } /* end global settings*/ /* header elements */ .header .qtref { color: #00732F; font-weight: bold; font-size: 130%; } .header .content { margin-left: 5px; margin-top: 5px; margin-bottom: 0.5em; } .header .breadcrumb { font-size: 90%; padding: 0.5em 0 0.5em 1em; margin: 0; background-color: #fafafa; height: 1.35em; border-bottom: 1px solid #d1d1d1; } .header .breadcrumb ul { margin: 0; padding: 0; } .header .content { word-wrap: break-word; } .header .breadcrumb ul li { float: left; background: url(../images/breadcrumb.png) no-repeat 0 3px; padding-left: 1.5em; margin-left: 1.5em; } .header .breadcrumb ul li.last { font-weight: normal; } .header .breadcrumb ul li a { color: #00732F; } .header .breadcrumb ul li.first { background-image: none; padding-left: 0; margin-left: 0; } .header .content ol li { background: none; margin-bottom: 1.0em; margin-left: 1.2em; padding-left: 0 } .header .content li { background: url(../images/bullet_sq.png) no-repeat 0 5px; margin-bottom: 1em; padding-left: 1.2em; } /* end header elements */ /* content elements */ .content h1 { font-weight: bold; font-size: 130% } .content h2 { font-weight: bold; font-size: 120%; width: 100%; } .content h3 { font-weight: bold; font-size: 110%; width: 100%; } .content table p { margin: 0 } .content ul { padding-left: 2.5em; } .content li { padding-top: 0.25em; padding-bottom: 0.25em; } .content ul img { vertical-align: middle; } .content a:visited { color: #4c0033; text-decoration: none; } .content a:visited:hover { color: #4c0033; text-decoration: underline; } a:hover { color: #4c0033; text-decoration: underline; } descr p a { text-decoration: underline; } .descr p a:visited { text-decoration: underline; } .alphaChar{ width:95%; background-color:#F6F6F6; border:1px solid #E6E6E6; -moz-border-radius: 7px 7px 7px 7px; border-radius: 7px 7px 7px 7px; -webkit-border-radius: 7px 7px 7px 7px; font-size:12pt; padding-left:10px; margin-top:10px; margin-bottom:10px; } .flowList{ /*vertical-align:top;*/ /*margin:20px auto;*/ column-count:3; -webkit-column-count:3; -moz-column-count:3; /* column-width:100%; -webkit-column-width:200px; -col-column-width:200px; */ column-gap:41px; -webkit-column-gap:41px; -moz-column-gap:41px; column-rule: 1px dashed #ccc; -webkit-column-rule: 1px dashed #ccc; -moz-column-rule: 1px dashed #ccc; } .flowList dl{ } .flowList dd{ /*display:inline-block;*/ margin-left:10px; min-width:250px; line-height: 1.5; min-width:100%; min-height:15px; } .flowList dd a{ } .mainContent { padding-left:5px; } .content .flowList p{ padding:0px; } .content .alignedsummary { margin: 15px; } .qmltype { text-align: center; font-size: 120%; } .qmlreadonly { padding-left: 5px; float: right; color: #254117; } .qmldefault { padding-left: 5px; float: right; color: red; } .qmldoc { } .generic .alphaChar{ margin-top:5px; } .generic .odd .alphaChar{ background-color: #F6F6F6; } .generic .even .alphaChar{ background-color: #FFFFFF; } .memItemRight{ padding: 0.25em 1.5em 0.25em 0; } .highlightedCode { margin: 1.0em; } .annotated td { padding: 0.25em 0.5em 0.25em 0.5em; } .toc { font-size: 80% } .header .content .toc ul { padding-left: 0px; } .content .toc h3 { border-bottom: 0px; margin-top: 0px; } .content .toc h3 a:hover { color: #00732F; text-decoration: none; } .content .toc .level2 { margin-left: 1.5em; } .content .toc .level3 { margin-left: 3.0em; } .content ul li { background: url(../images/bullet_sq.png) no-repeat 0 0.7em; padding-left: 1em } .content .toc li { background: url(../images/bullet_dn.png) no-repeat 0 5px; padding-left: 1em } .relpage { -moz-border-radius: 7px 7px 7px 7px; -webkit-border-radius: 7px 7px 7px 7px; border-radius: 7px 7px 7px 7px; border: 1px solid #DDDDDD; padding: 25px 25px; clear: both; } .relpage ul { float: none; padding: 1.5em; } h3.fn, span.fn { -moz-border-radius:7px 7px 7px 7px; -webkit-border-radius:7px 7px 7px 7px; border-radius:7px 7px 7px 7px; background-color: #F6F6F6; border-width: 1px; border-style: solid; border-color: #E6E6E6; font-weight: bold; word-spacing:3px; padding:3px 5px; } .functionIndex { font-size:12pt; word-spacing:10px; margin-bottom:10px; background-color: #F6F6F6; border-width: 1px; border-style: solid; border-color: #E6E6E6; -moz-border-radius: 7px 7px 7px 7px; -webkit-border-radius: 7px 7px 7px 7px; border-radius: 7px 7px 7px 7px; width:100%; } .centerAlign { text-align:center; } .rightAlign { text-align:right; } .leftAlign { text-align:left; } .topAlign{ vertical-align:top } .functionIndex a{ display:inline-block; } /* end content elements */ /* footer elements */ .footer { color: #393735; font-size: 0.75em; text-align: center; padding-top: 1.5em; padding-bottom: 1em; background-color: #E6E7E8; margin: 0; } .footer p { margin: 0.25em } .small { font-size: 0.5em; } /* end footer elements */ .item { float: left; position: relative; width: 100%; overflow: hidden; } .item .primary { margin-right: 220px; position: relative; } .item hr { margin-left: -220px; } .item .secondary { float: right; width: 200px; position: relative; } .item .cols { clear: both; display: block; } .item .cols .col { float: left; margin-left: 1.5%; } .item .cols .col.first { margin-left: 0; } .item .cols.two .col { width: 45%; } .item .box { margin: 0 0 10px 0; } .item .box h3 { margin: 0 0 10px 0; } .cols.unclear { clear:none; } } /* end of screen media */ /* start of print media */ @media print { input, textarea, .header, .footer, .toolbar, .feedback, .wrapper .hd, .wrapper .bd .sidebar, .wrapper .ft, #feedbackBox, #blurpage, .toc, .breadcrumb, .toolbar, .floatingResult { display: none; background: none; } .content { background: none; display: block; width: 100%; margin: 0; float: none; } } /* end of print media */ /* modify the TOC layouts */ div.toc ul { padding-left: 20px; } div.toc li { padding-left: 4px; } /* Remove the border around images*/ a img { border:none; } /*Add styling to the front pages*/ .threecolumn_area { padding-top: 20px; padding-bottom: 20px; } .threecolumn_piece { display: inline-block; margin-left: 78px; margin-top: 8px; padding: 0; vertical-align: top; width: 25.5%; } div.threecolumn_piece ul { list-style-type: none; padding-left: 0px; margin-top: 2px; } div.threecolumn_piece p { margin-bottom: 7px; color: #5C626E; text-decoration: none; font-weight: bold; } div.threecolumn_piece li { padding-left: 0px; margin-bottom: 5px; } div.threecolumn_piece a { font-weight: normal; } /* Add style to guide page*/ .fourcolumn_area { padding-top: 20px; padding-bottom: 20px; } .fourcolumn_piece { display: inline-block; margin-left: 35px; margin-top: 8px; padding: 0; vertical-align: top; width: 21.3%; } div.fourcolumn_piece ul { list-style-type: none; padding-left: 0px; margin-top: 2px; } div.fourcolumn_piece p { margin-bottom: 7px; color: #40444D; text-decoration: none; font-weight: bold; } div.fourcolumn_piece li { padding-left: 0px; margin-bottom: 5px; } div.fourcolumn_piece a { font-weight: normal; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/css/reset.css0000644000015301777760000000153312321005637025257 0ustar pbusernogroup00000000000000/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html version: 3.3.0 build: 3167 */ html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/css/scratch.css0000644000015301777760000000350612321005637025566 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ body { margin: 0; } div.toc ul { padding: 0; } div.toc li { margin-bottom: 3px; } h1.title { font-size: 36px; line-height: 1.1; font-weight: normal; } h0, h2 { font-size: 24px; line-height: 1.2; margin: 14px 0; font-weight: normal; display: block; } a:hover { color: #dd4814; text-decoration: underline; outline: 0; } table, pre { border-radius: 0; white-space: pre-wrap; } .annotated td { padding: 0.8em 1em 0.3em; } .wrapper { width: 940px; margin: 0 auto; } .main-content { width: 668px; position: relative; left: 270px; } .title { margin-left: -270px; margin-top: 30px; margin-bottom: 50px; } .toc { margin-left: -270px; font-size: 100%; margin-bottom: 40px; padding: 0; z-index: 2; position: absolute; top: 100px; width: 250px; } .breadcrumb { position: relative; left: -270px; top: 30px; width: auto; padding-bottom: 30px; margin-bottom: 30px; float:left; } .breadcrumb li { float: left; margin-right: 8px; } .breadcrumb a:link, .breadcrumb a:visited { color: #AEA79F; } .breadcrumb a:after { content: '\0000a0\0000a0 >'; } .title { margin-top: 50px; clear:both; } .breadcrumb + .toc { top: 170px; } .breadcrumb p { display: inline; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/css/base.css0000644000015301777760000002706712321005637025061 0ustar pbusernogroup00000000000000/** * Ubuntu Developer base stylesheet * * A base stylesheet containing site-wide styles * * @project Ubuntu Developer * @version 1.0 * @author Canonical Web Team: Steve Edwards * @copyright 2011 Canonical Ltd. */ /** * @section Global */ body { font-family: 'Ubuntu', 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-size: 13px; line-height: 1.4; color: #333; } a { color: #dd4814; text-decoration: none; outline: 0; } p, dl { margin-bottom: 10px; } strong { font-weight: bold; } em { font-style: italic; } code{ padding: 10px; font-family: 'Ubuntu Mono', 'Consolas', 'Monaco', 'DejaVu Sans Mono', Courier, monospace; background-color: #fdf6f2; display: block; margin-bottom: 10px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } h1 { font-size: 36px; line-height: 1.1; margin-bottom: 20px; } article h1, h2 { font-size: 24px; line-height: 1.2; margin-bottom: 14px; } h3 { font-size: 16px; line-height: 1.3; margin-bottom: 8px; } h4 { font-weight: bold; } time { color:#999; } /** * @section Structure */ .header-login, .header-navigation div, .header-content div { margin: 0 auto; width: 940px; } .header-content h1{ background-color:#ffffff; display:inline-block; } .header-content h2{ background-color:#ffffff; display:table; } .header-login ul { margin: 4px 0; float: right; } .header-login li { margin-right: 10px; float: left; } .header-login a { color: #333; } .header-navigation { border-top: 2px solid #dd4814; border-bottom: 2px solid #dd4814; background-color: #fff; height: 54px; clear: right; overflow: hidden; } .header-navigation nav ul { border-right: 1px solid #dd4814; float: right; } .header-navigation nav li { border-left: 1px solid #dd4814; float: left; height: 54px; } .header-navigation nav a { padding: 18px 14px 0; font-size: 14px; display: block; height: 36px; } .header-navigation nav a:hover { background-color: #fcece7; } .header-navigation nav .current_page_item a, .header-navigation nav .current_page_parent a, .header-navigation nav .current_page_ancestor a { background-color: #dd4814; color: #fff; } .header-navigation input { margin: 12px 10px 0 10px; padding: 5px; border-top: 1px solid #a1a1a1; border-right: 1px solid #e0e0e0; border-bottom: 1px solid #fff; border-left: 1px solid #e0e0e0; width: 90px; font-style: italic; color: #ccc; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; -moz-box-shadow: inset 0 1px 1px #e0e0e0; -webkit-box-shadow: inset 0 1px 1px #e0e0e0; box-shadow: inset 0 1px 1px #e0e0e0; } .header-navigation h2 { margin: 18px 0 0 6px; text-transform: lowercase; font-size: 22px; color: #dd4814; float: left; } .header-navigation .logo-ubuntu { margin-top: 12px; float: left; } .header-content .header-navigation-secondary { margin-bottom: 40px; padding: 0; position: relative; z-index: 2; } .header-navigation-secondary div { padding: 0; border: 2px solid #dd4814; -moz-border-radius: 0px 0px 4px 4px; -webkit-border-radius: 0px 0px 4px 4px; border-radius: 0px 0px 4px 4px; background: #fff; border-top: 0px; width: 936px; } .header-navigation-secondary nav li { float: left; } .header-navigation-secondary nav li a { color: #333; display: block; height: 25px; padding: 8px 8px 0; } .header-navigation-secondary nav li:hover, .header-navigation-secondary nav .current_page_item a { background: url("../img/sec-nav-hover.gif"); } .header-content { padding-bottom: 30px; border-bottom: 1px solid #e0e0e0; -moz-box-shadow: 0 1px 3px #e0e0e0; -webkit-box-shadow: 0 1px 3px #e0e0e0; box-shadow: 0 1px 3px #e0e0e0; margin-bottom: 3px; position: relative; overflow: hidden; } footer { padding: 10px 10px 40px 10px; position: relative; -moz-border-radius: 0 0 4px 4px; -webkit-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px; font-size: 12px; background: url("../img/background-footer.png") repeat scroll 0 0 #f7f6f5; } footer div { margin: 0 auto; padding: 0 10px; width: 940px; } footer a { color: #000; } footer nav ul { margin: 10px 17px 30px 0; width: 172px; display: inline-block; vertical-align: top; height: auto; zoom: 1; *display: inline; } footer nav ul.last { margin-right: 0; } footer nav li { margin-bottom: 8px; } footer nav li:first-child { font-weight: bold; } footer p { margin-bottom: 0; } #content { padding-top: 35px; } .arrow-nav { display: none; position: absolute; top: -1px; z-index: 3; } .shadow { margin: 30px 0 3px 0; border-bottom: 1px solid #e0e0e0; -moz-box-shadow: 0 2px 3px #e0e0e0; -webkit-box-shadow: 0 2px 3px #e0e0e0; box-shadow: 0 2px 3px #e0e0e0; height: 3px; } /** * @section Site-wide */ #content h2{ font-size:24px; } .box-orange { padding: 10px; border: 3px solid #dd4814; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .box-orange .link-action-small { float: right; margin: 0 0 0 20px; } .link-bug { margin-left: 10px; color: #999; } .link-action { float: left; margin-bottom: 20px; padding: 8px 12px; display: block; background-color: #dd4814; color: #fff; -moz-border-radius: 20px; -webkit-border-radius: 20px; border-radius: 20px; font-size: 16px; line-height: 1.3; border-top: 3px solid #e6633a; border-bottom: 3px solid #c03d14; } .link-action2 { float: left; display: block; color: #fff; font-size: 16px; line-height: 1.3; } .link-action2 span{ display:block; float:left; } .link-action2 .cta-left{ background:url(../img/button-cta-left.png) no-repeat; width:22px; height:48px; } .link-action2 .cta-center{ background:url(../img/button-cta-slice.png) repeat-x; line-height:45px; height:48px; } .link-action2 .cta-right{ background:url(../img/button-cta-right.png) no-repeat; width:22px; height:48px; } .link-action-small { float: left; display: block; color: #fff; font-size: 16px; } .link-action-small span{ display:block; float:left; height:42px; } .link-action-small .cta-left{ background:url(../img/button-cta-left-small.png) no-repeat; width:19px; } .link-action-small .cta-center{ background:url(../img/button-cta-slice-small.png) repeat-x; line-height:42px; } .link-action-small .cta-right{ background:url(../img/button-cta-right-small.png) no-repeat; width:19px; } .link-action:active { position: relative; top: 1px; } .link-action2:active { position: relative; top: 1px; } .link-action-small:active { position: relative; top: 1px; } .list-bullets li { margin-bottom: 10px; list-style: disc; list-style-position: inside; } .box { margin-bottom: 30px; padding: 15px; border: 1px solid #aea79f; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .box-padded { margin-bottom: 30px; padding: 5px; border: 2px solid #aea79f; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; background: url("../img/pattern-featured.gif") repeat scroll 0 0 #ebe9e7; overflow: hidden; } .box-padded h3 { margin: 5px 0 10px 5px; } .box-padded div { padding: 10px; border: 1px solid #aea79f; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; background-color: #fff; overflow: hidden; } .box-padded li { padding: 0 10px; float: left; width: 211px; border-right: 1px dotted #aea79f; } .box-padded li.first { padding: 0; margin-bottom: 0; } .box-padded li.last { border: 0; width: 217px; } .box-padded img { margin: 0 10px 50px 0; float: left; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } .box-clear { margin-bottom: 40px; } .box-clear .grid-4.first { margin-right: 15px; padding-right: 15px; } .box-clear .grid-4 { margin-left: 0; margin-right: 10px; padding-right: 10px; width: 298px; } .box-clear time { display: block; border-bottom: 1px dotted #aea79f; padding-bottom: 10px; margin-bottom: 10px; } .box-clear div.first { border-right: 1px dotted #aea79f; } .box-clear a { display: block; } .box-clear .rss { background: url("../img/rss.jpg") no-repeat scroll 0 center; padding-left: 20px; } .box-clear .location { display: block; margin-bottom: 1px; } .box-clear .last { margin: 0; padding-right: 0; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 293px; } /* Widgets */ .ui-state-focus { outline: none; } .ui-accordion { border-bottom: 1px dotted #aea79f; } .ui-accordion a { display: block; } .ui-accordion h3 { margin-bottom: 0; border-top: 1px dotted #aea79f; position: relative; font-size: 13px; font-weight: bold; } .ui-accordion h3 a { padding: 10px 0; color: #333; } .ui-accordion h4 { margin-bottom: 5px; } .ui-accordion div fieldset { padding-bottom: 5px; } .ui-accordion div li, .ui-accordion div input { margin-bottom: 10px; } .ui-accordion .ui-icon { position: absolute; top: 15px; right: 0; display: block; width: 8px; height: 8px; background: url("../img/icon-accordion-inactive.png") 0 0 no-repeat transparent; } .ui-accordion .ui-state-active .ui-icon { background-image: url("../img/icon-accordion-active.png"); } .ui-accordion .current_page_item a { color: #333; } .container-tweet { -moz-border-radius: 4px 4px 4px 4px; -webkit-border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px; padding: 10px 10px 10px; background-color: #f7f7f7; } .container-tweet .tweet-follow { margin-top: 10px; margin-bottom: -10px; padding-left: 55px; padding-bottom: 6px; background: url("../img/tweet-follow.png") 0 5px no-repeat; display: block; } .container-tweet .tweet-follow span { font-size: 16px; font-weight: bold; line-height: 1.2; display: block; } .tweet a { display: inline; } .tweet .tweet_text { padding: 10px; background-color: #fff; -moz-border-radius: 4px 4px 4px 4px; -webkit-border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px; border: 1px solid #dd4814; font-size: 16px; display: block; clear: both; } .tweet.tweet-small .tweet_text { font-size: inherit; } .tweet .tweet_text a { color: #333; } .tweet .tweet_time, .tweet .tweet_user_and_time { padding: 15px 0 10px 0; position: relative; top: -2px; background: url("../img/tweet-arrow.png") no-repeat; display: block; } .tweet .tweet_odd .tweet_time, .tweet .tweet_odd .tweet_user_and_time { background-position: right 0; float: right; } .tweet .tweet_even .tweet_time, .tweet .tweet_even .tweet_user_and_time { background-position: left 0; float: left; } /* Search */ #content .list-search li { list-style-type:none; border:0px; margin-bottom: 15px; padding-top: 15px; } /* Blog */ .blog-article #nav-single { margin-top: 30px; margin-bottom: 30px; } .blog-article #nav-single .nav-next { float: right; } .blog-article article header .entry-meta { margin-bottom: 20px; } .blog-article article .entry-meta { color: #999; } .blog-article #respond form input[type="submit"] { float: left; cursor: pointer; margin-bottom: 20px; padding: 8px 12px; display: block; background-color: #dd4814; color: #fff; -moz-border-radius: 20px; -webkit-border-radius: 20px; border-radius: 20px; font-size: 16px; line-height: 1.3; border-top: 3px solid #e6633a; border-left: 3px solid #e6633a; border-right: 3px solid #e6633a; border-bottom: 3px solid #c03d14; } .blog-article #respond form input[type="submit"]:active { position: relative; top: 1px; } .alignnone{ float:left; margin:10px 20px 10px 0; } .alignleft{ float:left; margin:10px 20px 10px 0; } .alignright{ float:right; margin:10px 0 10px 20px; } .aligncenter{ float:left; margin:10px 20px 10px 0; } .entry-content h2, .entry-content h3{ margin-top:20px; } .entry-content ul li{ list-style-type: circle; margin-left:16px; } .entry-content hr{ border:none; border-top: 1px dotted #AEA79F; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/statesaving.qdoc0000644000015301777760000001427212321005637026037 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \page statesaving.html \title Automatic State Saving \nextpage Application name, IDs During application development it is often required to start an application from a view which depends on the previous application runs. Like a web browser should remember the number of opened tabs, their content or the browsing history, or a news reader application should continue from the last news the application was opened on, preferably from the same position. Ubuntu UI toolkit provides a simple way to save the state of any component within an application, by using the attached component \l StateSaver. By simply attaching this component to any QtQuick component and specifying the \l{StateSaver::properties}{properties} to be saved, applications can be restored to any previous state they were before being closed. Consider the following simple QtQuick application, which on button press randomly changes its background. \snippet statesaver/ColorChanger.qml color-saver But let's see what else is neded to properly save an application's components proeprties. */ /*! \page statesaving1.html \title Application name, IDs \section1 Application name First of all, the application must have a proper application name set. If you use Qt Creator's Ubuntu project wizards, you will have the application name set by default, name which is in sync with the name from the application's desktop file. The application name plays an essential role in storing the state archive. By specifying different application names, different state archives can be serialized for the application. However runtime application name change would require application restart. Having these preconditions, we can deduct that \l {MainView::applicationName}{MainView.applicationName} property is one of the properties which cannot be serialized. \section1 IDs Components for which property saving is wanted should define an ID, even though it is otherwise not justified. For example the following code snippet would give runtime error: \qml Rectangle { color: "green" StateSaver.properties: "color" } \endqml but giving an ID would make it serializable: \qml Rectangle { id: rectangle color: "green" StateSaver.properties: "color" } \endqml This rule must also be applied on component parents in the object hierarchy. \qml Item { id: root Rectangle { id: rectangle color: "green" StateSaver.properties: "color" } } \endqml \nextpage Saving multiple properties */ /*! \page statesaving2.html \title Saving multiple properties \section1 Specifying more properties So far we have saved one single property, but as the \{StateSaver::properties} property name suggests, there can be more properties serialized at the same time. For example, to serialize both color and opacity of a Rectangle, the code would look as follows: \qml Rectangle { id: rectangle color: "green" opacity: 0.9 StateSaver.properties: "color, opacity" } \endqml \b Note that not all types of properties can be saved. Object types or list models for example are excluded from the types that can be saved, but all properties listed as \l{http://qt-project.org/doc/qt-5.0/qtqml/qtqml-typesystem-basictypes.html}{QML base types} can be serialized. \section1 Grouped properties Grouped properties, which have serializable types can also be saved. It simply needs to be specified together with the group identifier. \snippet statesaver/MultiplePropertySaver.qml group-saver \section1 Property groups Using the same logic, custom property groups can also be saved. \snippet statesaver/PropertyGroupSaver.qml property-group-saver Alternatively, individual properties of the property group can be saved in the following way: \snippet statesaver/PropertyGroupSaver2.qml alt-group-saver \nextpage Recap on state saving */ /*! \page statesaving3.html \title Recap on state saving The following issues must be considered when deciding on state saving: \list \li - don't try to save MainView.applicationName, as its change will take effect next time the application is launched \li - specify IDs for all components as well as for parents even if their presence is not justified in the document \li types other than the ones listed in \l{http://qt-project.org/doc/qt-5.0/qtqml/qtqml-typesystem-basictypes.html}{QML base types} will not be serialized \li - grouped properties can be saved by specifying the complete path to the property i.e. \a border.width, \a border.color, etc. \endlist \raw HTML
\endraw When chosing the IDs, try to use as unique identifiers as possible. In most of the cases applications load content (document) dynamically using Loaders. Usually elements in these documents use different IDs for their elements, but there can be cases when the same IDs will be used with the same hierarchy (i.e. root->item can occur in several documents). UID computation takes into account the file name and line number the property's owner (attachee) is declared, therefore the property saving will be successful in these cases too. See documentation on \l StateSaver properties under \l{Services} section. \nextpage {Ubuntu User Interface Toolkit} */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-ui-toolkit-common.qdocconf0000644000015301777760000000136512321005637031262 0ustar pbusernogroup00000000000000project = UbuntuUserInterfaceToolkit url = http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/ description = Ubuntu User Interface Toolkit Documentation sourcedirs = ./ sourcedirs += ../modules/Ubuntu/Components headerdirs = ../modules/Ubuntu/Components/plugin sourcedirs += ../modules/Ubuntu/Layouts headerdirs += ../modules/Ubuntu/Layouts/plugin sourcedirs += ../modules/Ubuntu/PerformanceMetrics headerdirs += ../modules/Ubuntu/PerformanceMetrics/plugin exampledirs += snippets imagedirs = images sources.fileextensions = "*.qml *.qdoc *.cpp" headers.fileextensions = "*.h" outputdir = html outputformats = HTML version = 0.1 syntaxhighlighting = true sourceencoding = UTF-8 outputencoding = UTF-8 HTML.templatedir = . HTML.endheader = "\n" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/ubuntu-ui-toolkit-online.qdocconf0000644000015301777760000000162612321005637031256 0ustar pbusernogroup00000000000000include(ubuntu-ui-toolkit-offline.qdocconf) include(ubuntu-appdev-site-header.qdocconf) include(ubuntu-appdev-site-footer.qdocconf) HTML.nobreadcrumbs = "false" HTML.headerstyles = \ "\n" \ "\n" \ "\n" \ "\n" \ "\n" \ "\n" \ "\n" \ "\n" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/documentation/docs.sh0000755000015301777760000000435412321005637024126 0ustar pbusernogroup00000000000000#!/bin/sh # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # DOC_PATH=$1 if [ ! $SRC -o ! $DOC_PATH ]; then echo "Error - SRC and DOC_PATH must be defined" exit 1 fi # Offline docs for QtCreator qdoc $DOC_PATH/ubuntu-ui-toolkit-qtcreator.qdocconf 2> $DOC_PATH/qdoc.log # FIXME: With Qt 5.2 this warning shows up, forcibly omit it from errors cat $DOC_PATH/qdoc.log | grep -v "qdoc: warning: No documentation for 'global'" > $DOC_PATH/qdoc.err cat $DOC_PATH/qdoc.err test ! -s $DOC_PATH/qdoc.err || exit 1 echo docs: Offline done. qhelpgenerator -o "$DOC_PATH/ubuntuuserinterfacetoolkit.qch" "$DOC_PATH/offline/ubuntuuserinterfacetoolkit.qhp" echo docs: qch done: $DOC_PATH # Online docs. Run qdoc twice: the second run with indexes for cross-referencing # other APIs but discard errors because qdoc inherits all doc bugs otherwise qdoc $DOC_PATH/ubuntu-ui-toolkit-online.qdocconf 2> $DOC_PATH/qdoc.log cat $DOC_PATH/qdoc.log | grep -v "qdoc: warning: No documentation for 'global'" > $DOC_PATH/qdoc.err cat $DOC_PATH/qdoc.err test ! -s $DOC_PATH/qdoc.err || exit 1 echo docs: Online done. qdoc $DOC_PATH/ubuntu-ui-toolkit-online-indexes.qdocconf 2> /dev/null echo docs: Cross-referenced done. sed -r -i 's@("main-content">)@\1\1@g' $1/html/*.html sed -r -i 's@(

)

@\1@g' $1/html/*.html sed -r -i 's@()(.+)()@

  • \1\3\4
  • @g' $1/html/*.html sed -r -i 's@(href="qmlmodule-ubuntu-components0-ubuntu-components-0-1.html">Basic QML Types)@href="overview-ubuntu-sdk.html">Ubuntu User Interface Toolkit@g' $1/html/*.html echo docs: HTML fixes done. ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/ubuntu-sdk.pro0000644000015301777760000000333712321005637022611 0ustar pbusernogroup00000000000000include( documentation/documentation.pri ) TEMPLATE = subdirs SUBDIRS += modules/ubuntu-ui-toolkit.pro tests examples po/po.pro tests/unit.depends = modules/ubuntu-ui-toolkit.pro # additional 'make test' target required by continuous integration system test.target = test test.commands = make check test.depends = license modules/ubuntu-ui-toolkit.pro QMAKE_EXTRA_TARGETS += test test_performance.target = test-performance test_performance.commands = cd tests/unit/tst_performance; make check test_performance.depends = modules/ubuntu-ui-toolkit.pro QMAKE_EXTRA_TARGETS += test_performance test_api.target = test-api test_api.commands = cd tests/unit/tst_components; make check test_api.depends = modules/ubuntu-ui-toolkit.pro QMAKE_EXTRA_TARGETS += test_api test_components.target = test-components test_components.commands = cd tests/autopilot; python3 -m autopilot.run run ubuntuuitoolkit test_components.depends = modules/ubuntu-ui-toolkit.pro QMAKE_EXTRA_TARGETS += test_components test_components2.target = test-components2 test_components2.commands = cd tests/autopilot; python2 -m autopilot.run run ubuntuuitoolkit test_components2.depends = modules/ubuntu-ui-toolkit.pro QMAKE_EXTRA_TARGETS += test_components2 qmluitests.target = qmluitests qmluitests.commands = cd tests/unit_x11; make check qmluitests.depends = modules/ubuntu-ui-toolkit.pro QMAKE_EXTRA_TARGETS += qmluitests license.target = license license.commands = ./tests/license/checklicense.sh QMAKE_EXTRA_TARGETS += license DOC_SRC = . equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { DOC_SRC = documentation } DOC_PATH=$$system(pwd)/documentation docs.target = docs docs.commands = SRC=$$DOC_SRC ./documentation/docs.sh $$DOC_PATH; QMAKE_EXTRA_TARGETS += docs ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/NEWS0000644000015301777760000000074512321005637020465 0ustar pbusernogroup00000000000000===================== Ubuntu UI Toolkit 0.1 ===================== New Features ------------ - New AbstractButton component. - New Button component. - New Tab component. - New Tabs component. Improvements ------------ - Improvements to existing commands, especially improved performance or memory usage, or better results. Bug Fixes --------- - No bugs yet. Documentation ------------- - All classes are now documented. API Changes ----------- - This is the first version. ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/gallery.sh0000755000015301777760000000150212321005637021754 0ustar pbusernogroup00000000000000#!/bin/bash # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # source export_modules_dir.sh if [ "$1" == "--autopilot" ] then examples/ubuntu-ui-toolkit-gallery/gallery -testability & autopilot vis else examples/ubuntu-ui-toolkit-gallery/gallery fi ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/ubuntu-sdk.qmlproject0000644000015301777760000000104712321005637024165 0ustar pbusernogroup00000000000000/* File generated by Qt Creator, version 2.4.1 */ import QmlProject 1.1 Project { mainFile: "examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml" /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." } JavaScriptFiles { directory: "." } ImageFiles { directory: "." } Files { directory: "." filter: "*.py" } /* List of plugin directories passed to QML runtime */ importPaths: [ "modules" ] } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/.bazaar/0000755000015301777760000000000012321006415021271 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/.bazaar/Makefile0000644000015301777760000000010512321005637022732 0ustar pbusernogroup00000000000000install: mkdir -p ~/.bazaar/plugins cp plugins/* ~/.bazaar/plugins ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/.bazaar/plugins/0000755000015301777760000000000012321006415022752 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/.bazaar/plugins/makecheck_ubuntu_ui_toolkit.py0000755000015301777760000000310412321005637031111 0ustar pbusernogroup00000000000000#!/usr/bin/python # Copyright 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # Author: Juhapekka Piiroinen import os import subprocess from bzrlib import branch from bzrlib import errors from bzrlib.urlutils import local_path_from_url def execute_makecheck(local_branch, master_branch, old_revision_number, old_revision_id, future_revision_number, future_revision_id, tree_delta, future_tree): if (master_branch.get_parent().find("ubuntu-ui-toolkit") == -1): return print "Set work directory to %s" % local_path_from_url(master_branch.base) os.chdir(local_path_from_url(master_branch.base)) print "Execute 'make check'.." if (subprocess.call("make check", shell=True) != 0): raise errors.BzrError("Tests failed, fix them before commit!") branch.Branch.hooks.install_named_hook('pre_commit', execute_makecheck, 'make check pre-commit') ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/0000755000015301777760000000000012321006415020371 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/ko.po0000644000015301777760000002334712321005637021360 0ustar pbusernogroup00000000000000# Korean translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-07-04 17:02+0000\n" "Last-Translator: Jinkyu Yi \n" "Language-Team: Korean \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "빠르게" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "느리게" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "전화" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "색" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "아이콘" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "열기" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "여러 색" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "값" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "값 1" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "값 2" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "값 3" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "값 4" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "밀어서 없애기" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "끝이 없음" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "값 = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "범위" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "여기에 치세요..." #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "암호" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "숫자" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "기본" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "늘이기" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "그림" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "가로세로 길이" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "지우기" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "길이" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "무게" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "사용법: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "모두 고르기" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "자르기" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "붙이기" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "되돌리기" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "다시 하기" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/update-pot.sh0000755000015301777760000000301312321005637023014 0ustar pbusernogroup00000000000000#!/bin/sh # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # #~ Usage: #~ update-pot.sh [DOMAIN] [SOURCE_DIR] [PO_DIR] #~ #~ Example: #~ update-pot.sh ubuntu-ui-toolkit modules po set -e if [ -z "$3" ]; then grep -e '^#~' $0 | sed s/#~// exit 0 fi DOMAIN=$1 SOURCE_DIR=$(readlink -f $2) PO_DIR=$(readlink -f $3) PROGNAME=$(basename $0) # Create a list of files to scan GETTEXT_FILES=$(mktemp --tmpdir $DOMAIN.lst.XXXXX) trap 'rm -f "$GETTEXT_FILES"' EXIT cd $SOURCE_DIR find \( -name '*.cpp' -o -name '*.qml' -o -name '*.js' -o -name '*.desktop' \) \ -a ! \( -path './build/*' \) | sort \ > $GETTEXT_FILES # Generate pot from our list xgettext \ --output $PO_DIR/$DOMAIN.pot \ --files-from $GETTEXT_FILES \ --qt --c++ \ --add-comments=TRANSLATORS \ --keyword=tr \ --keyword=tr:1,2 \ --package-name $DOMAIN \ --copyright-holder "Canonical Ltd" echo "$PROGNAME: $PO_DIR/$DOMAIN.pot updated based on $SOURCE_DIR" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/es.po0000644000015301777760000002502212321005637021346 0ustar pbusernogroup00000000000000# Spanish translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2014-01-11 19:09+0000\n" "Last-Translator: Leo Arias \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "Estándar" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "Duraciones estándares" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "Rápido" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "Lento" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "Dormido" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "Llamada" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Color" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Icono" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "Desactivado" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "Abrir" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "Coloración" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "Etiqueta" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "Subtitulado" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "Etiqueta secundaria" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "Progresión" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "Valor único" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "Valor múltiple" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "Valor 1" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "Valor 2" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "Valor 3" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "Valor 4" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "Selector de valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "Control" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "Extraíble" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "Deslice para eliminar" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "Lista agrupada" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "Acción n.º 1" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "Acción n.º 2" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "Acción n.º 3" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "Acción n.º 4" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "Acción n.º 5" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Barra de progreso" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "Infinito" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "Indicador de actividad" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" "El estilo visual de la Hoja es trabajo prematuro y por eso se ve tosco." #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "Título" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "valor = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "Actualización en vivo" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "Intervalo" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "Escríbame..." #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "Contraseña" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "Números" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "Predeterminado" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "Expansible" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "Texto enriquecido" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "No seleccionado" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "Seleccionado" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "Imagen" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "Radio" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "Tamaños" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "Limpiar" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "Longitudes" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "Pesos" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "Uso: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "Opciones:" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "%1 espera un argumento adicional: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "%1 espera un valor para el argumento: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "%1 espera argumentos adicionales: %2" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "Seleccionar todo" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "Seleccionar palabra" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "Cortar" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "Copiar" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "Pegar" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "Deshacer" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "Rehacer" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "Atrás" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "Mi página personalizada" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" "Esta es una página externa con\n" "una barra de herramientas bloqueada." #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "Página raíz" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "Página uno" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "Página externa" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "Primera página" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "Página raíz (de nuevo)" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "Rectángulo rojo" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "Página simple" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "Externo" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "Vista de lista" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/po.pro0000644000015301777760000000243212321005637021537 0ustar pbusernogroup00000000000000TEMPLATE = subdirs PROJECTNAME = ubuntu-ui-toolkit SOURCECODE = `find .. -name *.qml` message("") message(" Project Name: $$PROJECTNAME ") message(" Source Code: $$SOURCECODE ") message("") message(" run 'make pot' to generate the pot file from source code. ") message(" run 'qmake; make install' to install the mo files. ") message("") ## generate pot file 'make pot' potfile.target = pot potfile.commands = ./update-pot.sh ubuntu-ui-toolkit ../modules .; QMAKE_EXTRA_TARGETS += potfile ## generate pot file for gallery potfile.commands += ./update-pot.sh ubuntu-ui-toolkit-gallery ../examples/ubuntu-ui-toolkit-gallery ../examples/ubuntu-ui-toolkit-gallery/po; ## Installation steps for mo files. 'make install' MO_FILES = $$system(ls *.po) install_mo_commands = for(po_file, MO_FILES) { mo_file = $$replace(po_file,.po,.mo) system(msgfmt $$po_file -o $$mo_file) mo_name = $$replace(mo_file,.mo,) mo_targetpath = $(INSTALL_ROOT)/usr/share/locale/$${mo_name}/LC_MESSAGES mo_target = $${mo_targetpath}/ubuntu-ui-toolkit.mo !isEmpty(install_mo_commands): install_mo_commands += && install_mo_commands += test -d $$mo_targetpath || mkdir -p $$mo_targetpath install_mo_commands += && cp $$mo_file $$mo_target } install.commands = $$install_mo_commands QMAKE_EXTRA_TARGETS += install ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/uk.po0000644000015301777760000002272512321005637021365 0ustar pbusernogroup00000000000000# Ukrainian translation for ubuntu-ui-toolkit # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2014-01-16 21:18+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/sv.po0000644000015301777760000002274612321005637021401 0ustar pbusernogroup00000000000000# Swedish translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-07-03 11:17+0000\n" "Last-Translator: Joachim Johansson \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "Oändlig" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "värde = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/oc.po0000644000015301777760000002333512321005637021345 0ustar pbusernogroup00000000000000# Occitan (post 1500) translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-10-15 16:29+0000\n" "Last-Translator: Cédric VALMARY (Tot en òc) \n" "Language-Team: Occitan (post 1500) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "General" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "Aimentar" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "Rapida" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "Lenta" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "Acossomit" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "Sonar" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Color" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Icòna" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "Desactivar" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "Dobrir" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "Redimensionament" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "Legenda" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "Progression" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "Valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "Valor 2" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "Valor 3" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "Valor 4" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "Contraròtle" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "Mobil" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "Accion #1" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "Accion #2" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "Accion #3" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "Accion #4" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "Accion #5" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Barra de progression" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "Infinit" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/nl.po0000644000015301777760000002271512321005637021356 0ustar pbusernogroup00000000000000# Dutch translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-05-31 13:18+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/de.po0000644000015301777760000002510012321005637021324 0ustar pbusernogroup00000000000000# German translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-07-09 17:34+0000\n" "Last-Translator: Hendrik Knackstedt \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "NummerAnimation" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "Standard" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "Standarddauer" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "Einrasten" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "Schnell" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "Langsam" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "Schläfrig" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "Anruf" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Farbe" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Symbol" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "Deaktiviert" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "Öffnen" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "Skalieren" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "Kolorierung" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "Bezeichnung" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "Untertitelt" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "Untergeordnet Bezeichnung" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "Verlauf" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "Einfacher Wert" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Wert" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "Vielfacher Wert" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "Wert 1" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "Wert 2" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "Wert 3" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "Wert 4" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "Werteauswahl" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "Steuerung" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "Entfernbar" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "Zu entfernende Folie" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "Gruppierte Liste" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "Umschaltbar" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "Aktion #1" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "Aktion #2" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "Aktion #3" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "Aktion #4" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "Aktion #5" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Fortschrittsanzeige" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "Unendlich" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "Aktivitäts-Indikator" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" "Die Arbeit am visuellen Stil der Seite ist noch nicht abgeschlossen und " "sieht daher etwas unförmig aus." #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "Titel" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "Wert = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "Echtzeitaktualisierung" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "Bereich" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "Geben Sie mich ein …" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "Passwort" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "Zahlen" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "Vorgabe" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "Ausdehnung" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "Rich-Text" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "Nicht ausgewählt" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "Ausgewählt" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "Bild" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "Radius" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "Größen" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "Löschen" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "Längen" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "Gewichtungen" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "Aufruf: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "Optionen:" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "%1 erwartet ein zusätzliches Argument: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "%1 erwartet einen Wert für das Argument: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "%1 erwartet zusätzliche Argumente: %2" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "Alles auswählen" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "Wort auswählen" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "Ausschneiden" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "Kopieren" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "Einfügen" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "Rückgängig" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "Wiederherstellen" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "Zurück" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "Meine angepasste Seite" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" "Dies ist eine externe Seite\n" "mit einer gesperrten Werkzeugleiste." #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "Hauptseite" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "Seite eins" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "Externe Seite" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "Erste Seite" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "Hauptseite (nochmal)" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "Rotes Rechteck" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "Einfache Seite" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "Extern" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "Listenansicht" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/ca.po0000644000015301777760000002340212321005637021322 0ustar pbusernogroup00000000000000# Catalan translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-07-03 07:50+0000\n" "Last-Translator: David Planella \n" "Language-Team: Catalan \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "Estàndard" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "Ajustament" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "Ràpid" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "Lent" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "Trucada" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Color" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Icona" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "Inhabilitat" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "Etiqueta" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "Control" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Barra de progrés" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "Indicador d'activitat" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "Títol" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "Valor = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "Actualització en viu" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "Rang" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "Contrasenya" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "Números" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "Predeterminat" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "Imatge" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "Radi" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "Mides" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "Neteja" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "Llargades" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "Pesos" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "Opcions:" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "Selecciona-ho tot" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "Retalla" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "Copia" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "Enganxa" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "Desfés" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "Refés" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "Enrere" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/ubuntu-ui-toolkit.pot0000644000015301777760000002247512321005637024554 0ustar pbusernogroup00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/fi.po0000644000015301777760000002312712321005637021341 0ustar pbusernogroup00000000000000# Finnish translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-09-27 13:37+0000\n" "Last-Translator: Jiri Grönroos \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Väri" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Kuvake" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Arvo" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Edistymispalkki" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "Salasana" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "Oletus" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "Kuva" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "Käyttö: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "Valitse kaikki" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "Leikkaa" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "Kopioi" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "Liitä" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "Kumoa" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "Tee uudelleen" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "Edellinen" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "Ensimmäinen sivu" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/gl.po0000644000015301777760000002501512321005637021343 0ustar pbusernogroup00000000000000# Galician translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-07-21 20:10+0000\n" "Last-Translator: Miguel Anxo Bouzada \n" "Language-Team: Galician \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "Estándar" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "Duracións estándares" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "Axustar" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "Rápida" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "Lenta" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "Adurmiñado" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "Chamar" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Cor" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Icona" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "Desactivado" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "Aberto" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "Escala" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "Coloración" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "Etiqueta" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "Subtitulado" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "Etiqueta secundaria" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "Evolución" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "Valor único" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "Valor múltiple" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "Valor 1" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "Valor 2" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "Valor 3" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "Valor 4" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "Selector de valor" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "Control" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "Extraíbel" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "Deslice para retirar" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "Lista agrupada" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "Acción n.º 1" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "Acción n.º 2" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "Acción n.º 3" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "Acción n.º 4" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "Acción n.º 5" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Barra de progreso" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "Infinito" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "Indicador de actividade" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "Titulo" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "valor = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "Actualización en vivo" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "Intervalo" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "Escríbame..." #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "Contrasinal" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "Números" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "Predeterminado" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "Expansíbel" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "Texto mellorado" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "Non seleccionado" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "Seleccionado" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "Imaxe" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "Radio" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "Tamaños" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "Limpar" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "Lonxitudes" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "Pesos" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "Uso: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "Opcións:" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "%1 está agardando por un argumento adicional: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "%1 está agardando por un valor para o argumento: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "%1 está agardando por argumentos adicionais: %2" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "Selecionar todo" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "Seleccionar palabra" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "Cortar" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "Copiar" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "Pegar" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "Desfacer" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "Refacer" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "Atrás" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "A miña páxina personalizada" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" "Esta é unha páxina externa cunha\n" "barra de ferramentas bloqueada." #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "Páxina raíz" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "Primeira páxina" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "Páxina externa" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "Primeira páxina" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "Páxina raíz (outra vez)" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "Rectángulo vermello" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "Páxina única" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "Externa" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "Vista de lista" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/pt_BR.po0000644000015301777760000002275612321005637021760 0ustar pbusernogroup00000000000000# Brazilian Portuguese translation for ubuntu-ui-toolkit # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2014-01-10 16:05+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/my.po0000644000015301777760000002656012321005637021374 0ustar pbusernogroup00000000000000# Burmese translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-09-07 10:58+0000\n" "Last-Translator: Pyae Sone \n" "Language-Team: Burmese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "စံ" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "စံကြာချိန်များ" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "မြန်" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "နှေး" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "အိပ်ချင်" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "ခေါ်မည်" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "အရောင်" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Icon" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "ပိတ်ထား" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "ဖွင့်" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "အဆင့်" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "စာတမ်းထိုး" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "ဒုတိယအဆင့်" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "တိုးတက်မှု့" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "တန်ဖိုး" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "တန်ဖိုးအများအပြား" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "တန်ဖိုး ၁" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "တန်ဖိုး ၂" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "တန်ဖိုး ၃" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "တန်ဖိုး ၄" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "တန်ဖိုးရွေးချယ်မှု့" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "ထိန်းချုပ်" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "ဖြုတ်လို့ရသော" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "ဖြုတ်ရန် ဘေးသို့ဆွဲပါ" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "အုပ်စုစာရင်း" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "လုပ်ဆောင်ချက် #၁" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "လုပ်ဆောင်ချက် #၂" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "လုပ်ဆောင်ချက် #၃" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "လုပ်ဆောင်ချက် #၄" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "လုပ်ဆောင်ချက် #၅" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "လုပ်ဆောင်ခြင်းအတန်း" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "ခေါင်းစဉ်" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "တန်ဖိုး = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "အတိုင်းအတာ" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "စကားဝှက်" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "နံပါတ်များ" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "မူလပုံစံ" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "အမှန်ခြစ်ဖြုတ်" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "အမှန်ခြစ်မည်" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "ပုံ" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "အချင်း၀က်" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "အရွယ်အစားများ" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "ရှင်းလင်းမည်" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "အရှည်အလျား" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "အလေးချိန်" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "အသုံးပြုမှု့- " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "အားလုံးကို ရွေးချယ်ပါ" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "စကားလုံးကိုရွေးမည်" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "ဖြတ်" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "မိတ္တူ" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "ပွားယူ" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "နောက်ပြန်" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "ပြန်ပြင်ပါ" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "နောက်သို့" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "ကျွန်ုပ်စိတ်ကြိုက်စာမျက်နှာ" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "စာမျက်နှာ တစ်" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "နောက်အပိုစာမျက်နှာ" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "ပထမစာမျက်နှာ" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "အနီရောင်လေးထောင့်" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "ရိုးရိုးစာမျက်နှာ" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/fr.po0000644000015301777760000002271712321005637021356 0ustar pbusernogroup00000000000000# French translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-06-26 00:38+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/hu.po0000644000015301777760000002504712321005637021362 0ustar pbusernogroup00000000000000# Hungarian translation for ubuntu-ui-toolkit # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2014-01-07 18:39+0000\n" "Last-Translator: Gabor Kelemen \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "Általános" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "Szabványos hosszak" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "Illesztés" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "Gyors" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "Lassú" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "Álmos" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "Hívás" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "Szín" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "Ikon" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "Kikapcsolva" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "Nyitott" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "Átméretezés" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "Színezés" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "Címke" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "Feliratozott" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "Másodlagos címke" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "Előrehaladás" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "Egy értékű" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "Érték" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "Több értékű" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "1. érték" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "2. érték" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "3. érték" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "4. érték" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "Érték kiválasztó" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "Vezérlő" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "Eltávolítható" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "Csúsztassa az eltávolításhoz" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "Csoportosított lista" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "1. művelet" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "2. művelet" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "3. művelet" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "4. művelet" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "5. művelet" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "Állapotjelző" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "Végtelen" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "Aktivitás jelző" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "A lap vizuális stílusa kiinduló munka, és emiatt néz ki otrombán." #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "Fejléc" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "érték = %1" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "Élő frissítés" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "Tartomány" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "Gépeljen ide" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "Jelszó" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "Számok" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "Alapértelmezett" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "Kiterjesztett" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "Nem bejelölt" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "Bejelölt" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "Kép" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "Sugár" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "Méretek" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "Törlés" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "Hosszúságok" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "Súlyok" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "Használat: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "Beállítások:" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "A %1 egy további paramétert vár: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "A %1 egy értéket vár a következő paraméterhez: %2" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "A %1 további paramétereket vár: %2" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "Minden kijelölése" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "Szó kijelölése" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "Kivágás" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "Másolás" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "Beillesztés" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "Visszavonás" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "Újra" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "Vissza" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "Személyes lapom" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" "Ez egy külső lap\n" "zárolt eszköztárral." #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "Gyökér lap" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "Első lap" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "Külső lap" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "Első lap" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "Gyökér lap (újra)" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "Piros négyszög" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "Egyszerű lap" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "Külső" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "Listanézet" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/po/he.po0000644000015301777760000002374312321005637021343 0ustar pbusernogroup00000000000000# Hebrew translation for ubuntu-ui-toolkit # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the ubuntu-ui-toolkit package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: ubuntu-ui-toolkit\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-05-30 14:06+0200\n" "PO-Revision-Date: 2013-07-03 08:23+0000\n" "Last-Translator: Yaron \n" "Language-Team: Hebrew \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-04-08 07:08+0000\n" "X-Generator: Launchpad (build 16976)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 msgid "NumberAnimation" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:25 #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:27 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:23 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:59 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:38 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:71 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:25 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:44 msgid "Standard" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:56 msgid "Standard Durations" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:60 msgid "Snap" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:96 msgid "Fast" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:132 msgid "Slow" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:157 msgid "Sleepy" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:28 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:36 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:50 #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:59 msgid "Call" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:33 #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:26 msgid "Color" msgstr "צבע" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:42 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:41 msgid "Icon" msgstr "סמל" #: examples/ubuntu-ui-toolkit-gallery/Buttons.qml:56 #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:73 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:75 msgid "Disabled" msgstr "מנוטרל" #: examples/ubuntu-ui-toolkit-gallery/Dialog.qml:30 #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:42 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:41 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:74 msgid "Open" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:25 msgid "Scaling" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Icons.qml:50 msgid "Colorization" msgstr "צביעה" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:26 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:34 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:44 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:53 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:62 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:71 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:83 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:95 msgid "Label" msgstr "תווית" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:31 msgid "Subtitled" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:35 msgid "Secondary label" msgstr "תווית משנית" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:50 msgid "Progression" msgstr "התקדמות" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:59 msgid "Single value" msgstr "ערך יחיד" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:63 msgid "Value" msgstr "ערך" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:68 msgid "Multi value" msgstr "ריבוי ערכים" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:72 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:84 msgid "Value 1" msgstr "ערך 1" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:73 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:85 msgid "Value 2" msgstr "ערך 2" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:74 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:86 msgid "Value 3" msgstr "ערך 3" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:75 #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:87 msgid "Value 4" msgstr "ערך 4" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:80 msgid "Value selector" msgstr "בוחר ערכים" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:92 msgid "Control" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:103 msgid "Removable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:106 msgid "Slide to remove" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ListItems.qml:116 msgid "Grouped list" msgstr "רשימה מקובצת" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:38 msgid "Flickable" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:74 msgid "Action #1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:78 msgid "Action #2" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:82 msgid "Action #3" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:86 msgid "Action #4" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Popover.qml:90 msgid "Action #5" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:22 msgid "Progress Bar" msgstr "פס התקדמות" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:45 msgid "Infinite" msgstr "אינסופי" #: examples/ubuntu-ui-toolkit-gallery/ProgressBars.qml:55 msgid "Activity Indicator" msgstr "מחוון פעילות" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:26 msgid "The visual style of the Sheet is early work and thus clunky looking." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:51 #: examples/ubuntu-ui-toolkit-gallery/Sheet.qml:84 msgid "Title" msgstr "כותרת" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:32 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:45 #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:60 #, qt-format msgid "value = %1" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:37 msgid "Live Update" msgstr "עדכון חי" #: examples/ubuntu-ui-toolkit-gallery/Sliders.qml:50 msgid "Range" msgstr "טווח" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:47 msgid "Type me in..." msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:53 msgid "Password" msgstr "ססמה" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:63 msgid "Numbers" msgstr "מספרים" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:87 msgid "Default" msgstr "בררת מחדל" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:96 msgid "Expanding" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/TextInputs.qml:107 msgid "Rich Text" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:26 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:60 msgid "Unchecked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:33 #: examples/ubuntu-ui-toolkit-gallery/Toggles.qml:67 msgid "Checked" msgstr "" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:44 msgid "Image" msgstr "תמונה" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:57 msgid "Radius" msgstr "רדיוס" #: examples/ubuntu-ui-toolkit-gallery/UbuntuShape.qml:87 msgid "Sizes" msgstr "גדלים" #: examples/unit-converter/unit-converter.qml:147 msgid "Clear" msgstr "ניקוי" #: examples/unit-converter/unit-converter.qml:161 msgid "Lengths" msgstr "אורכים" #: examples/unit-converter/unit-converter.qml:179 msgid "Weights" msgstr "גבהים" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:188 msgid "Usage: " msgstr "שימוש: " #: modules/Ubuntu/Components/plugin/ucarguments.cpp:209 msgid "Options:" msgstr "אפשרויות:" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:498 #, qt-format msgid "%1 is expecting an additional argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:503 #, qt-format msgid "%1 is expecting a value for argument: %2" msgstr "" #: modules/Ubuntu/Components/plugin/ucarguments.cpp:520 #, qt-format msgid "%1 is expecting additional arguments: %2" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:24 msgid "Select All" msgstr "בחירת הכול" #: modules/Ubuntu/Components/TextInputPopover.qml:29 msgid "Select Word" msgstr "" #: modules/Ubuntu/Components/TextInputPopover.qml:34 msgid "Cut" msgstr "גזירה" #: modules/Ubuntu/Components/TextInputPopover.qml:39 msgid "Copy" msgstr "העתקה" #: modules/Ubuntu/Components/TextInputPopover.qml:44 msgid "Paste" msgstr "הדבקה" #: modules/Ubuntu/Components/TextInputPopover.qml:49 msgid "Undo" msgstr "ביטול" #: modules/Ubuntu/Components/TextInputPopover.qml:54 msgid "Redo" msgstr "ביצוע חוזר" #: modules/Ubuntu/Components/ToolbarActions.qml:86 msgid "Back" msgstr "חזרה" #: tests/resources/pagestack/MyCustomPage.qml:21 #: tests/resources/tabs/MyCustomPage.qml:21 msgid "My custom page" msgstr "" #: tests/resources/pagestack/MyCustomPage.qml:33 #: tests/resources/tabs/MyCustomPage.qml:33 msgid "" "This is an external page\n" "with a locked toolbar." msgstr "" #: tests/resources/pagestack/PageStack.qml:38 msgid "Root page" msgstr "" #: tests/resources/pagestack/PageStack.qml:44 msgid "Page one" msgstr "" #: tests/resources/pagestack/PageStack.qml:49 msgid "External page" msgstr "" #: tests/resources/pagestack/PageStack.qml:58 msgid "First page" msgstr "" #: tests/resources/pagestack/PageStack.qml:64 msgid "Root page (again)" msgstr "" #: tests/resources/pagestack/PageStack.qml:69 msgid "Red rectangle" msgstr "" #: tests/resources/tabs/Tabs.qml:32 msgid "Simple page" msgstr "" #: tests/resources/tabs/Tabs.qml:77 msgid "External" msgstr "חיצוני" #: tests/resources/tabs/Tabs.qml:85 msgid "List view" msgstr "תצוגת רשימה" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/mkspecs/0000755000015301777760000000000012321006415021420 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/run_tests.sh0000755000015301777760000000161112321005637022344 0ustar pbusernogroup00000000000000#!/bin/bash # # Copyright 2012, 2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # cd tests/autopilot echo running with arg: $1 UBUNTU_UI_TOOLKIT_AUTOPILOT_FROM_SOURCE=1 if [ "$1" == "" ]; then python3 -m autopilot.run run ubuntuuitoolkit else python3 -m autopilot.run run -o ../../$1 -f xml -r -rd ../../ ubuntuuitoolkit fi exit 0 ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/components.api0000644000015301777760000006503612321005670022647 0ustar pbusernogroup00000000000000modules/Ubuntu/Components/AbstractButton.qml ActionItem signal clicked() signal pressAndHold() property bool pressed property bool hovered property bool __acceptEvents property internal __mouseArea modules/Ubuntu/Components/Action.qml UnityActions.Action property url iconSource property string iconName property bool visible property Component itemHint modules/Ubuntu/Components/ActionItem.qml StyledItem property Action action property string text property url iconSource property string iconName signal triggered(var value) function trigger(value) modules/Ubuntu/Components/ActionList.qml QtObject default property list children property list actions modules/Ubuntu/Components/ActivityIndicator.qml AnimatedItem property bool running modules/Ubuntu/Components/Button.qml AbstractButton property color color property Gradient gradient property string iconPosition modules/Ubuntu/Components/CheckBox.qml AbstractButton property bool checked modules/Ubuntu/Components/Colors/UbuntuColors.qml QtObject readonly property color orange readonly property color lightAubergine readonly property color midAubergine readonly property color darkAubergine readonly property color warmGrey readonly property color coolGrey property Gradient orangeGradient property Gradient greyGradient modules/Ubuntu/Components/CrossFadeImage.qml Item property url source property int fillMode property int fadeDuration readonly property bool running property size sourceSize readonly property int status modules/Ubuntu/Components/Header.qml StyledItem property bool animate function show() function hide() property string title property Item contents property Flickable flickable modules/Ubuntu/Components/Icon.qml Item property string name property color color property color keyColor modules/Ubuntu/Components/Label.qml Text property string fontSize modules/Ubuntu/Components/ListItems/Base.qml Empty property variant icon property url iconSource property string iconName property url fallbackIconSource property string fallbackIconName property bool progression property bool iconFrame property real __iconWidth property real __iconHeight property real __leftIconMargin property real __rightIconMargin property bool __iconIsItem property internal children modules/Ubuntu/Components/ListItems/Caption.qml Item property string text modules/Ubuntu/Components/ListItems/Divider.qml Image modules/Ubuntu/Components/ListItems/Empty.qml AbstractButton property bool selected property bool highlightWhenPressed property bool removable property bool confirmRemoval readonly property string swipingState readonly property bool waitingConfirmationForRemoval signal itemRemoved property int __height property bool showDivider default property internal children property internal __contents property list backgroundIndicator property ThinDivider divider property real __contentsMargins function cancelItemRemoval() modules/Ubuntu/Components/ListItems/Expandable.qml Empty property bool expanded property real collapsedHeight property real expandedHeight property bool collapseOnClick default property QtObject children modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml Flickable readonly property Item expandedItem function expandItem(item) function collapse() default property QtObject children modules/Ubuntu/Components/ListItems/Header.qml Item property string text property internal __foregroundColor modules/Ubuntu/Components/ListItems/ItemSelector.qml ListItem.Empty property var model property bool expanded property bool multiSelection property bool colourImage property real containerHeight property int selectedIndex property bool currentlyExpanded readonly property real itemHeight signal delegateClicked(int index) signal expansionCompleted() modules/Ubuntu/Components/ListItems/MultiValue.qml Base property variant values modules/Ubuntu/Components/ListItems/SingleControl.qml Empty property Item control function __updateControl() modules/Ubuntu/Components/ListItems/SingleValue.qml Base property string value modules/Ubuntu/Components/ListItems/Standard.qml Empty property variant icon property url iconSource property string iconName property url fallbackIconSource property string fallbackIconName property bool progression property real __iconWidth property real __iconHeight property real __leftIconMargin property real __rightIconMargin property Item control property bool iconFrame property bool __controlAreaPressed property bool __iconIsItem property internal __foregroundColor modules/Ubuntu/Components/ListItems/Subtitled.qml Base property string text property string subText modules/Ubuntu/Components/ListItems/ThinDivider.qml Image modules/Ubuntu/Components/ListItems/ValueSelector.qml Empty property variant icon property url iconSource property string iconName property url fallbackIconSource property string fallbackIconName property real __iconWidth property real __iconHeight property real __leftIconMargin property real __rightIconMargin property bool iconFrame property variant values property int selectedIndex property bool expanded modules/Ubuntu/Components/MainView.qml PageTreeNode property string applicationName property bool anchorToKeyboard property color headerColor property color backgroundColor property color footerColor property bool automaticOrientation property bool useDeprecatedToolbar default property internal contentsItem property list actions property UnityActions.ActionManager actionManager modules/Ubuntu/Components/Object.qml QtObject default property internal children modules/Ubuntu/Components/OptionSelector.qml ListItem.Empty property var model property bool expanded property bool multiSelection property bool colourImage property real containerHeight property int selectedIndex property bool currentlyExpanded readonly property real itemHeight signal delegateClicked(int index) signal expansionCompleted() modules/Ubuntu/Components/OptionSelectorDelegate.qml ListItem.Standard property string text property string subText property url icon property url iconSource property string iconName property bool constrainImage property bool colourImage property color assetColour readonly property ListView listView readonly property string fragColourShader modules/Ubuntu/Components/OrientationHelper.qml Item property bool automaticOrientation property bool transitionEnabled property alias rotating property int __orientationAngle property int orientationAngle modules/Ubuntu/Components/Page.qml PageTreeNode property string title property Flickable flickable property list actions modules/Ubuntu/Components/PageStack.qml PageTreeNode property bool __showHeader property int depth property Item currentPage function push(page, properties) function pop() function clear() modules/Ubuntu/Components/Panel.qml Item default property list contents property int align property bool opened function open() function close() property int hideTimeout property bool locked property real hintSize property real triggerSize readonly property real position property bool animate readonly property bool animating property bool __closeOnContentsClicks property bool __openOnHover property bool pressed modules/Ubuntu/Components/Pickers/DatePicker.qml StyledItem property string mode property date date property date minimum property date maximum readonly property int year readonly property int month readonly property int day readonly property int week readonly property int hours readonly property int minutes readonly property int seconds property var locale readonly property bool moving modules/Ubuntu/Components/Pickers/Dialer.qml StyledItem property real minimumValue property real maximumValue property real size property real handSpace readonly property Item centerItem property list centerContent readonly property list hands signal handUpdated(var hand) modules/Ubuntu/Components/Pickers/DialerHand.qml StyledItem property real value property DialerHandGroup hand readonly property Dialer dialer default property list overlay readonly property int index property internal __grabber modules/Ubuntu/Components/Pickers/Picker.qml StyledItem property bool circular property var model property Component delegate property int selectedIndex property bool live readonly property bool moving function positionViewAtIndex(index) property int __clickedIndex modules/Ubuntu/Components/Pickers/PickerDelegate.qml AbstractButton readonly property Picker picker modules/Ubuntu/Components/Pickers/PickerPanel.qml Object function openDatePicker(caller, property, mode) modules/Ubuntu/Components/Popups/ActionSelectionPopover.qml Popover property Item target property var actions property Component delegate modules/Ubuntu/Components/Popups/ComposerSheet.qml SheetBase signal cancelClicked signal confirmClicked modules/Ubuntu/Components/Popups/DefaultSheet.qml SheetBase property bool doneButton signal closeClicked signal doneClicked modules/Ubuntu/Components/Popups/Dialog.qml PopupBase default property list contents property string title property string text property Item caller property Item pointerTarget property real edgeMargins property real callerMargin property bool modal modules/Ubuntu/Components/Popups/Popover.qml PopupBase default property list container property real contentWidth property real contentHeight property Item caller property Item pointerTarget property real edgeMargins property real callerMargin property bool autoClose property Component foregroundStyle function show() function hide() function __makeInvisible() modules/Ubuntu/Components/Popups/PopupBase.qml OrientationHelper property Item dismissArea property bool grabDismissAreaEvents function show() function hide() function __closeIfHidden() function __closePopup() property Item __foreground property bool __closeOnDismissAreaPress property internal __dimBackground property internal __eventGrabber modules/Ubuntu/Components/Popups/SheetBase.qml PopupBase default property list container property real contentsWidth property real contentsHeight property string title property bool modal property internal __leftButton property internal __rightButton modules/Ubuntu/Components/ProgressBar.qml AnimatedItem property bool indeterminate property real minimumValue property real maximumValue property real value modules/Ubuntu/Components/Scrollbar.qml StyledItem property Flickable flickableItem property int align property bool __interactive property internal __private modules/Ubuntu/Components/Slider.qml StyledItem property real minimumValue property real maximumValue property real value property bool live property bool pressed signal touched(bool onThumb) function formatValue(v) property internal __internals modules/Ubuntu/Components/StyledItem.qml FocusScope property Component style readonly property Item __styleInstance modules/Ubuntu/Components/Switch.qml CheckBox modules/Ubuntu/Components/Tab.qml PageTreeNode property string title property url iconSource property Item page readonly property int index property internal __protected modules/Ubuntu/Components/TabBar.qml StyledItem property Item tabsItem property var model readonly property bool pressed property bool selectionMode property int selectedIndex property bool alwaysSelectionMode property bool animate modules/Ubuntu/Components/Tabs.qml PageTreeNode property int selectedTabIndex readonly property Tab selectedTab readonly property Item currentPage property TabBar tabBar default property list tabChildren readonly property int count signal modelChanged() modules/Ubuntu/Components/TextArea.qml StyledItem property bool highlighted property string placeholderText readonly property string displayText property bool selectByMouse property bool autoExpand property bool autoSize property int maximumLineCount property real contentWidth property real contentHeight property var popover property bool activeFocusOnPress property url baseUrl property bool canPaste property bool canRedo property bool canUndo property color color property Component cursorDelegate property int cursorPosition property rectangle cursorRectangle property bool cursorVisible property enumeration effectiveHorizontalAlignment property font font property enumeration horizontalAlignment property bool inputMethodComposing property enumeration inputMethodHints property int length property int lineCount property enumeration mouseSelectionMode property enumeration persistentSelection property bool readOnly property enumeration renderType property string selectedText property color selectedTextColor property color selectionColor property int selectionEnd property int selectionStart property string text property enumeration textFormat property enumeration verticalAlignment property enumeration wrapMode signal linkActivated(string link) function copy() function cut() function deselect() function insert(position, text) function positionAt(x, y) function isRightToLeft(start, end) function moveCursorSelection(position, mode) function paste(data) function positionToRectangle(position) function redo() function select(start, end) function selectAll() function selectWord() function getFormattedText(start, end) function getText(start, end) function remove(start, end) function undo() function forceActiveFocus() property internal __internal modules/Ubuntu/Components/TextField.qml ActionItem property bool highlighted property string placeholderText property bool hasClearButton property Component customSoftwareInputPanel property var popover property list primaryItem property list secondaryItem property bool errorHighlight property bool acceptableInput property bool activeFocusOnPress property bool autoScroll property bool canPaste property bool canRedo property bool canUndo property color color property real contentHeight property real contentWidth property Component cursorDelegate property int cursorPosition property rectangle cursorRectangle property bool cursorVisible property string displayText property enumeration echoMode property font font property string inputMask property bool inputMethodComposing property enumeration inputMethodHints property int length property int maximumLength property enumeration mouseSelectionMode property bool persistentSelection property bool readOnly property enumeration renderType property bool selectByMouse readonly property string selectedText property int selectionStart property int selectionEnd property string text property Validator validator property enumeration horizontalAlignment property enumeration effectiveHorizontalAlignment property enumeration verticalAlignment property string passwordCharacter property color selectionColor property color selectedTextColor signal accepted() function copy() function cut() function paste(data) function deselect() function insert(position, text) function positionAt(x, position) function positionToRectangle(pos) function select(start, end) function selectAll() function selectWord() function forceActiveFocus() function isRightToLeft(start, end) function moveCursorSelection(position, mode) function redo() function undo() function remove(start, end) function getText(start, end) property internal __internal modules/Ubuntu/Components/Themes/Palette.qml QtObject property PaletteValues normal property PaletteValues selected modules/Ubuntu/Components/Themes/PaletteValues.qml QtObject property color background property color backgroundText property color base property color baseText property color foreground property color foregroundText property color overlay property color overlayText property color field property color fieldText modules/Ubuntu/Components/ToolbarButton.qml ActionItem modules/Ubuntu/Components/ToolbarItems.qml Item default property list contents property Item back property Item pageStack property bool opened property bool locked modules/Ubuntu/Components/UbuntuListView.qml ListView property int expandedIndex modules/Ubuntu/Components/UbuntuNumberAnimation.qml NumberAnimation modules/Ubuntu/Components/UbuntuShape.qml Item property color color property color gradientColor property string radius property Item image property url borderSource modules/Ubuntu/PerformanceMetrics/PerformanceOverlay.qml Item property bool active modules/Ubuntu/Test/UbuntuTestCase.qml TestCase function findChild(obj,objectName) function findInvisibleChild(obj,objectName) function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay) function tryCompareFunction(func, expectedResult, timeout) plugins.qmltypes name: "InverseMouseAreaType" prototype: "QQuickMouseArea" exports: ["InverseMouseArea 0.1"] Property { name: "sensingArea"; type: "QQuickItem"; isPointer: true } Property { name: "topmostItem"; type: "bool" } Method { name: "contains" Parameter { name: "point"; type: "QPointF" } name: "ShapeItem" prototype: "QQuickItem" exports: ["Shape 0.1"] name: "HAlignment" name: "VAlignment" Property { name: "color"; type: "QColor" } Property { name: "gradientColor"; type: "QColor" } Property { name: "radius"; type: "string" } Property { name: "image"; type: "QVariant" } Property { name: "stretched"; type: "bool" } Property { name: "horizontalAlignment"; type: "HAlignment" } Property { name: "verticalAlignment"; type: "VAlignment" } Property { name: "borderSource"; type: "string" } Signal { name: "borderChanged" } Method { name: "gridUnitChanged" } name: "UCAlarm" prototype: "QObject" exports: ["Alarm 0.1"] name: "Status" name: "Operation" name: "Error" name: "AlarmType" name: "DayOfWeek" name: "DaysOfWeek" Property { name: "enabled"; type: "bool" } Property { name: "message"; type: "string" } Property { name: "date"; type: "QDateTime" } Property { name: "type"; type: "AlarmType" } Property { name: "daysOfWeek"; type: "DaysOfWeek" } Property { name: "sound"; type: "QUrl" } Property { name: "error"; type: "int"; isReadonly: true } Property { name: "status"; type: "Status"; isReadonly: true } Signal { name: "statusChanged" Parameter { name: "operation"; type: "Operation" } Method { name: "save" } Method { name: "cancel" } Method { name: "reset" } name: "UCAlarmModel" prototype: "QAbstractListModel" exports: ["AlarmModel 0.1"] Property { name: "count"; type: "int"; isReadonly: true } Method { name: "get" Parameter { name: "index"; type: "int" } name: "UCArgument" prototype: "QObject" exports: ["Argument 0.1"] Property { name: "name"; type: "string" } Property { name: "help"; type: "string" } Property { name: "required"; type: "bool" } Property { name: "valueNames"; type: "QStringList" } Method { name: "at" Parameter { name: "i"; type: "int" } name: "UCArguments" prototype: "QObject" exports: ["Arguments 0.1"] Property { name: "defaultArgument"; type: "UCArgument"; isPointer: true } Property { name: "arguments"; type: "UCArgument"; isList: true; isReadonly: true } Property { name: "values"; type: "QQmlPropertyMap"; isReadonly: true; isPointer: true } Property { name: "error"; type: "bool"; isReadonly: true } Property { name: "errorMessage"; type: "string"; isReadonly: true } Method { name: "printUsage" } Method { name: "quitWithError" Parameter { name: "errorMessage"; type: "string" } Method { name: "quitWithError" } name: "UCInverseMouse" prototype: "UCMouse" exports: ["InverseMouse 0.1"] name: "UCMouse" prototype: "QObject" exports: ["Mouse 0.1"] name: "Priority" Property { name: "enabled"; type: "bool" } Property { name: "acceptedButtons"; type: "Qt::MouseButtons"; isReadonly: true } Property { name: "hoverEnabled"; type: "bool"; isReadonly: true } Property { name: "clickAndHoldThreshold"; type: "int" } Property { name: "forwardTo"; type: "QQuickItem"; isList: true; isReadonly: true } Property { name: "priority"; type: "Priority" } Signal { name: "pressed" Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "released" Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "clicked" Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "pressAndHold" Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "doubleClicked" Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "positionChanged" Parameter { name: "mouse"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "entered" Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } Signal { name: "exited" Parameter { name: "event"; type: "QQuickMouseEvent"; isPointer: true } name: "UCQQuickImageExtension" prototype: "QQuickImageBase" exports: ["QQuickImageBase 0.1"] Property { name: "source"; type: "QUrl" } Signal { name: "sourceChanged" Parameter { type: "QUrl" } Signal { name: "sourceChanged" Parameter { type: "QUrl" } name: "UCStateSaver" prototype: "QObject" exports: ["StateSaver 0.1"] name: "UCStateSaverAttached" prototype: "QObject" Property { name: "enabled"; type: "bool" } Property { name: "properties"; type: "string" } name: "UCUbuntuAnimation" prototype: "QObject" exports: ["UbuntuAnimation 0.1"] Property { name: "SnapDuration"; type: "int"; isReadonly: true } Property { name: "FastDuration"; type: "int"; isReadonly: true } Property { name: "BriskDuration"; type: "int"; isReadonly: true } Property { name: "SlowDuration"; type: "int"; isReadonly: true } Property { name: "SleepyDuration"; type: "int"; isReadonly: true } Property { name: "StandardEasing"; type: "QEasingCurve"; isReadonly: true } Property { name: "StandardEasingReverse"; type: "QEasingCurve"; isReadonly: true } name: "UCUnits" prototype: "QObject" exports: ["UCUnits 0.1"] Property { name: "gridUnit"; type: "float" } Method { name: "dp" Parameter { name: "value"; type: "float" } Method { name: "gu" Parameter { name: "value"; type: "float" } name: "UCUriHandler" prototype: "QObject" exports: ["UriHandler 0.1"] Signal { name: "opened" Parameter { name: "uris"; type: "QStringList" } name: "UbuntuI18n" prototype: "QObject" exports: ["i18n 0.1"] Property { name: "domain"; type: "string" } Property { name: "language"; type: "string" } Method { name: "bindtextdomain" Parameter { name: "domain_name"; type: "string" } Parameter { name: "dir_name"; type: "string" } Method { name: "tr" Parameter { name: "text"; type: "string" } Method { name: "tr" Parameter { name: "singular"; type: "string" } Parameter { name: "plural"; type: "string" } Parameter { name: "n"; type: "int" } Method { name: "dtr" Parameter { name: "domain"; type: "string" } Parameter { name: "text"; type: "string" } Method { name: "dtr" Parameter { name: "domain"; type: "string" } Parameter { name: "singular"; type: "string" } Parameter { name: "plural"; type: "string" } Parameter { name: "n"; type: "int" } name: "ULConditionalLayout" prototype: "QObject" exports: ["ConditionalLayout 0.1"] Property { name: "name"; type: "string" } Property { name: "when"; type: "QQmlBinding"; isPointer: true } Property { name: "layout"; type: "QQmlComponent"; isPointer: true } name: "ULItemLayout" prototype: "QQuickItem" exports: ["ItemLayout 0.1"] Property { name: "item"; type: "string" } name: "ULLayouts" prototype: "QQuickItem" exports: ["Layouts 0.1"] Property { name: "currentLayout"; type: "string"; isReadonly: true } Property { name: "layouts"; type: "ULConditionalLayout"; isList: true; isReadonly: true } name: "ULLayoutsAttached" prototype: "QObject" Property { name: "item"; type: "string" } name: "UPMCpuUsage" prototype: "QQuickItem" exports: ["CpuUsage 0.1"] Property { name: "graphModel"; type: "UPMGraphModel"; isReadonly: true; isPointer: true } Property { name: "period"; type: "int" } Property { name: "samplingInterval"; type: "int" } name: "UPMGraphModel" prototype: "QObject" Property { name: "image"; type: "QImage"; isReadonly: true } Property { name: "shift"; type: "int"; isReadonly: true } Property { name: "samples"; type: "int" } Property { name: "currentValue"; type: "int"; isReadonly: true } name: "UPMRenderingTimes" prototype: "QQuickItem" exports: ["RenderingTimes 0.1"] Property { name: "period"; type: "int" } Property { name: "samples"; type: "int" } Property { name: "graphModel"; type: "UPMGraphModel"; isReadonly: true; isPointer: true } Property { name: "timerType"; type: "RenderTimer::TimerType" } Signal { name: "frameRendered" Parameter { name: "renderTime"; type: "qlonglong" } name: "UPMTextureFromImage" prototype: "QQuickItem" exports: ["TextureFromImage 0.1"] Property { name: "image"; type: "QImage" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/COPYING0000644000015301777760000001674312321005637021026 0ustar pbusernogroup00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/scripts/0000755000015301777760000000000012321006415021442 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/scripts/pre-execution.sh0000755000015301777760000000122612321005637024576 0ustar pbusernogroup00000000000000#!/bin/bash # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # cd $1 qmake make ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/0000755000015301777760000000000012321006415022370 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/TEST_TEMPLATE.txt0000644000015301777760000000133512321005637025212 0ustar pbusernogroup00000000000000#Please use this template for adding new manual-tests to ensure a consistency. #Text to be changed is enclosed in <<>> # #Please also note that Tests should test ONE THING ONLY. If you want to test #more than one thing, write multiple tests. That helps us to automate them as #well as execute them manually. # #If you're testing purely visual changes, please make sure you link to a #reference image or add it to the bzr repository. <> ---------------------------------------------------- <> Setup: <> Actions: <> Expected Result: <> ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/compile_testcaseexecutor.sh0000755000015301777760000000124412321005637030037 0ustar pbusernogroup00000000000000#!/bin/bash # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # cd testcaseexecutor qmake make ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/tst_button_lmb-on-enabled-disabled.txt0000644000015301777760000000070612321005637031747 0ustar pbusernogroup00000000000000QML Button Mouse Events - LMB click on Enabled/disabled ---------------------------------------------------- Disable button, click button, Enable button, click button Setup: N/A Actions: #. Disable Button #. Click button #. Enable Button #. Click button Expected Result: #. button is disabled, color is <> #. no clicked() signal is emitted #. color is color, button is enabled #. clicked() signal is emitted Glossary: MLB = Mouse Left Button ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/tst_button_iconPosition.txt0000644000015301777760000000051512321005637030101 0ustar pbusernogroup00000000000000QML Button Mouse Events - iconPosition ---------------------------------------------------- button iconPosition Setup: N/A Actions: #. Set iconSource #. Set iconPosition to left #. Set iconPosition to right Expected Result: #. iconSource is set and icon is loaded #. icon to left of text #. icon to right of text Glossary: N/A ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/0000755000015301777760000000000012321006415025762 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/tst_manualtestcase.h0000644000015301777760000000215712321005637032050 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #ifndef TST_MANUALTESTCASE_H #define TST_MANUALTESTCASE_H #include #include class tst_manualtestcase : public QObject { Q_OBJECT public: explicit tst_manualtestcase(QObject *parent = 0); private slots: void list(); void run(); protected: void runTest(QString testcase, QString testdata, QString qmlFile); QStringList m_testCases; }; #endif // TST_MANUALTESTCASE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/testcaseexecutiondialog.cpp0000644000015301777760000000620612321005637033416 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #include "testcaseexecutiondialog.h" #include "ui_testcaseexecutiondialog.h" #include TestCaseExecutionDialog::TestCaseExecutionDialog(QString testcase, QString testdata, QUrl qmlFile, QWidget *parent) : QDialog(parent), m_declarativeView(new QDeclarativeView), m_ui(new Ui::TestCaseExecutionDialog) { m_ui->setupUi(this); m_ui->plainTextEdit->setPlainText(testdata); this->setWindowTitle(testcase); m_ui->horizontalLayout->addWidget(m_declarativeView); QFile qmldata(qmlFile.toLocalFile()); QString data; if (qmldata.open(QIODevice::ReadOnly)) { data = qmldata.readAll(); qmldata.close(); } m_ui->plainTextEdit_2->setPlainText(data); QTemporaryFile tmpQmlFile; tmpQmlFile.open(); tmpQmlFile.write(data.toAscii()); tmpQmlFile.close(); qDebug() << "using temporary file" << tmpQmlFile.fileName(); m_declarativeView->engine()->addImportPath("../modules/"); QGLFormat format = QGLFormat::defaultFormat(); format.setSampleBuffers(false); format.setSwapInterval(1); QGLWidget *glWidget = new QGLWidget(format); glWidget->setAttribute(Qt::WA_TranslucentBackground, false); m_declarativeView->setAttribute(Qt::WA_TranslucentBackground, false); m_declarativeView->setAttribute(Qt::WA_NoSystemBackground, true); m_declarativeView->setAttribute(Qt::WA_OpaquePaintEvent, true); m_declarativeView->setViewport(glWidget); m_declarativeView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); m_declarativeView->setSource(QUrl::fromLocalFile(tmpQmlFile.fileName())); m_declarativeView->show(); m_declarativeView->viewport()->setFocusPolicy(Qt::StrongFocus); } void TestCaseExecutionDialog::on_pushButton_clicked() { QTemporaryFile tmpQmlFile; tmpQmlFile.open(); tmpQmlFile.write(m_ui->plainTextEdit_2->toPlainText().toAscii()); tmpQmlFile.close(); m_declarativeView->engine()->clearComponentCache(); m_declarativeView->setSource(QUrl::fromLocalFile(tmpQmlFile.fileName())); } TestCaseExecutionDialog::~TestCaseExecutionDialog() { delete m_ui; } void TestCaseExecutionDialog::on_pushButtonQuit_clicked() { QApplication::quit(); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/testcaseexecutor.pro0000644000015301777760000000175012321005637032106 0ustar pbusernogroup00000000000000# # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # Author: Juhapekka Piiroinen # QT += declarative testlib opengl TARGET = testcase CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += \ tst_manualtestcase.cpp \ testcaseexecutiondialog.cpp HEADERS += \ tst_manualtestcase.h \ testcaseexecutiondialog.h FORMS += \ testcaseexecutiondialog.ui ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/testcaseexecutiondialog.h0000644000015301777760000000245412321005637033064 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #ifndef TESTCASEEXECUTIONDIALOG_H #define TESTCASEEXECUTIONDIALOG_H #include #include namespace Ui { class TestCaseExecutionDialog; } class TestCaseExecutionDialog : public QDialog { Q_OBJECT public: explicit TestCaseExecutionDialog(QString testcase, QString testdata, QUrl qmlFile, QWidget *parent = 0); ~TestCaseExecutionDialog(); protected slots: void on_pushButton_clicked(); void on_pushButtonQuit_clicked(); private: QDeclarativeView* m_declarativeView; Ui::TestCaseExecutionDialog *m_ui; }; #endif // TESTCASEEXECUTIONDIALOG_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/tst_manualtestcase.cpp0000644000015301777760000000351712321005637032404 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #include "tst_manualtestcase.h" #include "testcaseexecutiondialog.h" #include #include #include tst_manualtestcase::tst_manualtestcase(QObject *parent) : QObject(parent) { } void tst_manualtestcase::run() { foreach (QString testcase, m_testCases) { qDebug() << "Starting" << testcase; qDebug() << "Loading data to QDeclarativeView"; QString testfile = testcase.split("_").takeAt(1) + ".qml"; QFile test(testcase); if (test.open(QIODevice::ReadOnly)) { QString testdata = test.readAll(); test.close(); runTest(testcase,testdata,testfile); } } } void tst_manualtestcase::list() { QDir currentDirectory = QDir::currentPath(); m_testCases = currentDirectory.entryList(QStringList() << "tst*.txt"); qDebug() << m_testCases; } void tst_manualtestcase::runTest(QString testcase, QString testdata, QString qmlFile) { TestCaseExecutionDialog testcaseExecutor(testcase,testdata,QUrl::fromLocalFile(qmlFile)); int result = testcaseExecutor.exec(); QVERIFY((result==1)); } QTEST_MAIN(tst_manualtestcase) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/testcaseexecutor/testcaseexecutiondialog.ui0000644000015301777760000001024612321005637033250 0ustar pbusernogroup00000000000000 TestCaseExecutionDialog 0 0 758 517 Dialog Quit manual testing QML 0 0 Source Code 0 0 Apply 0 0 Manual Test 0 0 Was the manual test passed? Test case result Qt::Horizontal QDialogButtonBox::No|QDialogButtonBox::Yes buttonBox accepted() TestCaseExecutionDialog accept() 248 254 157 274 buttonBox rejected() TestCaseExecutionDialog reject() 316 260 286 274 ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/run_testcases.sh0000755000015301777760000000133012321005637025613 0ustar pbusernogroup00000000000000#!/bin/bash # # Copyright 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ./testcaseexecutor/testcase -vs -v1|egrep "QML|Declarative" |egrep -v "updateScene" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/button.qml0000644000015301777760000000135012321005637024422 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Button { id: button text: "Hello World" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/tst_button_lmb-press-out-up.txt0000644000015301777760000000072212321005637030557 0ustar pbusernogroup00000000000000QML Button Mouse Events - LMB press, out, release ---------------------------------------------------- Move mouse on top of the button, then press, move out, then release Setup: N/A Actions: #. Move mouse in #. Press MLB #. Move mouse out #. Release MLB Expected Result: #. mouseEnter() emitted #. color is the pressedColor, no clicked() signal emitted #. color is the color, mouseLeave emitted #. no clicked() signal emitted Glossary: MLB = Mouse Left Button ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/README.txt0000644000015301777760000000457412321005637024105 0ustar pbusernogroup00000000000000============== Manual Testing ============== Outline ------- Sometimes it is not possible to easily make an automated test for some use-cases. However just because something isn't easily tested automatically doesn't mean that there isn't value in creating a test for it, just that the test needs to be executed by a person until it is converted into an automated test. However please be very discriminatory about your manual tests. It's highly likely that you can automate whatever it is you're testing, and doing so will be of much more value to the quality of UI Toolkit. Manual tests are a last resort. They should not be written lightly, and should give you a feeling of shame. If you're to the point where you believe you need a manual test, then please come talk to the QA team and we will see if we can find an automatable solution. Format ------ Manual tests take the format of text files in this directory (the manual-test one). These files are formatted using `reStructured Text`_. A very comprehensive `quick reference`_ is available. .. _reStructured Text: http://en.wikipedia.org/wiki/ReStructuredText .. _quick reference: http://docutils.sourceforge.net/docs/user/rst/quickref.html Tests have a header, actions (steps to follow), and an expected result. You can use the TEST_TEMPLATE.txt file as template for new tests. There can be multiple tests in a single file, but they should all be related, and the filename should indicate the tests it contains. Example: Test Button --------- This test shows that the button emits a signal when pressed Setup: #. start examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml in qmlscene Actions: #. Select Buttons #. Press and hold LMB on top of the QML Button next to the Label which says "Standard" #. Release LMB Expected Result: #. Buttons page is visible #. QML Button is in pressedColor while LMB is pressed. #. QML Button emits signal clicked() when LMB is released. Directory Structure ------------------- It is expected that as we grow a number of manual tests, we will use directories to organise them. ========= Glossary ========= LMB = Left Mouse Button ========= HOW TO ========= How To See Which Testcase Tests Which Part Of The QML Component? = ---------- open .map file in text editor How To Get The Testcase Executor Binary ---------- /compile_testcaseexecutor.sh How To Execute Tests ---------- ./run_testcases.sh ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/manual-tests/tst_button_lmb-press-out-in-release.txt0000644000015301777760000000121212321005637032152 0ustar pbusernogroup00000000000000QML Button Mouse Events - LMB Press, out, in, release ---------------------------------------------------- Move mouse on top of Button, then press, move out, move in, then release Setup: N/A Actions: #. Move mouse in #. Press MLB #. Move mouse out #. Move mouse in #. Release MLB Expected Result: #. mouseEnter emitted, state is hovered #. color is the pressedColor, no clicked() signal emitted, state is pressed #. color is the color, mouseLeave emitted, state is <> #. color is the pressedColor, mouseEnter emitted, state is pressed #. color is the color, clicked() signal is emitted, state is <> Glossary: MLB = Mouse Left Button ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/CHANGES.syntax0000644000015301777760000000556512321005637022313 0ustar pbusernogroup00000000000000The CHANGES file documents all changes in the toolkit that will break applications. A strict syntax is defined below that eases the lives of developers. There are 2 types of changes, a section for each exists for each release of the toolkit: - API Changes - Compatibility Breaks Each change must be reported on a new bullet point and respect one of the following templates: * $TYPE_OF_CHANGE$ $OBJECT$ * $TYPE_OF_CHANGE$ IN $OBJECT$: $MEMBER_TYPE$ $OLD_SIGNATURE$ TO $NEW_SIGNATURE$ * $TYPE_OF_CHANGE$ IN $OBJECT$: description of the compatibility break Where $TYPE_OF_CHANGE$ is: - "DEPRECATED" - "CHANGED" - "REMOVED" Where $OBJECT$ is: - a QML class - a JavaScript module - a context property Where $MEMBER_TYPE$ is: - "property" - "signal" - "function" Original version not respecting the syntax: API Changes *********** * "clicked() and pressAndHold() signals of AbstractButton no longer take a mouse parameter as input." * ComponentUtils module is deprecated (affects componentUtils.js: hasStyle(), style(), delegateProperty() functions) * Property tools was deprecated for MainView, Tabs and PageStack. * Property page of Tab can no longer be a URL, but must be an Item (Page recommended). Use a Loader if you were using a URL first. Compatibility Breaks ******************** * Pages now automatically update MainView.toolbar.tools when they become active. * Disable swiping to switch tabs by default. * Header is now hidden when it has no title or contents * Page, PageStack and Tabs automatically determine their anchors and height inside a MainView, so there is no need to set them explicitly. * It is now recommended to always use Pages inside Tabs or PageStack. Non-Page items can still be used, but their margins will not automatically be set-up to align with the header of the MainView. Formatted version respecting the syntax: API Changes *********** * CHANGED IN AbstractButton: signal clicked(var mouse) TO clicked() * CHANGED IN AbstractButton: signal pressAndHold(var mouse) TO pressAndHold() * DEPRECATED ComponentUtils * DEPRECATED IN MainView: property ToolbarActions tools * DEPRECATED IN Tabs: property ToolbarActions tools * DEPRECATED IN PageStack: property ToolbarActions tools * CHANGED IN Tab: property var page TO Item page (where var page could be an Item or url) Compatibility Breaks ******************** * CHANGED IN Page: when it becomes active, MainView's property ToolbarActions toolbar.tools is automatically updated * CHANGED IN Tabs: swiping to switch tabs is disabled by default * CHANGED IN Header: becomes hidden when there is no title or contents * CHANGED IN Page, PageStack, Tabs: automatically determine their anchors and height inside a MainView * CHANGED IN Tabs, PageStack: it is recommended to always use Pages inside them. Non-Page items can still be used, but their margins will not automatically be set-up to align with the header of the MainView. ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/CHANGES0000644000015301777760000003354212321005637020762 0ustar pbusernogroup00000000000000SDK Release Notes ################# .. contents:: List of Releases :depth: 1 UNRELEASED ########## API Changes *********** * ADDED IN: PickerDelegate: readonly property Picker picker * CHANGED IN: OptionSelector: readonly property bool currentlyExpanded TO property bool currentlyExpanded * CHANGED IN: ItemSelector: readonly property bool currentlyExpanded TO property bool currentlyExpanded * ADDED IN: Action: property string iconName * ADDED IN: ActionItem: property string iconName * ADDED IN: OptionSelectorDelegate: property string iconName * ADDED IN: OptionSelectorDelegate: property url iconSource * DEPRECATED IN: OptionSelectorDelegate: property url icon * ADDED IN: ListItems.Base: property string fallbackIconName * ADDED IN: ListItems.Base: property string iconName * ADDED IN: ListItems.Base: property url iconSource * DEPRECATED IN: ListItems.Base: property variant icon * ADDED IN: ListItems.Standard: property string fallbackIconName * ADDED IN: ListItems.Standard: property string iconName * ADDED IN: ListItems.Standard: property url iconSource * DEPRECATED IN: ListItems.Standard: property variant icon * ADDED IN: TabBar: property int selectedIndex * DEPRECATED IN TabBar: property Item tabsItem * ADDED IN: OptionSelector: readonly property bool currentlyExpanded * ADDED IN: ItemSelector: readonly property bool currentlyExpanded * ADDED IN: Tab: readonly property int index * ADDED IN: ListItem.Empty: property bool confirmRemoval * ADDED IN: OptionSelector: property bool multiSelection * ADDED IN: ItemSelector: property bool multiSelection * ADDED IN: OptionSelector: readonly property real itemHeight * ADDED IN: ItemSelector: readonly property real itemHeight * ADDED IN: OptionSelector: signal expansionCompleted() * ADDED IN: ItemSelector: signal expansionCompleted() * ADDED IN: OptionSelectorDelegate: property bool constrainImage * ADDED IN: Empty: property alias divider * ADDED IN: ListItems/OptionSelector: signal delegateSelected() * REMOVED IN: OptionSelector: signal scroll() * ADDED IN: OptionSelector: signal delegateSelected() * ADDED: ListItem OptionSelector to Components/ListItems * ADDED: ListItemOptionSelectorStyle to Components/Ambiance/ListItems * ADDED: ListItemOptionSelectorStyle to Components/SuruDark/ListItems * ADDED: ListItemOptionSelectorStyle to Components/SuruGradient/ListItems * REMOVED IN ALL: attached property ItemStyle * ADDED IN OrientationHelper: property alias rotating * ADDED IN OrientationHelper: property alias __orientationHelper * ADDED IN OrientationHelper: property bool transitionEnabled * DEPRECATED IN QuickUtils: property Item rootObject * CHANGED IN OrientationHelper: property int __orientationHelper TO property int orientationHelper * CHANGED IN Toolbar: property bool active TO property bool opened * CHANGED IN Toolbar: property bool lock TO property bool locked * CHANGED IN ToolbarActions: property bool active TO property bool opened * CHANGED IN ToolbarActions: property bool lock TO property bool locked * REMOVED IN Toolbar: property bool active * REMOVED IN Toolbar: property bool lock * REMOVED IN ToolbarActions: property bool active * REMOVED IN ToolbarActions: property bool lock * CHANGED IN Page: property Header header TO property Header __propagated.header * CHANGED IN Page: property Toolbar toolbar TO property Toolbar __propagated.toolbar * CHANGED IN MainView: property Header header TO property Header __propagated.header * CHANGED IN MainView: property Toolbar toolbar TO property Toolbar __propagated.toolbar * DEPRECATED IN Page: property Header header * DEPRECATED IN Page: property Toolbar toolbar * DEPRECATED IN MainView: property Header header * DEPRECATED IN Page: property Toolbar toolbar * REMOVED in MainView: property QtObject __hud * CHANGED in ToolbarActions: INHERIT Item INSTEAD OF ActionList * CHANGED in Page: property ToolbarActions tools TO property Item tools * CHANGED IN Toolbar: property ToolbarActions tools TO property Item tools * DEPRECATED IN Action: property bool visible * DEPRECATED IN Action: property Item itemHint * REMOVED ToolbarActions (use ToolbarItems instead) * ADDED IN MainView: property bool anchorToKeyboard * CHANGED IN Tabs: property Component __headerContents TO property TabBar tabBar * CHANGED IN Header: property Component contents TO property Item contents * ADDED IN Panel: function open() * ADDED IN Panel: function close() * ADDED IN Panel: property int hideTimeout * DEPRECATED IN Panel: writable property opened. Will be made read-only. * ADDED IN: Empty: property bool waitingConfirmationForRemoval * ADDED IN: Empty: function cancelItemRemoval() * CHANGED in CrossFadeImage: readonly property size sourceSize TO property size sourceSize Compatibility Breaks ******************** - CHANGED IN Tabs: Automatically show the header when the title of the active tab changes - CHANGED IN Page/MainView: Only enable auto-hide behavior of header when the Page's flickable can be flicked vertically, so that manual setting of anchors is no longer needed for flickables that only flick horizontally - CHANGED IN Page: Automatic detection of flickable inside a Page to control the header is now limited to Flickables that are anchored to the top of the Page or fill the Page. Header automatically shows when flickable.contentHeight becomes <= flickable.height. - CHANGED IN Action, ActionItem, OptionSelectorDelegate: Setting iconName now always selects the requested icon from ubuntu-mobile theme, not the system icon theme. SDK 0.1.46 ########## API Changes *********** * None Compatibility Breaks ******************** * None SDK 0.1.45 ########## API Changes *********** * None Compatibility Breaks ******************** * None SDK 0.1.44 ########## API Changes *********** * CHANGED IN AbstractButton: signal clicked(mouse) TO signal clicked() * CHANGED IN AbstractButton: signal pressAndHold(mouse) TO signal pressAndHold() Compatibility Breaks ******************** * CHANGED IN Tabs: Swiping to switch tabs disabled by default SDK 0.1.43 ########## (Automatic builds) SDK 0.1.42 ########## Compatibility Breaks ******************** * None API Changes *********** * Style QML type as base type for all custom style objects * provides automatic property styling of styled item and its assotiated delegate * Deprecated APIs - ComponentUtils module is deprecated (affects componentUtils.js: hasStyle(), style(), delegateProperty() functions) - StyleUtils module is deprecated (affects styleUtils.js: itemStyleProperty(), animateOrSetValue(), animate() functions) - 'itemStyle' context property is no longer exposed to delegates - use of style type, second parameter of @qml-mapping is deprecated - Deprecated theme specific styles and delegates: ButtonStyle, CheckBoxStyle, NewTabsStyle, SwitchStyle, TabButtonStyle, TextAreaStyle, TextFieldStyle, TextFieldDelegate, UbuntuShapeStyle. These components were deprecated and their properties are now in the respective delegates. SDK 0.1.41 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.40 ########## Compatibility Breaks ******************** * Header is now hidden when it has no title or contents API Changes *********** * None SDK 0.1.39 ########## Compatibility Breaks ******************** * None API Changes *********** * ListItem.Empty: + backgroundIndicator: Defines the item background item to be showed during the item swiping + removable: Defines if the item can be removed or not + swipingState: The current swiping state ("SwipingLeft", "SwipingRight", "") + itemRemoved: This handler is called when the item is removed from the list SDK 0.1.38 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.37 ########## Compatibility Breaks ******************** * Page, PageStack and Tabs automatically determine their anchors and height inside a MainView, so there is no need to set them explicitly. * It is now recommended to always use Pages inside Tabs or PageStack. Non-Page items can still be used, but their margins will not automatically be set-up to align with the header of the MainView. API Changes *********** * Property tools was deprecated for MainView, Tabs and PageStack. Pages now automatically update MainView.toolbar.tools when they become active. * Property page of Tab can no longer be a URL, but must be an Item (Page recommended). Use a Loader if you were using a URL first. SDK 0.1.36 ########## Bugs Fixed ********** * HUD integration to the MainView Compatibility Breaks ******************** * None API Changes ********** * None SDK 0.1.35 ########## Bugs Fixed ********** Theming-related: * [POPOVER] is themed in correctly * [TOOLKIT] Activity indicator is themed incorrectly * [TOOLKIT] dialogue is themed incorrectly Toolbar-related: * [sdk-toolbar] share button in on gallery image does not function on the first button press * Sharing after post/cancel is not possible * [sdk-toolbar] after tap to dismiss toolbar doesn't work * [sdk] toolbar trigger area too big * when first showing the toolbar after opening a photo, it shows the toolbar buttons for the overview, not for the current photo Other: * [HUD, OSK] OSK doesn't focus on input field * Popover sometimes not dismissed Compatibility Breaks ******************** * SDK now depends on libqt5graphicaleffects5 for dropshadow of Popovers. API Changes *********** * None SDK 0.1.34 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.33 ########## Compatibility Breaks ******************** * None API Changes *********** * TextArea and TextField + popover: overrides the default popover of the text area * Slider + touched(bool onThumb): The signal is emitted when there is a click on the slider. The onThumb parameter provides information if the click, was inside of the thumb element SDK 0.1.32 ########## Compatibility Breaks ******************** * None API Changes *********** * Popover + autoClose: property to drive automatic closing of Popovers when tapped on the dismissArea *SheetBase, Dialog + modal: property to drive modal state of the sheets and dialogs SDK 0.1.31 ########## Compatibility Breaks ******************** * None API Changes *********** * Popover, Dialog + edgeMargins: specifies the margins from the dismissArea when positioning the foreground + callerMargin: specifies the margin from the caller when positioning the pointer SDK 0.1.30 ########## Compatibility Breaks ******************** * None API Changes *********** * TextField, TextArea + highlighted: enables to control highlighted state separately from focused SDK 0.1.29 ########## Compatibility Breaks ******************** * Property tools of Page and Toolbar must now be of type ToolbarActions (was: ActionList). API Changes *********** * Popover, Dialog + pointerAnchorItem: caller or a child/sibling of it where the pointer should be aligned to SDK 0.1.28 ########## Compatibility Breaks ******************** * TextArea - autoExpand: marked as deprecated. Use autoSize instead API Changes *********** * Popover + dismissArea: area where mouse events cause Popover dismissal + grabDismissAreaEvents: specifies whether to grab events from dismiss area + contentWidth, contentHeight: overrides the calculated width/height of the Popover's operative area * TextField, TextArea + paste(data): parameter added to paste custom data other than Clipboard content. * TextArea + autoSize: specifies to resize the area based on lineCount property SDK 0.1.27 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.26 ########## Compatibility Breaks ******************** * None API Changes *********** * ThemeEngine - contains only public API, no C++ specific API * Role element removed SDK 0.1.25 ########## Compatibility Breaks ******************** * None API Changes *********** * Removed UbuntuShape::borderSource and UbuntuShape::maskSource. That API in this form reveals to be too difficult to maintain while keeping an efficient implementation. In the future, we plan to expose these features through styling properties. SDK 0.1.22 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.21 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.20 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.16 ########## Compatibility Breaks ******************** * None API Changes *********** * ScrollbarStyle property changes - fadeAnimation property + interactive + overlay + overlayOpacityWhenHidden + overlayOpacityWhenShown + scrollbarFadeInAnimation + scrollbarFadeOutPause + scrollbarFadeOutAnimation SDK 0.1.15 ########## Compatibility Breaks ******************** * None API Changes *********** * TextCustom renamed to Label, TextCustom remains for backwards compatibility SDK 0.1.14 ########## Compatibility Breaks ******************** * None API Changes *********** * UbuntuShapeStyle: - 'borderSource' property renamed to 'borderIdle' - 'borderPressed' property added SDK 0.1.13 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.12 ########## New: Scrollbar component Compatibility Breaks ******************** * Tabs component no longer has properties buttonsExpanded and separator. These two properties can now be specified in the qmltheme of the Tabs. API Changes *********** * buttonsExpanded and separator properties removed from Tabs component. SDK 0.1.11 ########## Compatibility Breaks ******************** * None API Changes *********** * None SDK 0.1.7 ######### * Rule QML type removed from public API of the components SDK 0.1.5 ######### Compatibility Breaks ******************** * Meaning of TextCustom.fontSize has changed: the 'large' and 'x-large' sizes changed to be bigger. API Changes *********** * None ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/README0000644000015301777760000000263012321005637020641 0ustar pbusernogroup00000000000000================= Ubuntu UI Toolkit ================= Introduction ------------ This project consists of a set of QML components to ease the creation of beautiful applications in QML for Ubuntu. QML alone lacks built-in components for basic widgets like Button, Slider, Scrollbar, etc, meaning a developer has to build them from scratch. This toolkit aims to stop this duplication of work, supplying beautiful components ready-made and with a clear and consistent API. These components are fully themeable so the look and feel can be easily customized. Resolution independence technology is built in so UIs are scaled to best suit the display. Other features: - localisation through gettext This project supports QML2 and above. Building & Setup ---------------- You need Qt5 installed to proceed. To build this repository, run $ qmake $ make View the components gallery by running $ ./gallery.sh To install these components, run $ make install You may need to be root for this command to succeed. To use these components in QML without installing them, you need to set the QML2_IMPORT_PATH environment variable. This is done by running $ source export_modules_dir.sh from the root directory of this repository, but is lost when you close your shell. Documentation ------------- Once built, you may view the documentation by opening documentation/html/overview-ubuntu-sdk.html in your favorite web browser. ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/features/0000755000015301777760000000000012321006415021571 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/features/coverage.prf0000644000015301777760000000436312321005637024110 0ustar pbusernogroup00000000000000# Coverage Support # -------------------------------- # In order to generate coverage report you will have to: # 0) Install following packages: gcovr lcov # 1) Configure project with coverage enabled # 1.1) qmake CONFIG+=coverage # 2) Compile project with coverage target # 2.1) xml report # 2.1.1) make coverage-xml # 2.2) html report # 2.2.1) make coverage-html # # In order to regenerate the report you might need to do following steps: # 1) make distclean # 2) qmake -r CONFIG+=coverage # 3) make coverage-html or make coverage-xml # -------------------------------- OBJECTS_DIR = MOC_DIR = TOP_SRC_DIR = $$PWD LIBS += -lgcov QMAKE_CXXFLAGS += --coverage QMAKE_LDFLAGS += --coverage QMAKE_EXTRA_TARGETS += coverage cov QMAKE_EXTRA_TARGETS += clean-gcno clean-gcda coverage-html \ generate-coverage-html clean-coverage-html coverage-xml \ generate-xml generate-coverage-xml clean-coverage-xml clean-gcno.commands = \ "@echo Removing old coverage instrumentation"; \ "find -name '*.gcno' -print | xargs -r rm" clean-gcda.commands = \ "@echo Removing old coverage results"; \ "find -name '*.gcda' -print | xargs -r rm" coverage-html.depends = clean-gcda check generate-coverage-html generate-coverage-html.commands = \ "@echo Collecting coverage data"; \ "lcov --directory $${TOP_SRC_DIR} --capture --output-file coverage.info --no-checksum --compat-libtool"; \ "lcov --extract coverage.info \"*/modules/*.cpp\" -o coverage.info"; \ "lcov --remove coverage.info \"moc_*.cpp\" -o coverage.info"; \ "LANG=C genhtml --prefix $${TOP_SRC_DIR} --output-directory coverage-html --title \"Code Coverage\" --legend --show-details coverage.info" clean-coverage-html.depends = clean-gcda clean-coverage-html.commands = \ "lcov --directory $${TOP_SRC_DIR} -z"; \ "rm -rf coverage.info coverage-html" coverage-xml.depends = clean-gcda check generate-coverage-xml generate-coverage-xml.commands = \ "@echo Generating coverage GCOVR XML report"; \ "gcovr -x -r $${TOP_SRC_DIR} -o $${TOP_SRC_DIR}/coverage.xml -e \".*/moc_.*\" -e \"unit/.*\" -e \".*\\.h\"" clean-coverage-xml.depends = clean-gcda clean-coverage-xml.commands = \ "rm -rf $${TOP_SRC_DIR}/coverage.xml" QMAKE_CLEAN += *.gcda *.gcno coverage.info coverage.xml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/0000755000015301777760000000000012321006415021423 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/0000755000015301777760000000000012321006415022705 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/0000755000015301777760000000000012321006415025032 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Slider.qml0000644000015301777760000001470112321005637026777 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ // FIXME(loicm) Add support for keyboard shortcuts (basically left/right). import QtQuick 2.0 import "mathUtils.js" as MathUtils /*! \qmltype Slider \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Slider is a component to select a value from a continuous range of values. The slider's sensing area is defined by the width and height, therefore styles should take this into account when defining the visuals, and alter these values to align the graphics' sizes. \l {http://design.ubuntu.com/apps/building-blocks/slider}{See also the Design Guidelines on Sliders}. Example: \qml Item { Slider { function formatValue(v) { return v.toFixed(2) } minimumValue: -3.14 maximumValue: 3.14 value: 0.0 live: true } } \endqml */ StyledItem { id: slider /*! \preliminary The minimum value from the continuous range of values. If this value is greater than maximumValue, the component will be in an inconsistent state. */ property real minimumValue: 0.0 /*! \preliminary The maximum value from the continuous range of values. If this value is lesser than minimumValue, the component will be in an inconsistent state. */ property real maximumValue: 100.0 // FIXME(loicm) Add Support for the stepSize property. // /*! // \preliminary // The distance between two selectable values in the range defined by // [minimumValue, maximumValue]. // */ // property real stepSize: 1.0 /*! \preliminary The current value of the slider. This property is not changed while the thumb is dragged unless the live property is set to true. */ property real value: 0.0 /*! \preliminary Defines whether the value is updated while the thumb is dragged or just when the thumb is released. */ property bool live: false /*! \qmlproperty bool pressed \preliminary Whether the Slider is currently being pressed. */ property alias pressed: mouseArea.pressed /*! \preliminary The signal is emitted when there is a click on the slider. The onThumb parameter provides information if the click, was inside of the thumb element. */ signal touched(bool onThumb) /*! \preliminary This function is used by the value indicator to show the current value. Reimplement this function if you want to show different information. By default, the value v is rounded to the nearest interger value. */ function formatValue(v) { return v.toFixed(0) } // Private symbols. /*! \internal */ property alias __internals: mouseArea /*! \internal */ onValueChanged: mouseArea.liveValue = slider.value Binding { target: slider property: "value" value: mouseArea.liveValue when: slider.live } MouseArea { id: mouseArea anchors.fill: parent property Item bar: slider.__styleInstance ? slider.__styleInstance.bar : null property Item thumb: slider.__styleInstance ? slider.__styleInstance.thumb : null property real thumbSpacing: slider.__styleInstance ? slider.__styleInstance.thumbSpacing : 0 property real barMinusThumb: bar && thumb ? bar.width - (thumb.width + 2.0*thumbSpacing) : 0.0 property real liveValue: 0.0 property real normalizedValue: normalizedValueFromValue(liveValue) property real dragInitMouseX: 0.0 property real dragInitNormalizedValue: 0.0 function normalizedValueFromValue(value) { if (Qt.application.layoutDirection == Qt.RightToLeft) { return MathUtils.clampAndProject(value, slider.minimumValue, slider.maximumValue, 1.0, 0.0); } else { return MathUtils.clampAndProject(value, slider.minimumValue, slider.maximumValue, 0.0, 1.0); } } function valueFromNormalizedValue(normalizedValue) { if (Qt.application.layoutDirection == Qt.RightToLeft) { return MathUtils.lerp(MathUtils.clamp(normalizedValue, 0.0, 1.0), slider.maximumValue, slider.minimumValue); } else { return MathUtils.lerp(MathUtils.clamp(normalizedValue, 0.0, 1.0), slider.minimumValue, slider.maximumValue); } } /* Mimic the behaviour of the 'pressed' property with one important difference: 'pressed' is set to true only after the onPressed handler has been executed. That prevents us from doing interesting animations upon press. */ property bool isPressed: false onPressed: { isPressed = true; var thumbPressed = mouse.x >= thumb.x && mouse.x <= thumb.x + thumb.width; if (!thumbPressed) { var normalizedX = (mouseX - thumbSpacing - thumb.width * 0.5) / barMinusThumb; liveValue = valueFromNormalizedValue(normalizedX); } dragInitMouseX = mouse.x; dragInitNormalizedValue = normalizedValue; slider.touched(thumbPressed); } onReleased: { isPressed = false; if (!slider.live) { slider.value = liveValue; } } onPositionChanged: { // Left button dragging var normalizedOffsetX = (mouseArea.mouseX - dragInitMouseX) / barMinusThumb; liveValue = valueFromNormalizedValue(dragInitNormalizedValue + normalizedOffsetX); } } style: Theme.createStyleComponent("SliderStyle.qml", slider) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Header.qml0000644000015301777760000001350512321005637026746 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 // FIXME: When a module contains QML, C++ and JavaScript elements exported, // we need to use named imports otherwise namespace collision is reported // by the QML engine. As workaround, we use Ubuntu named import. // Bug to watch: https://bugreports.qt-project.org/browse/QTBUG-27645 import Ubuntu.Components 0.1 as Ubuntu /*! \internal \qmltype Header \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu */ StyledItem { id: header anchors { left: parent.left right: parent.right } y: 0 /*! Animate showing and hiding of the header. */ property bool animate: true Behavior on y { enabled: animate && !(header.flickable && header.flickable.moving) SmoothedAnimation { duration: Ubuntu.UbuntuAnimation.BriskDuration } } /*! \internal */ onHeightChanged: { internal.checkFlickableMargins(); internal.movementEnded(); } visible: title || contents onVisibleChanged: { internal.checkFlickableMargins(); } /*! Show the header */ function show() { header.y = 0; } /*! Hide the header */ function hide() { header.y = - header.height; } /*! The text to display in the header */ property string title: "" onTitleChanged: contentsChanged() /*! The contents of the header. If this is set, \l title will be ignored. */ property Item contents: null onContentsChanged: header.show() /*! The flickable that controls the movement of the header. Will be set automatically by Pages inside a MainView, but can be overridden. */ property Flickable flickable: null onFlickableChanged: { internal.checkFlickableMargins(); internal.connectFlickable(); header.show(); } QtObject { id: internal /*! Track the y-position inside the flickable. */ property real previousContentY: 0 /*! The previous flickable to disconnect events */ property Flickable previousFlickable: null /*! Disconnect previous flickable, and connect the new one. */ function connectFlickable() { if (previousFlickable) { previousFlickable.contentYChanged.disconnect(internal.scrollContents); previousFlickable.movementEnded.disconnect(internal.movementEnded); previousFlickable.interactiveChanged.disconnect(internal.interactiveChanged); } if (flickable) { // Connect flicking to movements of the header previousContentY = flickable.contentY; flickable.contentYChanged.connect(internal.scrollContents); flickable.movementEnded.connect(internal.movementEnded); flickable.interactiveChanged.connect(internal.interactiveChanged); flickable.contentHeightChanged.connect(internal.contentHeightChanged); } previousFlickable = flickable; } /*! Update the position of the header to scroll with the flickable. */ function scrollContents() { // Avoid updating header.y when rebounding or being dragged over the bounds. if (!flickable.atYBeginning && !flickable.atYEnd) { var deltaContentY = flickable.contentY - previousContentY; // FIXME: MathUtils.clamp is expensive. Fix clamp, or replace it here. header.y = MathUtils.clamp(header.y - deltaContentY, -header.height, 0); } previousContentY = flickable.contentY; } /*! Fully show or hide the header, depending on its current y. */ function movementEnded() { if (flickable && flickable.contentY < 0) header.show(); else if (header.y < -header.height/2) header.hide(); else header.show(); } /* Content height of flickable changed */ function contentHeightChanged() { if (flickable && flickable.height >= flickable.contentHeight) header.show(); } /* Flickable became interactive or non-interactive. */ function interactiveChanged() { if (flickable && !flickable.interactive) header.show(); } /* Check the topMargin of the flickable and set it if needed to avoid contents becoming unavailable behind the header. */ function checkFlickableMargins() { if (header.flickable) { var headerHeight = header.visible ? header.height : 0 if (flickable.topMargin !== headerHeight) { var previousHeaderHeight = flickable.topMargin; flickable.topMargin = headerHeight; // push down contents when header grows, // pull up contents when header shrinks. flickable.contentY -= headerHeight - previousHeaderHeight; } } } } style: Theme.createStyleComponent("HeaderStyle.qml", header) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ActionItem.qml0000644000015301777760000000532612321005637027614 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmlabstract ActionItem \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief A visual representation of an Action. The API of ActionItem is a copy of the API of \l Action, with additional properties to define visual aspects of the ActionItem. If \l action is set, the values of the other properties will by default be identical to the \l Action's property values. Setting the other properties will override the properties copied from the \l Action. See \l ToolbarItems for examples of how to use \l ToolbarButton or other ActionItems in a toolbar. */ StyledItem { id: actionItem /*! The \l Action associated with this ActionItem. If action is set, the values of the Action properties are copied to the values of the ActionItem properties. */ property Action action: null visible: action ? action.visible : true enabled: action ? action.enabled : true /*! The title of the actionItem. Default value: action.text */ property string text: action ? action.text : "" /*! The image associated with the actionItem. Default value: action.iconSource. If both iconSource and iconName are defined, iconName will be ignored. */ property url iconSource: action ? action.iconSource : (iconName ? "image://theme/" + iconName : "") /*! The icon associated with the actionItem in the ubuntu-mobile icon theme. Default value: action.iconName. If both iconSource and iconName are defined, iconName will be ignored. */ property string iconName: action ? action.iconName : "" /*! Called when the actionItem is triggered. */ signal triggered(var value) /*! If \l action is set, this will trigger it. */ onTriggered: if (action) action.trigger(value) /*! Trigger this action item if it is enabled. */ function trigger(value) { var passingValue = value ? value : null if (actionItem.enabled) actionItem.triggered(passingValue); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/artwork/0000755000015301777760000000000012321006415026523 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/artwork/tick@30.png0000644000015301777760000000112412321005637030431 0ustar pbusernogroup00000000000000PNG  IHDRZZ8AbKGD pHYs  tIME 5olsLIDATxU1 a1] ztG/\ci$܁Ak;_Ո> h4@&@ 4h4@&@ 4?n_4+@ it*d-Bd-BdE[֍V#o 6kA.Ȧ#+:{?{ٰS;UWQΈ쾼ScgEUV?gaƶD.3®,߂[c[|?Q~aB.3TAYQu~(Xyz2rk@zW9yγ%蘽uvdm=fh0|#9̓Qd:Z}Y%gF #K^g(UЖ8CwMl9bUDhU;Aۜ!VG.1:V@N hF^ ?Xneя:‰Uh&@Mh4heQ]\ IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/artwork/back@18.png0000644000015301777760000000065612321005637030416 0ustar pbusernogroup00000000000000PNG  IHDR$$hsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<fPLTE9!tRNS +,/?OZb}űiIDAT8ݒI@qEAnNFh3bjZzܵ@:y@({)nh򜉈C͑Hzj`ka5K_>TgT,Ӂ )!9ѥ3O#.IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/artwork/chevron_down@30.png0000644000015301777760000000315512321005637032200 0ustar pbusernogroup00000000000000PNG  IHDR<<:rtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp CIDATx[MQ r{P. /$yq\RL:e%"/F!2QH31j/oc33pk{o}kx^.E~^ ]m&Kl6{إb1 *d{I3t6#٩z8e,Za\3Tzhh(p {綯J?p"0W%@ y0^,54XCF V`|i:Ry]A;gk3+OstsPynjM3_*r-tauPҔ wtBOW-S>]+:. * */ import QtQuick 2.0 import Ubuntu.Components 0.1 as Ubuntu /*! \qmltype UbuntuNumberAnimation \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief UbuntuNumberAnimation is a NumberAnimation that has predefined settings to ensure that Ubuntu applications are consistent in their animations. Example of use: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { width: 100; height: 100 color: UbuntuColors.orange UbuntuNumberAnimation on x { to: 50 } } \endqml UbuntuNumberAnimation is predefined with the following settings: \list \li \e duration: \l{UbuntuAnimation::FastDuration}{UbuntuAnimation.FastDuration} \li \e easing: \l{UbuntuAnimation::StandardEasing}{UbuntuAnimation.StandardEasing} \endlist If the standard duration and easing used by UbuntuNumberAnimation do not satisfy a use case or you need to use a different type of Animation (e.g. ColorAnimation), use standard durations and easing defined in \l UbuntuAnimation manually in order to ensure consistency. */ NumberAnimation { duration: Ubuntu.UbuntuAnimation.FastDuration easing: Ubuntu.UbuntuAnimation.StandardEasing } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/PageTreeNode.qml0000644000015301777760000001115512321005637030057 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \internal \qmltype PageTreeNode \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The common parent of \l Page, \l MainView, \l PageStack and \l Tabs. It is used to propagate properties such as \l header and \l toolbar from a \l MainView (the root node) to each \l Page (leaf node) in the tree. */ StyledItem { id: node /*! \internal Used to determine whether an Item is a PageTreeNode */ property bool __isPageTreeNode: true /*! \internal */ onParentChanged: internal.updatePageTree() /*! \internal */ Component.onCompleted: internal.updatePageTree() /*! \deprecated The header of the node. Propagates down from the root node. This property is deprecated. */ property Header header: node.__propagated ? node.__propagated.header : null /*! \deprecated The toolbar of the node. Propagates down from the root node. This property is deprecated. */ property Toolbar toolbar: node.__propagated ? node.__propagated.toolbar : null /*! \internal QtObject containing all the properties that are propagated from the root (MainView) of a page tree to its leafs (Pages). This object contains properties such as the header and toolbar that are instantiated by the MainView. This property is internal because the derived classes (MainView and Page) need to access it, but other components using those classes should not have access to it. */ property QtObject __propagated: node.parentNode ? node.parentNode.__propagated : null /*! At any time, there is exactly one path from the root node to a Page leaf node where all nodes are active. All other nodes are not active. This is used by \l Tabs and \l PageStack to determine which of multiple nodes in the Tabs or PageStack is the currently active one. */ property bool active: node.parentNode ? node.parentNode.active : false /*! The \l PageStack that this Page has been pushed on, or null if it is not part of a PageStack. This value is automatically set for pages that are pushed on a PageStack, and propagates to its child nodes. */ // Note: pageStack is not included in the propagated property because there may // be multiple PageStacks in a single page tree. property Item pageStack: node.parentNode ? node.parentNode.pageStack : null /*! The parent node of the current node in the page tree. */ property Item parentNode: null /*! The leaf node that is active. */ property Item activeLeafNode /*! Whether or not this node is a leaf, that is if it has no descendant that are nodes. */ property bool isLeaf: true Binding { target: node.parentNode property: "activeLeafNode" value: node.isLeaf ? node : node.activeLeafNode when: node.active } Binding { target: node.parentNode property: "isLeaf" value: false } Item { id: internal function isPageTreeNode(object) { // FIXME: Use QuickUtils.className() when it becomes available. return (object && object.hasOwnProperty("__isPageTreeNode") && object.__isPageTreeNode); } /*! Return the parent node in the page tree, or null if the item is the root node or invalid. */ function getParentPageTreeNode(item) { var node = null; if (item) { var i = item.parent; while (i) { if (internal.isPageTreeNode(i)) { node = i; break; } i = i.parent; } } return node; } /*! Find the parent node. */ function updatePageTree() { node.parentNode = internal.getParentPageTreeNode(node); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/CheckBox.qml0000644000015301777760000000304412321005637027241 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype CheckBox \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief CheckBox is a component with two states, checked or unchecked. It can be used to set boolean options. The behavior is the same as \l Switch, the only difference is the graphical style. \l {http://design.ubuntu.com/apps/building-blocks/toggles}{See also the Design Guidelines on Toggles}. \b{This component is under heavy development.} Example: \qml Item { CheckBox { checked: true } } \endqml */ AbstractButton { id: checkBox /*! \preliminary Specifies whether the checkbox is checked or not. By default the property is set to false. */ property bool checked: false /*! \internal */ onTriggered: checked = !checked style: Theme.createStyleComponent("CheckBoxStyle.qml", checkBox) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/scrollbarUtils.js0000644000015301777760000001131412321005637030401 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library Qt.include("mathUtils.js") /*! \internal Object storing property names used in calculations. */ var _obj = { scrollbar: null, vertical: false, propOrigin: "", propContent: "", propPosRatio: "", propSizeRatio: "", propCoordinate: "", propSize: "", refresh: function () { _obj.vertical = (_obj.scrollbar.align === Qt.AlignLeading) || (_obj.scrollbar.align === Qt.AlignTrailing) _obj.propOrigin = (_obj.vertical) ? "originY" : "originX"; _obj.propContent = (_obj.vertical) ? "contentY" : "contentX"; _obj.propPosRatio = (_obj.vertical) ? "yPosition" : "xPosition"; _obj.propSizeRatio = (_obj.vertical) ? "heightRatio" : "widthRatio"; _obj.propCoordinate = (_obj.vertical) ? "y" : "x"; _obj.propSize = (_obj.vertical) ? "height" : "width"; } } /*! \internal Checks whether the _obj is valid or not. Must be called in every function as those can be invoked prior to the host (style) component completion. */ function __check(sb) { if (sb !== null && (_obj.scrollbar !== sb)) { _obj.scrollbar = sb; sb.flickableItemChanged.connect(_obj.refresh); sb.alignChanged.connect(_obj.refresh); _obj.refresh(); } return _obj.scrollbar; } /*! Returns whether the scrollbar is vertical or horizontal. */ function isVertical(scrollbar) { if (!__check(scrollbar)) return 0; return _obj.vertical; } /*! Calculates the slider position based on the visible area's ratios. */ function sliderPos(scrollbar, min, max) { if (!__check(scrollbar)) return 0; return clamp(scrollbar.flickableItem.visibleArea[_obj.propPosRatio] * scrollbar.flickableItem[_obj.propSize], min, max); } /*! Calculates the slider size for ListViews based on the visible area's position and size ratios, clamping it between min and max. The function can be used in Scrollbar styles to calculate the size of the slider. */ function sliderSize(scrollbar, min, max) { if (!__check(scrollbar)) return 0; var sizeRatio = scrollbar.flickableItem.visibleArea[_obj.propSizeRatio]; var posRatio = scrollbar.flickableItem.visibleArea[_obj.propPosRatio]; var sizeUnderflow = (sizeRatio * max) < min ? min - (sizeRatio * max) : 0 var startPos = posRatio * (max - sizeUnderflow) var endPos = (posRatio + sizeRatio) * (max - sizeUnderflow) + sizeUnderflow var overshootStart = startPos < 0 ? -startPos : 0 var overshootEnd = endPos > max ? endPos - max : 0 // overshoot adjusted start and end var adjustedStartPos = startPos + overshootStart var adjustedEndPos = endPos - overshootStart - overshootEnd // final position and size of thumb var position = adjustedStartPos + min > max ? max - min : adjustedStartPos var result = (adjustedEndPos - position) < min ? min : (adjustedEndPos - position) return result; } /*! The function calculates and clamps the position to be scrolled to the minimum and maximum values. The scroll and drag functions require a slider that does not have any minimum size set (meaning the minimum is set to 0.0). Implementations should consider using an invisible cursor to drag the slider and the ListView position. */ function scrollAndClamp(scrollbar, amount, min, max) { if (!__check(scrollbar)) return 0; return scrollbar.flickableItem[_obj.propOrigin] + clamp(scrollbar.flickableItem[_obj.propContent] - scrollbar.flickableItem[_obj.propOrigin] + amount, min, max); } /*! The function calculates the new position of the dragged slider. The amount is relative to the contentSize, which is either the flickable's contentHeight or contentWidth or other calculated value, depending on its orientation. The pageSize specifies the visibleArea, and it is usually the heigtht/width of the scrolling area. */ function dragAndClamp(scrollbar, cursor, contentSize, pageSize) { if (!__check(scrollbar)) return 0; scrollbar.flickableItem[_obj.propContent] = scrollbar.flickableItem[_obj.propOrigin] + cursor[_obj.propCoordinate] * contentSize / pageSize; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/OptionSelectorDelegate.qml0000644000015301777760000003076012321005637032164 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \qmltype OptionSelectorDelegate \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu-components \brief OptionSelector delegate which can display text, subtext and an image from a custom model. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components 0.1 Column { width: 250 OptionSelector { text: i18n.tr("Label") model: customModel delegate: OptionSelectorDelegate { text: name; subText: description; iconSource: image } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "images.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "images.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "images.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "images.png" } } } \endqml */ import QtQuick 2.0 import "ListItems" as ListItem import Ubuntu.Components 0.1 as Toolkit ListItem.Standard { id: option __height: units.gu(5) /*! \preliminary Main text. */ property string text /*! \preliminary Subtext which appears below the main text. */ property string subText /*! \deprecated \b{Use iconName or iconSource instead.} Left icon url. */ property url icon: iconSource onIconChanged: if (icon != iconSource) { console.warn("WARNING: OptionSelectorDelegate.icon is DEPRECATED. " + "Use iconName and iconSource instead.") } /*! The image shown for that option. \qmlproperty url iconSource This is a URL to any image file. In order to use an icon from the Ubuntu theme, use the iconName property instead. */ property url iconSource: iconName ? "image://theme/" + iconName : "" /*! The icon shown for that option. \qmlproperty string iconName If both iconSource and iconName are defined, iconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon theme is installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \endlist */ property string iconName /*! \preliminary Constrains the size of the image to nothing greater than that of the delegate. Changes fillMode to Image.PreserveAspectFit. */ property bool constrainImage: false /*! \preliminary Whether or not left image is coloured by our theme. */ property bool colourImage: listView.container.colourImage /*! \preliminary Colour of left image. */ property color assetColour: listView.container.themeColour /*! \preliminary OptionSelector's ListView. */ readonly property ListView listView: ListView.view /*! \preliminary Colourising fragment shader. */ readonly property string fragColourShader: "varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform lowp vec4 colour; uniform lowp float qt_Opacity; void main() { lowp vec4 sourceColour = texture2D(source, qt_TexCoord0); gl_FragColor = colour * sourceColour.a * qt_Opacity; }" showDivider: index !== listView.count - 1 ? 1 : 0 highlightWhenPressed: false selected: ListView.isCurrentItem anchors { left: parent.left right: parent.right } onClicked: { if (listView.container.currentlyExpanded) { listView.delegateClicked(index); if (!listView.multiSelection) { listView.previousIndex = listView.currentIndex; listView.currentIndex = index; } else { selected = !selected; } } if (!listView.expanded && !listView.multiSelection) { listView.container.currentlyExpanded = !listView.container.currentlyExpanded; } } Component.onCompleted: { height = listView.itemHeight = childrenRect.height; } //Since we don't want to add states to our divider, we use the exposed alias provided in Empty to access it and alter it's opacity from here. states: [ State { name: "dividerExpanded" when: listView.container.state === "expanded" && index === listView.currentIndex PropertyChanges { target: option.divider opacity: 1 } }, State { name: "dividerCollapsed" when: listView.container.state === "collapsed" && index === listView.currentIndex PropertyChanges { target: option.divider opacity: 0 } } ] //As with our states, we apply the transition with our divider as the target. transitions: [ Transition { from: "dividerExpanded" to: "dividerCollapsed" Toolkit.UbuntuNumberAnimation { target: option.divider properties: "opacity" duration: Toolkit.UbuntuAnimation.SlowDuration } } ] resources: [ Connections { target: listView.container onCurrentlyExpandedChanged: { imageExpansion.stop(); selectedImageCollapse.stop(); deselectedImageCollapse.stop(); if (listView.container.currentlyExpanded === true) { if (!option.selected) { optionExpansion.start(); //Ensure a source change. This solves a bug which happens occasionaly when source is switched correctly. Probably related to the image.source binding. image.source = listView.container.tick } else { imageExpansion.start(); } } else { if (!option.selected) { optionCollapse.start(); } else { if (listView.previousIndex !== listView.currentIndex) selectedImageCollapse.start(); else { deselectedImageCollapse.start(); } } } } }, SequentialAnimation { id: imageExpansion PropertyAnimation { target: image properties: "opacity" from : 1.0 to: 0.0 duration: Toolkit.UbuntuAnimation.FastDuration } PauseAnimation { duration: Toolkit.UbuntuAnimation.BriskDuration - Toolkit.UbuntuAnimation.FastDuration } PropertyAction { target: image property: "source" value: listView.container.tick } PropertyAnimation { target: image properties: "opacity" from : 0.0 to: 1.0 duration: Toolkit.UbuntuAnimation.FastDuration } }, PropertyAnimation { id: optionExpansion target: option properties: "opacity" from : 0.0 to: 1.0 duration: Toolkit.UbuntuAnimation.SlowDuration }, SequentialAnimation { id: deselectedImageCollapse PauseAnimation { duration: Toolkit.UbuntuAnimation.BriskDuration } PropertyAnimation { target: image properties: "opacity" from : 1.0 to: 0.0 duration: Toolkit.UbuntuAnimation.FastDuration } PauseAnimation { duration: Toolkit.UbuntuAnimation.FastDuration } PropertyAction { target: image property: "source" value: listView.container.chevron } PropertyAnimation { target: image properties: "opacity" from : 0.0 to: 1.0 duration: Toolkit.UbuntuAnimation.FastDuration } }, SequentialAnimation { id: selectedImageCollapse PropertyAnimation { target: image properties: "opacity" from : 0.0 to: 1.0 duration: Toolkit.UbuntuAnimation.FastDuration } PauseAnimation { duration: Toolkit.UbuntuAnimation.BriskDuration - Toolkit.UbuntuAnimation.FastDuration } PropertyAnimation { target: image properties: "opacity" from : 1.0 to: 0.0 duration: Toolkit.UbuntuAnimation.FastDuration } PauseAnimation { duration: Toolkit.UbuntuAnimation.FastDuration } PropertyAction { target: image property: "source" value: listView.container.chevron } PropertyAnimation { target: image properties: "opacity" from : 0.0 to: 1.0 duration: Toolkit.UbuntuAnimation.FastDuration } }, PropertyAnimation { id: optionCollapse target: option properties: "opacity" from : 1.0 to: 0.0 duration: Toolkit.UbuntuAnimation.SlowDuration } ] Row { spacing: units.gu(1) anchors { left: parent.left leftMargin: units.gu(2) verticalCenter: parent.verticalCenter } Image { id: leftIcon objectName: "icon" height: constrainImage ? option.height : sourceSize.height source: icon fillMode: constrainImage ? Image.PreserveAspectFit : Image.Stretch ShaderEffect { property color colour: assetColour property Image source: parent width: source.width height: source.height visible: colourImage fragmentShader: fragColourShader } } Column { anchors { verticalCenter: parent.verticalCenter } Label { text: option.text === "" ? modelData : option.text } Label { text: option.subText visible: option.subText !== "" ? true : false fontSize: "small" } } } Image { id: image width: units.gu(2) height: units.gu(2) source: listView.expanded || listView.multiSelection ? listView.container.tick : listView.container.chevron opacity: option.selected ? 1.0 : 0.0 anchors { right: parent.right rightMargin: units.gu(2) verticalCenter: parent.verticalCenter } //Our behaviour is only enabled for our expanded list due to flickering bugs in relation to all this other animations running on the expanding version. Behavior on opacity { enabled: listView.expanded Toolkit.UbuntuNumberAnimation { properties: "opacity" duration: Toolkit.UbuntuAnimation.FastDuration } } ShaderEffect { property color colour: assetColour property Image source: parent width: source.width height: source.height fragmentShader: fragColourShader } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/TabBar.qml0000644000015301777760000001145212321005735026707 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype TabBar \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Tab bar that will be shown in the header when \l Tabs is active. This component does not need to be instantiated by the developer, it is automatically created by the \l Tabs. */ StyledItem { id: tabBar /*! \deprecated The \l Tabs item that tab bar belongs to. Will be automatically set by \l Tabs when the TabBar is created. */ // tabsItem is of type Tabs, but using that type would cause an include loop property Item tabsItem /*! \internal */ onTabsItemChanged: console.error("tabsItem property is deprecated. TabBar functionality no longer requires it.") /*! The model containing the tabs to be controlled by the TabBar. The tabs are visualized by the style, displaying controlling elements based on the data specified by the roles. The default style mandates the existence of either the \b title or \b tab role, but different styles may require to have other roles (e.g. image, color). The order the role existence is checked is also determined by the style component, Default style checks the existence of the \b tab role first, and if not defined will use the \b title role. */ property var model: null /*! The user is interacting with the tab bar. Depends on the style pressed property. */ readonly property bool pressed: __styleInstance !== null && __styleInstance.hasOwnProperty("pressed") ? __styleInstance.pressed : false /*! An inactive tab bar only displays the currently selected tab, and an active tab bar can be interacted with to select a tab. */ property bool selectionMode: true /*! The property holds the index of the selected Tab item. */ property int selectedIndex: (model && internal.modelChecked && model.count > 0) ? 0 : -1 /*! Do not deactivate the tab bar after a specified idle time or when the user selects a new tab. Off by default. */ property bool alwaysSelectionMode: false /*! Automatically activate the tab bar when \l alwaysSelectionMode is set. */ onAlwaysSelectionModeChanged: { if (tabBar.alwaysSelectionMode) selectionMode = true; } /*! Show animations when the state changes. Default: true. */ property bool animate: true implicitHeight: units.gu(7.5) style: Theme.createStyleComponent("TabBarStyle.qml", tabBar) QtObject { id: internal property bool modelChecked: true; function checkRoles() { if (tabBar.model.count <= 0) return; modelChecked = true; var f = tabBar.model.get(0); if (f.tab === undefined && f.title === undefined) { console.error("TabBar model must provide either tab or title role."); tabBar.model = null; } if (f.tab !== undefined && f.tab.title === undefined) { console.error("TabBar model's tab role must have title property."); tabBar.model = null; } } } /*! \internal */ onModelChanged: { internal.modelChecked = true; if (!model) return; if (!model.hasOwnProperty("count")) { console.error("TabBar model must have count property defined."); tabBar.model = null; return; } if (!model.hasOwnProperty("get")) { console.error("TabBar model must provide get() function."); tabBar.model = null; return; } if (model.count > 0) { internal.checkRoles(); tabBar.selectedIndex = Math.max(Math.min(tabBar.selectedIndex, model.count - 1), 0); } else { internal.modelChecked = false; tabBar.selectedIndex = Qt.binding(function() { return (model && internal.modelChecked && model.count > 0) ? 0 : -1 }) } } Connections { target: !internal.modelChecked ? tabBar.model : null onCountChanged: internal.checkRoles(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/stack.js0000644000015301777760000000234112321005637026502 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library // By defining Stack as a function, we can make its variables private, // and force calls to Stack to make use of the functions we define. function Stack() { var elements; this.clear = function() { elements = []; } this.clear(); this.push = function(element) { elements.push(element); }; this.pop = function() { elements.pop(); }; this.size = function() { return elements.length; } this.top = function() { if (this.size() < 1) return undefined; return elements[elements.length-1]; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ToolbarItems.qml0000644000015301777760000001700512321005637030161 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ToolbarItems \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Row of Items to be placed in a toolbar. Each \l Page has a tools property that can be set to change the tools of toolbar supplied by \l MainView when the \l Page is active. Each ToolbarItems consists of a set of Items and several properties that specify the behavior of the toolbar when the \l Page is active. When a \l Page is used inside a \l MainView, \l Tabs or \l PageStack, the toolbar will automatically show the tools of the active \l Page. When the active \l Page inside the \l Tabs or \l PageStack is updated by changing the selected \l Tab or by pushing/popping a \l Page on the \l PageStack, the toolbar will automatically hide, except if the new active \l Page has the \l locked property set. \l {http://design.ubuntu.com/apps/building-blocks/toolbar}{See also the Design Guidelines on Toolbars}. It is recommended to use \l ToolbarButton inside the ToolbarItems to define the buttons that will be visible to the user: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(50) Page { title: "Tools example" Label { anchors.centerIn: parent text: "Custom back button\nToolbar locked" } tools: ToolbarItems { ToolbarButton { action: Action { text: "button" iconName: "compose" onTriggered: print("success!") } } locked: true opened: true } } } \endqml However, it is possible to include non-\l ToolbarButton Items inside ToolbarItems, and to mix ToolbarButtons and other Items (for example standard Buttons). ToolbarButtons automatically span the full height of the toolbar, and other Items you will probably want to center vertically: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(50) Page { title: "Tools example" Label { anchors.centerIn: parent text: "buttons!" } tools: ToolbarItems { ToolbarButton { action: Action { text: "toolbar" iconName: "compose" onTriggered: print("success!") } } Button { anchors.verticalCenter: parent.verticalCenter text: "standard" } } } } \endqml */ Item { id: toolbarItems anchors.fill: parent /*! Default property, holds the content which will shown in the toolbar. \qmlproperty list contents */ default property alias contents: toolsContainer.data /*! The back button. If it is visible, it will be shown on the left-side of the toolbar. If there is a \l PageStack with depth greater than 1, the back button will be visible and triggering it will pop the page on top of the stack. If there is no \l PageStack with depth greater than 1, the back button is hidden by default The following example shows how to have a classic cancel button that is always visible in the toolbar, instead of the default toolbar-styled back button: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(50) Page { title: "Custom back button" tools: ToolbarItems { back: Button { text: "cancel" } } } } \endqml */ property Item back: ToolbarButton { objectName: "back_toolbar_button" iconSource: Qt.resolvedUrl("artwork/back.png") text: i18n.tr("Back") visible: toolbarItems.pageStack && toolbarItems.pageStack.depth > 1 /*! If there is a \l PageStack of sufficient depth, triggering the back button will pop the \l Page on top of the \l PageStack. */ onTriggered: if (toolbarItems.pageStack && toolbarItems.pageStack.depth > 1) toolbarItems.pageStack.pop() } /*! PageStack for the back button. \l Page will automatically set the pageStack property of its tools. */ property Item pageStack: null /*! The toolbar is opened. When the toolbar is not locked, this value is automatically updated when the toolbar is opened/closed by user interaction or by other events (such as changing the active \l Page). */ property bool opened: false /*! The toolbar cannot be opened/closed by bottom-edge swipes. If the ToolbarItems contains no visible Items, it is automatically locked (in closed state). */ property bool locked: !internal.hasVisibleItems() QtObject { id: internal /* Determine whether this ToolbarItems has any visible Items */ function hasVisibleItems() { if (back && back.visible) return true; for (var i=0; i < toolsContainer.children.length; i++) { if (toolsContainer.children[i].visible) return true; } return false; } } Item { id: backContainer anchors { left: parent.left top: parent.top bottom: parent.bottom leftMargin: units.gu(2) } width: childrenRect.width // internal link to the previous back Item to unset its parent // when toolbarItems.back is updated. property Item previousBackItem: null function updateBackItem() { if (backContainer.previousBackItem) backContainer.previousBackItem.parent = null; backContainer.previousBackItem = toolbarItems.back; if (toolbarItems.back) toolbarItems.back.parent = backContainer; } Connections { target: toolbarItems onBackChanged: backContainer.updateBackItem() Component.onCompleted: backContainer.updateBackItem() } } Row { id: toolsContainer anchors { right: parent.right bottom: parent.bottom top: parent.top rightMargin: units.gu(2) } spacing: units.gu(1) } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ToolbarButton.qml0000644000015301777760000000545712321005637030363 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ToolbarButton \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief An \l ActionItem that represents a button in the toolbar. ToolbarButtons should be included in \l ToolbarItems to define the tools of a \l Page. The behavior and look of the toolbar button can be specified by setting an \l Action for the button, or by setting the other properties inherited by the \l ActionItem. Example of different ways to define the toolbar button: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(50) height: units.gu(80) Action { id: action1 text: "action 1" iconName: "compose" onTriggered: print("one!") } Page { title: "test page" Label { anchors.centerIn: parent text: "Hello, world" } tools: ToolbarItems { // reference to an action: ToolbarButton { action: action1 } // define the action: ToolbarButton { action: Action { text: "Second action" iconName: "add" onTriggered: print("two!") } // override the text of the action: text: "action 2" } // no associated action: ToolbarButton { iconName: "cancel" text: "button" onTriggered: print("three!") } } } } \endqml See \l ToolbarItems for more information on how to use ToolbarButton. */ ActionItem { id: toolbarButton height: parent ? parent.height : undefined width: units.gu(5) style: Theme.createStyleComponent("ToolbarButtonStyle.qml", toolbarButton) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/TextCursor.qml0000644000015301777760000000353212321005637027677 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "Popups" 0.1 StyledItem { id: cursorItem width: units.dp(1) /* Property holding the text input item instance. */ property var editorItem /* Property holding the text input's custor position property. Can be one of the following ones: cursorPosition, selectionStart and selectionEnd. */ property string positionProperty: "cursorPosition" /* The property contains the custom popover to be shown. */ property var popover /* The function opens the text input popover setting the text cursor as caller. */ function openPopover() { if (!visible) return; if (popover === undefined) { // open the default one PopupUtils.open(Qt.resolvedUrl("TextInputPopover.qml"), cursorItem, { "target": editorItem }) } else { PopupUtils.open(popover, cursorItem, { "target": editorItem }) } } style: Theme.createStyleComponent("TextCursorStyle.qml", cursorItem) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Components.pro0000644000015301777760000000011512321005637027703 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += plugin Themes Colors include(deployment.pri) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/colorUtils.js0000644000015301777760000000160312321005637027534 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ .pragma library function luminance(hexcolor){ hexcolor = String(hexcolor) var r = parseInt(hexcolor.substr(1,2),16); var g = parseInt(hexcolor.substr(3,2),16); var b = parseInt(hexcolor.substr(5,2),16); return ((r*212)+(g*715)+(b*73))/1000/255; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/sliderUtils.js0000644000015301777760000000210512321005637027676 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library /*! The function returns the live value of the slider. */ function liveValue(item) { return item.__internals.liveValue; } /*! The function returns the normalized live value of the slider. */ function normalizedValue(item) { return item.__internals.normalizedValue; } /*! The function returns whether the slider is being pressed or not. */ function isPressed(item) { return item.__internals.isPressed; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/0000755000015301777760000000000012321006415026320 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/Popover.qml0000644000015301777760000002275312321005637030503 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "internalPopupUtils.js" as InternalPopupUtils import Ubuntu.Components 0.1 /*! \qmltype Popover \inherits PopupBase \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief A popover allows an application to present additional content without changing the view. A popover has a fixed width and automatic height, depending on is contents. It can be closed by clicking anywhere outside of the popover area. \l {http://design.ubuntu.com/apps/building-blocks/popover}{See also the Design Guidelines on Popovers}. Example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem import Ubuntu.Components.Popups 0.1 Rectangle { color: Theme.palette.normal.background width: units.gu(80) height: units.gu(80) Component { id: popoverComponent Popover { id: popover Column { id: containerLayout anchors { left: parent.left top: parent.top right: parent.right } ListItem.Header { text: "Standard list items" } ListItem.Standard { text: "Do something" } ListItem.Standard { text: "Do something else" } ListItem.Header { text: "Buttons" } ListItem.SingleControl { highlightWhenPressed: false control: Button { text: "Do nothing" anchors { fill: parent margins: units.gu(1) } } } ListItem.SingleControl { highlightWhenPressed: false control: Button { text: "Close" anchors { fill: parent margins: units.gu(1) } onClicked: PopupUtils.close(popover) } } } } } Button { id: popoverButton anchors.centerIn: parent text: "open" onClicked: PopupUtils.open(popoverComponent, popoverButton) } } \endqml */ PopupBase { id: popover /*! \qmlproperty list container Content will be put inside the foreround of the Popover. */ default property alias container: containerItem.data /*! \qmlproperty real contentWidth Use this property to override the default content width. */ property alias contentWidth: foreground.width /*! \qmlproperty real contentHeight Use this property to override the default content height. */ property alias contentHeight: foreground.height /*! The Item such as a \l Button that the user interacted with to open the Dialog. This property will be used for the automatic positioning of the Dialog next to the caller, if possible. */ property Item caller /*! The property holds the item to which the pointer should be anchored to. This can be same as the caller or any child of the caller. By default the property is set to caller. */ property Item pointerTarget: caller /*! The property holds the margins from the popover's dismissArea. The property is themed. */ property real edgeMargins: units.gu(2) /*! The property holds the margin from the popover's caller. The property is themed. */ property real callerMargin: 0 /*! The property drives the automatic closing of the Popover when user taps on the dismissArea. The default behavior is to close the Popover, therefore set to true. When set to false, closing the Popover is the responsibility of the caller. Also, the mouse and touch events are not blocked from the dismissArea. */ property bool autoClose: true /*! \qmlproperty Component foregroundStyle Exposes the style property of the \l StyledItem contained in the Popover. Refer to \l StyledItem how to use it. */ property alias foregroundStyle: foreground.style /*! \preliminary Make the popover visible. Reparent to the background area object first if needed. Only use this function if you handle memory management. Otherwise use PopupUtils.open() to do it automatically. */ function show() { /* Cannot call parent's show() however PopupBase::show() does not do anything useful to us. https://bugreports.qt-project.org/browse/QTBUG-25942 http://qt-project.org/forums/viewthread/19577 */ visible = true; foreground.show(); } /*! \preliminary Hide the popover. Only use this function if you handle memory management. Otherwise use PopupUtils.close() to do it automatically. */ function hide() { foreground.hide(); } Component.onCompleted: foreground.hideCompleted.connect(popover.__makeInvisible) /*! \internal */ function __makeInvisible() { visible = false; } QtObject { id: internal property bool portrait: width < height // private function updatePosition() { var pos = new InternalPopupUtils.CallerPositioning(foreground, pointer, dismissArea, caller, pointerTarget, edgeMargins, callerMargin); pos.auto(); } } __foreground: foreground __eventGrabber.enabled: autoClose __closeOnDismissAreaPress: true StyledItem { id: foreground //styling properties property real minimumWidth: units.gu(40) property real maxWidth: dismissArea ? (internal.portrait ? dismissArea.width : dismissArea.width * 3/4) : 0.0 property real maxHeight: dismissArea ? (internal.portrait ? dismissArea.height * 3/4 : dismissArea.height) : 0.0 width: Math.min(minimumWidth, maxWidth) height: containerItem.height Item { id: containerItem parent: foreground.__styleInstance.contentItem anchors { left: parent.left top: parent.top right: parent.right } height: childrenRect.height } onWidthChanged: internal.updatePosition() onHeightChanged: internal.updatePosition() property point target: Qt.point(pointer.x - x, pointer.y - y) property string direction: pointer.direction property bool clipContent: true signal show() signal hide() signal showCompleted() signal hideCompleted() style: Theme.createStyleComponent("PopoverForegroundStyle.qml", foreground) } QtObject { id: pointer /* Input variables for InternalPopupUtils are the properties: - horizontalMargin - verticalMargin - size Output variables of InternalPopupUtils are the properties: - x - y - direction */ property real arrowSize: units.dp(15) property real cornerSize: units.dp(11) /* Minimum distance between the top or bottom of the popup and the tip of the pointer when the direction is left or right. */ property real horizontalMargin: arrowSize/2.0 + cornerSize /* Minimum distance between the left or right of the popup and the tip of the pointer when the direction is up or down. */ property real verticalMargin: arrowSize/2.0 + cornerSize /* Either: - distance between the left or right of the popup and the tip of the pointer when the direction is left or right. - distance between the top or bottom of the popup and the tip of the pointer when the direction is up or down. */ property real size: units.dp(6) property real x property real y property string direction } /*! \internal */ onCallerChanged: internal.updatePosition() /*! \internal */ onPointerTargetChanged: internal.updatePosition() /*! \internal */ onWidthChanged: internal.updatePosition() /*! \internal */ onHeightChanged: internal.updatePosition() /*! \internal */ onRotationChanged: internal.updatePosition() } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/internalPopupUtils.js0000644000015301777760000003034612321005637032552 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library .import "../mathUtils.js" as MathUtils // Simple positioning on the screen, not relative to a caller Item. function SimplePositioning(foreground, area, edgeMargins) { // all coordinate computation are relative inside "area". // return the x-coordinate to center item horizontally in area this.horizontalCenter = function(item) { return area.width/2 - item.width/2; } // return the y-coordinate to center item vertically in area this.verticalCenter = function(item) { return area.height/2 - item.height/2; } // check whether item fits inside area, obeying the given margins this.checkVerticalPosition = function(item, y, marginBothSides, marginOneSide) { if (y < marginBothSides) return false; if (y + item.height > area.height - marginBothSides) return false; if (marginBothSides >= marginOneSide) return true; if (y > marginOneSide) return true; if (y + item.height < area.height - marginOneSide) return true; return false; } // check whether item fits inside area, obeying the given margins this.checkHorizontalPosition = function(item, x, marginBothSides, marginOneSide) { if (x < marginBothSides) return false; if (x + item.width > area.width - marginBothSides) return false; if (marginBothSides >= marginOneSide) return true; if (x > marginOneSide) return true; if (x + item.width < area.width - marginOneSide) return true; return false; } // position foreground at the top of the screen, horizontally centered this.autoSmallScreenPortrait = function() { foreground.x = this.horizontalCenter(foreground); foreground.y = 0; } // position foreground at the left side of the screen, vertically centered this.autoSmallScreenLandscape = function() { foreground.x = 0; foreground.y = this.verticalCenter(foreground); } // position foreground centered on a large screen this.autoLargeScreen = function() { foreground.x = this.horizontalCenter(foreground); foreground.y = this.verticalCenter(foreground); } // automatically position foreground on the screen this.auto = function(margin) { if (foreground.width >= area.width - 2*edgeMargins) { // the popover uses (almost) the full width of the screen this.autoSmallScreenPortrait(); return; } if (foreground.height >= area.height - 2*edgeMargins) { // the popover uses (almost) the full height of the screen this.autoSmallScreenLandscape(); return; } this.autoLargeScreen(); } } // caller is optional. // if caller is given, pointer and callerMargins must be specified, otherwise they are ignored. function CallerPositioning(foreground, pointer, area, caller, pointerTarget, edgeMargins, callerMargins) { var simplePos = new SimplePositioning(foreground, area, edgeMargins); // -1 values are not relevant. // return y-coordinate to position item a distance of margin above caller this.above = function(item, margin, anchorItem) { return area.mapFromItem(anchorItem, -1, 0).y - (item ? item.height : 0) - margin; } // return y-coordinate to position item a distance of margin below caller this.below = function(item, margin, anchorItem) { return area.mapFromItem(anchorItem, -1, anchorItem.height).y + margin; } // return x-coordinate to position item a distance of margin left of caller this.left = function(item, margin, anchorItem) { return area.mapFromItem(anchorItem, 0, -1).x - (item ? item.width : 0) - margin; } // return x-coodinate to position item a distance of margin right of caller this.right = function(item, margin, anchorItem) { return area.mapFromItem(anchorItem, anchorItem.width, -1).x + margin; } // return x-coordinate to align center of item horizontally with center of caller this.horizontalAlign = function(item, anchorItem) { var x = area.mapFromItem(anchorItem, anchorItem.width/2, -1).x - item.width/2; return MathUtils.clamp(x, edgeMargins, area.width - item.width - edgeMargins); } // return y-coordinate to align center of item vertically with center of caller this.verticalAlign = function(item, anchorItem) { var y = area.mapFromItem(anchorItem, -1, anchorItem.height/2).y - item.height/2; return MathUtils.clamp(y, edgeMargins, area.height - item.height - edgeMargins); } this.closestToHorizontalCenter = function(anchorItem, margin) { var center = area.mapFromItem(anchorItem, anchorItem.width/2, -1).x; return MathUtils.clamp(center, edgeMargins + margin, area.width - (edgeMargins + margin)); } this.closestToVerticalCenter = function(anchorItem, margin) { var center = area.mapFromItem(anchorItem, -1, anchorItem.height/2).y; return MathUtils.clamp(center, edgeMargins + margin, area.height - (edgeMargins + margin)); } // position foreground and pointer automatically on a small screen in portrait mode this.autoSmallScreenPortrait = function() { if (!caller) { simplePos.autoSmallScreenPortrait(); pointer.direction = "none"; return; } foreground.x = simplePos.horizontalCenter(foreground); var ycoord = this.above(foreground, callerMargins + pointer.size, caller); if (simplePos.checkVerticalPosition(foreground, ycoord, 0, area.height/4)) { foreground.y = ycoord; pointer.direction = "down"; pointer.y = this.above(null, callerMargins, caller); pointer.x = this.closestToHorizontalCenter(pointerTarget, pointer.horizontalMargin); return; } ycoord = this.below(foreground, callerMargins + pointer.size, caller); if (simplePos.checkVerticalPosition(foreground, ycoord, 0, area.height/4)) { foreground.y = ycoord; pointer.direction = "up"; pointer.y = this.above(null, callerMargins, caller); pointer.x = this.closestToHorizontalCenter(pointerTarget, pointer.horizontalMargin); return; } simplePos.autoSmallScreenPortrait(); pointer.direction = "none"; } // position foreground and pointer automatically on a small screen in landscape mode. this.autoSmallScreenLandscape = function() { if (!caller) { simplePos.autoSmallScreenLandscape(); pointer.direction = "none"; return; } foreground.y = simplePos.verticalCenter(foreground); var xcoord = this.left(foreground, callerMargins + pointer.size, caller); if (simplePos.checkHorizontalPosition(foreground, xcoord, 0, area.width/4)) { foreground.x = xcoord; pointer.direction = "right"; pointer.x = this.left(null, callerMargins, caller); pointer.y = this.closestToVerticalCenter(pointerTarget, pointer.verticalMargin); return; } xcoord = this.right(foreground, callerMargins + pointer.size, caller); if (simplePos.checkHorizontalPosition(foreground, xcoord, 0, area.width/4)) { foreground.x = xcoord; pointer.direction = "left"; pointer.x = this.right(null, callerMargins, caller); pointer.y = this.closestToVerticalCenter(pointerTarget, pointer.verticalMargin); return; } // position at the left of the screen simplePos.autoSmallScreenLandscape(); pointer.direction = "none"; } // position foreground and pointer above caller; the pointer's y will be aligned // to the caller, and x to the pointerTarget this.positionAbove = function() { var coord = this.above(foreground, callerMargins + pointer.size, caller); if (simplePos.checkVerticalPosition(foreground, coord, edgeMargins, 0)) { foreground.y = coord; foreground.x = this.horizontalAlign(foreground, caller); pointer.direction = "down"; pointer.y = this.above(null, callerMargins, caller); pointer.x = this.closestToHorizontalCenter(pointerTarget, pointer.horizontalMargin); return true; } return false; } // position foreground and pointer below caller; the pointer's y will be aligned // to the caller, and x to the pointerTarget this.positionBelow = function() { var coord = this.below(foreground, callerMargins + pointer.size, caller); if (simplePos.checkVerticalPosition(foreground, coord, edgeMargins, 0)) { foreground.y = coord; foreground.x = this.horizontalAlign(foreground, caller); pointer.direction = "up"; pointer.y = this.below(null, callerMargins, caller); pointer.x = this.closestToHorizontalCenter(pointerTarget, pointer.horizontalMargin); return true; } return false; } // position foreground and pointer in front of caller; the pointer's x will be aligned // to the caller, and y to the pointerTarget this.positionInFront = function() { var coord = this.left(foreground, callerMargins + pointer.size, caller); if (simplePos.checkHorizontalPosition(foreground, coord, edgeMargins, 0)) { foreground.x = coord; foreground.y = this.verticalAlign(foreground, caller); pointer.direction = "right"; pointer.x = this.left(null, callerMargins, caller); pointer.y = this.closestToVerticalCenter(pointerTarget, pointer.verticalMargin); return true; } return false; } // position foreground and pointer behind caller; the pointer's x will be aligned // to the caller, and y to the pointerTarget this.positionBehind = function() { var coord = this.right(foreground, callerMargins + pointer.size, caller) if (simplePos.checkHorizontalPosition(foreground, coord, edgeMargins, 0)) { foreground.x = coord; foreground.y = this.verticalAlign(foreground, caller); pointer.direction = "left"; pointer.x = this.right(null, callerMargins, caller); pointer.y = this.closestToVerticalCenter(pointerTarget, pointer.verticalMargin); return true; } return false; } // position foreground and pointer automatically on a large screen. this.autoLargeScreen = function() { if (!caller) { simplePos.autoLargeScreen(); pointer.direction = "none"; return; } // position with the following priorities: above, below, right, left. var order = ["positionAbove", "positionBelow", "positionBehind", "positionInFront"]; for (var i = 0; i < order.length; i++) { if (this[order[i]]()) return; } // not enough space on any of the sides to fit within the margins. simplePos.autoLargeScreen(); pointer.direction = "none"; } this.auto = function() { // area may be null some times... if (!area) return; if (!pointerTarget) pointerTarget = caller; if (foreground.width >= area.width - 2*edgeMargins) { // the popover uses (almost) the full width of the screen this.autoSmallScreenPortrait(); return; } if (foreground.height >= area.height - 2*edgeMargins) { // the popover uses (almost) the full height of the screen this.autoSmallScreenLandscape(); return; } this.autoLargeScreen(); } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/ActionSelectionPopover.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/ActionSelectionPopover.qm0000644000015301777760000001241512321005637033325 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "../" 0.1 import "../ListItems" 0.1 /*! \qmltype ActionSelectionPopover \inherits Popover \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief A special popover presenting actions to the user. The popover is closed automatically when the action is chosen. The actions can be given either using ActionList or as an array of action objects. The visualization of the actions is realized either using the default visualization, which is realised using list items having centered text, or using the component given as delegate. The actions are triggered with the specified target as parameter. The popover recognizes the following properties from the delegate: \list \li data properties like \b modelData, \b refModelData or \b action. When either of these is detected the popover will set their value to the action object to be visualized. \li trigger signals like \b clicked, \b accepted or \b triggered. When these are detected, the popover will automatically connect those to the action's trigger. \endlist An example presenting list of actions using ActionList: \qml ActionSelectionPopover { delegate: ListItems.Standard { text: action.text } actions: ActionList { Action { text: "Action one" onTriggered: print(text) } Action { text: "Action two" onTriggered: print(text) } } } \endqml An array of actions can be used when the actions to be presented are reused from a set of predefined actions: \qml Item { Action { id: action1 text: "Action one" onTriggered: print(text) } Action { id: action2 text: "Action two" onTriggered: print(text) } Action { id: action3 text: "Action three" onTriggered: print(text) } ActionListPopover { actions: [action1, action3] delegate: ListItems.Standard { text: action.text } } } \endqml */ Popover { id: popover /*! The property holds the object on which the action will be performed. */ property Item target /*! The property holds the list of actions to be presented. Each action triggered will use the actionHost as caller. */ property var actions /*! The property holds the delegate to visualize the action. The delegate should define one of the data holder properties recognized by the popover in order to access action data. */ property Component delegate: Empty { id: listItem Label { text: listItem.text anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } wrapMode: Text.Wrap color: Theme.palette.normal.overlayText } /*! \internal */ onTriggered: popover.hide() visible: enabled height: visible ? implicitHeight : 0 } grabDismissAreaEvents: false Column { id: body anchors { left: parent.left top: parent.top right: parent.right } property bool isActionsObject: (popover.actions !== undefined) && popover.actions.hasOwnProperty("actions") Repeater { id: repeater model: body.isActionsObject ? popover.actions.children : popover.actions Loader { width: parent.width height: modelData.visible ? item.height : 0 sourceComponent: delegate onStatusChanged: { if (item && status == Loader.Ready) { // set model data if (item.hasOwnProperty("action")) item.action = modelData; if (item.hasOwnProperty("refModelData")) item.refModelData = modelData; if (item.hasOwnProperty("modelData")) item.modelData = modelData; // auto-connect trigger // if the delegate is a list item, hide divider of the last one if (item.hasOwnProperty("showDivider")) item.showDivider = index < (repeater.count - 1); } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/DefaultSheet.qml0000644000015301777760000000625712321005637031427 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype DefaultSheet \inherits SheetBase \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief The Default Sheet allows an application to insert a content view over the focused view without disrupting the navigation pattern (tabs state or drill-down path are maintained. When the sheet is dismissed the user continues the journey from the point (s)he left it). The Default Sheet can be closed using either a "close" button (top left) or a "done" button (top right). The sheet cannot be dismissed any other way. Use the \l doneButton property to configure whether the "close" or the "done" button is used. Example: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 Item { Component { id: defaultSheet DefaultSheet { id: sheet title: "Default sheet with done button" doneButton: true Label { anchors.fill: parent text: "A default sheet with a done button." wrapMode: Text.WordWrap } onDoneClicked: PopupUtils.close(sheet) } } Button { anchors.centerIn: parent text: "default" width: units.gu(16) onClicked: PopupUtils.open(defaultSheet) } } \endqml */ SheetBase { id: sheet /*! \preliminary If set, a "done" button is visible in the top right of the sheet's header, if unset a "cancel" button is available in the top left of the sheet's header. */ property bool doneButton: false /*! \preliminary This handler is called when the close button is clicked. */ signal closeClicked /*! \preliminary This handler is called when the done button is clicked. */ signal doneClicked __leftButton: Button { text: i18n.dtr("ubuntu-sdk", "close") visible: !doneButton /*! \internal */ onClicked: { sheet.closeClicked(); sheet.hide(); } } __rightButton: Button { text: i18n.dtr("ubuntu-sdk", "done") color: UbuntuColors.orange visible: doneButton /*! \internal */ onClicked: { sheet.doneClicked(); sheet.hide(); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/SheetBase.qml0000644000015301777760000000645512321005637030715 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype SheetBase \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief Parent class of different types of sheets. Not to be used directly. Examples: See subclasses. \b{This component is under heavy development.} */ PopupBase { id: sheet /*! \preliminary \qmlproperty list container Content will be put inside the foreround of the sheet. */ default property alias container: containerItem.data /*! Override the default width of the contents of the sheet. Total sheet width will be clamped between 50 grid units and the screen width. \qmlproperty real contentsWidth */ property alias contentsWidth: foreground.contentsWidth /*! \preliminary Override the default height of the contents of the sheet. Total sheet height will be clamped between 40 grid units and the screen height. \qmlproperty real contentsHeight */ property alias contentsHeight: foreground.contentsHeight /*! \preliminary The text shown in the header of the sheet. \qmlproperty string title */ property alias title: foreground.title /*! The property controls whether the sheet is modal or not. Modal sheets block event propagation to items under dismissArea, when non-modal ones let these events passed to these items. The default value is true. */ property bool modal: true /*! \internal */ property alias __leftButton: foreground.leftButton /*! \internal */ property alias __rightButton: foreground.rightButton fadingAnimation: UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } __foreground: foreground __eventGrabber.enabled: modal StyledItem { id: foreground property string title property real contentsWidth: units.gu(64) property real contentsHeight: units.gu(40) property Button leftButton property Button rightButton y: Math.min(units.gu(15), (sheet.height - height)/2) anchors.horizontalCenter: parent.horizontalCenter property real minWidth: Math.min(units.gu(50), sheet.width) property real maxWidth: sheet.width property real minHeight: Math.min(units.gu(40), sheet.height) property real maxHeight: sheet.height Item { id: containerItem parent: foreground.__styleInstance.contentItem anchors { fill: parent margins: units.gu(1) } } style: Theme.createStyleComponent("SheetForegroundStyle.qml", sheet) } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/PopupBase.qml0000644000015301777760000001463312321005637030745 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype PopupBase \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief The base class for all dialogs, sheets and popovers. Do not use directly. Examples: See subclasses. */ OrientationHelper { id: popupBase /*! The property holds the area used to dismiss the popups, the area from where mouse and touch events will be grabbed. By default this area is the Popup itself. */ property Item dismissArea: popupBase /*! The property specifies whether to forward or not the mouse and touch events happening outside of the popover. By default all events are grabbed. */ property bool grabDismissAreaEvents: true /*! \internal FIXME: publish this property once agreed */ property PropertyAnimation fadingAnimation: PropertyAnimation{duration: 0} // without specifying width and height below, some width calculations go wrong in Sheet. // I guess popupBase.width is not correctly set initially width: parent ? parent.width : undefined height: parent ? parent.height : undefined // copy value of automaticOrientation from root object (typically a MainView) automaticOrientation: stateWrapper.rootItem && stateWrapper.rootItem.automaticOrientation ? stateWrapper.rootItem.automaticOrientation : false LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true /*! \preliminary Make the popup visible. Reparent to the background area object first if needed. Only use this function if you handle memory management. Otherwise use PopupUtils.open() to do it automatically. */ function show() { if (!dismissArea) dismissArea = stateWrapper.rootItem // Without setting the parent, mapFromItem() breaks in internalPopupUtils. parent = stateWrapper.rootItem; stateWrapper.state = 'opened'; } /*! \preliminary Hide the popup. Only use this function if you handle memory management. Otherwise use PopupUtils.close() to do it automatically. */ function hide() { stateWrapper.state = 'closed'; } /*! \internal When the popup is created by calling PopupUtils.open(), onVisibleChanged is connected to __closeIfHidden(). */ function __closeIfHidden() { if (!visible) __closePopup(); } /*! \internal The function closes the popup. This is called when popup's caller is no longer valid. */ function __closePopup() { if (popupBase !== undefined) { popupBase.destroy(); } } /*! \internal Foreground component excluded from InverseMouseArea */ property Item __foreground /*! \internal Set to true if the InverseMouseArea should dismiss the area */ property bool __closeOnDismissAreaPress: false /*! \internal Property driving dimming the popup's background. The default is the same as defined in the style */ property alias __dimBackground: background.dim /*! \internal Property to control dismissArea event capture. */ property alias __eventGrabber: eventGrabber // dimmer Rectangle { id: background // styling properties property bool dim: false anchors.fill: parent visible: dim color: popupBase.width > units.gu(60) ? Qt.rgba(0, 0, 0, 0.6) : Qt.rgba(0, 0, 0, 0.9) } InverseMouseArea { id: eventGrabber enabled: true anchors.fill: __foreground sensingArea: dismissArea propagateComposedEvents: !grabDismissAreaEvents onPressed: if (__closeOnDismissAreaPress) popupBase.hide() } MouseArea { anchors.fill: __foreground } // set visible as false by default visible: false opacity: 0.0 /*! \internal */ onVisibleChanged: stateWrapper.state = (visible) ? 'opened' : 'closed' /*! \internal */ onParentChanged: stateWrapper.rootItem = QuickUtils.rootItem(popupBase) Component.onCompleted: stateWrapper.rootItem = QuickUtils.rootItem(popupBase); Item { id: stateWrapper property Item rootItem: QuickUtils.rootItem(popupBase) states: [ State { name: 'closed' extend: '' }, State { name: 'opened' } ] transitions: [ Transition { from: "*" to: "opened" SequentialAnimation { ScriptAction { script: popupBase.visible = true } NumberAnimation { target: popupBase property: "opacity" from: 0.0 to: 1.0 duration: fadingAnimation.duration easing: fadingAnimation.easing } } }, Transition { from: "opened" to: "closed" SequentialAnimation { NumberAnimation { target: popupBase property: "opacity" from: 1.0 to: 0.0 duration: fadingAnimation.duration easing: fadingAnimation.easing } ScriptAction { script: { popupBase.visible = false; } } } } ] } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/qmldir0000644000015301777760000000044112321005637027537 0ustar pbusernogroup00000000000000module Ubuntu.Components.Popups Dialog 0.1 Dialog.qml PopupBase 0.1 PopupBase.qml Popover 0.1 Popover.qml SheetBase 0.1 SheetBase.qml DefaultSheet 0.1 DefaultSheet.qml ComposerSheet 0.1 ComposerSheet.qml ActionSelectionPopover 0.1 ActionSelectionPopover.qml PopupUtils 0.1 popupUtils.js ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/ComposerSheet.qml0000644000015301777760000000602012321005637031616 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype ComposerSheet \inherits SheetBase \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief Much like the \l DefaultSheet the Composer Sheet allows an application to insert a content view over the focused view without disrupting the navigation pattern. However the Composer Sheet is optimised for scenarios in which user content is at risk of corruption, most often (but not solely) when creating or editing content (e.g compose new message). There are two ways to dismiss it: user confirming the manipulation or user cancelling the manipulation, using the "confirm" and "cancel" buttons shown in the right and left side of the composer header. Example: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 Item { Component { id: composerSheet ComposerSheet { id: sheet title: "Composer sheet" Label { text: "A composer sheet has cancel and confirm buttons." } onCancelClicked: PopupUtils.close(sheet) onConfirmClicked: PopupUtils.close(sheet) } } Button { anchors.centerIn: parent text: "composer" width: units.gu(16) onClicked: PopupUtils.open(composerSheet) } } \endqml */ SheetBase { id: composer /*! \preliminary The user clicked the "cancel" button. */ signal cancelClicked /*! \preliminary The user clicked the "confirm" button. */ signal confirmClicked __leftButton: Button { text: i18n.dtr("ubuntu-sdk", "cancel") objectName: "cancelButton" /*! \internal */ // avoid warning when generating documentation onClicked: { composer.cancelClicked(); composer.hide(); } } __rightButton: Button { text: i18n.dtr("ubuntu-sdk", "confirm") objectName: "confirmButton" color: UbuntuColors.orange /*! \internal */ // avoid warning when generating documentation onClicked: { composer.confirmClicked(); composer.hide(); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/popupUtils.js0000644000015301777760000000521512321005637031052 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! The function opens a popup object which can be either a Component or in a separate QML document. The caller drives the Popup's and Dialog's placement as well as the pointer's. The third parameter (param) can hold a series of properties configuring the popup to be opened. This can be any property defined by the popups and additional custom ones defined in derived popups. caller parameter must be given when the Sheet or Dialog is specified using url and opened inside a Window component. If not, the Sheet or Dialog will use the application's root item as dismiss area. */ function open(popup, caller, params) { var popupComponent = null; var rootObject = null; if (popup.createObject) { // popup is a component and can create an object popupComponent = popup; rootObject = QuickUtils.rootItem(popup); } else if (typeof popup === "string") { popupComponent = Qt.createComponent(popup); rootObject = (caller !== undefined) ? QuickUtils.rootItem(caller) : QuickUtils.rootItem(null); } else { print("PopupUtils.open(): "+popup+" is not a component or a link"); return null; } var popupObject; if (params !== undefined) { popupObject = popupComponent.createObject(rootObject, params); } else { popupObject = popupComponent.createObject(rootObject); } if (!popupObject) { print("PopupUtils.open(): Failed to create the popup object."); return; } else if (popupObject.hasOwnProperty("caller") && caller) popupObject.caller = caller; // if caller is specified, connect its cleanup to the popup's close // so popups will be removed together with the caller. if (caller) caller.Component.onDestruction.connect(popupObject.__closePopup); popupObject.show(); popupObject.onVisibleChanged.connect(popupObject.__closeIfHidden); return popupObject; } /*! Closes (hides and destroys) the given popup. */ function close(popupObject) { popupObject.hide(); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Popups/Dialog.qml0000644000015301777760000001502012321005637030235 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import "internalPopupUtils.js" as InternalPopupUtils /*! \qmltype Dialog \inherits PopupBase \inqmlmodule Ubuntu.Components.Popups 0.1 \ingroup ubuntu-popups \brief The Dialog caters for cases in which the application requires the user to determine between optional actions. The Dialog will interrupt the user flow and lock the view for further interaction before the user has selected a desired action. It can only be closed by selecting an optional action confirming or cancelling the operation. \l {http://design.ubuntu.com/apps/building-blocks/dialog}{See also the Design Guidelines on Dialogs}. Example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Popups 0.1 Item { width: units.gu(80) height: units.gu(80) Component { id: dialog Dialog { id: dialogue title: "Save file" text: "Are you sure that you want to save this file?" Button { text: "cancel" onClicked: PopupUtils.close(dialogue) } Button { text: "overwrite previous version" color: UbuntuColors.orange onClicked: PopupUtils.close(dialogue) } Button { text: "save a copy" color: UbuntuColors.orange onClicked: PopupUtils.close(dialogue) } } } Button { anchors.centerIn: parent id: saveButton text: "save" onClicked: PopupUtils.open(dialog) } } \endqml */ PopupBase { id: dialog /*! \preliminary \qmlproperty list contents Content will be put inside a column in the foreround of the Dialog. */ default property alias contents: contentsColumn.data /*! \preliminary The title of the question to ask the user. \qmlproperty string title */ property alias title: foreground.title /*! \preliminary The question to the user. \qmlproperty string text */ property alias text: foreground.text /*! \preliminary The Item such as a \l Button that the user interacted with to open the Dialog. This property will be used for the automatic positioning of the Dialog next to the caller, if possible. */ property Item caller /*! The property holds the item to which the pointer should be anchored to. This can be same as the caller or any child of the caller. By default the property is set to caller. */ property Item pointerTarget /*! \internal */ onPointerTargetChanged: { console.debug("pointerTarget DEPRECATED") } /*! The property holds the margins from the dialog's dismissArea. The property is themed. */ property real edgeMargins: units.gu(2) /*! The property holds the margin from the dialog's caller. The property is themed. */ property real callerMargin: units.gu(1) /*! The property controls whether the dialog is modal or not. Modal dialogs block event propagation to items under dismissArea, when non-modal ones let these events passed to these items. In addition, non-modal dialogs do not dim the dismissArea. The default value is true. */ property bool modal: true /* QtObject { id: internal function updatePosition() { var pos = new InternalPopupUtils.CallerPositioning(foreground, pointer, dialog, caller, pointerTarget, edgeMargins, callerMargin); pos.auto(); } } Pointer { id: pointer } */ __foreground: foreground __eventGrabber.enabled: modal __dimBackground: modal fadingAnimation: UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } StyledItem { id: foreground width: Math.min(minimumWidth, dialog.width) anchors.centerIn: parent // used in the style property string title property string text property real minimumWidth: units.gu(38) property real minimumHeight: units.gu(32) property real maxHeight: 3*dialog.height/4 property real margins: units.gu(4) property real itemSpacing: units.gu(2) property Item dismissArea: dialog.dismissArea height: Math.min(childrenRect.height, dialog.height) Column { id: contentsColumn anchors { top: parent.top left: parent.left right: parent.right margins: foreground.margins } spacing: foreground.itemSpacing height: childrenRect.height + foreground.margins onWidthChanged: updateChildrenWidths(); Label { horizontalAlignment: Text.AlignHCenter text: dialog.title fontSize: "large" color: Qt.rgba(1, 1, 1, 0.9) } Label { horizontalAlignment: Text.AlignHCenter text: dialog.text fontSize: "medium" color: Qt.rgba(1, 1, 1, 0.6) wrapMode: Text.Wrap } onChildrenChanged: updateChildrenWidths() function updateChildrenWidths() { for (var i = 0; i < children.length; i++) { children[i].width = contentsColumn.width; } } } style: Theme.createStyleComponent("DialogForegroundStyle.qml", foreground) } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/dateUtils.js0000644000015301777760000000756412321005637027347 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library /* Extending Date with few prototypes */ Date.msPerDay = 86400e3 Date.msPerWeek = Date.msPerDay * 7 /*! The function returns a Date object with the current date and hour set to midnight. */ Date.prototype.midnight = function() { this.setHours(0, 0, 0, 0); return this; } /*! The function returns an invalid date object. Example of use: \code var invalidDate = Date.prototype.getInvalidDate.call(); var otherInvalidDate = (new Date()).getInvalidDate(); \endcode */ Date.prototype.getInvalidDate = function() { return new Date(-1, -1); } /*! The function checks whether the date object is a valid one, meaning the year, month and date fields are positive numbers */ Date.prototype.isValid = function() { if (Object.prototype.toString.call(this) !== "[object Date]") { return false; } return (this.getFullYear() > 0) && (this.getMonth() >= 0) && (this.getDate() > 0); } /*! The function returns the number of days in the month set in the Date object. */ Date.prototype.daysInMonth = function() { return [ 31/*an*/, 28/*Feb*/, 31/*Mar*/, 30/*Apr*/, 31/*May*/, 30/*Jun*/, 31/*Jul*/, 31/*Aug*/, 30/*Sep*/, 31/*Oct*/, 30/*Nov*/, 31/*Dec*/ ][this.getMonth()] + (this.getMonth() === 1) * this.leapYear(); } /*! The function checks whether the year in the Date object is a leap year or not. */ Date.prototype.leapYear = function() { var year = this.getFullYear(); return year % 400 == 0 || (year % 100 !== 0 && year % 4 == 0); } /*! The function returns the distance in months (not calendaristic months) between the Date object and the given one as parameter. */ Date.prototype.monthsTo = function(target) { return target.getMonth() - this.getMonth() + (12 * (target.getFullYear() - this.getFullYear())); } /*! Same as monthsTo, but returns the distance in days. */ Date.prototype.daysTo = function(target) { return !target.isValid() ? 0 : Math.ceil((target - this) / Date.msPerDay); } /*! Same as monthsTo, but returns the distance in hours. */ Date.prototype.hoursTo = function(target) { return !target.isValid() ? 0 : Math.ceil((target.getTime() - this.getTime()) / (1000 * 60 * 60)); } /*! Same as monthsTo, but returns the distance in minutes. */ Date.prototype.minutesTo = function(target) { return !target.isValid() ? 0 : Math.ceil((target.getTime() - this.getTime()) / (1000 * 60)); } /*! Same as monthsTo, but returns the distance in seconds. */ Date.prototype.secondsTo = function(target) { return !target.isValid() ? 0 : Math.ceil((target.getTime() - this.getTime()) / 1000); } /*! The function returns the week number of the date stored in the object. */ Date.prototype.getWeek = function() { // Copy date so don't modify original var date = new Date(this); date.setHours(0, 0, 0, 0); // Set to nearest Thursday: current date + 4 - current day number // Make Sunday's day number 7 date.setDate(date.getDate() + 4 - (date.getDay() || 7)); // Get first day of year var yearStart = new Date(date.getFullYear(), 0, 1); // Calculate full weeks to nearest Thursday var weekNo = Math.ceil((((date - yearStart) / 86400000) + 1) / 7); // Return array of year and week number return weekNo; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/TextInputPopover.qml0000644000015301777760000000414212321005637031072 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 as Toolkit import "Popups" 0.1 ActionSelectionPopover { objectName: "text_input_popover" actions: ActionList { Action { text: i18n.tr("Select All") enabled: target && target.text !== "" && target.text !== target.selectedText onTriggered: target.selectAll() } Action { text: i18n.tr("Select Word") enabled: target && target.text !== "" && target.selectedText === "" onTriggered: target.selectWord() } Action { text: i18n.tr("Cut") // If paste/editing is not possible, then disable also "Cut" operation // It is applicable for ReadOnly's TextFields and TextAreas enabled: target && target.selectedText !== "" && target.canPaste onTriggered: target.cut() } Action { text: i18n.tr("Copy") enabled: target && target.selectedText !== "" onTriggered: target.copy() } Action { text: i18n.tr("Paste") enabled: target && target.canPaste onTriggered: target.paste() } Action { text: i18n.tr("Undo") enabled: target && target.canUndo onTriggered: target.undo() } Action { text: i18n.tr("Redo") enabled: target && target.canRedo onTriggered: target.redo() } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/StyledItem.qml0000644000015301777760000000420412321005637027635 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmlabstract StyledItem \inqmlmodule Ubuntu.Components 0.1 \ingroup theming \brief The StyledItem class allows items to be styled by the theme. StyledItem provides facilities for making an Item stylable by the theme. In order to make an Item stylable by the theme, it is enough to make the Item inherit from StyledItem and set its \l style property to be the result of the appropriate call to Theme.createStyleComponent(). Example definition of a custom Item MyItem.qml: \qml StyledItem { id: myItem style: Theme.createStyleComponent("MyItemStyle.qml", myItem) } \endqml The Component set on \l style is instantiated and placed below everything else that the Item contains. A reference to the Item being styled is accessible from the style and named 'styledItem'. \sa {Theme} */ FocusScope { id: styledItem /*! Component instantiated immediately and placed below everything else. */ property Component style /*! \internal Instance of the \l style. */ readonly property Item __styleInstance: styleLoader.status == Loader.Ready ? styleLoader.item : null implicitWidth: __styleInstance ? __styleInstance.implicitWidth : 0 implicitHeight: __styleInstance ? __styleInstance.implicitHeight : 0 Loader { id: styleLoader anchors.fill: parent sourceComponent: style property Item styledItem: styledItem } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Panel.qml0000644000015301777760000005564212321005670026622 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 as Toolkit /*! \qmltype Panel \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief A panel that can be swiped in and out from an edge of the window by the user. For most applications, it is highly recommended to use the \l MainView instead which includes a toolbar at its bottom that can be swiped in or out. Unless your application has very specific needs for a Panel, use a \l MainView with the default toolbar. When using a Panel, do not theme it directly, but theme its contents, because the Panel itself should not have visible elements, since it is in the view (to detect mouse events) even when its contents should be invisible. Set the anchors and/or width/height of the Panel to specify the area that the Panel covers when opened. A black panel that can be swiped in from the lower-right of the window can be created like this: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(80) height: units.gu(80) Panel { id: panel anchors { right: parent.right bottom: parent.bottom } width: parent.width / 2 height: units.gu(8) Rectangle { anchors.fill: parent color: Theme.palette.normal.overlay Button { anchors.centerIn: parent text: "Click" } } } } \endqml A panel that looks like the standard (bottom-aligned) toolbar, but with custom contents, can be created like this: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(80) height: units.gu(80) Panel { id: panel anchors { left: parent.left right: parent.right bottom: parent.bottom } height: units.gu(8) Item { anchors.fill: parent // two properties used by the toolbar delegate: property bool opened: panel.opened property bool animating: panel.animating Button { anchors.centerIn: parent text: "Click" } } } } \endqml Any Items can be placed inside the Panel, but MouseAreas can block mouse events from reaching the panel and thus obstruct the swiping behavior for hiding the panel. As a result, the user cannot start swiping on the buttons in the examples above in order to hide the panel. To remedy this, clicked() signals are forwarded from the panel by calling the child's trigger() function. Example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { color: Theme.palette.normal.background width: units.gu(40) height: units.gu(40) Panel { id: panel anchors { left: parent.left right: parent.right bottom: parent.bottom } height: units.gu(8) Rectangle { color: Theme.palette.normal.overlay anchors.fill: parent Rectangle { width: units.gu(8) height: units.gu(4) anchors.centerIn: parent color: "red" function trigger() { print("The red rectangle was clicked"); } } } } Component.onCompleted: panel.open(); } \endqml Like this, the red rectangle accepts click events, but the user can still swipe down on top of the rectangle in order to hide the panel. */ Item { id: panel /*! Default property, holds the content which will be swiped in and out. \qmlproperty list contents */ default property alias contents: bar.data /*! The property defines the alignment of the panel. The implementation supports the following values: \list \li Qt.AlignBottom to swipe in the panel from the bottom (default) \li Qt.AlignTop to swipe in the panel from the top \li Qt.AlignLeft to swipe in the panel from the left \li Qt.AlignRight to swipe in the panel from the right \li Qt.AlignLeading left when layout mirrorring is disabled, right otherwise \li Qt.AlignTrailing right when layout mirroring is disabled, left otherwise \endlist The default value is \b Qt.AlignBottom, and it is not recommended to change the default value because the left, right and top edge are already used for system functions, while the bottom edge is reserved for app-specific functionality such as a default toolbar. The use of Qt.AlignLeading and Qt.AlignTrailing is preferred over Qt.AlignLeft and Qt.AlignRight in order to more easily support right-to-left user interfaces that use LayoutMirroring. */ property int align: Qt.AlignBottom /*! When opened, the panel is visible, otherwise it is hidden. Use edge swipes to open/close the panel. The opened property is not updated until the swipe gesture is completed. */ // opened is true if state is spread, or if state is moving/hint and the previous state was spread. property bool opened: (panel.state === "spread") || (panel.state === "moving" && internal.previousState === "spread") /*! \internal */ // FIXME: When opened is made read-only, onOpenedChanged can be removed entirely. onOpenedChanged: { if (internal.openedChangedWarning) { console.log("DEPRECATED use of Panel.opened property. This property will be made read-only, please use the opened property of the Page tools or use Panel.open() and Panel.close()."); if (opened) { panel.open(); } else { panel.close(); } // re-establish the previous binding for opened. panel.opened = Qt.binding(function() { return (panel.state === "spread") || (panel.state === "moving" && internal.previousState === "spread"); }) } internal.openedChangedWarning = true; } /*! Open the panel */ function open() { // FIXME: When opened is made readonly, openedChangedWarning must be removed internal.openedChangedWarning = false; panel.state = "spread"; hideTimer.conditionalRestart(); } /*! Close the panel */ function close() { // FIXME: When opened is made readonly, openedChangedWarning must be removed. internal.openedChangedWarning = false; panel.state = ""; hideTimer.stop(); } /*! The time in milliseconds before the panel automatically hides after inactivity when it is not locked. Interacting with the panel resets the timer. Note that adding contents to the panel that accepts mouse events will prevent the panel from detecting interaction and the timer will not be reset. Setting a negative value will disable automatic hiding. Default value: -1 (automatic hiding is disabled). \qmlproperty int hideTimeout */ property alias hideTimeout: hideTimer.interval /*! Disable edge swipe to open/close the panel. False by default. */ property bool locked: false /*! \internal */ onLockedChanged: { if (state == "hint" || state == "moving") { draggingArea.finishMoving(); } if (!hideTimer.conditionalRestart()) { hideTimer.stop(); } } Timer { id: hideTimer interval: -1 running: panel.opened && !panel.locked && interval >= 0 function conditionalRestart() { if (hideTimer.interval >= 0) { if (!panel.locked && panel.opened) { hideTimer.restart(); return true; } } return false; } onIntervalChanged: { if (!conditionalRestart()) { hideTimer.stop(); } } onTriggered: { if (!panel.locked) { panel.close(); } } } // disable the timer when the application is not active to avoid closing // the panel immediately after the application becomes active again Connections { target: Qt.application onActiveChanged: { if (Qt.application.active) { hideTimer.conditionalRestart(); } else { hideTimer.stop(); } } } /*! How much of the panel to show when the user touches the panel's edge. This gives the user a hint that there is a panel hiding at that edge and invites him/her to swipe to show the panel completely. Default value: units.gu(2). */ property real hintSize: units.gu(2) /*! The size (height for top or bottom-aligned panels, width for left or right-aligned panels) of the mouse area used to detect edge swipes to open the panel, when the panel is not opened. Default value: units.gu(2). */ property real triggerSize: units.gu(2) /*! \qmlproperty real position The current position of the edge of the panel. The value is 0 when the panel is opened, and has its maximum value when the panel is closed. The maximum value is the width of the Panel for a left or right-aligned panel, and the height of the panel for top or bottom-aligned panels. When the user drags the Panel from the edge to open it, the position will change from the maximum size (closed) to 0 (fully expanded). */ readonly property alias position: bar.position states: [ State { name: "hint" PropertyChanges { target: bar position: bar.size - panel.hintSize } }, State { name: "moving" PropertyChanges { target: bar position: MathUtils.clamp(draggingArea.mousePosition - internal.movingDelta, 0, bar.size) } }, State { name: "spread" PropertyChanges { target: bar position: 0 } }, State { name: "" PropertyChanges { target: bar position: bar.size explicit: true } } ] /*! Animate transitions between the different panel states. */ property bool animate: true /*! The toolbar is currently not in a stable hidden or visible state. */ readonly property bool animating: draggingArea.pressed || transitionToAll.running || transitionToHint.running || transitionToSpread.running transitions: [ Transition { id: transitionToAll to: "" UbuntuNumberAnimation { target: bar properties: "position" duration: internal.transitionDuration } }, Transition { id: transitionToHint to: "hint" UbuntuNumberAnimation { target: bar properties: "position" duration: internal.transitionDuration } }, Transition { id: transitionToSpread to: "spread" UbuntuNumberAnimation { target: bar properties: "position" duration: internal.transitionDuration } }, Transition { id: transitionToMoving to: "moving" UbuntuNumberAnimation { target: bar properties: "position" duration: panel.animate ? Toolkit.UbuntuAnimation.SnapDuration : 0 } } ] QtObject { id: internal // FIXME: Remove when opened property is made readonly property bool openedChangedWarning: true /*! The duration in milliseconds of sliding in or out transitions when opening, closing, and showing the hint. Default value: 250 */ property real transitionDuration: panel.animate ? Toolkit.UbuntuAnimation.FastDuration : 0 property string previousState: "" property int movingDelta // Convert from Qt.AlignLeading to Qt.AlignTrailing to Qt.AlignLeft and Qt.AlignRight property int align: { if (panel.align === Qt.AlignLeading) { if (panel.LayoutMirroring.enabled) { return Qt.AlignRight; } else { return Qt.AlignLeft; } } else if (panel.align === Qt.AlignTrailing) { if (panel.LayoutMirroring.enabled) { return Qt.AlignLeft; } else { return Qt.AlignRight; } } else { return panel.align; } } readonly property int orientation: (panel.align === Qt.AlignTop || panel.align === Qt.AlignBottom) ? Qt.Horizontal : Qt.Vertical } /*! \internal */ onStateChanged: { if (state == "hint") { internal.movingDelta = panel.hintSize + draggingArea.initialPosition - bar.size; } else if (state == "moving" && internal.previousState == "spread") { internal.movingDelta = draggingArea.initialPosition; } } /*! \internal \deprecated Enable the InverseMouseArea that closes the panel when the user clicks outside of the panel. This functionality moved to the Toolbar/Page implementation because the mouse area needs to access with the toolbar and header, but this InverseMouseArea is still in the Panel for backwards compatibility in apps that use it directly. Default value is true, but it is set to false in Toolbar. FIXME: Remove __closeOnContentsClicks and the IMA below when all apps use Toolbar instead of Panel. */ property bool __closeOnContentsClicks: true Toolkit.InverseMouseArea { anchors.fill: draggingArea onPressed: { mouse.accepted = false; // the mouse click may cause an update // of locked by the clicked Item behind if (!panel.locked) panel.close(); } propagateComposedEvents: true visible: panel.__closeOnContentsClicks && panel.locked == false && panel.state == "spread" } /*! \internal \deprecated Enable automatic reveal of panel on mouse hover over hint area, and hide when leaving the panel area. This is disabled by default, because Panel may be used to implement bottom edge behaviors that are completely different from the toolbar, but the property is enabled in Toolbar to make more usable on desktop. */ property bool __openOnHover: false /*! The user presses on the opened toolbar, or when the toolbar is closed but not locked, the user presses in the toolbar trigger area. \qmlproperty bool pressed */ // This is a simple alias to draggingArea.pressed, but the documentation is accurate // because of the visible definition of draggingArea. Pressed is false when draggingArea // is not visible. property alias pressed: draggingArea.pressed DraggingArea { id: draggingArea orientation: internal.orientation === Qt.Horizontal ? Qt.Vertical : Qt.Horizontal zeroVelocityCounts: true anchors { top: panel.align === Qt.AlignBottom ? undefined : parent.top bottom: panel.align === Qt.AlignTop ? undefined : parent.bottom left: panel.align === Qt.AlignRight || panel.align === Qt.AlignTrailing ? undefined : parent.left right: panel.align === Qt.AlignLeft || panel.align === Qt.AlignLeading ? undefined : parent.right } height: internal.orientation === Qt.Horizontal ? panel.opened ? bar.size + units.gu(1) : panel.triggerSize : undefined width: internal.orientation === Qt.Vertical ? panel.opened ? bar.size + units.gu(1) : panel.triggerSize : undefined visible: !panel.locked || panel.opened hoverEnabled: panel.__openOnHover property int mousePosition: getMousePosition() function getMousePosition() { switch (internal.align) { case Qt.AlignLeft: return -mouseX; case Qt.AlignRight: return mouseX; case Qt.AlignBottom: return mouseY; case Qt.AlignTop: return -mouseY; } } // set in onPressed, reset when entering "moving" state property Item pressedItem: null // find the first child with a triggered property: function getTriggerableItem(mouse) { var item = bar; // contains the children while (item && !item.hasOwnProperty("trigger")) { var coords = mapToItem(item, mouse.x, mouse.y); // FIXME: When using a ListView the highlight may be // returned instead of the Item that you are looking for item = item.childAt(coords.x, coords.y); } return item; // will be null if no item has trigger() function. } // forward trigger() events to any child Item with trigger() function. // This must also happen when the panel is locked, so the DraggingArea is // never disabled, and other signal handlers will return when panel.locked is true. onClicked: { if (pressedItem && pressedItem === getTriggerableItem(mouse)) { // Click event positioned at the Item where the user first pressed pressedItem.trigger(); } } property int initialPosition onPressed: { hideTimer.stop(); pressedItem = getTriggerableItem(mouse); if (panel.locked) return; initialPosition = getMousePosition(); if (panel.state == "") panel.state = "hint"; } /*! The minimum amount of movement while pressed before switching to "moving" state. This threshold is needed to avoid detecting unintentional small movements while "clicking" as a drag. */ property real dragThreshold: units.gu(1) onPositionChanged: { if (!pressed) return; if (panel.locked) return; if (panel.state == "hint" && mousePosition < initialPosition - dragThreshold) { internal.previousState = "hint"; panel.state = "moving"; pressedItem = null; } else if (panel.state == "spread" && mousePosition > initialPosition + dragThreshold) { internal.previousState = "spread"; panel.state = "moving"; pressedItem = null; } } onReleased: { if (panel.state == "moving" || panel.state == "hint") { finishMoving(); } else { hideTimer.conditionalRestart(); } } // Mouse cursor moving out of the window while pressed on desktop onCanceled: { if (panel.state == "moving" || panel.state == "hint") { finishMoving(); } else { hideTimer.conditionalRestart(); } } onEntered: { // panel.__openOnHover panel.open(); hideTimer.stop(); } onExited: { // panel.__openOnHover // Ensure the panel is not still opening. The draggingArea will // change after the panel finishes the opening animation. if (!animating) { hideTimer.conditionalRestart(); } } // FIXME: Make all parameters below themable and resolution-independent. // The value of 44 was copied from the Launcher. function finishMoving() { if (draggingArea.dragVelocity < -44) { if (internal.align === Qt.AlignBottom || internal.align === Qt.AlignRight) { panel.open(); } else { panel.close(); } } else if (draggingArea.dragVelocity > 44) { if (internal.align === Qt.AlignBottom || internal.align === Qt.AlignRight) { panel.close(); } else { panel.open(); } } else { if (bar.position < bar.size / 2) { panel.open(); } else { panel.close(); } } } } Item { id: bar height: parent.height width: parent.width anchors { left: internal.orientation === Qt.Horizontal ? parent.left : undefined right: internal.orientation === Qt.Horizontal ? parent.right : undefined top: internal.orientation === Qt.Vertical ? parent.top : undefined bottom: internal.orientation === Qt.Vertical ? parent.bottom : undefined } property real size: internal.orientation === Qt.Horizontal ? height : width //position will always be in the range 0..size, where position==0 means spread, position==size means hidden. property real position: panel.opened ? 0 : size y: internal.align === Qt.AlignTop ? -position : internal.align === Qt.AlignBottom ? position : 0 x: internal.align === Qt.AlignLeft ? -position : internal.align === Qt.AlignRight ? position : 0 } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/UbuntuListView.qml0000644000015301777760000000742112321005637030527 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 as Toolkit /*! \qmltype UbuntuListView \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief A ListView with special features tailored for a look and feel fitting the Ubuntu Touch platform. The UbuntuListView works just like a regular ListView, but it adds special features such as expanding/collapsing items (when used together with the Expandable item). It provides features like automatically positioning the expanding item when it expands and collapsing it again when the user taps outside of it. Examples: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Item { ListModel { id: listModel } UbuntuListView { id: ubuntuListView anchors { left: parent.left; right: parent.right } height: units.gu(24) model: listModel delegate: ListItem.Expandable { id: expandingItem expandedHeight: units.gu(30) onClicked: { ubuntuListView.expandedIndex = index; } } } } \endqml \b{This component is under heavy development.} */ ListView { id: root /*! The index of the currently expanded item. -1 if no item is expanded. */ property int expandedIndex: -1 QtObject { id: priv function positionViewAtIndexAnimated(expandedIndex) { animation.from = root.contentY; root.currentIndex = expandedIndex; if (expandedIndex == root.count - 1) { root.positionViewAtIndex(expandedIndex, ListView.End); } else { root.positionViewAtIndex(expandedIndex + 1, ListView.End); } var effectiveExpandedHeight = Math.min(root.currentItem.expandedHeight, root.height - root.currentItem.collapsedHeight); if (root.contentY - root.originY == 0) { if (((root.currentIndex + 1) * root.currentItem.collapsedHeight) + effectiveExpandedHeight > root.height) { animation.to = ((root.currentIndex + 1) * root.currentItem.collapsedHeight + effectiveExpandedHeight) - root.height + root.originY } else { animation.to = root.originY } } else { animation.to = root.contentY + (effectiveExpandedHeight - root.currentItem.collapsedHeight); } animation.start(); } } /*! \preliminary Expand the item at the given index. */ onExpandedIndexChanged: { if (expandedIndex < 0) { return; } priv.positionViewAtIndexAnimated(expandedIndex, ListView.End) } UbuntuNumberAnimation { id: animation target: root property: "contentY" } MouseArea { parent: contentItem anchors.fill: parent z: 2 enabled: root.expandedIndex != -1 onClicked: root.expandedIndex = -1; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/0000755000015301777760000000000012321006415026747 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Header.qml0000644000015301777760000000412512321005637030661 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Header \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief Header for grouping list items together Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.Header { text: "Title" } ListItem.Standard { text: "Item one" } ListItem.Standard { text: "Item two" } ListItem.Divider { } ListItem.Standard { text: "Item three" } ListItem.Standard { text: "Item four" } } \endqml \b{This component is under heavy development.} */ Item { height: units.gu(4) anchors { left: parent ? parent.left : undefined right: parent ? parent.right : undefined } /*! \preliminary The text that is shown as the header text. \qmlproperty string text */ property alias text: label.text /*! \internal The \l foregroundGroundColor property stores the internal label color. */ property alias __foregroundColor: label.color LabelVisual { id: label fontSize: "medium" anchors { verticalCenter: parent.verticalCenter left: parent.left right: parent.right margins: units.gu(1) } } ThinDivider { anchors { left: parent.left right: parent.right bottom: parent.bottom } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Expandable.qml0000644000015301777760000001674212321005637031544 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype Expandable \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief An expandable list item with no contents. The Expandable class can be used for generic list items containing other components such as buttons. It subclasses \l Empty and thus brings all that functionality, but additionally provides means to expand and collapse the item. When used together with an \l UbuntuListView or \l ExpandablesColumn it can coordinate with other items in the list to make sure it is scrolled while expanding to be fully visible in the view. Additionally it is made sure that only one Expandable item is expanded at a time and it is collapsed when the user clicks outside the item. You can set \l expanded to true/false to expand/collapse the item. Examples: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Item { ListModel { id: listModel } ListItem.UbuntuListView { anchors { left: parent.left; right: parent.right } height: units.gu(24) model: listModel delegate: ListItem.Expandable { id: expandingItem expandedHeight: units.gu(30) onClicked: { expanded = true; } } } } \endqml \b{This component is under heavy development.} */ Empty { id: root implicitHeight: expanded ? priv.maxExpandedHeight : collapsedHeight /*! Reflects the expanded state. Set this to true/false to expand/collapse the item. */ property bool expanded: false /*! The collapsed (normal) height of the item. Defaults to the standard height for list items. */ property real collapsedHeight: __height /*! The expanded height of the item's content. Defaults to the same as collapsedHeight which disables the expanding feature. In order for the item to be expandable, set this to the expanded size. Note that the actual expanded size can be smaller if there is not enough space in the containing list. In that case the item becomes flickable automatically. */ property real expandedHeight: collapsedHeight /*! If set to true, the item will collapse again when the user clicks somewhere in the always visible (when collapsed) area. */ property bool collapseOnClick: false /*! Reparent any content to inside the Flickable \qmlproperty QtObject children \default */ default property alias children: flickableContent.data /*! \internal */ QtObject { id: priv /*! \internal Points to the containing ExpandablesListView or ExpandablesColumn */ property Item view: root.ListView.view ? root.ListView.view : (root.parent.parent.parent.hasOwnProperty("expandItem") ? root.parent.parent.parent : null) /*! \internal Gives information whether this item is inside an item based container supporting Expandable items, such as ExpandablesColumn */ readonly property bool isInExpandableColumn: view && view !== undefined && view.hasOwnProperty("expandItem") && view.hasOwnProperty("collapse") /*! \internal Gives information whether this item is inside an index based container supporting Expandable items, such as UbuntuListView */ readonly property bool isInExpandableListView: view && view !== undefined && view.hasOwnProperty("expandedIndex") /*! \internal Gives information if there is another item expanded in the containing ExpandablesListView or ExpandablesColumn */ readonly property bool otherExpanded: (isInExpandableColumn && view.expandedItem !== null && view.expandedItem !== undefined && view.expandedItem !== root) || (isInExpandableListView && view.expandedIndex !== -1 && view.expandedIndex !== index) /*! \internal Gives information about the maximum expanded height, in case that is limited by the containing ExpandablesListView or ExpandablesColumn */ readonly property real maxExpandedHeight: (isInExpandableColumn || isInExpandableListView) ? Math.min(view.height - collapsedHeight, expandedHeight) : expandedHeight } states: [ State { name: "" PropertyChanges { target: root; opacity: 1 } }, State { name: "otherExpanded"; when: priv.otherExpanded PropertyChanges { target: root; opacity: .5 } }, State { name: "expanded"; when: expanded PropertyChanges { target: root; z: 3 } } ] Component.onCompleted: { if (priv.isInExpandableListView && priv.view.expandedIndex == index) { root.expanded = true; } } Connections { target: priv.isInExpandableListView ? priv.view : null onExpandedIndexChanged: { if (priv.view.expandedIndex == index) { root.expanded = true; } else if (root.expanded = true) { root.expanded = false; } } } /*! \internal */ onExpandedChanged: { if (!expanded) { contentFlickable.contentY = 0; } if (priv.isInExpandableColumn) { if (expanded) { priv.view.expandItem(root); } else { priv.view.collapse(); } } } Behavior on height { UbuntuNumberAnimation {} } Behavior on opacity { UbuntuNumberAnimation {} } Flickable { id: contentFlickable objectName: "__expandableContentFlickable" anchors { fill: parent; leftMargin: root.__contentsMargins; rightMargin: __contentsMargins; bottomMargin: divider.height } interactive: root.expanded && contentHeight > height + root.divider.height contentHeight: root.expandedHeight flickableDirection: Flickable.VerticalFlick clip: true Behavior on contentY { UbuntuNumberAnimation {} } Item { id: flickableContent anchors { left: parent.left right: parent.right } height: childrenRect.height } } MouseArea { anchors { left: parent.left; top: parent.top; right: parent.right } enabled: root.collapseOnClick && root.expanded height: root.collapsedHeight onClicked: { if (priv.isInExpandableListView) { priv.view.expandedIndex = -1; } else { root.expanded = false; } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/0000755000015301777760000000000012321006415030440 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/ListItemDivider24px@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/ListItemDivide0000644000015301777760000000207112321005637033247 0ustar pbusernogroup00000000000000PNG  IHDR(I `tEXtSoftwareAdobe ImageReadyqe<fiTXtXML:com.adobe.xmp -iIDATx1 E`& 2"V44ߎ (@ ((@ ((@ ((@ (ș \IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/delete@8.png0000644000015301777760000000076012321005637032610 0ustar pbusernogroup00000000000000PNG  IHDR$$hsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<PLTES(#+tRNS !HLQSW[\zHGIDAT8Թ0(ʢ`D#φ2뤰/B UNӋr<]̯j,/{^֞;e76@HtQ&љFDWU=h4I4Nu3+;^%s]`%nD Ӓ7]/&DoO_~x2IENDB`././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/ListItemDivider6px@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/ListItemDivide0000644000015301777760000000201512321005637033245 0ustar pbusernogroup00000000000000PNG  IHDR(ptEXtSoftwareAdobe ImageReadyqe<fiTXtXML:com.adobe.xmp R=IDATxA `"0Ƨ?ѐ 2"V44ߎ @GCA8(YU[+x[IENDB`././@LongLink0000000000000000000000000000016700000000000011221 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/ListItemDividerHorizontal@18.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/artwork/ListItemDivide0000644000015301777760000000021612321005637033246 0ustar pbusernogroup00000000000000PNG  IHDR~bKGD pHYs  tIME8 LOIDATcd``Pcϟ@?yIENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/LabelVisual.qml0000644000015301777760000000276612321005637031705 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 // internal helper class for text inside the list items. Label { id: label property bool selected: false property bool secondary: false // FIXME: very ugly hack to detect whether the list item is inside a Popover property bool overlay: isInsideOverlay(label) function isInsideOverlay(item) { if (!item.parent) return false; return item.parent.hasOwnProperty("pointerTarget") || label.isInsideOverlay(item.parent) } fontSize: "medium" elide: Text.ElideRight color: selected ? UbuntuColors.orange : secondary ? overlay ? Theme.palette.normal.overlayText : Theme.palette.normal.backgroundText : overlay ? Theme.palette.selected.overlayText : Theme.palette.selected.backgroundText opacity: label.enabled ? 1.0 : 0.5 } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/IconVisual.qml0000644000015301777760000000313412321005637031544 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 // internal helper class to create the visuals // for the icon. Item { id: iconVisual /*! \qmlproperty url source */ property alias source: icon.source /*! \qmlproperty url fallbackSource */ property alias fallbackSource: icon.fallbackSource /*! \qmlproperty string fallbackIconName */ property string fallbackIconName visible: source != "" property bool hasFrame: true ImageWithFallback { id: icon visible: !iconVisual.hasFrame opacity: iconVisual.enabled ? 1.0 : 0.5 fillMode: Image.PreserveAspectCrop anchors.fill: parent smooth: true asynchronous: true fallbackSource: iconVisual.fallbackIconName ? "image://theme/" + iconVisual.fallbackIconName : "" } UbuntuShape { id: shape visible: iconVisual.hasFrame anchors.fill: parent image: icon } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/MultiValue.qml0000644000015301777760000000546512321005637031570 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype MultiValue \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief List item displaying multiple values. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.MultiValue { text: "Label" values: ["Value 1", "Value 2", "Value 3", "Value 4"] onClicked: selected = !selected } ListItem.MultiValue { text: "Label" iconName: "compose" values: ["Value 1", "Value 2", "Value 3", "Value 4"] progression: true onClicked: print("clicked") } } \endqml */ Base { id: multiValueListItem /*! \preliminary The list of values that will be shown under the label text */ property variant values Item { height: label.height + valueLabel.height anchors { verticalCenter: parent.verticalCenter left: parent.left right: parent.right } LabelVisual { id: label selected: multiValueListItem.selected anchors { top: parent.top left: parent.left right: parent.right } text: multiValueListItem.text } LabelVisual { id: valueLabel selected: multiValueListItem.selected secondary: true anchors { top: label.bottom left: parent.left right: parent.right } fontSize: "small" text: concatenatedValues(multiValueListItem.values) function concatenatedValues(values) { var n = values.length; var result = ""; if (n > 0) { result = values[0]; for (var i = 1; i < n; i++) { result = result + ", " + values[i]; } } return result; } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/SingleValue.qml0000644000015301777760000000443112321005637031707 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype SingleValue \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief A list item displaying a single value Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.SingleValue { text: "Label" value: "Status" onClicked: selected = !selected } ListItem.SingleValue { text: "Label" iconName: "compose" value: "Parameter" progression: true onClicked: print("clicked") } } \endqml \b{This component is under heavy development.} */ Base { id: listItem /*! \preliminary The text that is shown in the list item as a label. \qmlproperty string text */ /*! \preliminary \qmlproperty string value The values that will be shown next to the label text */ property alias value: valueLabel.text LabelVisual { id: label selected: listItem.selected anchors { verticalCenter: parent.verticalCenter left: parent.left } text: listItem.text width: Math.min(implicitWidth, parent.width * 0.8) } LabelVisual { id: valueLabel selected: listItem.selected anchors { verticalCenter: parent.verticalCenter right: parent.right left: label.right leftMargin: listItem.__contentsMargins } horizontalAlignment: Text.AlignRight fontSize: "medium" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Empty.qml0000644000015301777760000003406412321005637030574 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype Empty \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief A list item with no contents. The Empty class can be used for generic list items containing other components such as buttons. It is selectable and can take mouse clicks. It will attempt to detect if a thin dividing line at the bottom of the item is suitable, but this behaviour can be overridden (using \l showDivider). For specific types of list items, see its subclasses. The item will still remain in memory after being removed from the list so it is up to the application to destroy it. This can be handled by the signal \l itemRemoved that is fired after all animation is done. Examples: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Item { Model { id: contactModel ListElement { name: "Bill Smith" number: "555 3264" } ListElement { name: "John Brown" number: "555 8426" } } ListView { width: 180; height: 200 model: contactModel delegate: ListItem.Empty { height: units.gu(6) removable: true onItemRemoved: contactModel.remove(index) Text { text: name + " " + number anchors.centerIn: parent } } } } \endqml See the documentation of the derived classes of Empty for more examples. \b{This component is under heavy development.} */ AbstractButton { id: emptyListItem /*! \preliminary Specifies whether the list item is selected. */ property bool selected: false /*! \preliminary Highlight the list item when it is pressed. This is used to disable the highlighting of the full list item when custom highlighting needs to be implemented (for example in ListItem.Standard which can have a split). */ property bool highlightWhenPressed: true /*! \preliminary Defines if this item can be removed or not. */ property bool removable: false /*! \preliminary Defines if the item needs confirmation before removing by swiping. \qmlproperty bool confirmRemoval */ property alias confirmRemoval: confirmRemovalDialog.visible /*! \preliminary \qmlproperty string swipingState The current swiping state ("SwipingLeft", "SwipingRight", "") */ readonly property alias swipingState: backgroundIndicator.state /*! \preliminary \qmlproperty bool waitingConfirmationForRemoval Defines if the item is waiting for the user interaction during the swipe to delete */ readonly property alias waitingConfirmationForRemoval: confirmRemovalDialog.waitingForConfirmation /*! \preliminary This handler is called when the item is removed from the list */ signal itemRemoved /*! \internal Defines the height of the ListItem, so correct height of this component, including divider line is calculated. */ property int __height: units.gu(6) /*! \preliminary Set to show or hide the thin bottom divider line (drawn by the \l ThinDivider component). This line is shown by default except in cases where this item is the delegate of a ListView. */ property bool showDivider: true /*! \internal Reparent so that the visuals of the children does not occlude the bottom divider line. */ default property alias children: body.data /*! \internal Allows derived class to proper add items inside of this element */ property alias __contents: body /*! \preliminary \qmlproperty list backgroundIndicator Defines the item background item to be showed during the item swiping */ property alias backgroundIndicator: backgroundIndicator.children /*! \preliminary \qmlproperty ThinDivider divider Exposes our the bottom line divider. */ property alias divider: bottomDividerLine /*! \internal The spacing inside the list item. */ property real __contentsMargins: units.gu(2) /*! \preliminary Cancel item romoval */ function cancelItemRemoval() { priv.resetDrag() } width: parent ? parent.width : units.gu(31) implicitHeight: priv.removed ? 0 : __height + bottomDividerLine.height __mouseArea.drag.axis: Drag.XAxis // Keep compatible with the old version height: implicitHeight LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true /*! \internal */ QtObject { id: priv /*! \internal Defines the offset used when the item will start to move */ readonly property int mouseMoveOffset: units.gu(1) /*! \internal Defines the offset limit to consider the item removed */ readonly property int itemMoveOffset: confirmRemoval ? width * 0.5 : width * 0.3 /*! \internal Defines the initial pressed position */ property int pressedPosition: -1 /*! \internal Defines if the item is moving or not */ property bool held: false /*! \internal Defines if the item should be removed after the animation or not */ property bool removeItem: false /*! \internal Defines if the item was removed or not */ property bool removed: false /*! \internal notify the start of the drag operation */ function startDrag() { __mouseArea.drag.target = body held = true __mouseArea.drag.maximumX = parent.width __mouseArea.drag.minimumX = (parent.width * -1) backgroundIndicator.visible = true } /*! \internal Resets the item dragging state */ function resetDrag() { confirmRemovalDialog.waitingForConfirmation = false body.x = 0 pressedPosition = -1 __mouseArea.drag.target = null held = false removeItem = false backgroundIndicator.opacity = 0.0 backgroundIndicator.visible = false backgroundIndicator.state = "" } /*! \internal Commit the necessary changes to remove or not the item based on the mouse final position */ function commitDrag() { if (removeItem) { if (!confirmRemoval) { removeItemAnimation.start() } } else { resetDrag() } } /*! \internal notify the releaso of the mouse button and the end of the drag operation */ function endDrag() { if (Math.abs(body.x) < itemMoveOffset && held == true) { held = false removeItem = false if (body.x == 0) { resetDrag() } else { body.x = 0; } } else if (held == true) { held = false removeItem = true var finalX = body.width if (emptyListItem.confirmRemoval) { finalX = itemMoveOffset } if (body.x > 0) { body.x = finalX } else { body.x = -finalX } } } } ThinDivider { id: bottomDividerLine anchors.bottom: parent.bottom visible: showDivider && !priv.removed } Item { id: bodyMargins clip: body.x != 0 visible: body.height > 0 anchors { left: parent.left right: parent.right top: parent.top bottom: parent.bottom } Item { id: body anchors { top: parent.top bottom: parent.bottom } width: parent.width Behavior on x { enabled: !priv.held SequentialAnimation { UbuntuNumberAnimation { } ScriptAction { script: { confirmRemovalDialog.waitingForConfirmation = true priv.commitDrag() } } } } onXChanged: { if (x > 0) { backgroundIndicator.state = "SwipingRight" } else { backgroundIndicator.state = "SwipingLeft" } } } Item { id: backgroundIndicator opacity: 0.0 visible: false anchors { left: parent.left right: parent.right top: parent.top bottom: parent.bottom } LayoutMirroring.enabled: false LayoutMirroring.childrenInherit: true Item { id: confirmRemovalDialog objectName: "confirmRemovalDialog" property bool waitingForConfirmation: false visible: false width: units.gu(15) x: body.x - width - units.gu(2) anchors { top: parent.top bottom: parent.bottom } Row { anchors { top: parent.top bottom: parent.bottom left: parent.left right: parent.right leftMargin: units.gu(2) rightMargin: units.gu(2) } spacing: units.gu(2) Image { source: "artwork/delete.png" fillMode: Image.Pad anchors { verticalCenter: parent.verticalCenter } width: units.gu(5) } Label { text: i18n.tr("Delete") verticalAlignment: Text.AlignVCenter anchors { verticalCenter: parent.verticalCenter } width: units.gu(7) fontSize: "medium" } } MouseArea { visible: confirmRemovalDialog.waitingForConfirmation anchors.fill: parent onClicked: removeItemAnimation.start() } } states: [ State { name: "SwipingRight" AnchorChanges { target: backgroundIndicator anchors.left: parent.left anchors.right: body.left } PropertyChanges { target: backgroundIndicator opacity: 1.0 } PropertyChanges { target: confirmRemovalDialog x: body.x - confirmRemovalDialog.width - units.gu(2) } }, State { name: "SwipingLeft" AnchorChanges { target: backgroundIndicator anchors.left: body.right anchors.right: parent.right } PropertyChanges { target: backgroundIndicator opacity: 1.0 } PropertyChanges { target: confirmRemovalDialog x: units.gu(2) } } ] } } SequentialAnimation { id: removeItemAnimation running: false UbuntuNumberAnimation { target: emptyListItem property: "height" to: 0 } ScriptAction { script: { priv.removed = true itemRemoved() priv.resetDrag() } } } Connections { target: (emptyListItem.removable) ? __mouseArea : null onPressed: { priv.pressedPosition = mouse.x } onMouseXChanged: { var mouseOffset = priv.pressedPosition - mouse.x if ((priv.pressedPosition != -1) && !priv.held && ( Math.abs(mouseOffset) >= priv.mouseMoveOffset)) { priv.startDrag(); } } onClicked: { if (body.x != 0) { priv.resetDrag() } } onReleased: { priv.endDrag(); } onCanceled: { priv.endDrag(); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/ThinDivider.qml0000644000015301777760000000343612321005637031706 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ThinDivider \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief Narrow line used as a divider between ListItems. ListItems will usually include this line at the bottom of the item to give a visually pleasing list of items. But a divider line can also be inserted manually using this component. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { width: 250 ListItem.ThinDivider {} //can be used as header for list ListItem.Standard { text: "List Item without thin divider line" showDivider: false } ListItem.ThinDivider {} // manually inserted divider line ListItem.Standard { text: "ListItem with thin divider line" } } \endqml */ Image { anchors { left: (parent) ? parent.left : null right: (parent) ? parent.right : null } height: (visible) ? units.dp(2) : 0 source: "artwork/ListItemDividerHorizontal.png" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/ProgressionVisual.qml0000644000015301777760000000170212321005637033165 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 // Internal helper class for the visuals of // the progression symbol. StyledItem { id: progressionVisual property bool showSplit: false property real splitMargin style: Theme.createStyleComponent("ProgressionVisualStyle.qml", progressionVisual) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/qmldir0000644000015301777760000000105512321005637030170 0ustar pbusernogroup00000000000000Empty 0.1 Empty.qml Base 0.1 Base.qml Caption 0.1 Caption.qml Divider 0.1 Divider.qml Header 0.1 Header.qml internal IconVisual IconVisual.qml internal LabelVisual LabelVisual.qml MultiValue 0.1 MultiValue.qml ItemSelector 0.1 ItemSelector.qml internal ProgressionVisual ProgressionVisual.qml ValueSelector 0.1 ValueSelector.qml SingleValue 0.1 SingleValue.qml Standard 0.1 Standard.qml Subtitled 0.1 Subtitled.qml SingleControl 0.1 SingleControl.qml ThinDivider 0.1 ThinDivider.qml Expandable 0.1 Expandable.qml ExpandablesColumn 0.1 ExpandablesColumn.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Base.qml0000644000015301777760000001452612321005637030351 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype Base \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief Parent class of various list item classes that can have an icon and a progression symbol. Examples: See subclasses \b{This component is under heavy development.} */ Empty { id: baseListItem /*! \deprecated \b{Use iconName or iconSource instead.} The location of the icon to show in the list item (optional), or an Item that is shown on the left side inside the list item. The icon will automatically be anchored to the left side of the list item, and if its height is undefined, to the top and bottom of the list item. \qmlproperty variant icon */ property variant icon: iconSource != "" ? iconSource : undefined /*! The image shown in the list item. \qmlproperty url iconSource This is a URL to any image file. In order to use an icon from the Ubuntu theme, use the iconName property instead. */ property url iconSource: iconName ? "image://theme/" + iconName : "" /*! The icon shown in the list item. \qmlproperty string iconName If both iconSource and iconName are defined, iconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property string iconName /*! \preliminary The location of the icon to show in the list item if iconSource failed to load (optional). \qmlproperty url fallbackIconSource */ property alias fallbackIconSource: iconHelper.fallbackSource /*! The icon shown in the list item if iconName failed to load (optional). \qmlproperty string fallbackIconName If both fallbackIconSource and fallbackIconName are defined, fallbackIconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property alias fallbackIconName: iconHelper.fallbackIconName /*! \preliminary Show or hide the progression symbol. */ property bool progression: false /*! \preliminary Show or hide the frame around the icon \qmlproperty bool iconFrame */ property alias iconFrame: iconHelper.hasFrame /*! \internal \deprecated Width of the icon to be displayed */ property real __iconWidth /*! \internal \deprecated Height of the icon to be displayed */ property real __iconHeight /*! \internal \deprecated The margin on the left side of the icon. */ property real __leftIconMargin /*! \internal \deprecated The margin on the right side of the icon. */ property real __rightIconMargin IconVisual { id: iconHelper width: height height: Math.min(units.gu(5), parent.height - units.gu(1)) anchors { left: parent.left leftMargin: baseListItem.__contentsMargins verticalCenter: parent.verticalCenter } } /*! \internal The \l icon property is an Item. The value is false if \l icon is a string, or when no icon was set. */ property bool __iconIsItem: false /*! \internal */ onIconChanged: { if (icon == undefined) return; if (icon != iconSource) { console.warn("WARNING: ListItems.Base.icon is DEPRECATED. " + "Use iconName and iconSource instead.") } if (typeof icon == "string" || typeof icon == typeof iconSource) { // icon is the url of an image iconHelper.source = icon; __iconIsItem = false; } else { // icon is an Item. __iconIsItem = true; iconHelper.source = ""; icon.parent = baseListItem; icon.anchors.left = baseListItem.left; icon.anchors.margins = Qt.binding(function() { return baseListItem.__contentsMargins }); if (!icon.height) { icon.anchors.top = baseListItem.top; icon.anchors.bottom = baseListItem.bottom; } } } /*! \internal */ property alias children: middle.data Item { id: middle property bool anchorToIconHelper: !__iconIsItem && iconHelper.source != "" anchors { top: parent.top bottom: parent.bottom left: anchorToIconHelper ? iconHelper.right : parent.left right: baseListItem.progression ? progressionHelper.left : parent.right rightMargin: baseListItem.__contentsMargins leftMargin: __iconIsItem ? icon.width + 2 * baseListItem.__contentsMargins : baseListItem.__contentsMargins } } ProgressionVisual { id: progressionHelper visible: baseListItem.progression anchors { right: parent.right rightMargin: baseListItem.__contentsMargins top: parent.top bottom: parent.bottom } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Caption.qml0000644000015301777760000000335612321005637031073 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype Caption \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief List item that shows a piece of text. Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.Standard { text: "Default list item." } ListItem.Caption { text: "This is a caption text, which can span multiple lines." } } \endqml \b{This component is under heavy development.} */ Item { height: captionText.height + units.gu(1) width: parent ? parent.width : units.gu(31) /*! \preliminary The text that is shown in the list item as a label. \qmlproperty string text */ property alias text: captionText.text Label { id: captionText anchors.centerIn: parent width: parent.width - units.gu(1) wrapMode: Text.Wrap color: Theme.palette.normal.backgroundText horizontalAlignment: Text.AlignLeft fontSize: "small" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Standard.qml0000644000015301777760000002543712321005637031242 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype Standard \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief The standard list item class. It shows a basic list item with a label (text), and optionally an icon, a progression arrow, and it can have an embedded Item (\l control) that can be used for including Buttons, Switches etc. inside the list item. \l {http://design.ubuntu.com/apps/building-blocks/list-items}{See also the Design Guidelines on List Items}. Examples: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.Standard { text: "Selectable standard list item" selected: false onClicked: selected = !selected } ListItem.Standard { text: "List item with icon" iconName: "compose" } ListItem.Standard { text: "With a progression arrow" progression: true } ListItem.Standard { text: "Control" control: Button { text: "Click me" width: units.gu(19) onClicked: print("Clicked") } progression: true } } \endqml \b{This component is under heavy development.} */ Empty { id: listItem /*! \deprecated \b{Use iconName or iconSource instead.} The location of the icon to show in the list item (optional), or an Item that is shown on the left side inside the list item. The icon will automatically be anchored to the left side of the list item, and if its height is undefined, to the top and bottom of the list item. \qmlproperty variant icon */ property variant icon: iconSource != "" ? iconSource : undefined /*! The image shown in the list item. \qmlproperty url iconSource This is a URL to any image file. In order to use an icon from the Ubuntu theme, use the iconName property instead. */ property url iconSource: iconName ? "image://theme/" + iconName : "" /*! The icon shown in the list item. \qmlproperty string iconName If both iconSource and iconName are defined, iconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property string iconName /*! \preliminary The location of the icon to show in the list item if iconSource failed to load (optional). \qmlproperty url fallbackIconSource */ property alias fallbackIconSource: iconHelper.fallbackSource /*! The icon shown in the list item if iconName failed to load (optional). \qmlproperty string fallbackIconName If both fallbackIconSource and fallbackIconName are defined, fallbackIconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property alias fallbackIconName: iconHelper.fallbackIconName /*! \preliminary The text that is shown in the list item as a label. \qmlproperty string text */ /*! \preliminary Show or hide the progression symbol. */ property bool progression: false /*! \internal \deprecated Width of the icon to be displayed */ property real __iconWidth /*! \internal \deprecated Height of the icon to be displayed */ property real __iconHeight /*! \internal \deprecated The margins on the left side of the icon. */ property real __leftIconMargin /*! \internal \deprecated The margins on the right side of the icon. */ property real __rightIconMargin /*! \preliminary An optional control that is displayed inside the list item. The width of the control must be specified in order to determine the layout of the list item. \qmlproperty Item control */ property alias control: controlContainer.control /*! \preliminary Show or hide the frame around the icon \qmlproperty bool iconFrame */ property alias iconFrame: iconHelper.hasFrame // If there is a control, the controlArea covers the listItem's mouseArea, // so in that case use the highlights below when pressed highlightWhenPressed: !listItem.control // Avoid emit clicked signals when clicking on the control area __acceptEvents: false /*! \internal */ property bool __controlAreaPressed: false Rectangle { id: controlHighlight visible: listItem.swipingState === "" ? control && __controlAreaPressed : false anchors { top: parent.top right: progressionHelper.visible ? progressionHelper.left : parent.right bottom: parent.bottom left: parent.left } color: Theme.palette.selected.background } Rectangle { id: progressionHighlight visible: listItem.swipingState === "" ? listItem.progression && progressionHelper.showSplit && listItem.pressed && !__controlAreaPressed : false anchors { left: progressionHelper.left top: parent.top bottom: parent.bottom right: parent.right } color: Theme.palette.selected.background } IconVisual { id: iconHelper width: height height: Math.min(units.gu(5), parent.height - units.gu(1)) anchors { left: parent.left leftMargin: listItem.__contentsMargins verticalCenter: parent.verticalCenter } } /*! \internal The \l icon property is an Item. The value is false if \l icon is a string, or when no icon was set. */ property bool __iconIsItem: false /*! \internal */ onIconChanged: { if (icon == undefined) return; if (icon != iconSource) { console.warn("WARNING: ListItems.Standard.icon is DEPRECATED. " + "Use iconName and iconSource instead.") } if (typeof icon == "string" || typeof icon == typeof iconSource) { // icon is the url of an image iconHelper.source = icon; __iconIsItem = false; } else { // icon is an Item. __iconIsItem = true; iconHelper.source = ""; icon.parent = listItem; icon.anchors.left = listItem.left; icon.anchors.margins = Qt.binding(function() { return listItem.__contentsMargins }); if (!icon.height) { icon.anchors.top = listItem.top; icon.anchors.bottom = listItem.bottom; } } } /*! \internal The \l foregroundGroundColor property stores the internal label color. */ property alias __foregroundColor: label.color LabelVisual { id: label property bool anchorToIconHelper: !__iconIsItem && iconHelper.source != "" selected: listItem.selected anchors { verticalCenter: parent.verticalCenter left: anchorToIconHelper ? iconHelper.right : parent.left leftMargin: __iconIsItem ? icon.width + 2 * listItem.__contentsMargins : listItem.__contentsMargins right: control ? controlContainer.left : (progression ? progressionHelper.left : parent.right) rightMargin: listItem.__contentsMargins } text: listItem.text } Item { id: controlContainer property Item control // use the width of the control if there is (possibly elided) text, // or full width available if there is no text. width: control ? control.width : undefined height: control ? control.height : undefined anchors { right: listItem.progression ? progressionHelper.left : parent.right rightMargin: listItem.__contentsMargins verticalCenter: parent.verticalCenter } onControlChanged: { if (control) control.parent = controlContainer; } Connections { target: listItem.__mouseArea onClicked: { if (control && __mouseArea.mouseX < progressionHelper.x) { if (control.enabled && control.hasOwnProperty("clicked")) control.clicked(); } else { listItem.clicked(); } } onPressAndHold: { if (control && control.enabled && __mouseArea.mouseX < progressionHelper.x && control.hasOwnProperty("pressAndHold")) { control.pressAndHold(); } else { listItem.pressAndHold(); } } } } /*! \internal */ onPressedChanged: { if (listItem.pressed && control && control.enabled && (__mouseArea.mouseX < progressionHelper.x)) { listItem.__controlAreaPressed = true } else { listItem.__controlAreaPressed = false } } ProgressionVisual { id: progressionHelper visible: listItem.progression anchors { right: parent.right rightMargin: listItem.__contentsMargins top: parent.top bottom: parent.bottom } showSplit: control ? true : false splitMargin: listItem.__contentsMargins } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/SingleControl.qml0000644000015301777760000000476112321005637032261 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 /*! \qmltype SingleControl \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief A list item containing a single control Examples: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.SingleControl { control: Button { anchors { margins: units.gu(1) fill: parent } text: "Large button" } } } \endqml \b{This component is under heavy development.} */ // TODO: Add more examples when more types of controls become available. Empty { id: singleControlListItem /*! \preliminary The control of this SingleControl list item. The control will automatically be re-parented to, and centered in, this list item. */ property Item control /*! \internal */ onClicked: if (control && control.enabled && control.hasOwnProperty("clicked")) control.clicked() pressed: __mouseArea.pressed || (control && control.pressed) /*! \internal */ onPressedChanged: if (control && control.enabled && control.hasOwnProperty("pressed")) control.pressed = singleControlListItem.pressed // Ensure that there is always enough vertical padding around the control __height: control.height + __contentsMargins /*! \internal */ function __updateControl() { if (control) { control.parent = __contents; control.anchors.centerIn = __contents; } } /*! \internal This handler is an implementation detail. Mark as internal to prevent QDoc publishing it */ onControlChanged: __updateControl() } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/ValueSelector.qml0000644000015301777760000002510212321005637032244 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! ****DEPRECATED! PLEASE USE ITEM SELECTOR OR FOR THE UBUNTU SHAPE VERSION THE OPTION SELECTOR.**** \qmltype ValueSelector \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief List item displaying single selected value when not expanded, where expanding it opens a listing of all the possible values for selection. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { width: 250 ListItem.ValueSelector { text: "Standard" values: ["Value 1", "Value 2", "Value 3", "Value 4"] } ListItem.ValueSelector { text: "Disabled" values: ["Value 1", "Value 2", "Value 3", "Value 4"] enabled: false } ListItem.ValueSelector { text: "Expanded" values: ["Value 1", "Value 2", "Value 3", "Value 4"] expanded: true } ListItem.ValueSelector { text: "Icon" iconName: "compose" values: ["Value 1", "Value 2", "Value 3", "Value 4"] selectedIndex: 2 } } \endqml */ Empty { id: selector __height: column.height /*! \preliminary The text that is shown in the list item as a label. \qmlproperty string text */ /*! \deprecated \b{Use iconName or iconSource instead.} The location of the icon to show in the list item (optional), or an Item that is shown on the left side inside the list item. The icon will automatically be anchored to the left side of the list item, and if its height is undefined, to the top and bottom of the list item. \qmlproperty variant icon */ property alias icon: selectorMain.icon /*! The image shown in the list item. \qmlproperty url iconSource This is a URL to any image file. In order to use an icon from the Ubuntu theme, use the iconName property instead. */ property url iconSource: iconName ? "image://theme/" + iconName : "" /*! The icon shown in the list item. \qmlproperty string iconName If both iconSource and iconName are defined, iconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property string iconName /*! \preliminary The location of the icon to show in the list item if iconSource failed to load (optional). \qmlproperty url fallbackIconSource */ property alias fallbackIconSource: selectorMain.fallbackIconSource /*! The icon shown in the list item if iconName failed to load (optional). \qmlproperty string fallbackIconName If both fallbackIconSource and fallbackIconName are defined, fallbackIconName will be ignored. \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property alias fallbackIconName: selectorMain.fallbackIconName /*! \internal \deprecated Width of the icon to be displayed */ property real __iconWidth /*! \internal \deprecated Height of the icon to be displayed */ property real __iconHeight /*! \internal \deprecated The margins on the left side of the icon. */ property real __leftIconMargin /*! \internal \deprecated The margins on the right side of the icon. */ property real __rightIconMargin /*! \preliminary Show or hide the frame around the icon \qmlproperty bool iconFrame */ property alias iconFrame: selectorMain.iconFrame /*! \preliminary The list of values that will be shown under the label text */ property variant values /*! \preliminary The index of the currently selected element from the \l values array. */ property int selectedIndex: 0 /*! \preliminary Specifies whether the selector is 'open' or 'closed'. */ property bool expanded: false showDivider: false Column { id: column anchors { left: parent.left right: parent.right topMargin: units.dp(2) bottomMargin: units.dp(2) } Base { id: selectorMain height: units.gu(6) showDivider: true onClicked: selector.expanded = !selector.expanded selected: selector.selected iconSource: selector.iconSource LabelVisual { id: label anchors { verticalCenter: parent.verticalCenter left: parent.left } text: selector.text width: Math.min(implicitWidth, parent.width * 0.8) } LabelVisual { id: valueLabel anchors { verticalCenter: parent.verticalCenter right: accordion.left rightMargin: selector.__contentsMargins leftMargin: selector.__contentsMargins left: label.right } fontSize: "small" text: selector.values[selector.selectedIndex] font.bold: selector.expanded horizontalAlignment: Text.AlignRight } Item { id: accordion width: accordionIcon.width anchors { right: parent.right top: parent.top bottom: parent.bottom } Image { id: accordionIcon anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter // TODO: Replace this placeholder graphic with the official one. source: "artwork/ListItemProgressionArrow.png" opacity: enabled ? 1.0 : 0.5 rotation: expanded ? 270 : 90 width: implicitWidth / 1.5 height: implicitHeight / 1.5 states: [ State { name: "expanded" when: selector.expanded PropertyChanges { target: accordionIcon; rotation: 270 } }, State { name: "closed" when: !selector.expanded PropertyChanges { target: accordionIcon; rotation: 90 } } ] transitions: Transition { UbuntuNumberAnimation { target: accordionIcon properties: "rotation" duration: UbuntuAnimation.SnapDuration } } } } } Repeater { id: valueRepeater property int valueHeight: selector.expanded ? units.gu(5) : 0 states: [ State { name: "expanded" when: selector.expanded PropertyChanges { target: valueRepeater valueHeight: units.gu(5) } }, State { name: "closed" when: !selector.expanded PropertyChanges { target: valueRepeater valueHeight: 0 } } ] transitions: Transition { UbuntuNumberAnimation { target: valueRepeater properties: "valueHeight" duration: UbuntuAnimation.SnapDuration } } model: selector.values Rectangle { color: Qt.lighter(Theme.palette.normal.base) height: valueRepeater.valueHeight width: parent.width Empty { id: valueBase height: parent.height visible: valueBase.height > 0 onClicked: { selector.selectedIndex = index selector.expanded = false } selected: index === selector.selectedIndex LabelVisual { text: modelData anchors { left: parent.left leftMargin: units.gu(3) verticalCenter: parent.verticalCenter } font.bold: valueBase.selected property real heightMargin: valueBase.height - implicitHeight visible: heightMargin > 0 // fade in/out the values when expanding/contracting the selector. opacity: heightMargin < 10 ? heightMargin/10 : 1 } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Divider.qml0000644000015301777760000000212012321005637031050 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Divider \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief Divider to break up list items into groups. Examples: see \l Header \b{This component is under heavy development.} */ Image { source: "artwork/ListItemDivider6px.png" anchors { left: parent ? parent.left : undefined right: parent ? parent.right : undefined } height: units.gu(1) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml0000644000015301777760000001010712321005637033072 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype ExpandablesColumn \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief A column to be used together with the \l Expandable item. This lays out its content just like a regular Column inside a Flickable but when used together with items of type \l Expandable it provides additional features like automatically positioning the expanding item when it expands and collapsing it again when the user taps outside of it. Examples: \qml import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem ListItem.ExpandablesColumn { anchors { left: parent.left; right: parent.right } height: units.gu(24) Repeater { model: 8 ListItem.Expandable { expandedHeight: units.gu(30) onClicked: { expanded = true; } } } } \endqml \b{This component is under heavy development.} */ Flickable { id: root contentHeight: column.height /*! \preliminary Points to the currently expanded item. Null if no item is expanded. \qmlproperty Item expandedItem */ readonly property alias expandedItem: priv.expandedItem /*! \preliminary Expand the given item. The item must be a child of this ListView. */ function expandItem(item) { if (!item.hasOwnProperty("expandedHeight") || !item.hasOwnProperty("collapsedHeight")) { return; } if (priv.expandedItem != null) { priv.expandedItem.expanded = false; } priv.expandedItem = item; var maxExpandedHeight = root.height - item.collapsedHeight; var expandedItemHeight = Math.min(item.expandedHeight, maxExpandedHeight); var bottomIntersect = root.mapFromItem(item).y + expandedItemHeight - maxExpandedHeight; if (bottomIntersect > 0) { contentY += bottomIntersect; } } /*! \preliminary Collapse the currently expanded item. If there isn't any item expanded, this function does nothing. */ function collapse() { priv.expandedItem.expanded = false; priv.expandedItem = null; } /*! Reparent any content to inside the Column. \qmlproperty QtObject children \default */ default property alias children: column.data /*! \internal */ QtObject { id: priv /*! \internal Points to the currently expanded item. Null if no item is expanded. */ property var expandedItem: null } Behavior on contentY { UbuntuNumberAnimation { } } Column { id: column anchors { left: parent.left; right: parent.right } } MouseArea { anchors { left: parent.left; right: parent.right; top: parent.top } height: root.mapFromItem(priv.expandedItem).y + root.contentY enabled: priv.expandedItem != null onClicked: root.collapse(); } MouseArea { anchors { left: parent.left; right: parent.right; bottom: parent.bottom } height: priv.expandedItem != null ? root.contentHeight - (root.mapFromItem(priv.expandedItem).y + root.contentY + priv.expandedItem.height) : 0 enabled: priv.expandedItem != null onClicked: root.collapse(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/Subtitled.qml0000644000015301777760000000667412321005637031443 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype MultiValue \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief List item displaying a second string under the main label. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { ListItem.Subtitled { text: "Idle" subText: "Secondary label" } ListItem.Subtitled { text: "Disabled" enabled: false subText: "Secondary label" } ListItem.Subtitled { text: "Selected" selected: true subText: "Secondary label" } ListItem.Subtitled { text: "Progression" subText: "Secondary label" progression: true } ListItem.Subtitled { text: "Icon" subText: "Secondary label" iconName: "compose" } ListItem.Subtitled { text: "Multiple lines" subText: "This is a multi-line subText.\nUp to 5 lines are supported." } ListItem.Subtitled { text: "Multiple lines" subText: "It also works well with icons and progression." iconName: "compose" progression: true } } \endqml */ Base { id: subtitledListItem __height: Math.max(middleVisuals.height, units.gu(6)) /*! \preliminary The text that is shown in the list item as a label. \qmlproperty string text */ property alias text: label.text /*! \preliminary The list of strings that will be shown under the label text \qmlproperty string subText */ property alias subText: subLabel.text Item { id: middleVisuals anchors { left: parent.left right: parent.right verticalCenter: parent.verticalCenter } height: childrenRect.height + label.anchors.topMargin + subLabel.anchors.bottomMargin LabelVisual { id: label selected: subtitledListItem.selected anchors { top: parent.top left: parent.left right: parent.right } } LabelVisual { id: subLabel selected: subtitledListItem.selected secondary: true anchors { left: parent.left right: parent.right top: label.bottom } fontSize: "small" wrapMode: Text.Wrap maximumLineCount: 5 } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/ImageWithFallback.qml0000644000015301777760000000262712321005637032774 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Image { id: image property url fallbackSource property bool fallbackRequired: false function isSourceDefined(sourceUrl) { return sourceUrl != "" && sourceUrl != undefined } function tryLoadingFallbackSource() { if (isSourceDefined(fallbackSource)) { source = fallbackSource } } function checkStatus() { if (!isSourceDefined(source) || (status == Image.Error && source != fallbackSource)) { fallbackRequired = true tryLoadingFallbackSource() } } onSourceChanged: fallbackRequired = false onFallbackSourceChanged: if (fallbackRequired) tryLoadingFallbackSource() onStatusChanged: checkStatus() Component.onCompleted: checkStatus() } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ListItems/ItemSelector.qml0000644000015301777760000002361612321005637032076 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "." as ListItem import Ubuntu.Components 0.1 /*! \qmltype ItemSelector \inqmlmodule Ubuntu.Components.ListItems 0.1 \ingroup ubuntu-listitems \brief ListItem displaying either a single selected value or expanded multiple choice with an optional image and subtext when not expanded, when expanding it opens a listing of all the possible values for selection with an additional option of always being expanded. If multiple choice is selected the list is expanded automatically. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components.ListItems 0.1 as ListItem Column { anchors.left: parent.left anchors.right: parent.right spacing: units.gu(3) ListItem.ItemSelector { text: i18n.tr("Label") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } ListItem.ItemSelector { text: i18n.tr("Label") expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } ListItem.ItemSelector { text: i18n.tr("Multiple Selection") alwaysExpanded: false expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } ListItem.ItemSelector { text: i18n.tr("Label") model: customModel expanded: true colourImage: true delegate: selectorDelegate } Component { id: selectorDelegate Toolkit.OptionSelectorDelegate { text: name; subText: description; iconSource: image } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "images.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "images.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "images.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "images.png" } } ListItem.ItemSelector { text: i18n.tr("Label") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } ListItem.ItemSelector { text: i18n.tr("Label") expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } } \endqml */ ListItem.Empty { id: itemSelector /*! \preliminary The list of values that will be shown under the label text. This is a model. */ property var model /*! \preliminary Specifies whether the list is always expanded. */ property bool expanded: false /*! \preliminary If multiple choice selection is enabled the list is always expanded. */ property bool multiSelection: false /*! \preliminary Colours image according to the fieldText colour of the theme, otherwise source colour is maintained. */ property bool colourImage: false /*! \preliminary ListView delegate. */ property Component delegate: OptionSelectorDelegate { id: selectorDelegate } /*! \preliminary Custom height for list container which allows scrolling inside the selector. */ property real containerHeight: { /*The reason for this slightly unconventional method of setting the container height is due to the fact that if we set it to the selector height by default (which is bound to the colum height) then we wouldn't be able to scroll to the end of the bottom boundary. The text is also invisible if none is set so this is taken into account too.*/ var textHeight = text === "" ? 0 : label.height + column.spacing; if (parent && parent.height > 0 && parent.height < list.contentHeight) { return parent.height - textHeight; } else { return list.contentHeight; } } /*! \qmlproperty int selectedIndex The index of the currently selected element in our list. */ property alias selectedIndex: list.currentIndex /*! \qmlproperty bool currentlyExpanded Is our list currently expanded? */ property alias currentlyExpanded: listContainer.currentlyExpanded /*! \qmlproperty real itemHeight Height of an individual list item. */ readonly property alias itemHeight: list.itemHeight /*! Called when delegate is clicked. */ signal delegateClicked(int index) /*! Called when the selector has finished expanding or collapsing. */ signal expansionCompleted() __height: column.height showDivider: false Column { id: column anchors { left: parent.left right: parent.right } ListItem.Standard { id: label text: itemSelector.text visible: itemSelector.text !== "" ? true : false } ListItem.Standard { id: listContainer objectName: "listContainer" readonly property url chevron: __styleInstance.chevron readonly property url tick: __styleInstance.tick readonly property color themeColour: Theme.palette.selected.fieldText readonly property alias colourImage: itemSelector.colourImage property bool currentlyExpanded: expanded || multiSelection anchors { left: parent.left right: parent.right } state: itemSelector.expanded ? "expanded" : "collapsed" style: Theme.createStyleComponent("ListItemOptionSelectorStyle.qml", listContainer) states: [ State { name: "expanded" when: listContainer.currentlyExpanded PropertyChanges { target: listContainer height: list.contentHeight < containerHeight ? list.contentHeight : containerHeight } }, State { name: "collapsed" when: !listContainer.currentlyExpanded PropertyChanges { target: listContainer height: list.itemHeight } } ] transitions: [ Transition { SequentialAnimation { UbuntuNumberAnimation { properties: "height" duration: UbuntuAnimation.BriskDuration } ScriptAction { script: { if (listContainer.currentlyExpanded) { expansionCompleted(); } else { list.positionViewAtIndex(selectedIndex, ListView.Beginning); } } } } } ] ListView { id: list objectName: "listView" property int previousIndex: list.currentIndex readonly property alias expanded: itemSelector.expanded readonly property alias multiSelection: itemSelector.multiSelection readonly property alias container: listContainer property real itemHeight signal delegateClicked(int index) onDelegateClicked: itemSelector.delegateClicked(index); interactive: listContainer.height !== list.contentHeight && listContainer.currentlyExpanded ? true : false clip: true currentIndex: 0 model: itemSelector.model anchors.fill: parent delegate: itemSelector.delegate Behavior on contentY { UbuntuNumberAnimation { properties: "contentY" duration: UbuntuAnimation.BriskDuration } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/CrossFadeImage.qml0000644000015301777760000001706012321005637030372 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 // FIXME: When a module contains QML, C++ and JavaScript elements exported, // we need to use named imports otherwise namespace collision is reported // by the QML engine. As workaround, we use Ubuntu named import. // Bug to watch: https://bugreports.qt-project.org/browse/QTBUG-27645 import Ubuntu.Components 0.1 as Ubuntu /*! \qmltype CrossFadeImage \ingroup ubuntu \brief An Image like component which smoothly fades when its source is updated. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 CrossFadeImage { width: units.gu(100) height: units.gu(75) source: "http://design.ubuntu.com/wp-content/uploads/ubuntu-logo14.png" fadeDuration: 1000 MouseArea { anchors.fill: parent onClicked: parent.source = "http://design.ubuntu.com/wp-content/uploads/canonical-logo1.png" } } \endqml */ Item { id: crossFadeImage /*! The image being displayed. Can be a URL to any image format supported by Qt. */ property url source /*! \qmlproperty enumeration fillMode Defaults to \c Image.PreserveAspectFit. \list \li Image.Stretch - the image is scaled to fit \li Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping \li Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary \li Image.Tile - the image is duplicated horizontally and vertically \li Image.TileVertically - the image is stretched horizontally and tiled vertically \li Image.TileHorizontally - the image is stretched vertically and tiled horizontally \li Image.Pad - the image is not transformed \endlist */ property int fillMode : Image.PreserveAspectFit /*! The time over which to fade between images. Defaults to \c UbuntuAnimation.FastDuration. \sa UbuntuAnimation */ property int fadeDuration: Ubuntu.UbuntuAnimation.FastDuration /*! Whether the animation is running */ readonly property bool running: nextImageFadeIn.running /*! The actual width and height of the loaded image This property holds the actual width and height of the loaded image. Unlike the width and height properties, which scale the painting of the image, this property sets the actual number of pixels stored for the loaded image so that large images do not use more memory than necessary. Note: Changing this property dynamically causes the image source to be reloaded, potentially even from the network, if it is not in the disk cache. */ // FIXME: Support resetting sourceSize property size sourceSize: internals.loadingImage ? Qt.size(internals.loadingImage.sourceSize.width, internals.loadingImage.sourceSize.height) : Qt.size(0, 0) Binding { target: crossFadeImage property: "sourceSize" value: internals.loadingImage ? Qt.size(internals.loadingImage.sourceSize.width, internals.loadingImage.sourceSize.height) : Qt.size(0, 0) when: internals.forcedSourceSize === undefined } /*! \internal */ onSourceSizeChanged: { if (internals.loadingImage && (sourceSize != Qt.size(internals.loadingImage.sourceSize.width, internals.loadingImage.sourceSize.height))) { internals.forcedSourceSize = sourceSize; } } /*! \qmlproperty enumeration status This property holds the status of image loading. It can be one of: \list \li Image.Null - no image has been set \li Image.Ready - the image has been loaded \li Image.Loading - the image is currently being loaded \li Image.Error - an error occurred while loading the image \endlist */ readonly property int status: internals.loadingImage ? internals.loadingImage.status : Image.Null QtObject { id: internals /*! \internal Source size specified by the setting crossFadeImage.sourceSize. */ property size forcedSourceSize /*! \internal Defines the image currently being shown */ property Image currentImage: image1 /*! \internal Defines the image being changed to */ property Image nextImage: image2 property Image loadingImage: currentImage function swapImages() { internals.currentImage.z = 0; internals.nextImage.z = 1; nextImageFadeIn.start(); var tmpImage = internals.currentImage; internals.currentImage = internals.nextImage; internals.nextImage = tmpImage; } } Image { id: image1 anchors.fill: parent cache: false asynchronous: true fillMode: parent.fillMode z: 1 Binding { target: image1 property: "sourceSize" value: internals.forcedSourceSize when: internals.forcedSourceSize !== undefined } } Image { id: image2 anchors.fill: parent cache: false asynchronous: true fillMode: parent.fillMode z: 0 Binding { target: image2 property: "sourceSize" value: internals.forcedSourceSize when: internals.forcedSourceSize !== undefined } } /*! \internal Do the fading when the source is updated */ onSourceChanged: { // On creation, the souce handler is called before image pointers are set. if (internals.currentImage === null) { internals.currentImage = image1; internals.nextImage = image2; } nextImageFadeIn.stop(); // Don't fade in initial picture, only fade changes if (internals.currentImage.source == "") { internals.currentImage.source = source; internals.loadingImage = internals.currentImage; } else { nextImageFadeIn.stop(); internals.nextImage.opacity = 0.0; internals.nextImage.source = source; internals.loadingImage = internals.nextImage; // If case the image is still in QML's cache, status will be "Ready" immediately if (internals.nextImage.status === Image.Ready || internals.nextImage.source === "") { internals.swapImages(); } } } Connections { target: internals.nextImage onStatusChanged: { if (internals.nextImage.status == Image.Ready) { internals.swapImages(); } } } UbuntuNumberAnimation { id: nextImageFadeIn target: internals.nextImage property: "opacity" to: 1.0 duration: crossFadeImage.fadeDuration onRunningChanged: { if (!running) { internals.nextImage.source = ""; } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/AnimatedItem.qml0000644000015301777760000000476512321005637030127 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /*! \qmltype AnimatedItem \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The AnimatedItem drives the animated components behavior inside a Flickable. Reports whether the component whos parent is a Flickable is in the visible area or not, so derived components can pause animations while off-screen. */ import QtQuick 2.0 StyledItem { id: root /*! \preliminary Specifies whether the component is on the visible area of the Flickable or not. */ property bool onScreen: true QtObject { id: internal property Flickable flickable // returns whether the component is in the visible area of the flickable function checkOnScreen() { var pos = root.mapToItem(flickable, 0, 0) root.onScreen = (pos.y + root.height >= 0) && (pos.y <= internal.flickable.height) && (pos.x + root.width >= 0) && (pos.x <= internal.flickable.width) } // lookup for a flickable parent function updateFlickableParent() { var flickable = root.parent while (flickable) { if (flickable.hasOwnProperty("flicking") && flickable.hasOwnProperty("flickableDirection")) { // non-interactive flickables must be skipped as those do not provide // on-screen detection support if (flickable.interactive) break } flickable = flickable.parent } internal.flickable = flickable } } Connections { target: internal.flickable onContentXChanged: internal.checkOnScreen() onContentYChanged: internal.checkOnScreen() } Component.onCompleted: internal.updateFlickableParent() onParentChanged: internal.updateFlickableParent() } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/DraggingArea.qml0000644000015301777760000000674312321005637030077 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "mathUtils.js" as MathLocal MouseArea { id: draggingArea property int orientation: Qt.Vertical property bool dragging property real dragVelocity: 0 property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y) : (mouseX - __pressedPosition.x)) property real lateralPosition: orientation == Qt.Horizontal ? MathLocal.clamp(mouseY, 0, height) : MathLocal.clamp(mouseX, 0, width) property point __pressedPosition: Qt.point(0, 0) property var __dragEvents: [] property bool clickValidated: true property bool zeroVelocityCounts: false signal dragStart signal dragEnd onDragValueChanged: { if (dragValue != 0 && pressed) { dragging = true } } onDraggingChanged: { if (dragging) { dragStart() } else { dragEnd() } } function updateSpeed() { var totalSpeed = 0 for (var i=0; i<__dragEvents.length; i++) { totalSpeed += __dragEvents[i][3] } if (zeroVelocityCounts || Math.abs(totalSpeed) > 0.001) { dragVelocity = totalSpeed / __dragEvents.length * 1000 } } function cullOldDragEvents(currentTime) { // cull events older than 50 ms but always keep the latest 2 events for (var numberOfCulledEvents=0; numberOfCulledEvents<__dragEvents.length-2; numberOfCulledEvents++) { // __dragEvents[numberOfCulledEvents][0] is the dragTime if (currentTime - __dragEvents[numberOfCulledEvents][0] <= 50) break } __dragEvents.splice(0, numberOfCulledEvents) } function getEventSpeed(currentTime, event) { if (__dragEvents.length != 0) { var lastDrag = __dragEvents[__dragEvents.length-1] var duration = Math.max(1, currentTime - lastDrag[0]) if (orientation == Qt.Vertical) { return (event.y - lastDrag[2]) / duration } else { return (event.x - lastDrag[1]) / duration } } else { return 0 } } function pushDragEvent(event) { var currentTime = new Date().getTime() __dragEvents.push([currentTime, event.x, event.y, getEventSpeed(currentTime, event)]) cullOldDragEvents(currentTime) updateSpeed() } onPositionChanged: { if (dragging) { pushDragEvent(mouse) } if (!draggingArea.containsMouse) clickValidated = false } onPressed: { __pressedPosition = Qt.point(mouse.x, mouse.y) __dragEvents = [] pushDragEvent(mouse) clickValidated = true } onReleased: { dragging = false __pressedPosition = Qt.point(mouse.x, mouse.y) } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/AbstractButton.qml0000644000015301777760000000623412321005637030516 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtFeedback 5.0 /*! \qmlabstract AbstractButton \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The AbstractButton class defines the behavior of the button. \b{This component is under heavy development.} This class defines the behavior of the button: it defines the MouseArea and the states. All components deriving from this class support haptic feedback out of the box. */ ActionItem { id: button /*! If an action is specified, the button's clicked signal will trigger the action. Subclasses of AbstractButton can use other properties of action (for example the text and iconName). \qmlproperty Action action */ /*! This handler is called when there is a mouse click on the button and the button is not disabled. If \l action is defined, the action will be triggered. */ signal clicked() /*! If a button is clicked, its triggered() signal will automatically be called. */ onClicked: button.trigger() Keys.onEnterPressed: clicked() Keys.onReturnPressed: clicked() /*! This handler is called when there is a long press. */ signal pressAndHold() /*! True if the user presses a mouse button in the button's mouse area. */ property bool pressed: mouseArea.pressed /*! True if the mouse cursor hovers over the button's mouse area. */ property bool hovered: __acceptEvents && mouseArea.containsMouse /*! \internal Disable or enable signal emition by default. Some classes want to emit the signal by themselves (ListItem.Standard) */ property bool __acceptEvents: true /*! \internal To get the properties of the mouse area in subclasses. */ property alias __mouseArea: mouseArea HapticsEffect { id: pressEffect attackIntensity: 0.0 attackTime: 250 intensity: 1.0 duration: 100 fadeTime: 250 fadeIntensity: 0.0 } MouseArea { id: mouseArea anchors.fill: parent // if mouseArea is given a new value, disable defaultMouseArea // as it might occlude the newly assigned mouse area. hoverEnabled: true onClicked: { if (button.__acceptEvents) { pressEffect.start() button.clicked() } } onPressAndHold: { if (button.__acceptEvents) { button.pressAndHold() } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Object.qml0000644000015301777760000000245512321005637026766 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Object \internal \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Internal type used for lightweight objects that can have children. */ QtObject { id: object // internal objects using nested elements, // which isn't allowed by QtObject; this fix makes this possible /*! \internal Default property to allow adding of children. */ default property alias children: object.__defaultPropertyFix /*! \internal Property list to allow adding of children. */ property list __defaultPropertyFix: [QtObject {}] //QML doesn't allow an empty list here } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/mathUtils.js0000644000015301777760000000252212321005637027350 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ .pragma library // FIXME(loicm) It would be better to have these functions available in a global // set of common native C++ functions. function clamp(x, min, max) { if (min <= max) { return Math.max(min, Math.min(x, max)); } else { // swap min/max if min > max return clamp(x, max, min); } } function lerp(x, a, b) { return ((1.0 - x) * a) + (x * b); } // Linearly project a value x from [xmin, xmax] into [ymin, ymax] function projectValue(x, xmin, xmax, ymin, ymax) { return ((x - xmin) * ymax - (x - xmax) * ymin) / (xmax - xmin) } function clampAndProject(x, xmin, xmax, ymin, ymax) { return projectValue(clamp(x, xmin, xmax), xmin, xmax, ymin, ymax) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Colors/0000755000015301777760000000000012321006415026273 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Colors/FIXME0000644000015301777760000000027212321005637027074 0ustar pbusernogroup00000000000000UbuntuColors.qml is located in the Colors subdirectory because QuickUtils::createQmlObject() fails if the QML file is located in a folder that has a qmldir file with JavaScript modules. ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Colors/Colors.pro0000644000015301777760000000027212321005637030264 0ustar pbusernogroup00000000000000TEMPLATE = subdirs uri = Ubuntu.Components.Colors installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) qml_files.path = $$installPath qml_files.files = *.qml INSTALLS += qml_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Colors/UbuntuColors.qml0000644000015301777760000000443312321005637031463 0ustar pbusernogroup00000000000000/* Copyright 2013 Canonical Ltd. * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 3. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype UbuntuColors \inqmlmodule Ubuntu.Components 0.1 \ingroup theming \brief Singleton defining the Ubuntu color palette. Each color of the Ubuntu color palette is accesible from it. For more information on how to appropriately use the colors according to the context, please refer to the \l{http://design.ubuntu.com/brand/colour-palette}{Ubuntu brand guidelines}. Example of use: \qml Rectangle { color: UbuntuColors.orange } \endqml */ QtObject { /*! Ubuntu core color: Ubuntu orange */ readonly property color orange: "#DD4814" /*! Ubuntu supporting color: light aubergine */ readonly property color lightAubergine: "#77216F" /*! Ubuntu supporting color: mid aubergine */ readonly property color midAubergine: "#5E2750" /*! Ubuntu supporting color: dark aubergine */ readonly property color darkAubergine: "#2C001E" /*! Ubuntu neutral color: warm grey */ readonly property color warmGrey: "#AEA79F" /*! Ubuntu neutral color: cool grey */ readonly property color coolGrey: "#333333" /*! Ubuntu orange gradient \sa Button::gradient */ property Gradient orangeGradient: Gradient { GradientStop { position: 0.0; color: "#DD4814" } GradientStop { position: 1.0; color: "#D9722D" } } /*! Ubuntu grey gradient \sa Button::gradient */ property Gradient greyGradient: Gradient { GradientStop { position: 0.0; color: "#888888" } GradientStop { position: 1.0; color: "#BBBBBB" } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/0000755000015301777760000000000012321006415026432 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/DialerHand.qml0000644000015301777760000001773612321005637031163 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "../" 0.1 /*! \qmltype DialerHand \inqmlmodule Ubuntu.Components.Pickers 0.1 \ingroup ubuntu-pickers \brief DialerHand represents a value selector on a Dialer. DialerHand components have meaning only if those are placed inside Dialer components. The dialer hand presents a value selection from the given dialer's minimum and maximum values. By default all hands are placed on the dialer's hand space, on the outer dialer disk. By default all hands have teh same size, 0.5GU width and height same as the handSpace specified in \l Dialer, however themes can specify preset values for each hand. Hands can also be placed onto the inner disk by setting \a hand.toCenterItem property to true. \qml Dialer { DialerHand { // this dialer hand will take the space as defined by the theme. } DialerHand { hand.height: units.gu(3) // this hand will have its width as defined by the theme // but height as 3 GU } } \endqml Items declared as children will be placed over the hands. These items will not be rotated togehther with the hand, these will always be shown horizontally. The hand can be hidden by setting false to \a hand.visible property, but that does not hide the overlay content. The following example demonstrates how to create a hidden dialer hand having an overlay component on the hand. \qml Dialer { DialerHand { id: selector hand.visible: false Rectangle { anchors.centerIn: parent width: height height: units.gu(3) radius: width / 2 color: Theme.palette.normal.background antialiasing: true Label { text: Math.round(selector.value) anchors.centerIn: parent } } } } \endqml */ StyledItem { id: dialerHand /*! The property holds the selected value the dialer hand points to. */ property real value /*! \qmlproperty real hand.width \qmlproperty real hand.height \qmlproperty bool hand.draggable \qmlproperty bool hand.toCenterItem \qmlproperty bool hand.visible The \b hand.width and \b hand.height properties define the size of the hand. The height of the hand must be in the [0..dialer.handSpace] range in order to have the hand displayed in the hand area, however there is no restriction applied on the size of the dialer hand. If no value is set, the width and height will be defined by the style. \b draggable property specifies whether the hand is draggable or not. When set to not draggable, the hand is used only to indicate the given value. The default value is true. \b toCenterItem property specifies whether the hand should be placed on the hand space (on the outer disk - false) or onto the center disk (inner disk - true). The default value is false, meaning the hand will be placed onto the hand space disk. \b visible property specifies whether to show the hand marker or not. The default value is true. */ property DialerHandGroup hand: DialerHandGroup { width: __styleInstance.handPreset(index, "width") height: __styleInstance.handPreset(index, "height") draggable: __styleInstance.handPreset(index, "draggable") visible: __styleInstance.handPreset(index, "visible") toCenterItem: __styleInstance.handPreset(index, "toCenterItem") } /*! The property holds the dialer instance the hand is assigned to. This is a helper property to enable access to the dialer component hosting the hand. */ readonly property Dialer dialer: parent /*! \qmlproperty list overlay \default The property holds the items that can be added on top of the hand. Note that these items will not be rotated together with the hand pointer and pointer visibility does not affect the overlay items visibility. */ default property alias overlay: contentItem.data /*! \qmlproperty int index \readonly The property holds the index of the hand. Note that this is not the child index of the dialer children, this represents the index of the DialerHand component added to the \l dialer. */ readonly property alias index: grabber.index z: __styleInstance.handPreset(index, "z") anchors.centerIn: parent width: parent.width height: parent.height style: Theme.createStyleComponent("DialerHandStyle.qml", dialerHand) /*! \internal */ onParentChanged: { if (dialer && !dialer.hasOwnProperty("handSpace")) { console.log("WARNING: DialerHand can be a child of Dialer only."); } } /*! \internal */ onValueChanged: grabber.updateHand(); /*! \internal */ Component.onCompleted: grabber.updateHand(); /*! \internal */ property alias __grabber: grabber Item { id: grabber property int index: -1 parent: __styleInstance.handPointer width: units.gu(4) height: parent.height anchors { top: parent.top horizontalCenter: parent.horizontalCenter } Item { id: contentItem anchors.fill: parent rotation: 360 - __styleInstance.rotation } function updateHand() { if (!dialer || !__styleInstance) return; __styleInstance.rotation = MathUtils.projectValue(value, dialer.minimumValue, dialer.maximumValue, 0.0, 360.0); dialer.handUpdated(dialerHand); } MouseArea{ anchors.fill: parent; preventStealing: true; enabled: dialerHand.hand.draggable; property real centerX : dialerHand.width / 2 property real centerY : dialerHand.height / 2 property bool internalChange: false onPositionChanged: { if (internalChange) return; internalChange = true; var point = mapToItem (dialerHand, mouse.x, mouse.y); var diffX = (point.x - centerX); var diffY = -1 * (point.y - centerY); var rad = Math.atan (diffY / diffX); var deg = (rad * 180 / Math.PI); if (diffX > 0 && diffY > 0) { __styleInstance.rotation = 90 - Math.abs (deg); } else if (diffX > 0 && diffY < 0) { __styleInstance.rotation = 90 + Math.abs (deg); } else if (diffX < 0 && diffY > 0) { __styleInstance.rotation = 270 + Math.abs (deg); } else if (diffX < 0 && diffY < 0) { __styleInstance.rotation = 270 - Math.abs (deg); } dialerHand.value = MathUtils.projectValue(__styleInstance.rotation, 0.0, 360.0, dialer.minimumValue, dialer.maximumValue); internalChange = false; } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/DatePicker.qml0000644000015301777760000005705112321005637031175 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype DatePicker \inqmlmodule Ubuntu.Components.Pickers 0.1 \ingroup ubuntu-pickers \brief DatePicker component provides date and time value picking functionality. DatePicker combines up to three Picker elements providing different date or time value selection possibilities. It can be used to select full date (year, month, day), full time (hours, minutes, seconds) as well as to select a combination of year and month, month and day, hours and minutes, minutes and seconds or individual time units (i.e. year, month or day as well as hours, minutes or seconds). The selected date as well as the initial one is provided by the \l date property. For convenience the component provides also the \a year, \a month, \a day, \a week, \a hours, \a minutes and \a seconds values as separate properties, however these properties are not writable, and their initialization can happen only through the \l date property. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Column { Label { text: "Selected date: W" + datePicker.week + " - " + Qt.formatDate(datePicker.date, "dddd, dd-mmmm-yyyy") } DatePicker { id: datePicker } } \endqml The \l mode property specifies what time units should be shown by the picker. The property holds a string, combining \b Years, \b Months, \b Days, \b Hours, \b Minutes and \b Seconds strings sepatared with '|' character. A DatePicker which shows only year and month date units would look as follows: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Column { Label { text: "Selected month: " + Qt.formatDate(datePicker.date, "mmmm-yyyy") } DatePicker { id: datePicker mode: "Years|Months" } } \endqml The \b mode of the DatePicker is set to date picking. In case time picking is needed, the model should be set to contain the time specific mode flags. The following example demonstrates how to use DatePicker for time picking. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Column { Label { text: "Selected time: " + Qt.formatTime(datePicker.date, "hh:mm:ss") } DatePicker { id: datePicker mode: "Hours|Minutes|Seconds" } } \endqml Note that the order in which the mode flags are specified does not influence the order the pickers are arranged. That is driven by the date format of the \l locale used in the picker. Also not all combinations of mode flags are supported. See \l mode for the supported combinations. The default interval the date values are chosen is a window starting at the current date ending 50 years later. This window is defined by the \a minimum and \a maximum properties. The interval can be altered considering the following rules: \list \li - \a minimum must be less or equal than the \l date; if the \a date value is less than the given \a minimum, the date will be set to the minimum's value \li - \a maximum value must be greater than the \a minimum, or invalid. When the maximum is smaller than the \l date, the \l date property will be updated to get the maximum value. When set to invalid date (see Date.getInvalidDate()), the upper limit of the date interval becomes infinite, meaning the year picker will extend infinitely. This leads to increased memory use and should be avoided if possible. Invalid date will make hours picker presenting 24 hours. \endlist \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Column { Label { text: "Selected date: " + Qt.formatDate(datePicker.date, "dddd, dd-mmmm-yyyy") } DatePicker { id: datePicker minimum: { var d = new Date(); d.setFullYear(d.getFullYear() - 1); return d; } maximum: Date.prototype.getInvalidDate.call() } } \endqml \b Note: do not use the \l date property when initializing minimum and maximum as it will cause binding loops. \section2 Layout As mentioned earlier, DatePicker combines up to three Picker tumblers depending on the mode requested. These tumblers are laid out in a row in the order the default date format of the \l locale is. \section3 Date picker layout rules The date picker consist of three pickers: year, month, and date. The exact contents of the month and date pickers depends on the available width: \list \li * full name for month, number and full day for date (“August” “28 Wednesday”) \li * otherwise full name for month, number and abbreviated day for date (“August” “28 Wed”); \li * otherwise full name for month, number for date (“August” “28”); \li * otherwise abbreviated name for month, number for date (“Aug” “28”). \li * otherwise number for month, number for date (“08” “28”). \endlist \a{If the currently selected date becomes impossible due to year change (from a leap to a non-leap year when the date is set to February 29) or month change (e.g. from a month that has 31 days to one that has fewer when the date is set to 31), the date reduces automatically to the last day of the month (i.e February 28 or 30th day of the month).} \section3 Time picker layout rules Time units are shown in fixed width picker tumblers, numbers padded with leading zeroes. There is no other special rule on the formatting of the time unit numbers. \section3 How minimum/maximum affects the tumblers If minimum and maximum are within the same year, the year picker will be insensitive. If minimum and maximum are within the same month, the month picker will also be insensitive. */ StyledItem { id: datePicker /*! Specifies what kind of date value selectors should be shown by the picker. This is a string of 'flags' separated by '|' separator, where flags are: \table \header \li {2, 1} Date picker modes \header \li Value \li Description \row \li Years \li Specifies to show the year picker \row \li Months \li Specifies to show the month picker \row \li Days \li Specifies to show the day picker \header \li {2, 1} Time picker modes \header \li Value \li Description \row \li Hours \li Specifies to show the hours picker \row \li Minutes \li Specifies to show the minutes picker \row \li Seconds \li Specifies to show the seconds picker \endtable With some exceptions, any combination of these flags is allowed within the same group. Date and time picker modes cannot be combined. The supported combinations are: \a{Years|Months|Days}, \a{Years|Months}, \a{Months|Days}, \a{Hours|Minutes|Seconds}, \a{Hours|Minutes} and \a{Minutes|Seconds}, as well as each mode flag individually. The default value is "\a{Years|Months|Days}". */ property string mode: "Years|Months|Days" /*! The date chosen by the DatePicker. The default value is the date at the component creation time. The property automatically updates year, month and day properties. */ property date date: Date.prototype.midnight.call(new Date()) /*! \qmlproperty int minimum The minimum date (inclusive) to be shown in the picker. Both year and month values will be considered from the properties. The year and month picker values are filled based on these values. The year picker will be infinite (extending infinitely) if the maximum is an invalid date. If the distance between maximum and minimum is less than a year, the year picker will be shown disabled. The month picker will be circular if the distance between maximum and minimum is at least one year, or if the maximum date is invalid. The default values are the current date for the minimum, and 50 year distance value for maximum. */ property date minimum: Date.prototype.midnight.call(new Date()) /*! \qmlproperty int maximum The maximum date (inclusive) to be shown in the picker. Both year and month values will be considered from the properties. See \l minimum for more details. */ property date maximum: { var d = Date.prototype.midnight.call(new Date()); d.setFullYear(d.getFullYear() + 50); return d; } /*! For convenience, the \b year value of the \l date property. */ readonly property int year: datePicker.date.getFullYear() /*! For convenience, the \b month value of the \l date property. */ readonly property int month: datePicker.date.getMonth() /*! For convenience, the \b day value of the \l date property. */ readonly property int day: datePicker.date.getDate() /*! For convenience, the \b week value of the \l date property. */ readonly property int week: datePicker.date.getWeek() /*! For convenience, the \b hours value of the \l date property. */ readonly property int hours: datePicker.date.getHours() /*! For convenience, the \b minutes value of the \l date property. */ readonly property int minutes: datePicker.date.getMinutes() /*! For convenience, the \b seconds value of the \l date property. */ readonly property int seconds: datePicker.date.getSeconds() /*! The property defines the locale used in the picker. The default value is the system locale. \qml DatePicker { locale: Qt.locale("hu_HU") } \endqml */ property var locale: Qt.locale() /*! \qmlproperty bool moving \readonly The property holds whether the component's pickers are moving. \sa Picker::moving */ readonly property alias moving: positioner.moving implicitWidth: units.gu(36) implicitHeight: units.gu(20) /*! \internal */ onMinimumChanged: { if (internals.completed && !minimum.isValid()) { // set the minimum to the date minimum = date; } // adjust date if (date !== undefined && Date.prototype.isValid.call(minimum) && date < minimum && internals.completed) { date = minimum; } } /*! \internal */ onMaximumChanged: { // adjust date if (date !== undefined && Date.prototype.isValid.call(maximum) && date > maximum && maximum > minimum && internals.completed) { date = maximum; } } /*! \internal */ onWidthChanged: { // use dayPicker narrowFormatLimit even if the dayPicker is hidden // and clamp the width so it cannot have less width that the sum of // the three tumblers' narrowFormatLimit var minWidth = 0.0; for (var i = 0; i < tumblerModel.count; i++) { minWidth += tumblerModel.get(i).pickerModel.narrowFormatLimit; } width = Math.max(width, minWidth); } /*! \internal */ onModeChanged: internals.updatePickers() /*! \internal */ onLocaleChanged: internals.updatePickers() Component.onCompleted: { if (minimum === undefined) { minimum = date; } internals.completed = true; internals.updatePickers(); } // models YearModel { id: yearModel mainComponent: datePicker pickerCompleted: internals.completed && internals.showYearPicker pickerWidth: (!pickerItem) ? 0 : narrowFormatLimit function syncModels() { dayModel.syncModels(); } } MonthModel { id: monthModel mainComponent: datePicker pickerCompleted: internals.completed && internals.showMonthPicker pickerWidth: { if (!pickerItem) { return 0; } return MathUtils.clamp(datePicker.width - yearModel.pickerWidth - dayModel.pickerWidth, narrowFormatLimit, longFormatLimit); } function syncModels() { dayModel.syncModels(); } } DayModel { id: dayModel mainComponent: datePicker pickerCompleted: internals.completed && internals.showDayPicker pickerWidth: { if (!pickerItem) { return 0; } var w = Math.max(datePicker.width * internals.dayPickerRatio, narrowFormatLimit); if (w < longFormatLimit && w >= shortFormatLimit) { return shortFormatLimit; } return w; } } HoursModel { id: hoursModel mainComponent: datePicker pickerCompleted: internals.completed && internals.showHoursPicker pickerWidth: { if (!pickerItem) { return 0; } return narrowFormatLimit; } } MinutesModel { id: minutesModel mainComponent: datePicker pickerCompleted: internals.completed && internals.showMinutesPicker pickerWidth: { if (!pickerItem) { return 0; } return narrowFormatLimit; } } SecondsModel { id: secondsModel mainComponent: datePicker pickerCompleted: internals.completed && internals.showSecondsPicker pickerWidth: { if (!pickerItem) { return 0; } return narrowFormatLimit; } } style: Theme.createStyleComponent("DatePickerStyle.qml", datePicker) Binding { target: __styleInstance property: "view" value: positioner } Binding { target: __styleInstance property: "pickerModels" value: tumblerModel } Binding { target: __styleInstance property: "unitSeparator" value: (internals.showHoursPicker || internals.showMinutesPicker || internals.showSecondsPicker) ? ":" : "" } // tumbler positioner PickerRow { id: positioner parent: (datePicker.__styleInstance && datePicker.__styleInstance.hasOwnProperty("tumblerHolder")) ? datePicker.__styleInstance.tumblerHolder : datePicker mainComponent: datePicker model: tumblerModel margins: internals.margin anchors { top: parent.top bottom: parent.bottom horizontalCenter: parent.horizontalCenter } } // tumbler model ListModel { /* Model to hold tumbler order for repeaters. Roles: - pickerModel - pickerName */ id: tumblerModel /* Signal triggered when the model is about to remove a picker. We cannot rely on rowAboutToBeRemoved, as by the time the signal is called the list element is already removed from the model. */ signal pickerRemoved(int index) // the function checks whether a pickerModel was added or not // returns the index of the model object the pickerModel was found // or -1 on error. function pickerModelIndex(name) { for (var i = 0; i < count; i++) { if (get(i).pickerName === name) { return i; } } return -1; } // the function checks whether a pickerModel is present in the list; // moves the existing one to the given index or inserts it if not present function setPickerModel(model, name, index) { var idx = pickerModelIndex(name); if (idx >= 0) { move(idx, index, 1); } else { append({"pickerModel": model, "pickerName": name}); } } // removes the given picker function removePicker(name) { var idx = pickerModelIndex(name); if (idx >= 0) { pickerRemoved(idx); remove(idx); } } } // component to calculate text fitting Label { id: textSizer; visible: false } QtObject { id: internals property bool completed: false property real margin: units.gu(1.5) property real dayPickerRatio: 0.1 property bool showYearPicker: true property bool showMonthPicker: true property bool showDayPicker: true property bool showHoursPicker: false property bool showMinutesPicker: false property bool showSecondsPicker: false /* Update pickers. */ function updatePickers() { if (completed) { // check mode flags first var modes = datePicker.mode.split(/\W/g); showYearPicker = showMonthPicker = showDayPicker = showHoursPicker = showMinutesPicker = showSecondsPicker = false; while (modes.length > 0) { var modeFlag = modes.pop(); switch (modeFlag) { case "Years": showYearPicker = true; break; case "Months": showMonthPicker = true; break; case "Days": showDayPicker = true; break; case "Hours": showHoursPicker = true; break; case "Minutes": showMinutesPicker = true; break; case "Seconds": showSecondsPicker = true; break; default: console.warn("Unhandled mode flag: " + modeFlag + ". Mode will not be set!"); return; } } // filter unaccepted date picking mode if (!showMonthPicker && showYearPicker && showDayPicker) { console.error("Invalid DatePicker mode: " + datePicker.mode); return; } // filter unaccepted time picking mode if (showHoursPicker && showSecondsPicker && !showMinutesPicker) { console.error("Invalid DatePicker mode: " + datePicker.mode); return; } // date and time picking not allowed at the same time if ((showYearPicker || showMonthPicker || showDayPicker) && (showHoursPicker || showMinutesPicker || showSecondsPicker)) { console.error("Date and Time picking not allowed at the same time."); return; } arrangeTumblers(); resetPickers(); } } /* Resets the pickers. Pickers will update their models with the given date, minimum and maximum values. */ function resetPickers() { if (!completed) return; for (var i = 0; i < tumblerModel.count; i++) { var pickerItem = tumblerModel.get(i).pickerModel.pickerItem; pickerItem.resetPicker(); } // calculate the ratio for the dayPicker var maxWidth = 0.0; maxWidth += showYearPicker ? yearModel.longFormatLimit : 0.0; maxWidth += showMonthPicker ? monthModel.longFormatLimit : 0.0; maxWidth += showDayPicker ? dayModel.longFormatLimit : 0.0; if (showDayPicker && maxWidth > 0.0) { dayPickerRatio = (dayModel.longFormatLimit / maxWidth).toPrecision(3); } } /* Detects the tumbler order from the date format of the locale */ function arrangeTumblers() { // disable completion so avoid accidental date changes completed = false; // use short format to exclude any extra characters var format = datePicker.locale.dateFormat(Locale.ShortFormat).split(/\W/g); // loop through the format to decide the position of the tumbler var formatIndex = 0; for (var i in format) { if (!format[i].length) continue; // check the first two characters switch (format[i].substr(0, 1).toLowerCase()) { case 'y': if (showYearPicker) { tumblerModel.setPickerModel(yearModel, "YearPicker", formatIndex); formatIndex++; } else { tumblerModel.removePicker("YearPicker"); } break; case 'm': if (showMonthPicker) { tumblerModel.setPickerModel(monthModel, "MonthPicker", formatIndex); formatIndex++; } else { tumblerModel.removePicker("MonthPicker"); } break; case 'd': if (showDayPicker) { tumblerModel.setPickerModel(dayModel, "DayPicker", formatIndex); formatIndex++; } else { tumblerModel.removePicker("DayPicker"); } break; } } // check hms if (showHoursPicker) { tumblerModel.setPickerModel(hoursModel, "HoursPicker", formatIndex); formatIndex++; } else { tumblerModel.removePicker("HoursPicker"); } if (showMinutesPicker) { tumblerModel.setPickerModel(minutesModel, "MinutesPicker", formatIndex); formatIndex++; } else { tumblerModel.removePicker("MinutesPicker"); } if (showSecondsPicker) { tumblerModel.setPickerModel(secondsModel, "SecondsPicker", formatIndex); formatIndex++; } else { tumblerModel.removePicker("SecondsPicker"); } // re-enable completion completed = true; } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/PickerRow.qml0000644000015301777760000001031512321005637031057 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Row { id: row /* Reference to the main composit component holding this row. */ property Item mainComponent /* The model populating the row. */ property alias model: rowRepeater.model /* Picker label margins */ property real margins: units.gu(1.5) /* Reports whether either of the pickers is moving */ property bool moving // the following functions/properties should be kept private in case the // component is ever decided to be published function pickerMoving(isMoving) { if (isMoving === undefined) { isMoving = this.moving; } if (isMoving) { row.moving = true; } else { for (var i = 0; i < row.model.count; i++) { var pickerItem = model.get(i).pickerModel.pickerItem; if (!pickerItem) return; if (pickerItem.moving) { row.moving = true; return; } } row.moving = false; } } function disconnectPicker(index) { var pickerItem = model.get(index).pickerModel.pickerItem; if (pickerItem) { pickerItem.onMovingChanged.disconnect(pickerMoving); } } Connections { target: row.model onPickerRemoved: disconnectPicker(index) } objectName: "PickerRow_Positioner"; Repeater { id: rowRepeater onModelChanged: row.pickerMoving(true) Picker { id: unitPicker objectName: "PickerRow_" + pickerName model: pickerModel enabled: pickerModel.count > 1 circular: pickerModel.circular live: false width: pickerModel.pickerWidth height: parent ? parent.height : 0 style: Rectangle { anchors.fill: parent color: (unitPicker.Positioner.index % 2) ? Qt.rgba(0, 0, 0, 0.03) : Qt.rgba(0, 0, 0, 0.07) } delegate: PickerDelegate { Label { objectName: "PickerRow_PickerLabel" text: pickerModel ? pickerModel.text(modelData) : "" anchors.fill: parent verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } Component.onCompleted: { if (pickerModel && pickerModel.autoExtend && (index === (pickerModel.count - 1))) { pickerModel.extend(modelData + 1); } } } onSelectedIndexChanged: { if (pickerModel && !pickerModel.resetting) { mainComponent.date = pickerModel.dateFromIndex(selectedIndex); pickerModel.syncModels(); } } /* Resets the Picker model and updates the new format limits. */ function resetPicker() { pickerModel.reset(); pickerModel.resetLimits(textSizer, margins); pickerModel.resetCompleted(); positionViewAtIndex(pickerModel.indexOf()); } Component.onCompleted: { // update model with the item instance pickerModel.pickerItem = unitPicker; unitPicker.onMovingChanged.connect(pickerMoving.bind(unitPicker)); row.pickerMoving(unitPicker.moving); } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/PickerDelegate.qml0000644000015301777760000000363712321005637032033 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "../" 0.1 /*! \qmltype PickerDelegate \inqmlmodule Ubuntu.Components.Pickers 0.1 \ingroup ubuntu-pickers \brief PickerDelegate component serves as base for Picker delegates. PickerDelegate is a holder component for delegates used in a Picker element. Each picker delegate must be derived from this type. */ AbstractButton { id: pickerDelegate /*! \qmlproperty Picker picker \readonly The property holds the Picker component the delegate belongs to. */ readonly property alias picker: internal.picker implicitHeight: units.gu(4) implicitWidth: picker ? internal.itemList.width : 0 /*! \internal */ onClicked: { if (internal.itemList.currentIndex === index) return; picker.__clickedIndex = index; internal.itemList.currentIndex = index; } style: Theme.createStyleComponent("PickerDelegateStyle.qml", pickerDelegate) QtObject { id: internal property bool inListView: pickerDelegate.parent && (QuickUtils.className(pickerDelegate.parent) !== "QQuickPathView") property Item itemList: !inListView ? pickerDelegate.PathView.view : pickerDelegate.ListView.view property Picker picker: itemList ? itemList.pickerItem : null } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/DayModel.qml0000644000015301777760000000542412321005637030655 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 PickerModelBase { circular: true function reset() { resetting = true; clear(); for (var i = 0; i < date.daysInMonth(); i++) { append({"day": i}); } } function resetLimits(label, margin) { label.text = '9999'; narrowFormatLimit = label.paintedWidth + 2 * margin; shortFormatLimit = longFormatLimit = 0.0; for (var day = 1; day <= 7; day++) { label.text = '99 ' + mainComponent.locale.dayName(day, Locale.ShortFormat) shortFormatLimit = Math.max(label.paintedWidth + 2 * margin, shortFormatLimit); label.text = '99 ' + mainComponent.locale.dayName(day, Locale.LongFormat) longFormatLimit = Math.max(label.paintedWidth + 2 * margin, longFormatLimit); } } function syncModels() { var newDaysCount = mainComponent.date.daysInMonth(mainComponent.year, mainComponent.month); var modelCount = count; var daysDiff = newDaysCount - modelCount; if (daysDiff < 0) { remove(modelCount + daysDiff, -daysDiff); } else if (daysDiff > 0) { for (var d = modelCount; d < modelCount + daysDiff; d++) { append({"day": d}); } } } function indexOf() { return date.getDate() - 1; } function dateFromIndex(index) { if (index < 0 || index >= count) { return date; } var newDate = new Date(date); newDate.setDate(index + 1); return newDate; } function text(value) { if (value === undefined) { return ""; } var thisDate = new Date(date); thisDate.setDate(value + 1); if (pickerWidth >= longFormatLimit) { return Qt.formatDate(thisDate, "dd ") + mainComponent.locale.dayName(thisDate.getDay(), Locale.LongFormat); } if (pickerWidth >= shortFormatLimit) { return Qt.formatDate(thisDate, "dd ") + mainComponent.locale.dayName(thisDate.getDay(), Locale.ShortFormat); } return Qt.formatDate(thisDate, "dd"); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/PickerModelBase.qml0000644000015301777760000001052212321005637032143 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /* Base model type for DatePicker */ ListModel { /* Holds the picker instance, the component the model is attached to. Should not be confused with the DatePicker. */ property Item pickerItem /* Property holding the composit picker component. */ property Item mainComponent /* The property holds the width of the picker tumbler to be set. */ property real pickerWidth: 0 /* Specifies whether the model is circular or not. */ property bool circular: false /* The property specifies whenther the Picker should auto-extend the model. Typical for year model. */ property bool autoExtend: false /* Narow, normal and long format limits. */ property real narrowFormatLimit: 0.0 property real shortFormatLimit: 0.0 property real longFormatLimit: 0.0 /* The function resets the model and the attached Picker specified in the item. The Picker must have a resetPicker() function available. */ function reset() {} /* The function completes the reset operation. */ function resetCompleted() { resetting = false; } /* Function called by the Picker to re-calculate values for the limit properties. The locale is retrieved from pickerItem. */ function resetLimits(label, margin) {} /* The function is called by the Picker component when a value gets selected to keep the pickers in sync. */ function syncModels() {} /* The function extends the model starting from a certain \a baseValue. */ function extend(baseValue) {} /* Returns the index of the value from the model. */ function indexOf() { return -1; } /* Returns a Date object from the model's \a index, relative to the given \a date. */ function dateFromIndex(index) { return new Date(); } /* Returns the date string for the value relative to the date, which fits into the given width. Uses the locale from pickerItem to fetch the localized date string. */ function text(value) { return ""; } /* Readonly properties to the composit picker's date properties */ readonly property date date: mainComponent.date readonly property date minimum: mainComponent.minimum readonly property date maximum: mainComponent.maximum property bool pickerCompleted: false /* The property specifies whether there is a reset operation in progress or not. Derivates overwriting reset() function must also set this flag to avoid unwanted date changes that may occur during reset operation due to selectedIndex changes. */ property bool resetting: false /* Call reset() whenever minimum or maximum changes, and update selected index of pickerItem whenever date changes. */ onMinimumChanged: { if (pickerCompleted && pickerItem && !resetting) { pickerItem.resetPicker(); } } onMaximumChanged: { if (pickerCompleted && pickerItem && !resetting) { pickerItem.resetPicker(); } } onDateChanged: { if (!pickerCompleted || !pickerItem || resetting) { return; } // use animated index update only if the change had happened because of the delegate update if (pickerItem.__clickedIndex >= 0) { pickerItem.selectedIndex = indexOf(); } else { // in case the date property was changed due to binding/update, // position tumbler without animating pickerItem.positionViewAtIndex(indexOf()); } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/Picker.qml0000644000015301777760000003737612321005637030407 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /*! \qmltype Picker \inqmlmodule Ubuntu.Components.Pickers 0.1 \ingroup ubuntu-pickers \brief Picker is a slot-machine style value selection component. The Picker lists the elements specified by the \l model using the \l delegate vertically using a slot-machine tumbler-like list. The selected item is always the one in the center of the component, and it is represented by the \l selectedIndex property. The elements can be either in a circular list or in a normal list. Delegates must be composed using PickerDelegate. Example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.Pickers 0.1 Picker { model: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"] delegate: PickerDelegate { Label { text: modelData } } selectedIndex: 5 onSelectedIndexChanged: { print("selected month: " + selectedIndex); } } \endqml \b Note: the \l selectedIndex must be set explicitly to the desired index if the model is set, filled or changed after the component is complete. In the following example the selected item must be set after the model is set. \qml Picker { selectedIndex: 5 // this will be set to 0 at the model completion delegate: PickerDelegate { Label { text: modelData } } Component.onCompleted: { var stack = []; for (var i = 0; i < 10; i++) { stack.push("Line " + i); } model = stack; // selectedIndex must be set explicitly selectedIndex = 3; } } \endqml \section3 Known issues \list \li [1] Circular picker does not react on touch generated flicks (on touch enabled devices) when nested into a Flickable - \l {https://bugreports.qt-project.org/browse/QTBUG-13690} and \l {https://bugreports.qt-project.org/browse/QTBUG-30840} \li [2] Circular picker sets \l selectedIndex to 0 when the model is cleared, contrary to linear one, which sets it to -1 - \l {https://bugreports.qt-project.org/browse/QTBUG-35400} \endlist */ StyledItem { id: picker /*! Property specifying whether the tumbler list is wrap-around (\a true), or normal (\a false). Default value is true. */ property bool circular: true /*! Specifies the model listing the content of the picker. */ property var model /*! The delegate visualizing the model elements. Any kind of component can be used as delegate, however it is recommended to use \l PickerDelegate, which integrates selection functionality into the Picker. */ property Component delegate /*! The property holds the index of the selected item */ property int selectedIndex /*! Defines whether the \l selectedIndex should be updated while the tumbler changes the selected item during draggingm or only when the tumbler's motion ends. The default behavior is non-live update. */ property bool live: false /*! The property holds whether the picker's view is moving due to the user interaction either by dragging, flicking or due to the manual change of the selectedIndex property. */ readonly property bool moving: (loader.item ? loader.item.moving : false) || movingPoll.indexChanging /*! The function positions the picker's view to the given index without animating the view. The component must be ready when calling the function, e.g. to make sure the Picker shows up at the given index, do the following: \qml Picker { model: 120 delegate: PickerDelegate { Label { anchors.fill: parent verticalCenter: Text.AlignVCenter text: modelData } } Component.onCompleted: positionViewAtIndex(10) } \endqml */ function positionViewAtIndex(index) { if (!loader.item || !internals.completed) { return; } loader.item.positionViewAtIndex(index, loader.isListView ? ListView.SnapPosition : PathView.SnapPosition); // update selectedIndex selectedIndex = loader.item.currentIndex; } implicitWidth: units.gu(8) implicitHeight: units.gu(20) style: Theme.createStyleComponent("PickerStyle.qml", picker) /*! \internal */ property int __clickedIndex: -1 // bind style instance's view property to the Loader's item Binding { target: __styleInstance property: "view" value: loader.item when: __styleInstance.hasOwnProperty("view") && loader.item } /* ListView/PathView do not change moding property when the current index is changed manually. Therefore we use an idle timer to poll the contentY to detect whether the views are still moving. PathView's currentIndex changes while the component is moving, however this is not true for ListView. */ Timer { id: movingPoll interval: 50 running: false property bool indexChanging: false property real prevContentY onTriggered: { if (prevContentY === loader.item.contentY) { indexChanging = false; } else { kick(); } } function kick() { if (!loader.item) return; indexChanging = true; prevContentY = loader.item.contentY; running = true; } } // tumbler Loader { id: loader objectName: "Picker_ViewLoader" asynchronous: false parent: __styleInstance.hasOwnProperty("tumblerHolder") ? __styleInstance.tumblerHolder : picker anchors.fill: parent sourceComponent: circular ? wrapAround : linear // property for loading completion property bool completed: item && (status === Loader.Ready) && item.viewCompleted // do we have a ListView or PathView? property bool isListView: (item && QuickUtils.className(item) === "QQuickListView") // update curentItem automatically when selectedIndex changes Binding { target: loader.item property: "currentIndex" value: picker.selectedIndex when: loader.completed && (picker.selectedIndex > 0) } // selectedIndex updater, live or non-live ones Connections { target: loader.item ignoreUnknownSignals: true onMovementEnded: { if (!loader.completed || !model) return; if (!picker.live) { picker.selectedIndex = loader.item.currentIndex; } } onCurrentIndexChanged: { movingPoll.kick(); if (!loader.completed) return; if (picker.live || (modelWatcher.modelSize() <= 0) || (picker.__clickedIndex >= 0 && (picker.__clickedIndex === loader.item.currentIndex)) || modelWatcher.cropping) { picker.selectedIndex = loader.item.currentIndex; modelWatcher.cropping = false; picker.__clickedIndex = -1; } } onModelChanged: { modelWatcher.connectModel(picker.model); if (!loader.completed) return; loader.moveToIndex((loader.completed) ? 0 : picker.selectedIndex); if (loader.completed && !picker.live) { picker.selectedIndex = 0; } } } function moveToIndex(toIndex) { var count = (loader.item && loader.item.model) ? modelWatcher.modelSize() : -1; if (completed && count > 0) { if (loader.isListView) { loader.item.currentIndex = toIndex; return; } else { loader.item.positionViewAtIndex(count - 1, PathView.Center); loader.item.positionViewAtIndex(toIndex, PathView.Center); } } } Component.onCompleted: modelWatcher.connectModel(picker.model); Component.onDestruction: modelWatcher.disconnectModel() } // circular list Component { id: wrapAround PathView { id: pView objectName: "Picker_WrapAround" // property declared for PickerDelegate to be able to access the main component property Item pickerItem: picker // property holding view completion property bool viewCompleted: false // declared to ease moving detection property real contentY: offset anchors { top: parent ? parent.top : undefined bottom: parent ? parent.bottom : undefined horizontalCenter: parent ? parent.horizontalCenter : undefined } width: parent ? parent.width : 0 clip: true model: picker.model delegate: picker.delegate currentIndex: picker.selectedIndex // put the currentItem to the center of the view preferredHighlightBegin: 0.5 preferredHighlightEnd: 0.5 pathItemCount: pView.height / (pView.currentItem ? pView.currentItem.height : 1) + 1 snapMode: PathView.SnapToItem flickDeceleration: 100 property int contentHeight: pathItemCount * (pView.currentItem ? pView.currentItem.height : 1) path: Path { startX: pView.width / 2 startY: -(pView.contentHeight - pView.height) / 2 PathLine { x: pView.width / 2 y: pView.height + (pView.contentHeight - pView.height) / 2 } } Component.onCompleted: { var complete = true if (modelWatcher.isObjectModel()) { complete = (model.count > 0); if (model.count >= 2) { positionViewAtIndex(1, PathView.SnapPosition); positionViewAtIndex(0, PathView.SnapPosition); } } else if (Object.prototype.toString.call(model) === "[object Number]") { if (model >= 2) { positionViewAtIndex(1, PathView.SnapPosition); positionViewAtIndex(0, PathView.SnapPosition); } } viewCompleted = complete; } } } // linear list Component { id: linear ListView { id: lView objectName: "Picker_Linear" // property declared for PickerDelegate to be able to access the main component property Item pickerItem: picker // property holding view completion property bool viewCompleted: false anchors { top: parent ? parent.top : undefined bottom: parent ? parent.bottom : undefined horizontalCenter: parent ? parent.horizontalCenter : undefined } width: parent ? parent.width : 0 clip: true model: picker.model delegate: picker.delegate currentIndex: picker.selectedIndex preferredHighlightBegin: (height - (currentItem ? currentItem.height : 0)) / 2 preferredHighlightEnd: preferredHighlightBegin + (currentItem ? currentItem.height : 0) highlightRangeMode: ListView.StrictlyEnforceRange highlightMoveDuration: 300 flickDeceleration: 100 Component.onCompleted: viewCompleted = true } } /* Watch Picker's model to catch when elements are removed ro model is cleared. We need this to detect currentIndex changes in List/PathViews when non-live update mode is chosen, to know when do we need to update selectedIndex. */ QtObject { id: modelWatcher property var prevModel property bool cropping: false function isObjectModel() { return (prevModel && Object.prototype.toString.call(prevModel) === "[object Object]"); } function modelSize() { if (prevModel) { if (Object.prototype.toString.call(model) === "[object Object]") { return prevModel.count; } else if (Object.prototype.toString.call(model) === "[object Array]") { return prevModel.length; } else if (Object.prototype.toString.call(model) === "[object Number]") { return prevModel; } } return -1; } function connectModel(model) { disconnectModel(); prevModel = model; // check if the model is derived from QAbstractListModel if (model && Object.prototype.toString.call(model) === "[object Object]") { model.rowsAboutToBeRemoved.connect(itemsAboutToRemove); model.rowsInserted.connect(updateView); } } function disconnectModel() { if (isObjectModel()) { prevModel.rowsAboutToBeRemoved.disconnect(itemsAboutToRemove); prevModel.rowsInserted.disconnect(updateView); } } function updateView() { if (!loader.isListView && loader.item.count === 2) { // currentItem gets set upon first flick or move when the model is empty // at the time the component gets completed. Disable viewCompleted till // we move the view so selectedIndex doesn't get altered loader.item.viewCompleted = false; loader.item.positionViewAtIndex(1, PathView.SnapPosition); loader.item.positionViewAtIndex(0, PathView.SnapPosition); loader.item.viewCompleted = true; } } function itemsAboutToRemove(parent, start, end) { if ((end - start + 1) === loader.item.count) { cropping = true; } else if (selectedIndex >= start) { // Notify views that the model got cleared or got cropped // the loader.item.currentIndex is not yet updated, so we simply remember // that we need to update when currentIndex change is notified cropping = true; if (selectedIndex <= (start + end)) { // the selection is in between the removed indexes, so move the selection // to the closest available one loader.item.positionViewAtIndex(Math.max(start - 1, 0), (loader.isListView) ? ListView.SnapPosition : PathView.SnapPosition); } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/HoursModel.qml0000644000015301777760000000340412321005637031234 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 PickerModelBase { property int from circular: count >= 24 function reset() { resetting = true; clear(); from = minimum.getHours(); var distance = (!Date.prototype.isValid.call(maximum) || (minimum.daysTo(maximum) > 1)) ? 24 : minimum.hoursTo(maximum); for (var i = 0; i < distance; i++) { append({"hour": (from + i) % 24}); } resetting = false; } function resetLimits(label, margin) { label.text = "99"; narrowFormatLimit = shortFormatLimit = longFormatLimit = label.paintedWidth + 2 * margin; } function indexOf() { var index = date.getHours() - from; if (index >= count) { index = -1; } return index; } function dateFromIndex(index) { if (index < 0 || index >= count) { return date; } var newDate = new Date(date); newDate.setHours(index + from); return newDate; } function text(value) { return (value !== undefined) ? ("00" + value).slice(-2) : ""; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/qmldir0000644000015301777760000000047712321005637027662 0ustar pbusernogroup00000000000000module Ubuntu.Components.Pickers Picker 0.1 Picker.qml PickerDelegate 0.1 PickerDelegate.qml Dialer 0.1 Dialer.qml DialerHand 0.1 DialerHand.qml DatePicker 0.1 DatePicker.qml internal YearModel YearModel.qml internal MonthModel MonthModel.qml internal DayModel DayModel.qml internal PickerModelBase PickerModelBase.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/Dialer.qml0000644000015301777760000001223312321005637030353 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "../" 0.1 /*! \qmltype Dialer \inqmlmodule Ubuntu.Components.Pickers 0.1 \ingroup ubuntu-pickers \brief Dialer is a phone dialer style picker component. The Dialer component is dedicated for value selection where the value is compound of several sections, i.e. hour, minute and second, or integral and decimal values. Each section is defined by a DialerHand, which shares the same range as the dialer is having. Dialer hand visuals are placed on the same dialer disk, however this can be altered by setting different values to DialerHand propertries. The following example shows how to create a dialer component to select a value between 0 and 50. \qml import QtQuick 2.0 import Ubuntu.Components.Pickers 0.1 Dialer { size: units.gu(20) minimumValue: 0 maximumValue: 50 DialerHand { id: mainHand onValueChanged: console.log(value) } } \endqml \sa DialerHand */ StyledItem { /*! \qmlproperty real minimumValue: 0 \qmlproperty real maximumValue: 360 These properties define the value range the dialer hand values can take. The default values are 0 and 360. */ property real minimumValue: 0.0 /*! \internal - documented in previous block*/ property real maximumValue: 360.0 /*! The property holds the size of the dialer. The component should be sized using this property instead of using width and/or height properties. Sizing with this property it is made sure that the component will scale evenly. */ property real size: units.gu(32) /*! The property holds the height reserved for the dialer hands, being the distance between the outer and the inner dialer disks. This value cannot be higher than the half of the dialer \l size. */ property real handSpace: units.gu(6.5) /*! \qmlproperty Item centerItem The property holds the component from the center of the Dialer. Items wanted to be placed into the center of the Dialer must be reparented to this component, or listed in the \l centerContent property. Beside that, the property helps anchoring the center disk content to the item. \qml Dialer { DialerHand { id: hand Label { parent: hand.centerItem // [...] } } // [...] } \endqml */ readonly property alias centerItem: centerHolder /*! \qmlproperty list centerContent The property holds the list of items to be placed inside of the center disk. Items placed inside the center disk can either be listed in this property or reparented to \l centerItem property. \qml Dialer { DialerHand { id: hand centerContent: [ Label { // [...] } // [...] ] } // [...] } \endqml */ property alias centerContent: centerHolder.data /*! \qmlproperty list hands \readonly The property holds the list of DialerHands added to Dialer. This may be the same as the children, however will contain only DialerHand objects. */ readonly property alias hands: internal.hands /*! \qmlmethod void handUpdated(DialerHand hand) The signal is emited when the hand value is updated. */ signal handUpdated(var hand) id: dialer implicitWidth: size implicitHeight: size style: Theme.createStyleComponent("DialerStyle.qml", dialer) Item { id: internal // internal property holding only the list of DialerHand components // workaround for readonly public property property var hands: [] height: size - handSpace * 2 width: size - handSpace * 2 anchors.centerIn: parent Item { id: centerHolder anchors.fill: parent z: 1 } } /*! \internal */ onChildrenChanged: { // apply dialer presets if the hand sizes were not set // check dialers only var idx = 0; var stack = []; for (var i in children) { if (children[i].hasOwnProperty("hand")) { children[i].__grabber.index = idx++; stack.push(children[i]); } internal.hands = stack; } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/SecondsModel.qml0000644000015301777760000000344312321005637031535 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 PickerModelBase { property int from circular: count >= 60 function reset() { resetting = true; clear(); from = minimum.getSeconds(); var distance = (!maximum.isValid() || (minimum.daysTo(maximum) > 1) || (minimum.secondsTo(maximum) >= 60)) ? 59 : minimum.secondsTo(maximum); for (var i = 0; i <= distance; i++) { append({"seconds": (from + i) % 60}); } resetting = false; } function resetLimits(label, margin) { label.text = "99"; narrowFormatLimit = shortFormatLimit = longFormatLimit = label.paintedWidth + 2 * margin; } function indexOf() { var index = date.getSeconds() - from; if (index >= count) { index = -1; } return index; } function dateFromIndex(index) { if (index < 0 || index >= count) { return date; } var newDate = new Date(date); newDate.setSeconds(index + from); return newDate; } function text(value) { return (value !== undefined) ? ("00" + value).slice(-2) : ""; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/MinutesModel.qml0000644000015301777760000000344112321005637031561 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 PickerModelBase { property int from circular: count >= 60 function reset() { resetting = true; clear(); from = minimum.getMinutes(); var distance = (!maximum.isValid() || (minimum.daysTo(maximum) > 1) || (minimum.minutesTo(maximum) >= 60)) ? 60 : minimum.minutesTo(maximum); for (var i = 0; i < distance; i++) { append({"minute": (from + i) % 60}); } resetting = false; } function resetLimits(label, margin) { label.text = "99"; narrowFormatLimit = shortFormatLimit = longFormatLimit = label.paintedWidth + 2 * margin; } function indexOf() { var index = date.getMinutes() - from; if (index >= count) { index = -1; } return index; } function dateFromIndex(index) { if (index < 0 || index >= count) { return date; } var newDate = new Date(date); newDate.setMinutes(index + from); return newDate; } function text(value) { return (value !== undefined) ? ("00" + value).slice(-2) : ""; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/YearModel.qml0000644000015301777760000000364512321005637031043 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 PickerModelBase { // local properties property int from circular: false autoExtend: !maximum.isValid() function reset() { resetting = true; clear(); from = (minimum.getFullYear() <= 0) ? date.getFullYear() : minimum.getFullYear(); var to = (maximum < minimum) ? -1 : maximum.getFullYear(); extend(from, to - from); } function resetLimits(label, margin) { label.text = "9999"; narrowFormatLimit = shortFormatLimit = longFormatLimit = label.paintedWidth + 2 * margin; } function extend(baseYear, items) { if (items === undefined || items < 0) { items = 50; } for (var i = baseYear; i <= baseYear + items; i++) { append({"modelData" : i}); } } function indexOf() { var index = date.getFullYear() - from; if (index >= count) { index = -1; } return index; } function dateFromIndex(index) { if (index < 0 || index >= count) { return date; } var newDate = new Date(date); newDate.setFullYear(index + from); return newDate; } function text(value) { return (value) ? value : ""; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/MonthModel.qml0000644000015301777760000000640612321005637031226 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 PickerModelBase { circular: (count >= 11) // local properties property int from function reset() { resetting = true; clear(); var modelDate = new Date(date); modelDate.setDate(1); // if maximum is invalid, we have full model (12 months to show) var distance, to; distance = to = maximum.isValid() ? minimum.monthsTo(maximum) : 11; if (to < 0 || to > 11) to = 11; from = (to < 11) ? minimum.getMonth() : 0; // fill the model for (var i = from; i <= from + to; i++) { modelDate.setMonth(i); append({"month": modelDate.getMonth()}); } } function resetLimits(label, margin) { label.text = '9999'; narrowFormatLimit = label.paintedWidth + 2 * margin; shortFormatLimit = longFormatLimit = 0.0; for (var month = 0; month < 12; month++) { label.text = mainComponent.locale.monthName(month, Locale.LongFormat); shortFormatLimit = Math.max(label.paintedWidth + 2 * margin, shortFormatLimit); label.text = mainComponent.locale.monthName(month, Locale.LongFormat); longFormatLimit = Math.max(label.paintedWidth + 2 * margin, longFormatLimit); } } function indexOf() { var index = date.getMonth() - from; if (index >= count) { index = -1; } return index; } function dateFromIndex(index) { if (index < 0 || index >= count) { return date; } var newDate = new Date(date); // check if the days are in the diff zone (29-31) var fromDay = newDate.getDate(); // move the day to the 1st of the month so we don't overflow when setting the month newDate.setDate(1); newDate.setMonth(get(index).month); var maxDays = newDate.daysInMonth(); // check whether the original day would overflow // and trim to the mont's maximum date newDate.setDate((fromDay > maxDays) ? maxDays : fromDay); return newDate; } function text(value) { if (!mainComponent || value === undefined) { return ""; } if (pickerWidth >= longFormatLimit) { return mainComponent.locale.monthName(value, Locale.LongFormat); } if (pickerWidth >= shortFormatLimit) { return mainComponent.locale.monthName(value, Locale.ShortFormat); } var thisDate = new Date(date); thisDate.setDate(1); thisDate.setMonth(value); return Qt.formatDate(thisDate, "MM"); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/DialerHandGroup.qml0000644000015301777760000000172212321005637032164 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "../" 0.1 /*! \internal Component serving as group property for DialerHhand.hand property. */ QtObject { property real width: units.gu(0.5) property real height: parent.dialer.handSize property bool draggable: true property bool visible: true property bool toCenterItem: false } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Pickers/PickerPanel.qml0000644000015301777760000002032612321005637031352 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Window 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 import Ubuntu.Components.Popups 0.1 /*! \qmltype PickerPanel \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu-pickers \brief Provides a panel for opening a DatePicker in place of the input panel or as Popover, depending on the form factor. PickerPanel is a singleton component designed to open a DatePicker in the input panel area or in a Popover, depending on the form factor, following the design guides on date pickers. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainWindow { width: units.gu(40) height: units.gu(71) Page { title: "PickerPanel" Button { id: dateButton property date date: new Date() text: Qt.formatDateTime(date, "yyyy/MMMM") onClicked: PickerPanel.openDatePicker(dateButton, "date", "Years|Months") } } } \endqml The opened panel is closed automatically when the user taps/presses outside of the panel or Popover area. */ Object { /*! The function opens a DatePicker component in the input method area or in a popover, depending on the availability of an input method provider in the system and whether the size of the main screen width/height defines a phone form factor. The picked date will be read from and reported to the \a property of the \a caller as date type. This implies that the caller must have defined the given property of type date. On failure, the function returns null. On success, the returned object has the following properties: \code Object { property DatePicker picker property string pickerMode property date date property Item caller property string callerProperty signal closed() } \endcode \table \header \li Property \li Description \row \li \b picker \li instance of the DatePicker component shown in the panel/popup \row \li \b pickerMode \li represents the \l DatePicker::mode to be used. This is an optional parameter and if not defined, the default mode will be used. \row \li \b date \li represents the date selected \row \li \b caller \li the instance of the component opening the panel \row \li \b callerProperty \li the property of the caller holding the date value which will be updated by the picker. \header \li Signal \li Description \row \li closed() \li the signal is emitted when the panel or popover gets closed. The signal is handy when actions are performed upon panel close. \endtable */ function openDatePicker(caller, property, mode) { if (mode === undefined) { mode = "Years|Months|Days"; } var params = { "date": caller[property], "pickerMode": mode, "callerProperty": property } if (!internal.isPhone) { // we have no input panel defined, or the therefore we show the picker in a Popover return internal.openPopover(caller, params); } // OSK panel return internal.openPanel(caller, params); } QtObject { id: internal objectName: "PickerPanel_Internals" property bool formFactorPhone: Screen.width <= units.gu(40) && Screen.height <= units.gu(71) // present in a property so we can test it in property bool isPhone: false Component.onCompleted: isPhone = formFactorPhone && (QuickUtils.inputMethodProvider !== "") function openPopover(caller, params) { var popover = PopupUtils.open(datePickerPopover, caller, params); popover.parent = QuickUtils.rootItem(null); return popover; } function openPanel(caller, params) { params["caller"] = caller; var panel = datePickerPanel.createObject(QuickUtils.rootItem(null), params); return panel; } } // popover Component { id: datePickerPopover Popover { property alias picker: picker property alias date: picker.date property alias pickerMode: picker.mode property string callerProperty signal closed() contentWidth: frame.width contentHeight: frame.height Item { id: frame width: picker.width + units.gu(4) height: picker.height + units.gu(4) DatePicker { id: picker anchors.centerIn: parent Binding { target: caller property: callerProperty when: callerProperty != undefined value: picker.date } } } Component.onDestruction: closed() } } // OSK panel Component { id: datePickerPanel Rectangle { property alias picker: picker property alias date: picker.date property alias pickerMode: picker.mode property string callerProperty property Item caller signal closed() id: panel // no additional styling is needed color: Theme.palette.normal.overlay width: parent.width height: Qt.inputMethod.keyboardRectangle.height > 0 ? Qt.inputMethod.keyboardRectangle.height : units.gu(26) y: parent.height ThinDivider { anchors.bottom: parent.top } DatePicker { id: picker anchors { fill: panel margins: units.gu(2) } Binding { target: caller property: callerProperty when: callerProperty != undefined value: picker.date } } InverseMouseArea { anchors.fill: parent onPressed: panel.state = '' } Component.onCompleted: state = 'opened' states: [ State { name: 'opened' PropertyChanges { target: panel y: parent.height - height } } ] transitions: [ Transition { from: '' to: 'opened' UbuntuNumberAnimation { target: panel property: 'y' } }, Transition { from: 'opened' to: '' SequentialAnimation { UbuntuNumberAnimation { target: panel property: 'y' } ScriptAction { script: { closed(); panel.destroy(); } } } } ] } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Toolbar.qml0000644000015301777760000001050512321005670027152 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \internal \qmltype Toolbar \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Application toolbar. This class is not exposed because it will be automatically added when a Page defines tools. */ Panel { id: toolbar anchors { left: parent.left right: parent.right bottom: parent.bottom } height: background.height LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true // Closing of the toolbar on app contents interaction is handled by the Page. __closeOnContentsClicks: false // Open toolbar on hover (for desktop only) __openOnHover: true /*! \preliminary The list of \l Actions to be shown on the toolbar */ property Item tools: null hideTimeout: 5000 /*! \internal */ onToolsChanged: { internal.updateVisibleTools(); if (tools) { if (tools && tools.hasOwnProperty("locked")) locked = tools.locked; // open the toolbar, except when it is locked in closed position if (tools && tools.hasOwnProperty("locked") && tools.hasOwnProperty("opened") && !tools.opened && tools.locked) { // toolbar is locked in closed state toolbar.close(); } else { toolbar.open(); } if (tools && tools.hasOwnProperty("opened")) { tools.opened = toolbar.opened; } } else { // no tools locked = true; toolbar.close(); } } // if tools is not specified, lock the toolbar in closed position locked: tools && tools.hasOwnProperty("locked") ? tools.locked : false onOpenedChanged: { if (tools && tools.hasOwnProperty("opened")) { tools.opened = toolbar.opened; } } Connections { target: tools ignoreUnknownSignals: true onOpenedChanged: { if (tools.opened) { toolbar.open(); } else { toolbar.close(); } } onLockedChanged: { toolbar.locked = tools.locked; // open the toolbar when it becomes unlocked // (may be because a new page was pushed to the page stack) if (!toolbar.locked) toolbar.open(); } } QtObject { id: internal property Item visibleTools: tools function updateVisibleTools() { if (internal.visibleTools !== toolbar.tools) { if (internal.visibleTools) internal.visibleTools.parent = null; internal.visibleTools = toolbar.tools; if (internal.visibleTools) internal.visibleTools.parent = visibleToolsContainer; } } } onAnimatingChanged: { if (!animating && !opened) { internal.updateVisibleTools(); } } StyledItem { // FIXME: // All theming items go into the background because only the children // of the Panel are being shown/hidden while the toolbar // itself may stay in place. id: background anchors { left: parent.left right: parent.right bottom: parent.bottom } height: units.gu(8) // The values of opened and animated properties are used in the style property bool opened: toolbar.opened property bool animating: toolbar.animating style: Theme.createStyleComponent("ToolbarStyle.qml", background) } Item { id: visibleToolsContainer anchors { fill: background } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Page.qml0000644000015301777760000002057212321005712026426 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Unity.Action 1.1 as UnityActions /*! \qmltype Page \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief A page is the basic Item that must be used inside the \l MainView, \l PageStack and \l Tabs. Anchors and height of a Page are automatically determined to align with the header of the \l MainView, but can be overridden. \l MainView provides a header and toolbar for Pages it includes. Each page automatically has its header and toolbar property linked to that of its parent \l MainView. The text of the header, and the buttons in the toolbar are determined by the \l title and \l tools properties of the page: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Page { title: "Example page" Label { anchors.centerIn: parent text: "Hello world!" } tools: ToolbarItems { ToolbarButton { action: Action { text: "one" } } ToolbarButton { action: Action { text: "two" } } } } } \endqml See \l MainView for more basic examples that show how to use a header and toolbar. Advanced navigation structures can be created by adding Pages to a \l PageStack or \l Tabs. */ PageTreeNode { id: page anchors { left: parent ? parent.left : undefined right: parent ? parent.right : undefined bottom: parent ? parent.bottom : undefined } // avoid using parent.height because parent may be a Loader which does not have its height set. height: parentNode ? page.flickable ? parentNode.height : parentNode.height - internal.headerHeight : undefined /*! The title of the page. Will be shown in the header of the \l MainView. If the page is used inside a Tab, by default it takes the title from the Tab. Otherwise, the default value is an empty string. */ property string title: parentNode && parentNode.hasOwnProperty("title") ? parentNode.title : "" /*! The toolbar items associated with this Page. It is recommended to use \l ToolbarItems to specify the tools, but any Item is allowed here. */ property Item tools: ToolbarItems { } /*! Optional flickable that controls the header. This property is automatically set to the first child of the page that is Flickable and anchors to the top of the page or fills the page. For example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(30) height: units.gu(50) Page { id: page title: "example" //flickable: null // uncomment to disable hiding of the header Flickable { id: content anchors.fill: parent contentHeight: units.gu(70) Label { text: "hello" anchors.centerIn: parent } } } } \endqml In this example, page.flickable will automatically be set to content because it is a Flickable and it fills its parent. Thus, scrolling down in the Flickable will automatically hide the header. This property be set to null to avoid automatic flickable detection, which disables hiding of the header by scrolling in the Flickable. In cases where a flickable should control the header, but it is not automatically detected, the flickable property can be set. */ property Flickable flickable: internal.getFlickableChild(page) /*! \internal */ onActiveChanged: { internal.updateHeaderAndToolbar(); internal.updateActions(); } /*! \internal */ onTitleChanged: internal.updateHeaderAndToolbar() /*! \internal */ onToolsChanged: internal.updateHeaderAndToolbar() /*! \internal */ onPageStackChanged: internal.updateHeaderAndToolbar() /*! \internal */ onFlickableChanged: internal.updateHeaderAndToolbar() /*! Local actions. These actions will be made available outside the application (for example, to HUD) when the Page is active. For actions that are always available when the application is running, use the actions property of \l MainView. \qmlproperty list actions */ property alias actions: actionContext.actions Object { id: internal UnityActions.ActionContext { id: actionContext property var actionManager: page.__propagated && page.__propagated.hasOwnProperty("actionManager") ? page.__propagated.actionManager : null onActionManagerChanged: addLocalContext(actionManager) Component.onCompleted: addLocalContext(actionManager) function addLocalContext(manager) { if (manager) manager.addLocalContext(actionContext); } } function updateActions() { actionContext.active = page.active; } property Header header: page.__propagated && page.__propagated.header ? page.__propagated.header : null property Toolbar toolbar: page.__propagated && page.__propagated.toolbar ? page.__propagated.toolbar : null // Used to position the Page when there is no flickable. // When there is a flickable, the header will automatically position it. property real headerHeight: internal.header && internal.header.visible ? internal.header.height : 0 onHeaderChanged: internal.updateHeaderAndToolbar() onToolbarChanged: internal.updateHeaderAndToolbar() function updateHeaderAndToolbar() { if (page.active) { if (internal.header) { internal.header.title = page.title; internal.header.flickable = page.flickable; } if (tools) { if (tools.hasOwnProperty("pageStack")) tools.pageStack = page.pageStack; } if (internal.toolbar) { internal.toolbar.tools = page.tools; } } } function isVerticalFlickable(object) { if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) { var direction = object.flickableDirection; if ( ((direction === Flickable.AutoFlickDirection) && (object.contentHeight !== object.height) ) || direction === Flickable.VerticalFlick || direction === Flickable.HorizontalAndVerticalFlick) { return true; } } return false; } /*! Return the first flickable child of this page. */ function getFlickableChild(item) { if (item && item.hasOwnProperty("children")) { for (var i=0; i < item.children.length; i++) { var child = item.children[i]; if (internal.isVerticalFlickable(child)) { if (child.anchors.top === page.top || child.anchors.fill === page) { return item.children[i]; } } } } return null; } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/PageStack.qml0000644000015301777760000001435012321005637027417 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "stack.js" as Stack /*! \qmltype PageStack \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief A stack of \l Page items that is used for inter-Page navigation. Pages on the stack can be popped, and new Pages can be pushed. The page on top of the stack is the visible one. PageStack should be used inside a \l MainView in order to automatically add a header and toolbar to control the stack. The PageStack will automatically set the header title to the title of the \l Page that is currently on top of the stack, and the tools of the toolbar to the tools of the \l Page on top of the stack. When more than one Pages are on the stack, the toolbar will automatically feature a back-button that pop the stack when triggered. Pages that are defined inside the PageStack must initially set their visibility to false to avoid the pages occluding the PageStack before they are pushed. When pushing a \l Page, its visibility is automatically updated. Example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: units.gu(48) height: units.gu(60) PageStack { id: pageStack Component.onCompleted: push(page0) Page { id: page0 title: i18n.tr("Root page") visible: false Column { anchors.fill: parent ListItem.Standard { text: i18n.tr("Page one") onClicked: pageStack.push(page1, {color: UbuntuColors.orange}) progression: true } ListItem.Standard { text: i18n.tr("External page") onClicked: pageStack.push(Qt.resolvedUrl("MyCustomPage.qml")) progression: true } } } Page { title: "Rectangle" id: page1 visible: false property alias color: rectangle.color Rectangle { id: rectangle anchors { fill: parent margins: units.gu(5) } } } } } \endqml As shown in the example above, the push() function can take an Item, Component or URL as input. */ PageTreeNode { id: pageStack anchors.fill: parent /*! \internal Please do not use this property any more. \l MainView now has a header property that controls when the header is shown/hidden. */ property bool __showHeader: true QtObject { property alias showHeader: pageStack.__showHeader onShowHeaderChanged: print("__showHeader is deprecated. Do not use it.") } /*! \preliminary The current size of the stack */ //FIXME: would prefer this be readonly, but readonly properties are only bound at //initialisation. Trying to update it in push or pop fails. Not sure how to fix. property int depth: 0 /*! \preliminary The currently active page */ property Item currentPage: null /*! \preliminary Push a page to the stack, and apply the given (optional) properties to the page. The pushed page may be an Item, Component or URL. */ function push(page, properties) { if (internal.stack.size() > 0) internal.stack.top().active = false; internal.stack.push(internal.createWrapper(page, properties)); internal.stack.top().active = true; internal.stackUpdated(); } /*! \preliminary Pop the top item from the stack if the stack size is at least 1. Do not do anything if 0 or 1 items are on the stack. */ function pop() { if (internal.stack.size() < 1) { print("WARNING: Trying to pop an empty PageStack. Ignoring."); return; } internal.stack.top().active = false; if (internal.stack.top().canDestroy) internal.stack.top().destroyObject(); internal.stack.pop(); internal.stackUpdated(); if (internal.stack.size() > 0) internal.stack.top().active = true; } /*! \preliminary Deactivate the active page and clear the stack. */ function clear() { while (internal.stack.size() > 0) { internal.stack.top().active = false; if (internal.stack.top().canDestroy) internal.stack.top().destroyObject(); internal.stack.pop(); } internal.stackUpdated(); } QtObject { id: internal /*! The instance of the stack from javascript */ property var stack: new Stack.Stack() function createWrapper(page, properties) { var wrapperComponent = Qt.createComponent("PageWrapper.qml"); var wrapperObject = wrapperComponent.createObject(pageStack); wrapperObject.reference = page; wrapperObject.pageStack = pageStack; wrapperObject.properties = properties; return wrapperObject; } function stackUpdated() { pageStack.depth =+ stack.size(); if (pageStack.depth > 0) currentPage = stack.top().object; else currentPage = null; } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/0000755000015301777760000000000012321006415026257 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Themes.pro0000644000015301777760000000050712321005637030235 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += Ambiance \ SuruDark \ SuruGradient uri = Ubuntu.Components.Themes installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) qmldir_file.path = $$installPath qmldir_file.files = qmldir qml_files.path = $$installPath qml_files.files = *.qml INSTALLS += qmldir_file qml_files ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/0000755000015301777760000000000012321006415030017 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/artwork/0000755000015301777760000000000012321006415031510 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/artwork/chevron@27.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/artwork/chevron@0000644000015301777760000000306512321005637033210 0ustar pbusernogroup00000000000000PNG  IHDRD}>0tEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp 1IDATxKHQgI[-ZkZ(-ʍJ=D 1ZG"QEH0"AC4]" $3%h!.|?p=W?ύ~ =`4 aeD"IBk{qwIHSJASJq-hE~K5/AR׋H) @ ~dkI/Paǃ>sťӠmZϔ>o\ ѻSzkHj`r@֑Ϙ-uNYmjHi1R"!&ԐL\b;ZR*L?SCәҒRMnfrtjH))&`#Siclq ՐR=!zAbL0zK4Zw,P%}1ZRW%"Pf')x֤AG 69=ު4l -&/^{/9.&eIqQ0qp]sHs̨ݎ=&i7ƬI΋8>[|/4:vhY_W:";*&wh[2wSV̶HK+y&>I@E}2yW %.kHsuG4MU@hH'yFގڒxhϱEwI鎼h/e3Mp8UQmڍB]=T$r's,e/IENDB`ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/parent_theme0000644000015301777760000000004212321005637032416 0ustar pbusernogroup00000000000000Ubuntu.Components.Themes.Ambiance ././@LongLink0000000000000000000000000000016400000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/ListItemOptionSelectorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/ListItemOptionSe0000644000015301777760000000137112321005637033164 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 OptionSelectorStyle { id: suruDarkStyle } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/SuruDark.pro0000644000015301777760000000133112321005637032304 0ustar pbusernogroup00000000000000TEMPLATE = subdirs uri = Ubuntu.Components.Themes.SuruDark installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) PARENT_THEME_FILE = parent_theme QMLDIR_FILE = qmldir QML_FILES = *.qml ARTWORK_FILES += artwork/*.png \ artwork/*.svg \ artwork/*.sci parent_theme_file.path = $$installPath parent_theme_file.files = $$PARENT_THEME_FILE qmldir_file.path = $$installPath qmldir_file.files = $$QMLDIR_FILE qml_files.path = $$installPath qml_files.files = $$QML_FILES artwork_files.path = $$installPath/artwork artwork_files.files = $$ARTWORK_FILES INSTALLS += parent_theme_file qmldir_file qml_files artwork_files OTHER_FILES += $$PARENT_THEME_FILE $$QMLDIR_FILE $$QML_FILES $$ARTWORK_FILES ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/TabBarStyle.qml0000644000015301777760000000143512321005637032716 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 as Ambiance Ambiance.TabBarStyle { indicatorImageSource: "artwork/chevron.png" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/qmldir0000644000015301777760000000005112321005637031233 0ustar pbusernogroup00000000000000module Ubuntu.Components.Themes.SuruDark ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/MainViewStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/MainViewStyle.qm0000644000015301777760000000136312321005637033126 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 MainViewStyle { backgroundSource: "" } ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/OptionSelectorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/OptionSelectorSt0000644000015301777760000000137112321005637033231 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 OptionSelectorStyle { id: suruDarkStyle } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruDark/Palette.qml0000644000015301777760000000241712321005637032141 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes 0.1 Palette { normal: PaletteValues { background: "#221E1C" backgroundText: "#33F3F3E7" base: "#19000000" baseText: "#F3F3E7" foreground: "#888888" foregroundText: "#F3F3E7" overlay: "#F2F2F2" overlayText: "#888888" field: "#19000000" fieldText: "#7F7F7F7F" } selected: PaletteValues { background: "#88D6D6D6" // FIXME: not from design backgroundText: "#F3F3E7" foreground: "#DD4814" foregroundText: "#F3F3E7" field: "#FFFFFF" fieldText: "#888888" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/0000755000015301777760000000000012321006415027756 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TextAreaStyle.qm0000644000015301777760000000414612321005637033065 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 // frame Item { id: visuals // style properties property url iconSource: "artwork/clear.svg" // FIXME: needs type checking in themes to define the proper type to be used // if color type is used, alpha value gets lost property color color: (styledItem.focus || styledItem.highlighted) ? Theme.palette.selected.fieldText : Theme.palette.normal.fieldText /*! Background fill color */ property color backgroundColor: (styledItem.focus || styledItem.highlighted) ? Theme.palette.selected.field : Theme.palette.normal.field property color errorColor: UbuntuColors.orange /*! Spacing between the frame and the text editor area */ property real frameSpacing: units.gu(1) property real overlaySpacing: units.gu(0.5) anchors.fill: parent z: -1 property Component background: UbuntuShape { property bool error: (styledItem.hasOwnProperty("errorHighlight") && styledItem.errorHighlight && !styledItem.acceptableInput) onErrorChanged: (error) ? visuals.errorColor : visuals.backgroundColor; color: visuals.backgroundColor; anchors.fill: parent MouseArea { anchors.fill: parent onPressed: if (!styledItem.activeFocus && styledItem.activeFocusOnPress) styledItem.forceActiveFocus() } } Loader { id: backgroundLoader sourceComponent: background anchors.fill: parent } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DialerStyle.qml0000644000015301777760000000762312321005637032727 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import QtGraphicalEffects 1.0 // FIXME: Replace this once UbuntuShape support for gradients and shading has landed Rectangle { anchors.fill: parent radius: width / 2 antialiasing: true property real offset : units.gu(0.2) gradient: Gradient { GradientStop { position: 0.0; color: "#512F48" } GradientStop { position: 0.25; color: "#583048" } GradientStop { position: 0.5; color: "#653449" } GradientStop { position: 0.75; color: "#6D384A" } GradientStop { position: 1.0; color: "#753B4A" } } // draws the outter shadow/highlight Rectangle { id: sourceOutter anchors { fill: parent; margins: -offset } radius: (width / 2) antialiasing: true gradient: Gradient { GradientStop { position: 0.0; color: "black" } GradientStop { position: 0.5; color: "transparent" } GradientStop { position: 1.0; color: "white" } } } // mask for outer 3D effect Rectangle { id: maskOutter anchors.fill: sourceOutter color: "transparent" radius: (width / 2) antialiasing: true border { width: offset; color: "black" } } // outter effect OpacityMask { anchors.fill: sourceOutter opacity: 0.65 source: ShaderEffectSource { sourceItem: sourceOutter hideSource: true } maskSource: ShaderEffectSource { sourceItem: maskOutter hideSource: true } } // center item // FIXME: Replace this once UbuntuShape support for gradients and shading has landed Rectangle { parent: styledItem.centerItem.parent anchors.fill: parent radius: width / 2; antialiasing: true; gradient: Gradient { GradientStop { position: 0.0; color: "#7A4C68" } GradientStop { position: 0.25; color: "#804563" } GradientStop { position: 0.5; color: "#864660" } GradientStop { position: 0.75; color: "#86465E" } GradientStop { position: 1.0; color: "#964E66" } } // draws the inner highlight / shadow Rectangle { id: sourceInner; anchors { fill: parent; margins: -offset } radius: (width / 2) antialiasing: true gradient: Gradient { GradientStop { position: 0.0; color: "white" } GradientStop { position: 0.5; color: "transparent" } GradientStop { position: 1.0; color: "black" } } } // mask for inner 3D effect Rectangle { id: maskInner color: "transparent" anchors.fill: sourceInner radius: (width / 2) antialiasing: true border { width: offset; color: "black" } } // inner effect OpacityMask { opacity: 0.65 anchors.fill: sourceInner source: ShaderEffectSource { sourceItem: sourceInner hideSource: true } maskSource: ShaderEffectSource { sourceItem: maskInner hideSource: true } } } } ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DialogForegroundStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DialogForeground0000644000015301777760000000161312321005637033141 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: dialogForegroundStyle visible: styledItem.dismissArea.width > units.gu(60) UbuntuShape { id: background anchors.fill: parent color: Qt.rgba(0, 0, 0, 0.7) } } ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ProgressionVisualStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ProgressionVisua0000644000015301777760000000314012321005637033226 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: progressionVisualStyle property url progressionDividerSource: "artwork/progression_divider.png" property url progressionIconSource: "artwork/chevron.png" implicitWidth: progressIcon.width + (styledItem.showSplit ? styledItem.splitMargin + progressionDivider.width : 0) Image { id: progressIcon source: progressionIconSource anchors { verticalCenter: parent.verticalCenter right: parent.right } opacity: enabled ? 1.0 : 0.5 mirror: Qt.application.layoutDirection == Qt.RightToLeft } Image { id: progressionDivider visible: styledItem.showSplit anchors { top: parent.top bottom: parent.bottom right: progressIcon.left rightMargin: styledItem.splitMargin } source: progressionDividerSource opacity: enabled ? 1.0 : 0.5 } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/0000755000015301777760000000000012321006415031447 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_shadow@20.sciubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_s0000644000015301777760000000025512321005637033156 0ustar pbusernogroup00000000000000border.top: 53 border.bottom: 53 border.left: 52 border.right: 52 horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch source: bubble_shadow@20.png ././@LongLink0000000000000000000000000000017700000000000011222 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/PageHeaderBaseDividerBottom@18.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/PageHead0000644000015301777760000000164412321005637033042 0ustar pbusernogroup00000000000000PNG  IHDRetEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp IDATxb@GX_/IENDB`././@LongLink0000000000000000000000000000016700000000000011221 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/progression_divider@18.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/progress0000644000015301777760000000022212321005637033237 0ustar pbusernogroup00000000000000PNG  IHDR3^bKGD pHYs  tIMER-IDATcd``Pc```;&4@,znIENDB`././@LongLink0000000000000000000000000000016400000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/background_paper@27.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/backgrou0000644000015301777760000043676412321005637033220 0ustar pbusernogroup00000000000000PNG  IHDR\rftEXtSoftwareAdobe ImageReadyqe<hiTXtXML:com.adobe.xmp x:"IDATx4$ّfy3}|A7'=2Pٞ#-ʌp7W~iuR)kty-snLw*R9^*tM:S>KR9>RtvO/EZ,&eF~6u*}4iݮg*/Cz/!S7uO_q[j*eٚ+JhE5G|YwR1"rq/霚 _-:;{BsttU[&wT~3zH+(QU:^s#À}o]ϝoy1y:=y'! (h^YM8uyh<Åx˲83tkPGX]#?CaŨx;&20-:E]};8#MX6(8mYI(qKKXἐsA9q*Ј1ouzCj DD'4DkI K/Z5۪Aj!kYpDЏciyX7;ˇ|CP uݨ Q9.֤.W-^WUar|D(\\nB(o#|lP ⡑j.@Gnh$Ql-0:ɽ@;/D-# = )Ŏ ז)XQ&.sΠZJ(= rSZ3ڃZn(ДްxkdGI="z~FБ> x &2uD ϼ7j?ق@c 0$rbwxf幑0Do/٢%ss"YuHJ5 j'ӌw^Ȕ8;IRC֙Nxۂh҃]9cJΖD~>;V8w*ؑޭ Z8 lJ7\C!ĺ̵EY8/9wˈ6R0/lF3e kh sP+`ɧ[` \s9'CC>qM>\rڼ10d&#>7JxpJaX=<009+VΥCc%](CY:eW *6a|ǰmK.gY UMXSЗ)pwQsY;Y'!3-93aG(x^v/\n!9)ω),a͹~6k -1a9B(or<| S6? O|ae%v|Q80X>e0<oA۰5BhTr=a;d!ȯ-z{Bp6l#rPxgų g3(^aeQtc8jD7BKoaلjNpj":i8,(<=y ,*3Ox aK%-;Zi{=-PqF*9gX?pi%BYAɣ1j( P#͋(ǐw@cTg$0l {i,ϙmj!5zΰ<5|ބQxV#B*ʹ1ȕfd/Ў||:fzs[@ݜC*PjMY|>K|>=w!a\w YwpR iQ@$|-mޫ"}1pFKNTǮF( (Xm2n" CzuQDۛ-B9Co5657a桪oQayTJ[ b Y A4  -g-z0(Z}~pgZql(y=s-QbH6KUYҭQӎ"JꧫfW0CZ=|"/ R̥17))Ο7ϋȻR/lpyG yчX}L P2Pqi@Pn"g"Հ1ְM|F4Vw Q)G+!ur(]eU_oW' NDX\ڣx"CE5s݂ÿf[32ZG4`]N vV藈bzW 1) ֆ7L>hqNy)9.ᕡ^iaߥVa=ш>6+g>qǧ%'Q3wýq5콢͢L 㳬b7AJcJɑ7 V;/tKva; XD$`{ JVM\ZײC(9V^޷-l'/oxxd+I讗,8FP#O(5Ji Fm9܅w04h,N~|[`--y*wcض%FXQ`ƀ&D>#UYkwWJoҸUn *9kNNș8yGSD:q3r^!j+O8K8q}at #r7(V἟hQA%Ɣ:m԰oQ[KmOT '/;S~V(nȪ xhcQ ɑϱgWBd#ޅ"ҭ$ 24=T\Lp߄l/+{U3C5EpF+)P`m-cѨo2Q~C/޶hQkm`XTt8ʩ-[PsÛIߺ\xw{"#-k97ƺ;sa<@$URVo(WFEk =BIb'"CaT39: R@Bp ⥺@L|n!N$# 9/; "Pp O2jr6 ڕMKDsӽtOp^KK`# m C,3jQڶϵ񾕕veL51FSXE$1<)ZNzx{#Ex̰TEY:qo9=Zc@SFH\U+\?ʟoZٟ,fQq4?:d<Ի*|R!<, p<4P2(DžeĖR9m//f)]-ÂVVJ0 O$㣈`jQL3#(&&%dFr쁠w<%Jd߭c$0VmC3ӮXkʫ):%ӸX#,g.WȧQuX0b劒w<:#)mi:\eLkIoe-,uE#sP)#(Aak L9|֎{h/_LMH 6 [5(/"w0*p"ҹ)Ÿݑ]z:-}ęj u/ /eSr[Ͻr_ Pv^d7]h*k'#sjݨiӂ,D,{^:@w[ rEF`+P$D8LD Ѕ9Wg>Ϻ^*n_*{wԅ K*m&". u|2zgO]@]]Cͺ Dڐ?Vk346OBcMtA<-Ƥ'HdJrOw乹`[~$:&`hƟ΃QV#!EgNaȺ(W z\ɵan_UBMORn@)PAh^D\>~!\,;q4FVx^Q8Vq;6g4QMP]oAL0ޚ=?'c;Oe,"4 5e'Ű},FHq1 g|Ά('}So $B.0\9Gcv&|_V 𐶆wy {<1+rWc$ .~/^Xȗ`gh]v p&wm(Ywg82ҘMmZdNR :Xq_y.n#z˔EbpDw==&ZAM#uyj1'-ۉ&*d#*f7x=+|'/v " ˖!<#Dhҳ!/BiJZ`boG-l{֫,(P/HD0rq=r Eod>A6D=Oi"S♖Զ|=e¸pU0I/lOx #f lE?jK?!("/K0 tד 1cڅ}g/^ELk+w'B DTQ-ƻ2,\`UhwEA\󩽝TS``; o ER~FJc!њ<䪙`Lu6gp8}AwND}nzEtFkŝX+2!N K%00m/ ҧ|~زЛTvH~ŜK.أ٫褸#FYK/]Xֶi+ܼKg4&ԃyR6=˜MY4RT0C0ֺՒjN9wY{sV73.CcX`H܆·HП*~CF r/B Ua>}{x-C1 `N킅G++x}\"&̿x^qxξu(Ӱ|df!*ȯânBPJu W/*p'a$$D@0Xph2,ݍPPg\w8x`\h[L3POՈj%Zh'D8!BIFuW{NAѻyH3ZL%yDNN wh4"74F'< em~#\/0+:J"m";q稭 n"o{p,J99? Y@n0[/J\>ocNIψHj8c1n\@]Q[)[]M'}!ɉ2ц] cd*$R[EL 8n071hjKxkvN4bm`MGR eyø0 -jN ġ9)yDjGl3 sh<Ƃ;ta;$šs[um˰1xz>RmsXbmn)S+)ȷsҬƙ[p99{yIVeMr /7#F޴\f1P/zw8y"@gb\ιOKD`QQIh4@$ZW&84|aV}>kyZY5]ў@agJ/#+6= %B{ zk_+┳h1v[]g!h&.^AL9sP.@UB,bѱ9$vX( ނPl\ T߄\pvc$PA0ŜTl?sۏEȩbז6hB-*53&:Ka wFu(%0{Z0р1NNZ;PnBxA&49XpVsn4D* ثc !-Uo 3QDH#Aǽ}*~ăB̈́IG^q!NYgv{C8;W=-48v\S"]ph-I`JVN)v.ʎ+8֔1O"$)"xs8>Dҝ +1PTiY,IGs:MP7( ڔE/,)'É 2w=UP =EuQI:EVAe&\XV; 鹶0<ttuO)`qSL]hDZ_#<%Cqg1,B9X&}X(@}{}ЄVæ eb,B8Z^C7n8Xb$^5[L{/_? ;a{õ^b4BӍoaU'sC68s;BojH݋+9)P,4V}Sʁ26'tm-P)䤘5|}2ΎZfb Y[#Yǃ+ "NF?F|Lf`,r1 Tކ^У=R^ xygo9mux̶M?C*h(CLyS,ޥg4֖&BI; 3n4^'-b7F>Ɏlk0#Cdax%ʍMԼ<@*즈? y=PbLkŨri+P\>2Xq7^m>#2639Zy IDdȠ&"YΧ_LWǀ>O/Bʣ!pƉ .Sxg'bb.(sA?hxњuC'97e-F+E| " i| 8-@}(gǃ|~O?C 1u"Fq`uA4VX_V]+޶照-' `K|ZlTxκ U"2 mz J~#e[':Mm@i<(@W8qL i' # ^*P,> zxwtU2 ܩy!jjN0 o`kBp}җh*yZGv,11Z? @j56@>GQA*)& sx_xO۵Gokw}{˛(yw0ș-@Թ>joχ6B1q5ePldYO, ?i;/0tdQ|p/?P-W7ֶg ]"[ zQ;NYsѷ:YnksPqVpT:3hLCX3_ϏeQE~;n{'T`}005 |*^=rfl)VV2 ekzgޞe!UPq!b㹅#腄~7ˁUmMG1B/,x&X; j6eVY0ͶzKDNK gtv+J8CQlخt*͍ s-Qd g)Z{[ܶrע*In Ve(e8*] Ct|:8>v(u4.0$Ȳ Y@l#Hb(Նzl 1U;1o:'SsT (%#-i`!N\߁Z8e)nhzA5z~tkE; ¨,I0S3sW5<6NT|[N[ڞ4=X^e~Ӡ$v@߉q `O?,ȎR/{測 3w4R:% "aZU >]Xbۂy[МY^Z(7t,-%yQI@jHJ[ba@ <'8?Y3/]+rVϘ[!'W-V"w0( ٰh D tÅ|LRo3Q_xq+Qmw6Su):+v/xۄGtr^XPN ÉNvHEV翥㻷 M~y?-MyMe)blqr<ϲBCx[/dԁ!cXWɃ&*dzQ$ό P6]mP[qԵ|:;NYdE{ۖٷ0Ӫ('։Jd j|zR[D;w)#\$ 1z˂ćہ%R3>Wy4ʥcc+&?%m紝 j/ZRAJC4Yqs!~aT\Q٤x@,Ho?*IQ냱/pHF7U}t ب)} Y;fߞsu,>ݹFh kO]{j1aqZΐ<5XItC`WUh'TnpPiNڈ$j]jR_?á 端8V UԺA bOteM5 7!wm,@K$cBk"rrPE::-ӑRN:.e|I~44rbΣB/{ns80 +qM , VfNe'{NVʯ:PtL3U]mpl]锤߽P_c=xڏR:<CVdkWcBv3BY,s̝Y% 4ܢЬp–jt.CT+5X(BG4hvvH iTB(7nz#)<y: Lr1:!& oYUlCtsh)4kg"$({`(Ҫɭq/HYmpsFMsiP:[S:`9##HSc(5^1Ptg1Ȉ%,kb7kJVآ6BI%uuzOط9և:&Ү;P{PQS3<Ȧl-iQBHǏFpF5̟h'P\K.QQ, S<`n6*&'5S=&k9ZHdu" pAeNl\\f6ƹ eO(PSf5EZ>S ;H^P0C{gqSl ` a *,Un(3¶ģ[\qk2`pںJu#`@(ukU^~bazG`+CwQ 1g0B&Iff1kʟ>1ZH4 { g0k(SX8dHeȞa~GYLW30]OAr*P%623UIMR?Gu'N(pD8ih{JqFByu!w#ܗ4oQ J4cHo. ɧ>{G. Xb>@~\al;FN Fw]>CdY.гb,sz>L>0)H8şmr( u<$T? %>'mm;̎J:bAn8+Qcg)cvCPrN5 ,ߑVԂdJ9>)ySzA c(rǟWLjqMPWɳ'dZ7_"ffTg-y끆\mDb$0awWTftJ@YvF[A>mU 0T 2gS->*]4mIvHc \sNIhҠ^kxrzr).b, EA\l#\thyzݹu˥rNC%6D%Ì=?ܝ& ȠBQV&^NeOm08Oؿ@Ww%k {.if7۠/ZeU29S<&1}Fw 9 jn{$ "<YEYDW-+!sr-(Yb~`+9&UX^"A$8%v\%)gjv[PN DE4J%y8*r-cs9 T'-]0њ8 .Pag|<FX,h449$1!'a+OBCX=~ODOF?+ 0EZF\Vo\Q$IKdÝ(B"ևo/UVjQuU(>dieC%\ BJDe}yKwxcWFM bГ;\8pK~fB-gy1858U7+O(5.%~̑?y'5]w2jMf((X;zs0# I A4GvM4w8f'/(Ib{o(Cgl 6ŊM]򉳒w;3r vŊ\}5h]cSu訳Xd[#R?Q&FbT(nZ09q.[sX~!DUDgX?k4{V a|FL8 u,hb] 16:]: cD8z \1K8) Ii!/`cE"|%b[2gNH"q2lT_]t߳%"#!u3kxt1K!hXZIqQl䯸OW?,^.Nk<[ǘ 1 K"EQpUve֬\f.<&$4"\ Bz3qzdz|1=$я:MJk.mM{9`x 1%X&C ?:+ő <;+Y+f/ZgXhTvm16:z!f!I|aUBc5VױM."喫YՅ[-YlNe߁w*E.h&w1hKO6g"zϺק0F/x/w9c?qVK`#>"ۖ\v5D"[i v}2ћk,ҴHz#1 xC&WM=\t׀gœ.X`BAhߍWT77sv$ xch8c긬C׷Ს-;O___c@Olڒ ٔp0GvmeJs_xˉFDTSta NBc&\'}D>.~A9$+q'"[p3Bs YXq❨7$eL))ëw:C5e\2Ǝ]kGv>gh8lރuMU:bt1YzYZ8`1H0͖0n=9)--]Ξ7hJgSM`o1U.ΞgrD +RIC9~FavF H޼Ӛd* 1ҁ*BXח rҽ}lqjb:g5gTE(b1 u q5Φ ÑHXS_ϭ9?h ɯyˠC4d"kF9/{$# aiococ`WTQ89p_Q\-N~@ 9QsSKNQgEyrр"dLxbHG3w&$[ӍK٘(c:5aeDW|n*sp|8,]Χy q)=J Rp勥vD9o7nߒ;;(_Rf!eÑ4&Z0.;Pt">(s>~_ad]m㖬{q*N8||{RI*o WYv+};pE?\Y_xW$ӰtEZo1#zvߡSqZҞfY}] !jl3 mFMZgZ1x0r#J 9.!A೼R w!"akaB,MD ܎)B7#wrlqK0q}>#GlNf4igG3x{]#&0A8yF.;,j"w3yu+Tf|ZE |?!1z=e3. P}gQoCEj"].m(W7uWL agVŮ"d_RFWY#\C)s۝TQpZUiԼI@*kQrP#;"kʐ,N~ՆҼjDU.4HŨE+s3RA}tn9KS2O943c=x)[:g][ rne-b L<#s DžvRX'n:yt4G,uPHK˅0ֺCBܣ Zrvhؽ~ h@6(>2;[b4i$H N ㌋??.zsDX/GxIu1tSJC^?RjWa @k8F]mM;_Y[B()Va݂af^!2Qጉ/r0bUms 軸]~HNE@.)ZW95wpLȒ]3M֢GJR`$9mJ4e8|p=Z |^HO~cUb*JYVdzM<.wf3<O<>\C5\nr.|!V]$ܹj#EgaTWI祡(lVvOJao1/#eA/讟cY5alpuD(uJP1sDI*tnst4l*~!tdP&6*_Ne_ew=>_@Zv?b(R|爻Qͱ^mE3u<'X'hBu+eҘ۱D)R4v%Fs3z6v~A/9?v5D5Wy,%ب4Fm_?3pVƢh(|Xd\0`j>@e|ET?g%{grŀ^=bQxRS7b< _?T az9+BJ@4fQ1$A̷dx7P*D <Yh\A-΁y;g-*E49۰wbLRHiH`jq#YA,gWjwct *˞vW)p[ݏ] >?)6q;uVޭm* 9ŧj#ҤE^Ĺ\#@$ 6*3 jWs0lPXy-%}J;2M܏G0\yΨm܂"ˆV ?'E(<6]/d\= ;%<ۤޡb$!"564S%zJȄd{_OZt=vOTB(grz5<3R|ʴo_"_92Gw5~s Pv)"~,c9D^ :agb$6!÷t"˛Y6ܱpn\Vbdy ]Υ8%-,>))}AK"^tg䟒S~Yzo!VyMXop F mb\gݛyHDmP 'hZ1 S7aYN jGOgTO0k!z??㎥:ܤ2i!f ح00i$P =A C$ɜش: X8ӤYӻ֪:7 QddiZN}eBL>6ݖ;bݶW#ѰQt|3O"Lk<1.DCRY-l"_R6;e=DߍލFqUO۱ZWp!p%h/Ck{<+$u:=aL=Xw[([rڼ,\渹E3%E|$o}MV>ֵsYF?;Mˆc"E؟K&" JC5=X{hJ\S[@f4bJ "WtL!4IP[سV0 e*V4 9*!n­RBEPVȦrcIJ-3 rfC^![dv)E^578 "X{HZshf*[$xtnDPƨ:fI>;!D֫TJl[)#vESS"pUme^JjbZb.yHƑږQS|-UeW8N&tjԬHwŗGO}oPڨ5XZbA"y\PJ?XU6=Cc><G(j, .n3L0,h:j`F,z3B>V{eaX^l8aT["K(8.??w{kSF RMZnVĨu `yz1&/ ()b Yw龘r]47^HI!˳j!>ѝi:RZhb[~Rrsg @5d7K9t`=jK",E-;thE'JY?hSUU%V(4 ːh oVsu6=GRk.fDbG/=MޓzLQ9Q(*2D$ UX3VjUAi*oqNZ}9Vf6C>|`*a XW`;n-*m6K*<5!RjFp-^oX"e~`qT0^Cd`~uzYkQaɇ/,j3e\+ Z8@zү"(j/LGXj=ZOZe()i=XL\Șq 1r9 SW*^m=aTciӓA|#^2)JFŐ!l)EYlD.²i 诱`RAl:ǢF  TL%;*e`5?Y<饌{5tfl@7FFu R/zyZj\BeXR2ws(E} ;Q&Rt֬;T& 1pt^Nȅv%6K}|me 6zv#у_a(ʸ #2? g_k;6[MMV>8E`6VxHP{(oE+ƮИ^:.#(:fCGAy* Pԥk ".خQj=uiѭdם?@HMWTkvUap+Ɔ-50mKÆGAOb-Dsg*P<PO,(Av%bi^ GY?ckOzEKBjs̢;tFr`G7Hx!EE+Аg@pIUx aRpY9<3nhdM[gZ}WU +EԊ=둆G,*=Fb$E 3K֞[g%݋-!4b=$,;1gFupz0ř5lKPӆn@)zN킠*lf,d*.IjJueu{E %իٵ7#zA{oD>?67~u!L,◀GGG wASpfA!<ǝ>pO pҮsۃ@E%PJUƙy,.W~O,2 jS6p [Xڧ &b؉'n/T.:V.n*e`!,#].*A>>fAmPֆ9bٶ 8 lŸ^= ށ P]"UT~x_EZφ٩ݘyx`sQBR&_Jυ\+7`=e'mU: ƞ;Pt7a=Z ;0;.ׇ'!/MfD ģه|! 61hXa[YƂ&J+)k2n1ݒSUQ6v39ȳ fty(=eX .EO~#`~{CQaF6]|uFi]HZalZf|ZAhjI6F`B/  $ 6 ɗ:|AanXS5w۟TpF*ӼF u(|atlHo*3V%5z55~xq/=X!>CyCvg='9.%V\Tn< K!%}~brXE/\u@u\CT ,D"Ί}#j'b ;0EX8AU [J5yOj1NT?<(4y]hԷYrًmU,bbO<xwÏO TnؠUڤ3Ь8K*4> VLII~9ݮ1]}M>8j䋑78D(7ySFHVЃjht6pu{Dq B"- ,gdo,ώ$";I#L\HG=iP!Y?G IV'=.1hzd)h0}v_}.@Vc:/Zzr`/gK֫7Wzp@+Zu^, C bXB ;)h]VYyiJRζZ}m0+pgȲqeW{ ye0:B*IX0UЧvLPBWS<|JVW@EF{AYBw=}qsUFd`؍}02x6fKP"`Kx\F3.7Of RϾ1 oW%lev_67!cpL>!ˉ3<+03pmh۳-g2Ph[> [4RQoT&\ " ԾL@)IOepl>W>KO:oIS**>+TٯV te}iCP;+*gیbLSќK([@WL?ӷ7|4CsUag2F\C1"S!QG c^u0@swWᘕt kFƎH/s!$#tXVFƴצ3(=z+e gpسvYwbOܷ.M?g*(DR<`UmOFP$ 0 Z)B.ZYE=FPcE9&\8BXE\~8Uzw#̋(O7E:=% |&=3^"(SA0%bDƅ)8o%1~v(u8$@7UlX9 w׬k1E5k;>J"C+ĈdG0{פߗB`% 揃Ejm!=32rZ3 ሙSs3nM3p1aa6{O{[hpZjdަa>coj,Dǡۢz)A%M%:5#;Byj$CBM1ۡG,\ #33G[ؗ!nay˚b(=0(0 -̮wԴo`9ŚP>۱1ɦnM4DXGhR&`y~!dxm슃)2ErAfIz=x [NPƮݰc5!4@E^\-$rPcҋ8E R%)y0Ӏ92;;Q@,I"v]f*"zX%B?|N  j-.K X Cٱ uǥt $Z0BiEE@R-޻*FgϓrèY}4v VU7c:3j=a]km*٤d3UASsw`,!q/GXC%.]'[cZ،;􈕁* nϺfנ!5NaXm 8P4nC7/zZ(S2-9ּ`I^x.Aͺc`O/LCuf/;fȓ`} uew!քK 3TuLR˾ǜ݀ngkg}10Zj ذK:m5w/H :KQX+bQoyPdo Rਲʊ#U[m$SWajс.3?`h0)8Eו?+GDO!hӥz{݆3WUcb > 9{O Z{ɗYwFj2Ŷ0jyeSgv Ap=,vmI*g?yNTnY86 +N~ܢd'C?iO\" 7*~~. Xֳ=2xy9%y1ȡK?(CآGY:g.i%kT(h%T\M^*-!S1Tp-u|7f76Q=<5> îJD-2 ~V8V'&0A/Lv}\#ܠT&5 ֏ JES)PmVYMi6.ip?>njN$zk6!R)?  [6amR+w+vo#MU(Y4$m2pdv'LXx&t#gUjiކRNTqR*0~y^7vh ZA/҈={`O,x N nN[l"!WB+ h_V8¶JkO)J<]QU?4n{52t~l{$[H0rw = |InSxOWgSTK =N PЗ~fT+{oa6@NMkt"Pe4kVL~{8]VrF^yS! E-|m_mK[SyΚ 9" e^jaK|Yv>TL뀌?6rXo}GJ\T̺tKȟpY ?K:zXP ɇJ?/\0 V>Op*9"?opsbfj(]7rd1=cq{`x9l}_UF _ՎOm`]mp[(߫[&$Rp$ϚEev!'꼈̅Ҝj~,7`zLTG_Xn&"[n@E(8$6HI)E7 c>3-Gi'Sn)Մl(8wΊG# ^7$ Sh6 @J14C1u(;-& dYɃBP\iF|HuXWR_z)p!~+k|u=^ָ}Y=KXHܠ[Ɠ4I!Wóp"WV\u.\Dsrqc| %3Iϭy(6VƀhdbFD%j߀&@QD! &Ĵ} bswϗIPfn6d@|Bѯ, ӭ>^[@1!ŕl,a3OCY1\hR"d3sKʀMV#V.UjUm<$ݎCJU&)]d,ˡ?!fmn}UZ B7a퍚OLƱ _PLFHW#(>TrL_V,epBc?*[Z<Kes.5[UwwcVgMPQ;́DQEocf! /UdiOPFUV[ A( Be$%bsP8cV)c^@?!jq]Dod=wlƺ=+ mI4Dɜkw^,"^ ,j9nUfTuڬt/˙Q`XI0RH5(`.Ɍ$g1PbhCVXh'<=PY6DhL ;zma: =@,__޵G}e|g@䡦yo|Q v^]q@«̆L*Xpȃ#)| 34[`?Z޻쭧\ף\eؾYL޸[a?v0Ф{N>M ;<@Ȟ)@4șEH@(AU4^y9B tDȊ2QƆG]U\ϟR?"`*p3SԨRtې|XlhC bBgc=zz ]pN䪐?+KoR! 0&B-B{Y+r2wAk=YQPiӐC]-ul1 p0T{8ϖNVnsKpe1Uw3 ֺg }1N1ELG ->@]"arbD~ȉ[0j;hTY|'iJw/f)-J oe.Ul;`CթَC~~T@$ѣ pSsG|\r2dB6,T$x4w2- V-0Dc_L7]ˤ$x-j[,mjCֻ;{:~Rދ D=УƑ 76:%J騨6ܰ&h? CDԨ֋³ tVײI[]<4 2Tf,Y=XW8 xɮ>獞RΊq @ ­l ajwżbEt]oT㼘 )cxSM$mY Bh~[oqbͳ`EASꇒ@x{CLf˟JL]k7kts@/;ndɶd3ZYҀkm-VЕEB0n:SmYuÓB;cDWmk3 Ņp "QDlbag[<5mӁ܍~iա7Cc c鰙FR \{x@`AwYluk6; P  U.D=)"gD5`1* hl<> )N?FⵖN0@&%JˬSr K Zt NMhP-=;yRLg#?CQIHdskmc~#u)8٨(uQ;YWuWXba(9 iE)jSg" : $-, n<!Tq4Mzm0ZggYYR`8)clPO[AeD賨g#R|yH:XTls K&1ς嫊PeN % yY s3o2 Ёe(M/&z%+ё~>zJp]Nm - qs{d?vRHCKV%:s)@*&iF 2 +e튡~MX,rJ9?g~< =5VUR`T pȰz? v䤞~2̰اg"Т(>^{d䣊_EwMX=XGĸ5=.oۻd|]oGKUf} .s#K\ΡY%4qWUYH+xuPϙU seuhhobaxeZu}IGe~=lŻ'pf7Z]  xx7v)MY% Mꟹ":j9^n~gj nL23oKn56bXn<1ŢeRci'$C0hSZ̢jad)zǙh塲 =rPi 2 ;#%*SnU(NjdLETY;kLe1aBfȩL-.KUFE2ʨ dM%ߨLLf LMUA+ 3ϝ[ ❍~7 ?у@"cFxA̋VuEY<wV2L*3#X X֘zc4۟Oa©E5Z:H_ ?wZ 0vHy2Zգsӕ˦dnd+KӼ7Ò RݶJ%bgKF@}Hr/e 3Va.lH|/第q6O`ljPuTymT5hg@L]C|8<; uыwׅMw%-`zu"UwyƨQ0}7ÌAjvUtc)]PO_2Wlő;Ca,2tmtV:ÎIM%1:x)":>ꆭˠw!g}F/Ld}TK5Y/+_lV޸g T\BDƀUF٭]`(rn8.zz@hL^2}clzU2 'H0o$uY Rz$zm/SpHcvhN&m6+NV(݈GUh$/. dD I&(" 1roed(ڎ9~9Q(>@C4Q g2 Ybfm%@X8DƺHva%<`YCJhԣЏbez$ȑwg2>6\ 7d8?dٺgu- c{n:ؾԴ{ަt#d}c5!zl;(~ >=/HFPmW0w/$W! ̽ڨqgiMdő#CG7X> >zvQniQ¦˯%R眧MTbnח~L~v|k<'yr 6 "^׿W"%F<dl洹D7^jf5˵66xSy XanI. F E&##aU TQa " ٌ߉,Tͽz]fф2E ZrkJ(edDJ"hV?y Sf^W~ps h)Y`-.+Ƌ<9F9 O4OF^HK#DJ=YC!U>qL@43fhHڍ SlV!q ~OT}k֯نPcJ 혁V}l]y0W.:;n{zS= f`J̶[[YR}x:(%¥w[ EaXBl " D"(GVvBjQ]YXtb }W X@63 YQܥ` ]蠲eMHq)X K+00Cc%8$Ur+EuWa,P_P4--[-L߿b:{psc2L PŬJ:FC42Ì3QƤ1}.30 9:WX*ԫ<_|6Xsȕ`$^Ϩ@|y3 ҎkJ1Ce71TD9A&Ҏ= Uq ɪrBC EZ ,m]L 41CkʲT ‚À8hƮ-Y=`*T ͭ,. '~@fAEIր -^M%ҀN!a`hDKesE*CY8*\R6<-]ŝϧ5Ə4+pXyjs`;P˞,PQ:0-~u4Y&"~aNZV`r1!%T ҒVqk6 Keq㧵[z;O 7j @PgXٷ9y!b3ͫ䡯m%C; 42 72{5`x1Ե}0T=lF d-* }7sHFeҳ@Yjtp»1JIYFcU{6{l(jLV!BU齏ճ[a7߈Sn&C;* hl6o(1cpAEf z#i4\A6l~@RS 2_qpW9xNҥ qa {[[| bI[06-vqPbJ3>PaͤȾ>)FN={PfPBT0vaIL黵P O7r{!Z+vzL}xEgBAl:{cuT-vZ^/pO6bt {$f33Oq* D" " |i! al8,Bڠ$/!iwo]z+ NF`! og{PڐpeK.lIm!i耎"6T t pB_S+H=LZaT| 5KswZ-^aea%_<0D'Y2{=<$XU&t%ATYQI䭞2a|1& Q ]&1h eƅ5-;+އg?-4ķA>YzG{3BJcFZ'[ٰP_OL;:t%mKζ#249ͼc=aꠗQVߔ yY/ vŤU%W>RoC20Z'ΐ;6\gK[FȫYbP@n];jg^1b &@PB{oOysծՈ|G|'FPMb}`&Hi[C9%#j 'xAB'yݷggtt&=sVdl>h~8]nܴ瓬tܓIU3>Ct0 BQ'dg;Ȑ7e{;jaEl7ňډ;%ߢy f;zO`у HQ$KʵessTz +!ugm=DTl[ޗ a}@IȈۯCCW;qo=#FEP^&YDo 2]T)ѓ&`w |ڐb)1UTJʥN%\qV"er| > UU ;h GXmkwu''h6˦Y@fV,:p;A.f 'c6 1-!$WpC'jYi Q0)y*+ҵe8\> $QK%iu b[./܅5{֭֟Ń ~ i)mDž FE}<38ʕW/(e(_BVw\-fWx簘j(~d`. =CP@oArv_pVؽ_TnhhiQQS~zN7e>ʥM=i +htѳ\Y׬*!(6Η =Q\2<%6s/Tʶ0b|3G؎**8|:j x@V>" /A! F*IVa+W"sn'ʤ@&-2wlK/]B]Z CT+ce:{'-5òѥgu`:lC.=fy) Jay+gOش_2~.<_]0*&e6Oty!q\yƖ6X/u62)ZoGsYt_M+07ӳYy϶#loA ݻUۄ* AZ;4y\wN3U_`.3Z;2,z=%W5ךZ\ C`w*8[+)h~JZqQFb= &4OmeCQYyJJ9ze9М6Y~5iaZZp̾sƠu;46kJ[Vzo&x`s`z_6mVSY .$r< hD^2G@m @B^5km%#8t(̕_:0 }VЩżF૛(^:Pz(oLƟn]MѮ, hf&fޕhE-!#]92k0x]2=2ٵ9I) .̉)ospL3c[Ee޴9O/љ˪㠫ؕ'6 )W ]*E'͗{f\A1ayKΜZTikفdm[wA7>=Yf wZU*Ue HSAF|tg\ 4z#( 7vaK>v=== )ȅo߰{'^.}ZjA?AUCz79@yDl76gN+g6auA5#e!i"DPTV;d^?: RcJP-JZJg!ʍ8 ]wA}5eN.mǾLY'>C[)ǣ }&.^sfԆT}!+"5Ve 0qd PlN֮@^{3DJ}6y*F w\=,y~Y|WYWdrkvU6Dt`?Vpшaj Bwf=񀩃z<{[`efibw%lHJz*ckˎZ$} 0, 0vmA8YҞq΋p0YyytD4mKY!Xq#*?#fJS Gi: /CiGѰDbHY US\,~CfE[ư`׎*~_ $gF)fA8s3s^FE/ <˂P)=,Ck3b[앭{ 7^ Kd>[0` P}xQIptbY[^@ezd ݓ ݺW`mQo4#ey2hC V8N q]8ʂLD Dg8#< -vquUoIu o̶d(s!th.d C1߈M> Auiˈ>rdud"Ɇ5:s/eUă[e-ct:ZemJMAΌo\ysV7wo)<&[ul&*kxp=:9ZCdloNxwL9\ȼӷ3/Ok@r|U!X1[5m`V}\rv+zh%0x*xZo,+^حWnz [c,f!3^ ~;2ZYR1TpqBD >PNA e wm "_aiTU|,Q既!idLz+=Ki\oV\}W,<[kӯM@{gƌ(Nz'Y~nMH_qWYA8AoCzx"]}6VEg0 5B ig2D@:{^6XJ>k72ZRP$!fJxWPZnšcsV ʩ .YԞdi1T <(BÌh=yfDY%U dT! ;V2u7Za(R6ݥ-6N٦=ݿ͖otm/ +vP6 ŋMF dw_MVHdEå=%' *({N\d&,&6`dDL5eaP,^uv<0A S*K[5,{ƒk]q B+tIVu,@{Lcov/j.9 z@n:` q ^z [VL oerL#7(>\(KdMߕ J۬j5W})8bR F2G §ulمxG#9@hn3 f4*ܵTь[6a.ٜ`Fqߊu50;KGulUY*2dX <^" Ky.Aۜ'B~$zpAso܁Bm7U:8e},|zT K/uĚ:lպPk8, ^kJ!Y !;βGY^|Xp(l *Vi!waK æJ\H?n;JfTOyͻ8׈ZZ sI (YpJ" AםgW̳D}g{RJ2w 84 A2D~fPyxǖ+K!NQbG:R WԣThG تǐP`^<3ǝ^+V1saV4 HV҅EQpEbMɝ z /J:^ "x h^r֫~c`ł!().WaA&Ƈ.qؽS6ڌBllIA*4"Jgq.ͮlsԦBD#Ao(-}[FJ[9N7X=2Bw,1nW$A7R o}\`P0@}'d!3ATL;r<+pqt~)ƘӐg}H6*S Ke>i]bmʠ=֥x` w ^9/tP&3y aF0Lw-XoB$]7MMd9 N2ng3Ql00Rs8jq'8#u t "+]T2BuK*z;UH>5 Xhn&{Zt9_Q;jHʘT>U_BTUeik(P[Q/VP9@Y貴H֥UYE⃁EYYoL1Lt_&\^^V։7b $8?gQ=]^\zeXk\-cF;+ 2ԛ xPk*L9dX«8Mt-xbH)OIJS.sd3 fpbRuQ NA3X1\{@h-6a0:3E70H2b@5zuiB53+gNȟ yӂ 9Z&MY{8 -8Jkv'=W#z=^ BbHffXwE>$VmA sAQo,=I lod~QܸP Ea zMm J.v5HEoWL&e5S`)`*jKy@ٟC0*$^ QxEk̍eqj wĚWWsmd1dE#SSQq УD![6WgNp!l ^&$3#K_:l$cͼmdv>*;ޔUmFX\"! LgC? 5f} EYҔIeyN>X6n`+I{UUJ-|<4;ݭWԜ++H1ZT^ S[\a!Xf!r6>j5ے4ht^ fP@'bK+.$ .L>ZoST) 8vi3f#nkDz\li$Q@|{>բŖop#$eVu~!s 5< >WJWG>8}$@xXx%m2pDYr7 `ҵy`ʊ ~d{@p=w6(3ڕSV2ruYTD%a vF@}Ie;F1C >sD!f pkZ񕟡Je x|sҥ!Cp_N }4઒-h(AW,k5*(lK=~X~bKse$h.4킩7]UrFMsPG  o#@*]n<ß/U]R)B6>:\5"N# (+䱼Gqv !j&hy:O6\6q(1E3(OA"0}63`IrK\@TW&eM0AA DG% K3"hcI &q֕0q1-_VJSqVw{MGea==ixJZS%{_\.J3טCX> l=f+⾣;M&Bko]C< 4H^miX.J 3!Vñ/[K,΢f%R-j ZblXY,oyZ%xW Vf&k ߚ3DI7K49@]zbsARn{AbYg39 {-l{H|p?M_Qb[ѣGbBJ_YA "Da30eڠÎ" I:Y~[Q.CƢ`>}=2Шں%qd>\a?/w6N?DKr;W,$Ro@nϙ9U@Ŀ vC>lР^퐝?>tسыٽ y=rYfSAyY{p1Xd7D $2l`&*+O2v4WCEd JB entS,0 ZXf HIOSR;ޠ".s(WL)9 SM#QP"9%O[yʍU- }RMI4Räy[xAFn ~WpGY| T|VA{mOh }TV>Bnި]Z'XCROfH==߅ ~Ü,jӛ:kWw atgS7 7 #j.$+{f>pyJEadt* I؛WqZ1APG %(HhA[z K'wJy=͈ "vДD|sYcLl$6E={\|VBlWft5 1 ?oʘF'^s I$rG7j7֧+" ~T6 ƕnMV5Q%\5+#qPN."Pe]D;@a?ːgI3袲#*5׸y?0 sed/i*}eSo?'6Ct Y [m+ mÎg=߆qz*OylC~Zua׭zȃw]BKm}qe9Ne=;dfl錗,d*j_0&ژ}2h;6E_};}y#N49yڳeh7D]aD2ߤI:8t`Ng犩0 -0sX2w\6eyaͻVҙ`\bbg/CڳT3$<ywʫGZ>oĵu& $j,3K&%PɃ,n @Xo SU5\@цoWCqw}mLբ0\UHT"4E,25_~S$81'Ұݚ.WY$`xoxqnմl}ɑb0lRL[GE| u]da,`(*d_vfuHX/2#LB/D,ӋC؂}t#;1dfQҮVK} zhB#ɐյ<9鿍3XMV٪.Լ heu~ ׸^uzf/2w ?\l"ӭ3)S_.deDRN 83gm4SA-Bh-A}3դ͢/쳮lG}l7K\a%Fg>Ppϐ>AuG]%fIAKg!&lԅ -@`j`<%An\R $ՕD$ɬKf*fy5<.NzW@l㍼Ω~o=nɃ Uכ~ Oe` wPa&^(F2jFؘ_'0+V_n-_͑ Wrp"Lc6 880ܮr/ PzvCA0١JphWjN@[T4dMr$ypYch,$B{ʤCrF iVvۊDQU^XM\EwUu({ui+]pϘZjp7spvݳE`nתJ|lҸ(UF*lm4#WLqzVPgsQ곡. ;7**qqT#W]~yaIڬ:* 9e?ۿY8ؤš͑:#S^{;[Y|{dd?wl!3(Vز,6H8@Q\n|-D!=۝AVEP=\ƽ ڳ2gv-0{RAqGQx(`oPTm'սE=,M9˞KP+`<`Bތ~ +B-"G yU{6c2}ҟ7q7qWJ""x&l>ŝ*ѶlVhaUmL 6Wqޠ`U{9(!IV^3%2>$1XEGwo tΣWe0a|pT1ec'= Wn??_]u.ffJKҥTP 3lʫB(DBV2d$dn86ԔL5w"b(/I0" ,6l0KuXTd)Vnú$̿>& w|7=i\((S=r]Vbc4u^ypC'/YKH./:2VY`l^tPD$!<U Af`6DE8le=0b5pb[._Nnk3bU2d!&|,AcZdҊLsfx΅׋a~1`7[ahԶ7mQ^;ŸsW&ii1Z4@GTHs C08 OPZ=UGrSУIQ=9uVI&1ڭQF'm?~5c/T*Vg{!WV+{Ti0cώLs]zx@|ofC R?x8nAKCq~YfҟUP8$m;C.0ń g.:Ug%!eƏz}YK9!z^dq,&۫Z `Q0،B׃Y}b` b2 F[{X@\yh>vԷT]q `!<^DtKcAQ]1o` e`^>x8 47 5802yf[yb3٣EX&Sهvf"`<&y2%HN2KڱKPҙT>x.O5,72.:چw0[dp2ѐ2l4_.,ɮCjYBB{~qb& +sM^,ZDƻǝVMv)W L0gwgӓsGPvfw%& [,7J:nNv(р 󧀱ѯ1qKђcgw۰TX杽qh`)!zc`bm;0Kťo'Z.+dޏWg8+Y< x=t} nzEuE3lX&PZzZUU6@(4f(c-d'VP3`pOE?Lm& `+<3_Ys 9oqbbFbԳN ո<᭤1[-ԍZ OPnP3kX`Fs'iSr*S 2\D7rlY5At:v}k4Sg#f@ V!⤛ kV;UBĦ _Qa68 i¬!4ef%E"`2ڿ<)HKJWitb;q2eIuFf2l  -1 4f ~!M䯷ޢ'-LzpXED &J ub}:0ȄsolK=Բ fT@;rΦp%8îj2IoG\}Qы()G2U\+ܷ ymtU(D0=/{>v?:-a>)c oH/^TX'Q~VA \6ꙁq` Oӝ}ﶈ*z=eԹtMyFU:x+01:Ax`-(J`{}hY/@4ɛ?Z.ݳz'X"XdRNdeuIV: p+0Ħ )TX&3нE4 \VJ^捐*%I0itӡFel>12 ˠN turջzS\lUR. S @i_LQYy$`4n|d[Bx=BQRA@cۅ~U .)sY^PuYu3'j g!uXlGgf+ {T aOJܜoXnL2d:r+"0jCƔ$W+ y,Fj̤=*,:-alԻg y٧10T9VѬ@q;\YC K;0J:[t!zU1y+q04%lh ${Qzt-Al_r،$!YȝWҟ>'4Eey襍O|ڋ,þYoOW S/mtəр PG0sJ>d+B%pe0(zv_An"OyB-~ڒ lLJzR/pH#\h>AL`] Ck8@&BYJ)K垇wybr[ro:ekMżP ym@q'Gl'QAj(9ZTYrA1Y2w g5voLH=EMbNB6!Ut)n smQ+(ewvVkuh++ӌ M}$NYj30 +k( 3LcU*IFϽaaIu+?a3 : AS3Q `T_afO%jv €AX`?tPU2, k*ܖp.8:^`rҥ=L Ɔ-; ŷlstooX x3lɑ7ƤVgve>&tA 5Mp7&iJ45' kկOƾ ꧱FjցlEGZ1k˥6TAP:6moZqE6^qKFWv6}CV;]dM ;}@r ا{z?C~|c(E^h^Pli5H>T9j*_]` ,O"`)Os(4,?^j[2M XɃ!VnnZ/e`b[)Is J2 jC %z{hWxD3 |u޷ ߻ {CҖPD YJI])eEkY`R@cTնJG["Ϳ#12UG^[&^;#\F. =}7j:HjOc_ yWZٟuPMO/ST& %С(d\L5J>S)B2Пу\t%B-iyOOUuC>ȯl?,Ly{^=A <}3PX,gVEz=3p^GX0gK5q3*‹#HWdϤ ?a {)z}@t_GI-rZ0AKdH!}`9 U0p(a|^ K@/&dRV(h*ܵ1f\\ZSC%9])&"]oelo|D-gή`O,38+v1!]rg ,@-dM%W}сEICm" eZ0_\q:CE~'s 2q/?LVQbBa(rq{5kQqAb;fU9L)w4*[mAf')*L:3zX]dldm/GF`x꽞Hן?'PL]eVNSGl )c2?yP\|j- aȪ4[rԿnlK>ްa221a AkuHdfKD WUSL[߯15yZ+pQbPIܻ7!; k}:-=Qq&:zГ^$K4]@[y /ko|-[ |ֈ8}Qe,'̗{1#`{rhdV9mLUYg,H?W0S.Y:0UL? Qgj m4d~E7X̃"Й^C7,E Kh 1a愤T!$Sp0O>`7xr )`i7D#LbRb 'AVV4e d!Q `;nRo,M[ bPh.t-&=kOZ` 4Xo| z [mtgC9$XVq{'m  dZد< 5b{:6$ QK_;~,b.G*Ec3ŮGmD Ee$tY9 it\ z\CF &] q: 6Rbp2e=D9>;V| ICSyK ƁV΢j?؀> NeCoi6-W)ϭ=_x}5:O%E_i Xe!PgS{asZ-ژYm#3d堖VuuL-9]Dߋ7rg+<b2%ҷŀ؇lRzdgf,aXљ).z7&Q.`Cܠ paQ:3#i gbݦW4xY!,ȁ8$!8Ty.xbb)Q5@ ò6&D]u1Fm79:|ܕᴰ޺=~ty7\]c{B^-^]83>2ua_PhoA/WLXkᴼbISd{g O"Q%{^uZ 0T4cs.l:d"@A qn$-Ԭnc?Rq֚Xh y؂']i3T@`;5xJT{zw^R-Ui~}`kmou+YdlLTUY]E֤8lWL H̩-@pzz>*rX3Qfp1׻8O,ԃ@TcCE)$_AWoQ !hhPiLlv0V)0@ rta{Tgq[QkF8w2)f'x#:Q29#}N--upLf쐑JيA/L#)F13Z#4g2@1@¦Ak#%#p?OxbΠ6@<bX Ǟ}:hhxZD!yx>h%deD?>zK,#ϼd`@8(`*R51>k6H<G +U !ALq#vӑ}Ya{Ia.(w}0l[AifTbx+0$d~v\hp :>̕2C + sںu|ecԂIwk{&@t@3:+TPFw9DXkLQZgs[W:03z$CevE ._ǤTi; _ȇ м1,sil;SŖ m= Xq7 K0f>숊8o!=>{bwm[i?+J^]tl0oX_6 "@S{pzPGW٬p⩤؍C3D),0dXQغUbT/He1{=]!£K}5 ~_!cfK=F! uvt!Pc(v%;d 5`14]P}9*[%q]} nEŀ*/.&WZ0z=>^Gxd(Ix㡈kSI,0ߦE[Arƫr@eK̥zœ9pHpEˑ JIB+.ͩ@.`>j={*xz\{m.?7=h< odcV,ژa4o~YNnd lYg6k0…ƪjB\+=p?]F㡠J=Pm׀zQ'p!Uyqp!C_h,7$FL՟fJ88Xv.7uٍ;,9U;q#iaOo+Sxl7q\ p`ZyYCլW:6z?3at3*Ld~9\`JVv[`W Z㫠}2d (hh|g(6} eZK!IrqR2Aw,B|2۟X7O4trؚCMt#@=SX1"@+:W% 82C4Mbqk0D8DI@W:D_UqJK<%ڱ F^tA#!*#Ԟ>oN nAJCj7^6H[G_UgKW`p OJ@g,I"jGf3xiWBW[huoϢa wFCAnw.{K3'%?]S} VDnY.~F!o*6WTEsLW& gq%`骃+-q\n1#{}5d-A}!Z>e\^vB+N@,Lzk@&林\KQ>]l>J2}{;wyV B˰EX`1 ' `c>Tq +f;2(rBޙDV i9_]q>2AC%컪yQz':n{]unl 䀢 \O1[nhL'e ݆%[.aY[KÃ# 1NQfB@!Vt^?O@QDlԪ~MKNj),;K*n*r `J6X;hχ9_72(Z!J[LD(77M#VŻX%qOpyԪ"07갏Uy}ԅƝhm["9q T]9ކsF&YYPDTWٙTUs5e*jz*JF%dʂک~5tz}&-KMXD7q>cewJMXGDT`!C~{bǤ/H}>U\Lb08e4-vzeˬWPUq(8ajY31|@Ă2)k|Y Y‰K+V0t$)W\H7X0 M̠zCÕx1:kB/B=[T;VYs >8Ѐ'ꐽ%ڝ>W?+Գ"P\NMS~8K>6Ako{*wh @dy3NhZFΜz2w7;'ʠw6[Ӧv8fᡠ46pv$ɮlVzUm.kdlV t*$JNT[>@c]¢&<&= "b_+hD|s2*A`qdE:mY-H<`U\/:dYn{#hp} s${XgVzpFH-4ڱw9d. F$=x8@Q&ٽ;s2ىFIF`c0 :}vJ80;BeZLƬZgvtͪi7ˬNʏ.>i;.^RxBPW[D]t.> Me8k ʱ-?@ݞ)qF$dA2 WgtőWV*ߗ[' B!DZ:ܳCq^V}f#],fԋF7N6;2ى-+CK?}VnEw8֯hB o,dnXt1&{4n]OPʋ&@+z6=@:ڃj]i`);lY5k+ňT0DEmϕ)ע8LJ],E~A֜GJSIr\0[a=5X{0jaFDp4M2mtWX\q pυ~[pZy Jyޣǭ`wY*bجyǬfun>ہoy΀IQv;6C!%Şꏲ쨒& TS ُ0F N؆a}d@Ge'buXRF x~25`ccb Ǭ;(4V!Xy~Ÿ. 6ZӠT~Q"ޛr׃$H|H"yeu"HWцvn.Zb:G2 OxeXLs^5;{/;&0T 㤃 3щRZZ[c llV2 (JrsQYBme Z8D,9fS*TyV%܆2/o$T_Z@UY[drm4զ̤Kأ5 وd3[|u0[G2oT8weZzVomp B6R6@$u\+LZ +[銃"e.ׇ|F7e͈ѬO3< :r~Q/<#w%oq*_v%;hG*8ȂCV^@&SӣG( ↴@#ﰣx񔈌Aʖ< Nz{:к-DSNY)CeЋl\Y:9YBYvC/CL֜\|z2d tQZ \d#Gn{uuYc;σ,F 9r\&Tf\V&0 (2gڪ;Ȃ0@GsJ֩1ohh=Ϙ<@S4NX `&`Z, b6INoFj%RpgULh30 8Ej٨ldZOVߟ]h} Z-pN'1v+4 Pe v\})TzNڄ\W);Jkcn2Rzb'\b ݕѤXbRicF82Shj `O3 r5rkP]̲"3E؀D&^B;: @\MOK$3vu0ߎ\4->$ -V,;(brLS[L|o+h-‰2 vTTQT Qn7tW}G a`Ń^^q2eW*>ÆZ&U31ŇoV,w*mGy3䃈Uw9b͕ nݬSpK.qc̦B` ]3/E#?nU5ک$~eIfQ< ,CMxDJ2<-;݁x!'F*Y7D)hTX6i{ԯe?.Xm]бhha0eƣ]S2y7*w塄+FTQl /a$|4XWm?TD`I4`14}La{c*A[,TYnXڲt5pS1wY+rp,JL}R ~6 9ri.Xf}6 K 9&`Qfuh0DC4Y@@b,6'8@U7d]bAdd9?(r( ꪾ}L$b րTf# \G(C "|@ֱARS%R|K?J&UFsXEj쳑Tg+mz(<+S@Xz.3y{,+GU9RYJ֜w ֲq`&y+Ch/< 9X܌I[L~_;p%ջbL޻Hgߍ 8pZUIVSߕ&p}T<1fL k+~(#ʡf|kv wC _=[ z'QuX2(^f,Vt!A9G(ld0ր__b' oT. 9j |E{Ω|M^Q&U`Fµh!e 6-ƛjj碔ez`="YSg6<;DViz'C[8+F=Bͷ[ؤϼƃDD6pA<iVѲ8}ݻU@{G95f] hxE5'%_'!od?O lT10]|QެC&tCu<5]EYt|*\))&4"&Af2` =U^x0W_'-z* !Uɵ#0f_1@߳lZk&TņrnInP8╵!k)wGr6#17̺SdZr * A G* 64ӏ>Z^nCAhXbUxAؽ*" m+ӟYuOVA9/ޡl3{nfC<(A$bc"}uZ W D.w-w;d붎[zirU`Ht=}hcю yuP5̃1T:Ao] $ PO8y~-WmAv󯳢6rP.@_`5:doG'n@Wxݑu7p0eOLXK" nW+f'8-i/YUoCSNPQ;rU ½HdOW7F F+Z\':+ȇdrІ,*ۮ- (n,p 8RA5/N^Tڡ96:;sqڃ5*TgIA?4:F\,go.^5cz-,k$_I64@2WB)V 6@knDzuܻQ`;YvQ( 'fdp=(WiۅV즊G=li'+/`do]j} _uAbFwj7(a eNL?9"dCHmk?=>;Rsfzw4~@d)W< # m06靖kp"gKXw=P^SeQfcK>OX6M4ARy7XZ⛪r70㩿5ڼnTˣ5ơF~AM#j^֨#Sl;Zh–J&A]5z af/~E^TUg֠[)/6EBXI>[; W KpV`,pzq V# {p((`2!7Է{*Ya1MYTu ?2ק^Kjw0+:AL.m^%^>Z[\}jgS%"+MR0zH\l`LZ+[W``7)[~ qg0eKKzPdn P.w7l_{6@@pL@`ׇE2@.ڛ ,;mi[O|&:_5'b1Y0OLY,.j3% \Ý]KlF/T+@n%}YW@ٜu G2<[!YX5Kz.Q]nc{]{Pվ`bClb gfۅ8ưRwFibfT a a)*ڂ=+ s}[`/$b:Tlyݴ8u=Eo>z[04(Yyl^gUX\85HÍ_c̺#GDJZf\X1Dof i~[iGި!lz[^1mfՅ[ c+`̇Q Ci79U."iȾa2má$j C0@ Y(})YQv{l9c>B~b+er%1g+ {8g͖js58v]!klEj8ԛh3tP 7[[Y*0[d&`AEF|{nv ss`ԨvT,TL]6~mp “mfYx 6[؍&\~b|r3=YP[v/XRN@/L6ľsM`[( f_̉ϋfLOtp|(hm33ȰY.-[,L3K1HpUET -b$;>ۜS\0}VVk3I3Z#A?u*S1ՇeD:L+#q9^8RH Vè9v*3&r}n@, fZUd Џ^P\,J ]_!D0xFZj.5Y9[oU5-(IF)C(0 Qf?(uʶrZ:IҔ|צxg-"HLȌ5CcBخ3rWzX NϿGX+ߢeхĹmJǿTՏhݪ,^vxql/'x@-"BR٭b%,;/lK5 GJWqJ ֕/">T& P{b$ VCe{Mϣ7w^A՝eCYT0TBXnxϱԇAC9X>-E: !_߅E"cxّ"pz FC&8TcJ@$հ`T_6Zg8e̾0) K0—@C|a5˩/ЏVnH#Vʺݞ* ݶ3safL T+%\mm%.KQ&1㘧AA lY=RFJwjBtR9~n.#`pj g`ڽ=Qd͹r+FtÑ,Wf=:aoZDBq@2ab] Oz EcC7?TFÀ d6 I _Y/ Ϗ[:+U]`* Ve['eNc@IxϮ&0(E,٥.$Ig!11`'p[ðx5:TY־q{c] WW_WvIS]w™BclVgz~Vbd\ꭲ~?BB| 1UEF`mGeջ2>NVoNH^:K Rodn٣,󭒫 ʋ9^ґF9(pDe݀T2!o(A'~pw| uӭtovk4ڑ L7.Bf@ 짆vP!Z^n2R[G…!,]oD٥rԡ !,22} ֝RFcw"GOVu.\2|twxh9!ңv4@[nZ_7%삛M:.-ٶ#ҩ PJ`Q%k|LT}^nmg{8 $$'EܘJr-Qa ~`Ȫw.v72;4R^Xq`C^9NQ P oXznT:h 2@ }m2/u)ԥMs:و#:K1GئWcf/hҚ,D]Pߟ`U"|ʤ &5l@ָq=5Bx=Z/2l2Kϥ"/̯:KΌRB"p=yn:=kP(De’u8sMl2O@:.ڨ^ji;Mu~@GGN}ʄqCR]; z#`S,M0&\QWdg?LTˑ'!5vCzSdoy\b=:%FzPiKv~5YkOyE ATAƸtSM0L@2Ky 툘;^%׬|5@+nR"d!|西y 8a2M_0@JJߐC` °L&M^ ބ8wK!0*KbZ}swv2#\se ,EcJ_qwgX{`*9Jm46T}tG!Lj'-xX݂*]*G#d'C_Gۢ*%]{ۊ*UkʑфKUm9{mΕm\4_`+Lf ˔j:iƤ&Z#eL2~x]@%+s5mѵ w߉ȀoAA)uDG<>壅u}*`4aj VJ+):&{XSaOj3z*/%j?A/kKg{[1髨?׻Js.,<ճ ư#v{m ǀY^2OVmXYm,sZ` .2$B =;"]'D\2^dq7b!7g_\Jl1Nha?}GF? ﰣܘV * 4\$u-Rk:0=I0t"LY1YrV!4 C;ώ5UwP:*ݺ3Ǥ7!nGZwyljWJ?S2d`׃ ( vءWJqgLLJ LX޸j̀kk1F#{<2>oab3ZP1kw~'xBA 1>EŸLx S7yєE2voPs4).g&iw9;}O C{8 uBv!:~F])Wz70ͬ.M d(rG q @[Ie(,]4d[QGɶ z톅̠Ln4,W(7ly'۸**q"{T ZpwW)kۃ/J 7Ӻg2fF&]k+}ă81Ъ(J;VFGLJ ڄ5Lƾ%Yn]8nAE ;rhXkjnԫ쵟<'(#ނsr@_Zz9qE99@GXAHAmd?Z ۔,BPl*m 5GvLwRaut؊\vVeg|PdD3ͫY1"nMJ"Wu2 9 DKГ@@qQAy gqrBtޖ`ө{1KL* UkB80؂փUc'@Qz y9 l贫a~?`FSd/ĽB3SjlyJ֬*4ē #W q0) Ԏ̫+)W6à' _Kj7;3Rn EYY N 9̽)oǐC7?vub{f@)J!{=L;JUDtz 0 pAM@VLCr#`2dh%[@2 U1f8\%+V-GCJWU|yj }?=Xn[E fw.ZD[6GU ~}Xʂ/ߢ6CvH+bd0N]WۭQ`3/yV i3؏m1c f2ǟ.Ĭ9ALAf DWdHARqmkt?zAc@DQi8LEoU8|¹ RE.TP*b }mL&M6@@ɷ:ump.?uurP"*;;8ޜlepᩣUxس1v 0 iV=&jMPAPαV5Su岞Qx^vr<@V*AV ,zzΪ\>Pd|=m&2.r,2v Z% 4#$2V=VK;>GƼCmxdA f/WG߲>zDEY.f:Tx{ j;%~$>%e3Ȁ B 8*a-T~KѪ ]jD(srK&[gK&h`r$8۝,?W"Cm+#ZQDH'$Z}ս'Yml noO5ٹ*hb;܂WKk (8, :>*l&"#*_\0xJ)mUm%Ok|z˘c@;6*S9k?3BsYC+dcG0 X{zf 8`V+Ru0؛3|>/&&p-ۙT\j BlUv 와 E4^kN,ͮ\H ɼH8.P%ƏƸWwDǡRa$B W ..$w&CD04ч1W%&ZhC% }q)ƽA̝D7Yݔ]lE-{u{pV;Mī1hTZkнieꋎ-߶b"s#gF yGaW_ p Q(+lUՂxE .mOuQoWc3/&O e[zC6la80ҽ.Vz]DPHu XgW<=v3`%L^hng"94־P%/DP ;ma݇j3?!xf2[Q* wS8Q0fv3}NgʴNS7⊛Y}DUtFǺޏ+v@r`=(뫇VԬ $~[q'3Jnu, ug=C4ʳ10>4B55߄ūݭ,9XGAxU#h B)ui鎬T~ӿ6C6Qh:I/G±^zt჆mT^GdLGEap@jzٳ.VтU1 a2ݬ`QzK b2$XKJďWi~zVK8sz~.Ga-?&?P` Kŕ2c U2ݘ\<5m6Z{ި2K6Gj }e.eAfaUQWehm^KP iH>ϰ4Ph-ӈs0gU5=T\* @<؋JEL[;X&sL; ؚA-h]Nd֒X3]R₪S8x~ۍ'2!m\U ,~ ZAƫ U[ոd? (DJ;bufYSTB_-Zwt g3T$s2ZlH;CvftT),e-2Vq@gX FF/¿68.nQc98=܃]L;NU4xׇ 7߼0Pb Ha/lKnKPُ S +#ۚ5 We 6 rX0ST$F@k.^i~c2c=>3>< Vi-Lsg3 V RO B :~qUӅ{PR}XԜ.N/mme9P2t3z<e.ND4.} ϶vn`aצ(L:U /b}>Ah0d=>s1CեMt_>/,YhC:U>VPL7*ڗ4'ݞ pϢ¥,)C+@'Ь##zq> H4BiTϘ_z6o8^24m]ZeyTkX-K\rcUnm&;^䏰aUM8Ah@lф6fUmi1)`٩7FYe؍Vh 7J:SgIwv~va‚{k``Qg i;XaꫳLjЮ?=#hMTh5~ 6 n.%6pi B#Ԩ|{o K`cDM鲘z}O[ aPb% QOxDkn'OKVbj@O\`N*@xHDQ9` `_-=, ~OK2Z",2m6K$h v\jL}<ѡa&RJ=*^ING%m)(*~=6:H]sq^Z$aZD+[l;t P?{PhPWhv`^$rT;]8Pՙ xP(S6vMR-Av4hyZaӉru3xE}TPVEVe N[LU06Z=!ҙ7 Jm""6;W&@'Ldb{gd]CjnŕvVLb[wM: ZǐnǑNydٞM:[#na]AcwkZ6u{߾1atT֙'JTFٵNkXRx"13Ov&yloŚ׍3+ôMyXVXA`n/@AY`69^2"CḮzU8fb|BicHzc2eN!Hoۄ:>5rRIlkX}R4I4ڡ4|BNjD.|fgBelB XijuΠSxDT] ?ǀP0F0'J5\L=JaVYiP|\SKPuLb[x"һBR99~nj$ [MahEtY7@MVŠ 4GEf(לϱ~{y:#fAp$w|JwF'el2)\nua'L"$ɮӽȐ_ʴ;ˣRBH)FN譣i$VԐm>^?kl+g(5FU ʚ6HPitAFLG}.&(\/a7BBwVV71ӣn^w{ɫUU ˶<3CϳgL`-6c,ݨ|ᑈf/|o`D#tYxՒL۶}- OZUa\<\F;.`1H#th Pd3Tw(Y̓9.*h{7cEȪr~7^pp)'fwa6X(_mGaiҹ]yWhbj:};r& \J:(;yPն&.2rڅIE&Xj ◷Grj Ad{t;t;do>Đhjz 7Žxx Xcoϟo\El tLըy74h"`qmëbG޳ꥃ z)lԚ]fc*Zq.3|R/# a&bc260=M,]ЁD`?/kv>DL"ڞ{X^}Ivx43yBi:*K- gū3z2C V SsAHb<ِ,75{fƌko5Πy:-;[] y1* #lʳa#ǙK:x% }AvGW`} ULCQ~JM:Gv U#u%t!lRz87;]L(טHSN0BƋR5ޞQĠu..s*[l66:e]4uۦ]BФK3(ڝR\ITJd8M#3#\álfte"\gehQR͢{DhS*1K4'8 y!>]d 9*|Q~!R]V~<}E iVVWr4XzFM/jzOYGT)4%Cʄe>7 ,ΎP!Ր]֋EZ#>/N^*Ghŋ IG[es5-(8tQ p ܃ j=MUZd2@!kyʓzT 6Z|!3kbpD~gYw\ㅸW"dQ \Je6*hTe쳇rx x :Tם+̄їf\~%^+l:ؤ1b`[٫PYYtKzX}$҆0SC}CBZ3@9x2Basx;vb؁\xD_2 깎^%^zY.'zӝmT]؊0[ ?"%R26[@&Aؔ^zfk[u0hؗӈ1:RS\U`kdEX@wmѵI`8tɰ_2T ҐM\?&rNԆ0c:`u֡KQ!!\*/X% `Eee/(1G^襋4n .}< ȕNmszz*}s}eN%5\{"P )GcR"M@/!fE Cc"Ⓥ{})%r/edQ`d 4^i]Z/,]LslME.U1vmYݩ5 1,ݢ1mtIrAņby7EԪPo"y3s KcHVz  +Tu'\H 4 ^cn;e5wRc0 DkYԞuyxЏoҪƛWVoqc32u1 :z#d \%6`l.r(rbA; }Kߞ]Z.G$#NBƫ_2= Rk(F}Tk->ڮ?9=fY{`7 ڒAcږ-pEP_Y=B[qz9} w)uMEnN컃 ЅYjAAt>!3y)oԞǾuUgAY'<59óc°#=, "x C-j~UvEi) 08/ 3VȍٜAЉ@]Dd}?s6A@~ s<]ϑ:ACQ~V~hUⳈFc̜uP9f4+)\ApY߃Rh3YȦl2cTwTɏKɀE%e8āEelU!&lC œ 񔥻Z^ _F}#Ty7sTo,m ,&Sۡ1+fɐyZ2KrTU\= _ |jKL݃;`!aVFq2j:`OHz #NڇШΔ'fmvd`n0TŰ[4Иs/܀h$@U&aww Td%ynl`<Je.d!?1 AJ&4Q'NL 8##8sުCTei ٞ}lBb¡ ݛWlC(F́+ u0Tf o-[Kg~Q)r;ЂbmZ>PnЧ4tB˖^:݇G]j,̮u(`Tvʆ8(s~j@9RثLºu'Yw2uTk;+Gz90c+5y r{-[fͧzhթ v.5%h1Z\f=F ͕J0D@.cx YՀU h3 M5nC\!_\_+׮FXlvTi&mjx1\ nE꣪e)l#f Bx֤8=FJ;VJ*gGjP^;gzъ37eZ6ifؤ @ ?Bzr&y}Åg-YCПzPd]NMygNEf:/πgam ] *UIYOxC8\%뢭Ș &Q jK`ԅabUqo> K P!4K_8B t܍GK!~zq.vI~LKK,m۞@q+cYztY=[ E43ӠW!וJkUq9bLơ?3⣞k!] @DwNvM~h57&۲8?vWN :nm"~;*eYAhJ{' 6T7j坕ڶ3kkAYKWO&xXs PSps{iRj,M@K`oR=ܕm鋘~cgkkT EgpBޱ-Rm~EPzAXKRCg9W5> VC}_ȮP~xs2x'LnA3W4eg#꘬!tgoD4^67lD;Aqh?vR=j3kPj 6Ac@{z&Гud:l^. .)1dVqʍUڠ)x%ALhثv.۹q^FSa`KҦ i_(ǣW erSp0bOOj whnHH]P/Q4+{s8<ʥ| {P/u^N$!ZߨV4g u6 XU(e-`a 8XW*5KM^ˢc[lpƊ2kanA}D]H?_#!+sy؛_F4QAFjE妿1d;Y,>,rTZRiazZю D@g=0:==9Q/Oc:X R'0 7}=X*o%:pp`1Q-k$cn~ 3؊׆[tIe!Ӽx(-6LPN;ՀRib l40`!ٲWs*ew+ =yP,DO!CN?^| )-鋩xކ F1sЬT0k+2c ,L6 m|xy5< w"Р bPk_2Di|뱏Țmާ:Sx ^ *zv;Km>rwq:2Smenw,b]` UZMl4o7._ g6Z FC b( d܀zs0W1 v%yDG\xQ:j{ͫ䫳:R36xm@qBdŒ&և?g4ʹx .ns7؎ w-Tqcu$|2zd!9+@]-ymZcAՕsbpU'g4,PEF+Xj1{±qZ .?`Ͻ63@"~Q 兿^@SXvR6tJP Tk+.]CJ~+0U 󥠥C!pC@,#TGV48Eu9}f#,U/ OL?./$̒ni1_(eqv|1=Ppv{5ͲL©!O!Er("gD-fFJDA< v6YZ{C*7cbZ6vt9_+wjۊ\8 %jΉq4V|A~©.B,= jU ڀ9śVt Kg}^9p!Ǚ% >BfZe=׌Nv8WH{#Zt߄t ^(#CIk0L"òEQ:ۻ\U\nF$ {WԮycꟖ5l=kK);Z{$ ܢP2 iDNDKJk ;XPݩ JŗhhVP¸4([2(NR L\m9y/zHGS&OC32UЊ Umpy2Vj!Q൉4氤AK`=k[a>" Fiue7D#|q1Z6#ƑU|Ty@0[0L93\>S|bfo`nOVHUwHSlڹI9th.GVZe$]FS{?,ldN:aJ=wC_.g]f )@&eŽ:1z⌈dfb^c|,TRg3R?*P; > $3mnm@%p֥YICta&Z DEażɉ%@mcFS>A.8\3Oy.;3Ǹ <wktvo AQA m =>s F~Ko$N\2[!m.cANNOiyYV*hMxV*B8h4ATc1Op5u\?m;|qfNOmw`} ȡE=폽Xrk*{6#/+5GVzT^gs].u^Szh#w:+h++A2qH㱘IᲔ"L(? FmG}D6Ov -- !e'>JI`9/]Y)\( k`x.0"w*kW-EGܘ.5Ei~WC`@;<2n䤌_Ws2K>{ez {^(g )-ŠCm>& i-JM~);z|PTcgFTeadIy{|`Ъ"Z9,f@^f,>Ql> Jڒ`h4;_P"Cs426?C*4 W e=П6[Ev$gp\Y#n GiGŠF,tfcWO`N_ɀ|Wᰒ]?@8J{C؁猧<˃K"Zz-]7mw}ohr_nr_mFj҃=V8pm]ꆘ hu`? p( |ށOe>p}kh^3.$M5.^J"QwWK%:bv2([d~F`xTV-Qir4bCi1f3 -d}fAMTl<2*1XWAl^,}f%\0hdgȆ ܀Ğ\=LV|H)S50 mNM⥲~M:/.FҼל]@{ig *x43[!΀$u>cH9`Jwt 8Vw+*>籫 ,Ze8!ZoUv&W"CK F 0fVQRez_P%0M,ՕsR%a$=76<2 m̤Erx ՘1 +=9/d9-%aź2wag=Ee^9@{z/rN 7|Xegb!8<(ҲC1}j# zk a#xpuVzBoGy͉cBO=7䊚C@]&)b:md`g e}=Yl5:}3(\Hp'_z& S;)X.q.ٖo~3bkwJ`$sT*#N|gWG<Ŋ=@ϻ/KR/K5[u5u]žQk +7}0}628&43zǶpp}!T,͑9k}-s)ukt3TEC_xM| ҈؊T q5rJ- 6ְJ01P0 J4e3;h[!e-zÞA1E_: vBJ!R1)u<.Pxs/{q osٵ_h2zk/gb^r;3J' /[#LCУ\~ M>fq(ַU}720r.@\ÎkR.Z ka)c` lʀ?h !YZ5@oPz{ʿЊ( w7C yRlfh. Fmז9Fڭ2̿A9RvoOw6]c)pT1-2k\|mF!Us_*ݘLBBOm-طZ_= Вa5,VUfO&=h<2Ha`H.4k3nj+(Tet.QRup#+d+vd0Ovllc|Ԍ0A2&K'osI_wZKe$eA< !QCaӋm"AQO!ISE9ލr4Exm[80c{~)~@vbE[o}`5(Up| s6,6YE&G>z7 MD2egF}¤RxwNB2L{Lh$@ߞwW*4 /=d HmbWt@ԝrܬ=^gyB>X2*%>zdJB8(>+zի겴nZgvl2fϾXa*&e@.ZԾqy-j8l^I Je-01[U/=RZhr3ũZY2udXk )-E}|b zH9>!t.Νz H*+UPֈ +&l8ouM( -acTZwx 6*!iM.'Þ뗲"t5֥XV7"_oX-u.3x5 $YREvKVD -F[܉@^zKqP3l@ĀK?7V<Sp*Q7h2R[N8QeoiIuܳb: 8 yΐ<GslĂqg[6@L^K#٪wCGqBUոϪBƣeP_mSYQ3,踺# F<1k ʸ(CܮU`8ҙc>#f.zHx㕜Wzڳ8)>zx0q(ׅkˡ sm%l|.e5󤹲>AAu"PS7:tz.$`")>UabRa YBRdm<3%3Tš4ٵ=>$B- ,H2csTB}thD(>J2[4^KFL@!D\;8ݖɠ*;WQ(<٬U}aVqU>QT)[/Zsϴס ;y@`w|ҸQ%b.X[UX[d 9lS6 6"37$vP!#gp'А<^Gݹ[bS4P" df %(2Chӝ'ꤓ^.ыs4?{h؃Pcݻ{y_y HzLz-Mנ Ddda@_xUMpî~H$SϬep$ E^Y}̱2~&[zUNz[e蹬_Ń..  Duq)ʊ4 ( />́Q *#zF4L{)P0w"hycXwU saWj^  w?B@P"nX "T]CG2'GNLF: m}]tr!h tPEqj{LX“(.a,DHa;-=2*36~ > ٳ>.ֈKKe~协-F%TecU0n2^נ(ݨHyNbZ3GZ*TT.@WfʢSⴞ垩jcZ>ڎAR!5"{PR0oefPfB.9iz"YA6r;ϜU:y:mEȐ~qGdyem;8cw|* pׇ?KQU_3N( &Tu\w!:q"yvFjQdXheuC^hs<@Wt2m?^3[m@uzQhNюm ! 0qZX{6 Rd0Pj!` mMehL5uK}/,٤,ѥ,(5b*n}؈3}gcؠ~%rD?k*O=]鱘bn=ȒV *n74=zd`4OG};dp(XɮȌ3kWC{nc"_0ȏ/KaQ!Pe[6 VFR Q#Jnk>$s5^\zPXHR!C$B/fsg^#TҀ`< du}9Tf\r XsQ'z2ߣԦYS(Hz݅Whk^k!bض֍^P9a%[1^ޣ YJN*iuFf;b~.ūd(x;VLnCA^vi .[ Ntm0*QêZI[rgbeNrlY1w¦A{?7`Z%qvF"i Oube3d E!\;[WTUy@O8$Y,]]=1hLK%܀#X s5AƥQB.^TELoˁ*ܛiA ݽӪPJIRy#"ҚoE?'8c|T veQ`io?a@m)&[ h.š"l"]8lXF(-чMU.J,3^ժPogƾ8h[$u8ya?jQ6m6y 02l]*=Sl2`~r~xce9m;VPEYw3{kr0XoϿT3^QT4bؠ[h?ю5XU⡒C[-\m Cj*ل} P#kȼ100_k.Fg KͶ~'g+mrq3_޾$k~<2)v}of-:,(4iw`on >O10LܠV@MIO%OͬD<h(Lx?: 3\6j!Rؖ;h(yo k#rJg?zޛ%BSa-?JCL2tW+OS0$wE6.9 6MJrb EZѭ"H?VV^WeB #.r j-d8Wer"L:'hM´v؃#P:H#ށ,3dE2#Ī >/vm1spJacw43֩b/$Jw_6:c3OBF w[kD8yl-x ((i02cJ?1T~9g%߿;#6ek!C:ʽESrnX: >wh <0 a]R=Z|5OЈEmd$Ġ[3l2`ȻmVuIuD=. `y:|C3d \ǃ/ώ{C /f lZ73hZCNo(ʳL.edX38ƭiìJ&k~7~>ü Jlկ :PC&{ r ~Ϙ$O}UԌmN@'t:gSwkI2k5s6SUVzhFi@ID[T'e%/ oY=E~g=Ր`B{FnlB/Oʊm=[%q@gYs`A9&/=Ppk] |_ stYl&#x%P$Ǫ7*ohJ`yvZ!)Leo65QQ P`A}#4٥TF!sYT*S4DF ?r끼T^~.x66"DP ƶ7<Bƨ`i4Uax߮.N0]~fX_ə4US\iSb=^ KMS)fEc#uz1-!2akШ2BBc̈́}[q#>GY㎃x䭴8clW9> pqʐOew`Y nP: }K*{{}oaZi].Q ) *>͐7/2< G\gBZtwe^g=#ɘ6 B`[t=qG1kmwT5|WØ@I!~[d F=yc\*{4(@jҏ ~ko) + pGD3A+A#($Zz#vwbgx1(D`(:Ԭ:gbDˋd =+vVOrǰMc|hqz=5F`0Y«MM}Xl_n  (>xDhDf [2m{2kjA `Ӵ 81gW+g>k(/RͪK,Ph!c"Бv#߅_pt^Pz\&2d4xj;x=ҠdcN^VqV@"`cjkzUYd΂S0^En'#::"vԦp, LJBND+~:, +aX>\ 4}5YB*Q@ìDA(gLmoz4 BvʺX=,(dZ` XDs.Xp_ l :,I}Z3k|DŽ-ßG=ѩꍪnf'x[Z'`1-6oZ^Śu'B~ӳAdUݠʈ{\̂+MՃ n㎘ړ0>o * b3>ۤ0VxmŖ4k! X"9TA?f?h@R)+"5u0F==W}(ɐ'G`ʪݑiS尽w)Sc?7{ 9_re/>/{Dۃh5@e+@l ŶtYzp$l+Std2* r4"m5RMXi`h/Deɣky:-ɑ:}ɚWIfHJ؝%X|mR*׻*jkKkT&DT0IJ\d;F_xd4GmʥV?5|4N~wg `3pLCڎlfk>v1* 3;GpUwގ`EiGnGo&pTu^geXBe<vqAՋ|Xj I1Gt]CbCː3uʤL ;CN'Y oe~{2wź7Bv ژ`YW\̚E-E|d:\5V0xp`dgg`r"W&'{k7U'S/k&.(kJ>1+t~6ZDltA!V :Z~4h\ERXTGYfYYyT U*\C垝VU,rx<\cm:g/ywl 8L!ͱf&b-ulYm8MK{(3lPPU.XRx#(LX~TO- JȢA*_!#>կLGz5t(z͑;å29 t6,T~2F*ü0Ǹnzh82 ˲:V1Gc̈́,7}@a2 D?6[00?탞FmF)UcȪrA,[^g)Kg.AY v=0Ģ ٳa-Kk?$ 9q(H `9˭`D{BbÚGӒNg @ܔ*@'`6;ʜ3LSQ~붢s _FqaT:p`=DDO@ه 1YDIop'R ²{s_^upvOqf{ȳ@:L&D*Jì70¶uhtX[g3^cP*c?`zZ0#'qM+S$?qn,ۡ ~ ;3 P@T٦j3o+}[-jG f/ngּ_7BN@3t^’5QTle@CSUN-$0<nsu-0@Sz+6 |Fu6 |6b ӣt 3`3~w!1,['XzG顔O>sk 4j(/_L0ϸ#J.7<-^Ӌ3o.ۢ.>7g~}*;׳ofӀ(VdP1bod,D/7Hj/e:])Qf7͍b_IdedTOEj+ GL@C4+MLbT "Y23Z*;x}JsOJ:gUx􂊎,8wWXC-W7:j܀WWm&&1L,˵P 7ī s8XIZY:C\+PUЗ˯6o%x}Ueu3o\ B1J=!G~DU~[Mv7|F 'f:$Иб94&м"?\rPF1݇(wߐ%:쉇hƵٖؼo &@$H+q4e.^(? CGp':"\ y@0Xu vaMCo}Qx A53Y2 Aԍ䁰..2).ʶqeJ>;δQ.ŔJ a?cɳFarUd::.N+hu|w<q3}E_Nq߂_o2BmA$IN~wck.W\L fSe7xc$%l5v7c{Ҏ H z4ź !Ò4m1?Y6A*<"j:WB8Z~lz+m;) ݜFd* hlWTheg2Uw.M:e<@C7~! V| -40L, gzY#ԺP9^`8{}|Q^)=@ѿJ3bT |@)X.="W+` :ka4\ @.BWU}ԦThqif˲_(ڬMWߛ?C ybbpVeSb'm-JŢʭn @~tH@-6) 7M|TΖ m/jz倞A%sKPC@J/j9[.cta؄r0uZǂā]дce ѝ]Uc7zm2l[V#%⨟!}^5f*U6/P`)V? Uѽ]Yf:8J "8s|@?Ř8A q=&!{h߭gQ)k ϓma˹eQP~,rK‹WV?> =g|[<E_,CՁ}E֣g9Pu; ?)ʰA@*7S?;u8w%][;<`+1ZPz¤{2?T$%f9b)i2C_cڀ̪,M>gD*qQ%3qw%16ag[|e-I{6*~ʧCum 5cSVKܤ;@8]);֌ؗ.jU1sk>/_у<=qm8Z<0 g*Q61fT! L~O,t<g׌֊&Cu6<^X!RoͼU73^5w<h~eR=u 990;cyqg˺tfd0[<Ʈp@;I߭G( piS(1Q(o6bFX ZW;{ Tj'"ŠĦc1,rRlM mK5^~tԦQ]{VaY^x LumI~=Ã?JVI.=LϡгO.W2(lceB@H0h-M)̍-u}kqiKa DLI U_+rmR=ui78gg,:pU( SM(q3, CބdieM?ǹکA VSC$ #6VʫniOs/k0cyo] 2;![I#İ-aPBXJ " ÇKCjU-g21_!v@Fd[-2Ӟ˯"O0bBpMe'Ϙܒp:c kkW4eҳշqO7Or%0ݨ"Q^{=h⬒K*|F!3cv,dKt ĺ X5ώ=Z]va3Wja4[ᚽ:_78+E$ L!r+eSaV&N )ci,3t?eN㙪Wm8!q;i$ˈdL 3ɨ0>yzO#*IeVZÊOX_G+3+ﱥA@-/_]v\eN:{10謁U&m;L |)Hlk Xo]dl~Yŋ-zTxtn)J#d4^x"T: Z*^5)f *XWo.eL?(QB ! GfL\tg]@4 AnC]?ZFY 3r Vѻ'\H8yxC`hhSxW"*%ͤڻ 񯭧" D`,أəodyjBo.z>v5f/k0L$ã ]0*@tT:UX\,*w.HeFLgW؎ ]׃Kef+DX=5hHV(,XaeX2Xȟ-y={ެCǐqÔs7dSE+A*;Gv@hL7 ,蕩e ^2 jiMikq`CX'H1+ȨpO8G6A |-mZ\A 5j)>Յ1@p= Ǵdfcg1s'(TT#7ו?(A&ܡ׿us ^Ͱfl+1#}PMh@~Cͯ=-5(sSff/`+㹩zq LP7QҞ3C}$6yOOJ+&8mÀhC=E{0=" ` ;Jp f3 m(W2jO`ٲʻ)[a3Ląxeʾeu>._jihH!l }Ri~55XN-]Si g L`uВ 9w]}.(.sg\ Bw/d^~|t_dfӊ<^Սgh&U?U%/],V )ֽaZl7 xZ]EO9uT,.Z;TZޞ *Wms=5Vbng|B4([5s[|Rлa}(*4z$:6M5MD)1!.jAomb  ']Sty"lP(.sAm9U"goAnqAB {L Hs,.z7h ?box>@šu^24 IOaHBVLQ2>T|1WpڼvE[šB|ly7Y9>ٯ".Xs$H 4! 'eybYcJB$h9NY/q+d LQa F`BG{2kVخKa~Xe}ZUً֡aUfk,1";̪@ˁt@_TUƷ4 X̡|2=Tt.R??D>ax۩"]6㛨S&:xI#K ~ؙQ hT,Vǖ`6vH &%zT6/VZy-EeQDdEv %އj?}: te-%bL]hC"}B+ Y H0/C/oҋ|:PIϞ4Z bBUq`۹gjQ |ε7J.O m ߳2z0939B%tZv%!s5dAy\MDmmλ0|:Co;}n+]],P60htt0@u?Em,nLD.5oY}̛gP=q1:}ؖh^&0`EWb *\Hl+k0 5#GQtSUZF.j/!Tq|@i.idT؋FG9kEeN<5*k#ih.NZƗ4i0ݸ\4LUKvV䩴m= #/EpaHUT;.rQlW?0@W=ʭe^l0XbZX,90aLu O2]60 sL*G%g欠KLX ] |-7o0v5Q9*\,Ҁ^ d'6,,z@czzWe]|?k5Vk0;VP!523gY!h,7 R;ڪ{tIfv[H߃"3x{I{T8bD1@11U*t1A+5R<<,|۳F MhL>: *s+"X2 ٩2HNH7׵?,P!$4s[s.&ﰝ3T[Wt$T)*G ;DNs{!o؊3ֱf m|i6f?߬H*Ab׃GcXi};N"]Dz8ԭâ.x٥D$_BuVuo-k\8(ë"2#)݁C'?/Q&zx@z`dH Q OWK1ÕfX 7ۛQͤ nfo:WP}#{Uצ'at$0_'xw64b6 }< RE%0 JDȢiWΌtkQ$gK{߮j0:`fr %ӳddM'I1ǁBT1"R6Wy~ު/u]7DfB)4ւvHܪLq.URC#\+a\)Lڦ"=]g4_i.33ٕojfa 6b2)ݚO 6$R! Q!OJ#խuZoE"KE@CE~߭s0"QeūD@UFN!E}mL9 X ,p#lCxX~ =Vfw .g'D몳əDՙ5i."5c>0{l61yVQ);6 !aelpY-PfhUyZ;x 1h*෿rҁ].5Dfy|X`o,:Chcց3|1Pz5\~fS =YBe~^BwyaO*lYn05uc+nϠpy;XvPZ}#{Spz qbњSK1,^7=Yeqzg@QVFN6Sghc]|U%BiLwwC 9nL h,k&`ׯc.RW|xB]`a/3yw{A:Ky]*~VL0( z,3΁.#؜ї؎ _#i@'o euLgȹ#\a]n[`yz*RSoˆ}s =1% x_*LahkX;˞c2Z:ϳdq;ir_Nw@ @О-+KgiΫʶ-aZ r&>9SԆx"ꃵ Ůെ^kBQu8ڢhqe~ͺB%\fG *d=DpLpMKFŧ T 2s%;LJ aa ]{wk7~~,~XhG==KEo"Jgpj2) =kRQ.1r(5隷]yڭoe RU-<<0JڬSqh6m@96nvB,H|+CWF&U7</sj107U֨ܲ!#%@A9>-́Vz~Xhz=hdHk7>zʟu]m@ȯ/HM V?Dc0P4ЩK˒};Ao֣>vc[ /'KhqqzZCZ)XP:D!x'Gd|/u Oq#/)M: f%=:j3|aYgtސ!5.,@+~DzbO1A+OYM?urgM+.Ƙ;(4d2p+5$ R?T>1CHYʇv*P/؛"Y^ DЋKդhC rrlMCU\ 6]ɆΖhLW|K/Ψeg(/2k^a60&*e缏nMǎF|ԖFo3k]f\1+?@yiU K]ãۭYpa- V0vXo*G8ڼ$k1r4i@ 8M%~m܉?.M^c-%Z2Z+pQ{11A E_rv]>ݛ~ O\w؍}1K=#VvJ0^W_>~Բu3 #*PKD[j=ԥgJEu3\{zpˊKNWi3 j;<}ಳ)2kCe-yK cԞ  |?]"| ԣ%ԧh]0 T}<} Ӫ8`1v :փbĐ( :8sc:%G;,WFo3^3+:@r njl c?4LlQBrE $h}VDH<K<8ԙD@'T0@6^F Nhs? a_6ŷ52k6BYD; 3FB8}mi[%URU_es98vn47n1~=fr\XbSĆ k9leLk0iΥD `EqnlZl >/ڎͅic\a,B.xIPn#@2e|Ui=vAv OǮPqcwId $^BHP')0.Ƭ2sWa 5Ύ2n.܎vno%Q0Q&l?MqV!}EnD+|s-Χ bQ;ٷ aB (BuXcd^?:nyCKaR3|w!VX=Maպ_b+3 dpn/tg=os`RQcZ_!p{)M&%@a &"}V0euS?YpjUHxOƨ/woq2174A_VYHLͯZ@K?úN!>X}A ZF} ֥&׶=Qٺ d4*g IQfϼf}N`Q/ڪ5opǖϗ vAVIޑCIo9;E.{FP<6+U6F!c=,j5d3UlE9*Mr~?(X: ubapmе wن`7%_l1m LTtnX}9=Q]򌡍5][kx.+q@ Ht:;d6;rKZ߷zw_wqi&<  \QW͞yթw3 X_|'U L$3RKF9bP3E,wŠ< h+"#цkwMYӤݜV蔅2. 'hVJL$MRM5Ƀ%.h58 LFmVR:x L1P/4N?;2^'hwVQ7#$\lj {aO? a\3taڴ),uL%*>3EV⁶X ={L<c2 Wj&*Ntvl EU-]vr=kL"Ir+pk\'^šdPUۀv+6 xu{dz.9_&gG @/BUd~J4'MǴCģG.zH"(ٗ?D HAt GѺk+hp;u n|[~rǮ\Y t!de(.Kb6{ 7ML_]`LZ"c A_ZH Tyg^*%֥К3eeF-0 ~gmJR7ta=dӠ>qoz7}w-zӐA0t4&#>{ Xf ` J0 ww|.VcHy1\Eÿj7K|[~o;c( cn<# 8`%xLJuY˹Mŭ-XgV35=`M3U >t1Xa6puv}5Ȋmi|AO(B8Q}梞XqЁ݂Ȥڿd!jPc̙(2>xJٻߪd`3feUfԆ $[H0!uNjw9hI0eLRiUv*yU ̤(ZQތ8Rʲe+&:AJTCG QΗh8c`sTE 33q mAO!dm:ÍPQU)>j\˦l&ۄ^V&Q`ky>PĪĒ @*nJDJmוa;ҕ:zniK!>?gR041yxȝL6m U DCBr2xiP/o,w t T־/LI ipN/c=4Ƈ>8,wx%aܨLf\6(V svi>s= F` $"Qc6$3@@Z%AF--X=>Ԭ2gGE t ++t /٥|DW8FQ e&)vӜ!lvazZahٟ,q_ww`OlDRm9Sfw6s5j+ncu~V^<x52MGBm&% ݈M ېF@<Eskkq^Wq'h<:1t^`Y +ecj ̻4 8<a^S߂(B;S6P?ɼ@H?\Ȅ4Բ&eu -"8VZ]s |aW$R@X%>]za^=~Oyz$ډdրM:ER:3+(am5d}z+UGf3 ѽҗ1}T1SQRC*{*=ǛO~o2.%⻩j`UXUâ^roXL~znc zQ +b*9m /w_2Cg[?҇g:ldVѥW[ө?HPy7IwLwKeMJ[B-o Kc6;vٝz+#w1NWLU <`7i0st<-z=U`+jINA5&-sDQ8 n*zȕJpYZ6]o~7< J-"."x|e`S\&#ϛ+5v$Bڗի~< &a('N95LQcr˛veT6zWA޼dP>j|1k T_ӗJiU+XpNj]qLS}q= -~܁63S1S@Deb 2h%Z U"Lɗp87GVe! *pQm`xNetPKΚ+*D>{@e|Y]y13$T]AM$сͬc*˼'+<~0ް=vg8@͕*un= ld#ȵfk4 ?bv 'v[;>cYYɘy]DVU*Ce U$|u` ںpLe`۳}jbzj!(^'V*| Lb? Z/xt릴 * :?E׷s9Ӗր6MH_1@%K`(1hoOF$;l[bиkAq>E_ږ_ғ@^]zU QOZ]Ȋpsڐ_ lyhAcIa= 2?T+uɶ͹lЉL ; ym@0; &NNVj TA-*^-ʙ. R1upvmc ՛ _P /}y3.YQO*)ۆ]LtHT= 'AZn> G Ӷ9X5=ޟ. CO}A{vf0 P<ᙧDi RZ8(4l뼅a!]ze]ShRqfm`7ZŐ#jCo˺ sgE Y=5W6v`=9h6Sf;vVN`?Žw^؄+]3T>.svFa>YfSvlTa`Ms1ceR*w@KQYZJf$VAr\(R 8TQ-}^V8>zp!*['d,)fOd`\uY  XԿY"2*h l lI23 di.^$- sPwl uNW@*Y=Tbaû92mi߷LI~e!$շ4[,Of;QF@mM'ks_*|plb B)kp,SWg~'\G\6,J[|*ȫ:˺cpMһ{EpB`e`S("DFg$eP1n@VbG#N+ CaA 0LJ溢峰d%u!FP9޼\VEIk}f 氼lv:`PBl(Q9*5$JMD8S3A_k/EruwKo nK@эߧւ%O`շ=PzB[oX k/Clc{9*4!" mv )CE]fQ =)hDȉ]wv嵭)Y{V%,^|bscEtl堼ޘ`";rRSb $z֧\7 t&@'MQ6k yT \H>ۺ\ev@^m,E'5'z=p )K#08O8T圾/pZjVmA!/M^wu O3V -K9ƥX '2rTr. *CoXu[`=6D(^rW_Rj%Ekls\ ѼrMQI..g:{gbaf&h32'@\6[@j n8\X%BhQ`.AN2q;Ҝz,F#1a? Yߡ_Qo z#zXpy `O$ jiXx,"u&#ko>7$fc$z brc8Ơiӊ *.RM< l>*:Il6vϙs^O.vD3,萼~,гTgВZBڎ; Sշ} *{nP89|(v*LC`d9dda93{Q { :#r'V;%}V<≙ 9Eש !blQޢuU/bY±2JN|pO7 U9B7rΞ%6=jȅ!ƁBݚs+V$_P XG׃[I;a;B4ꏪ4`zݲPp{=t]ypۃ*]^I4HMZ 5SD8C.d-A̕PF<6ya-GЉD^ >pMB@UgI&}ey&|lذUoM2B2dQ02 E6J&%,ML!Bo3'kvfa 1X& utBs ԳOk0>z6 #6cؽ?O,zE:/ ѿ-dW&-tmXvȦߍvrƮs`SB7q9 ۚ' 4(TQ=f  2q@sК"ʘ-W!z/:;j;P%y(%|ٮg]*9q0.3p#Kޏ~6+Bl(t=,Qv $*&Jt`G^1Vֹl{S_- ;i;V4OVA7I3뻡}^`,ZcU[I3WUw6s.OH _S{tܐ66`ө<Mw"^ ݴh=3獵FKXKepae (|).1N1E,32m@MWYG`$8[F?]#k9 bpbC\}̈́AС)S^W)3CRD`K9ѹDm ›^n>lJV!(E0¬m 2W u D6N@[W{ueY kȩ#~46KՈ3k:os.vh'mCy9~މ6=J[N4ۖHӅŋi@-a,678GHSPFNgSuN{7sÓY ,l I6cBZmjU=o6f$?o$VqdW X>bDNjWc/{h(k]@1&5pQV<6z 'ae3h,@pӨ0[N5{2". 9 e1F&76\~o>~F8{:!y`^cӛalM_"6%!vجan87_ "6E~DOUgw!"R ]mN(:U+vɈ1]V2bCԲ2I4d#Ǎܶ A˃m1ATǤt(KXzC7A;KfiBxV90Df=`97.R_,3VAPnW-3\8X3%W@jZGRu3rh[dd R$P ;r;-yt+LKg)F+'? Dy]Pd29JZvhv °G|0IT6YQC|竷0+I]G?|)uϐWԼ̦6d\hTFA"lj=t_|!T[*42BlbA vڌJ}iUc?(*/` G5! xٔypT* K L>l5Qee&2` .BD0{zq֨O5!:xs}x2p;ۗ=XjJ,M`ToRLz < &Zokcݾu;Se+^I]vsn'[}3)WJ-Aѻ\۟ta$>LI~F0@->Kz2ֈM `@Ղ> 0*.yx:5 10lB%t^`f5NZt˕P5׈=\^N s2k- /}q$lbDcLݿ, נj~Ӛ!XzWg EKLjR;L\J jG8}\;~i[<655݃YRQbxNx? Tf6svIEi'z[69^Κ;j NdRy/j2 eB)\gb>Z_!)NiN^ "-R8bņ*ЅiӃ AIYX׮п!Fڔ"0# l(kgo{EB 7ª==RMs_W}T2iX/vYY˱qJ7 !Y>;XSVV5JP8`-v&׼ԏefM_pb-l,uQv]E/Ȩ `5 1{cRC,zgF1`,h=Y]63E`T9 [ fylmUkLVv>u$:>CяrZQϠZ jf1o|ځo?Z@{QY(ag4;f\U xi\fk\~ Z ms g)8 w+@[?wو~5)N@?cg6iJZ.^*FW!T .=<+t{SwE7~f‰m;qꨲ" D=Ho}a/\"a0b5賚nḰb$rj8^PMƐ0< ð=.{CǬ[=> }{@D`=PwM38@2?fŨL9rJҰ>vfr&=.K^}P[admPu_WYK\d:YaXTKj2v2u6D!az(R sI a|R]7ޤ1 XVtǴYq谨#I;_YiYM0.3UUьVu%eCE e :`1m}%r3=[8g#$8.)2uk}JnĦg6du: tWpe Put~t\ h5.^f!\Ds.Ku6EyEo.P`P2ɅpSL$+%u-ɎQ)e<9]u1F;<8EpVU`qȴ؀l*rjsw]ԭeʺyPT /tӤZMrd"P&7e9z pK <uq4QR7| =3<كS`8ڵ2dZqQ݅ %g'7J2Kj )`x$ZqRoL7hA c B@7D-#pxY 5p]]VҾh*d`ۛZQUJo1DM:sЗ4`rQdU0V2E_7%f29+lb' S\w(rT,q@D@A CYC5Q u(L%BG3Џ)N@- a]ߑF3I5Xl/ =i22ښ>{Z? UDyJ?yA0 xglՃыrn+#ݮBT+`0 iqe:P]T H'tO@\ &Q)V>e]ћQ- ,pLPźUd1CBj:k#c k-|MO:g(kzE4ʍuZ;juX3wʖ C8q$;x^a:ojmUόSc\.}_&&>UFYΧo,˾@+6>WV#桙/U|(TWH{ָx @<\j.R!osl=v(O9{uH࿬K|lTM `J*":$hS(d~8⊻/j$XYfAV氰(5-;|YNdHYe&ƅd(q X.TDu! K?S%tبi\Ey3OFe)HDgCKә(r\G6=KAc68%R#}2QKDnǣG&A*3=0zp%"Rn>]UUcI+lf1w9WlNL |jaC *?:. tP Yu=d=j0id*=Ty.uj VqowKg$J51ܝNݶ@GEK' ~Vm.h<Ĵ@w@DgOo٠>!`aݯg1P JLbRZXp-fZHVE1K]t=z8?E2[oCVT.<1Iَcgj+vVX3X_)n=m֘dbQ9?"g&{"^2=uQ=SPaCz:1eryu9^({#?l\0఍BR[+/_Q!D>ԁ2p.mvxN8i?\¦7N+4.7bej<^xW |>*0\'ϳABˈX^ͫ}\NW1Ѻ'8t3pB>dcu8M:}#cB{ 6xnkMkS~M82эߏv,-L.CSvG,CTD ,--vEq[v𣣌30=S'e&x<4J˒5aJ<`#0u?/NR|>;4<h/@{x8'o^5FC{Ԝu*0^Ёt&!F| 5@D1X礶v`Xf-ػU&bu!N̠ׯo/)ܗ|vh=Y=f-E&ED8]qv(jXz7H\=@uq"&Dq ?4nD&$ k)ja-E74ouQҏzB!$I7N6-b@6|J E=s3mFdr$ٞU.ƞ1FD֢Y*SK-Ek}M {Ā#<'TcMP4eO_8Hi2aM h1F)نʨ2X@Ӑ\BIxJ ^4ҊG<AA%i"mbtGlWn!fT|]DU^Gܺ+rGk@i:\ڸz4Dvk%dIՖh`w=)jBIHѨH+b5R >BF2?0t2gLn\s-L[fFz@mډr1AA [eΰW8Zx尃Z˦5MP6KQ XDDH0mVQ:!DZX^%M!5~JEmS ?3U/CR9q*fl ]g0E rdwj)a,m^/!Vk484P( P) ''3{k7u.cpͰa(7Yrf>tpL}gJ#F$v$Zy6(Ȝ V2qʌ"A2YelvcT@wXLLt$:ϐwTZ3pAE^ЈЫk-.if(u&6@=YK*&׍҂F[ɹ/۞v݈@\ORC.k9X|[ݓ S673 gҍʴ]bcYsgE޽dE@Pl;vڌn5' 1Vs׆hNs[EcQd!6ͽeDqM8D%ƌU95'&怢gjy)cS%"%B^6́ݸg[no0aIAي ˡ(tn!\k"*7w","ӻ

    V;2hB [ŶZ}nc.!>ALKu9뜮?lԫd_^U숬>?:60)Hsf%~WeNQZQxXZnZ*X}BƔ2^!j]ڨLg+]tѡ'fvӭo2+#zd\8+&KBSV/W1!!u[`B @ wxJorble+RS&fJ>G1=lRkf*ҋްB2v<^+WyZ/r{I:wns@a)ޭ#"9qh)˳ p5T[^0ß9bҨ5gqGˤ. B`n.ܞLO~]O t :Tkb͆^Rg͍lW3A5=;GӁC Aւ+ZWG peN!E6$g/ @3-X=LAj볕:=Xe^b΂>˗Zԡh ب6DzgOut5R'|>Q抙*F]EEQ+/E.,w]P@ozg~D>ܯɋm|+UgVU¤uCpnZ+9jRMӟcӍZx56@DRM!Nܦ,BKnrKo=  u&d8I{hF=\C*TBe`'"AQhTq*A2*^(ߠ( 1Qewnb -d$ln/ST<}ˡȓ'w]OZ!FIuaE{MG>kpHH;;=Xuw}].ÄikxeE"$5!;h3ld3+:TD05R&<"ɖgJe.PptɼckۺqwMs:%)JKZW" TF١ۯ_!kWa0/O}(8lES3:6!Y C3n[ߟB⵳3WаwCVn'Rס+ڗl( IQ1eqpR"&=dkm.^uwgluuҵ?>qaVfcGz@cc @-1d ᤎ;by89[a;`|3B/.:BǔV?^6 ccko[czTK0+@5qEjC"AR fTnc/n (+8m d.=XuT Ʌ^seFnw ȣNC [S{B8&r[t0Xcص&1D.gapPT՛ktc X?O=PlD)BI92Y6@ɪv+~?JWu('ZrD5e1AqOj1:|.w7VE,hE<[7[4^|nIz'CcƏWc\9_ZFR&k&~Ɲ5gY'#ȍOHKO.жg}kc =q~rp`=~ f46۹MZG 䀀Á!!mQөks #tw::!;i/S|xy?/cL݇BNLM4sWX) tؕ[FE|(1 +*[hC~L*>y&Z?g`!"3գP'=$?,\KQu]FT k18m&ڸhQ5oɭCa҅( XD :BP8n .Q0#/r'@K]WɐvPd+ڿݧq@Aʒ$pb}x9}~f93C 7ޕb6&=dNvcڛn1wGavpy~4jm)/EL\.xݫ ]Q?}H<&"*c>\xN ̥uBDB 430 Nc_<ل6\ 1F͕0`?@BK88` &gKLQ$dn&fE[ ķE%5/]Yhu>Il[RKJ6DOӬbV 1=g*\0Ĥ مnzt J@0GKEEf*p)\>:h4t#\M]~(io!рӹӖʿq҅׼J4j6 i߱IUk%<in(y4i"Ns@>&挶h`@ u>&ƴd0Ea2~y5W̎8lYvPBl8] 5:0 و"Vjx@&ݲ)v&J*U}PC? H6mh<4q_.6 (9[%}|) d4ɞtj1Ha1QJA%{ȉ/K5Fq6B聃3u: +};oG0CK "[[3AdC&~:z ӤMYnepK]&_dZp1z +|Gt HQMRK)BxfDODypp&xFۚ v<[*BI[mm(چό{lڵiCJ T䝰X#ѳ'Hψ9:@) W*L@uIHkXZLk7X7Fucזϼ)uE{١#`z$p@96r)Uֺ<n."XG9J5he3Sv0WCgbhs6;IDG~ 4`-;̯7 aONڬ cȵ5='1в)XxQV:@Ц h`0*2◞537Ϥt `![i!]@9ro.ӵVt.=SufT@ߏ-m~~.}A f3bN>B$q,Zo:AԐLaheMGP@؁02=)dHѭ8r"QPik8gmQq^C'xvNEi8b{TɌt+%HJu*]\G;%ڨR{]1 僁:c0iӅc{t}tPhN͵ 2vGTfA1.,u:d+5*^ eiVfVȦ42pV1m[Sޑ`5 #㰯SJpbPdӈ<>GM%jC(>f1^۵tAuZmȤ6laE\400PN kLqiéwAMU";Q#n^YFvA*R7\v82muCk  4sy̳G-LjfxgTޙR9 F5HP|­?yh̻5$T_Q!$¸ΊFm"iDﶳSQن+DQVqHKnؽ L3L BÊlf2j-ڭ/&-~dYsuwGTN*O4-Ķr w[(e9bw(GǬk,2*%Y3.lۓcytnwԓg%W#p{q{Ԑfe2Kk-Z/Kϗ` >C+oZ^l00ܼKη",;츸UךR'Q{˅BXrR,\iTfY7KrQ 347pd?#fZ(7m rhH[ ULٳ7>>p/eQ1jsN>B#Z~J%z>˭|:33(QQ=f'hz@h>iSG""jϼHq8u.:iWLXtUןmI&k߳++!!.ZiB :>F/ 10>J!yD"|ͦ㢛MzYMamP[72 w}.v5Px-(A82w5+R-Cj<aϹlqSpNp/NZ]R;93YtU+ ҩ}7"Z|6|'ŀs*jtpH}۵iC^{s mk1A1N;M]CnWB6 5iQXGNիI]m(>c=zm~*cxh'x6yAVΟ&dXB G֗F}u5 p^rriKgAʰA%{PDgAN ߩQx& Bsd9Rve*:u*k-6Ij8`xg|b16C @׷T?^ ʦk2'?Ԙ!UfMfp ']B.h3 ܇zVlB) :?ȳ>za>Z`δ)O`YAP~fd} @NuL;1YN>Ƈ707Vx&8wSS+;YtL8 ឌwC䨜q]k;\zӐ8ة)aa~sc8~YRҪ Jp) o[`gdfpwbpT3OlPhil~*&%`@wV*kh E P9:(+0P8LvE.V]xXRkÿq&` ݎp[U6pM.gMOx,SC('3ESBAO S#44 c# 5*UO ҀV%(nnΕLh/pㄯ0M7_^,^*nE19ZcH3曪k[=Uj,m4m$a1e_MQ\;ur6u=z{hDS+ '*NKp-o0ejk iQ?5x tE5pP;7%` eJym=هrȨ.F|=O֭CӋ:m9e}=OZ^-ra Jt]l8eKb:.!SwG>+c7[U}mO1 Yt#2~Aya 0|<$p0M:jqD@#[gc6rϫ$m<ͻ QC/]l;-+EN lE|x3R hZE}]؏+Xu"&5_w9Iw~ІtTkv)#l*fjf05*0oR翿q95:ΐ |um)܏O*\LV ĴZeMlÆ"-"V,PjoTmN) (2 ݑVÙm,xfK썡NJ|PpQ$|O*=11UWu0]j&-x&4U ߖR9f:l4sOoCKuJWڣ!DKǠ29$/캅K\y~'>mK-NG5"PK+& q fq!e;\E?{-EE!AXxW{I1xilEtC>ÐSvڕ{t>۩#ų!N-qa59Tb`Ϗ )?fl Z( !-?Vt&V`EY˝Gy-_LXLE>hڑq.B^;LD&S /]ϰ>wX_+҃r܍Qx*±b RG}!JGk4[P3|}7',wUyX]=;ƟIS Po| .Ĵ촳=6T~(J(6uNVb&j"AvtN6g*ښ;fV a=jܽ+HP0bT[PzO IX0gϦGȳM)mXˆMHgg p]/bzؿL8>2K<~nՆdw[z}کFuSa-V_=:;+cӀK/ ZhF K*lz&'mp!,-@Fn!* @Ky]x0BigV(8%Mr%|? \ͅGa#nz}\jwfv`ժMǢnTnʾ6 3E/^oҒ3g4И/^OeJJ{2rbQJqS#L#V!9rz e?2*j2VbwPw.qxbbu{ml?K w5[z، +Xl ;_ 5~| ^1QeD0+LFJ}R'o$zRou';\(BM @4 i$ND7nNB"tݸ tpQQojܺI^ yBI+'9aGj{^ٮ Tv!EǸ -34־e;7'pP6Pg *]PѼ %h$}A)'6CƁi d}je3DWA;%4r2Gg4Ü\yFJzXjcw0= )7#mSRʓsia ā+Ǒ6QeG֮.+̰ <@5).~fJosX)D@tu2 uL6)Д(z\#1&݈;fi+b8h_24Ȱ]Ϡ6ia3:<A]ۏGs)@t RY,"74kg[Vv `k㯿ČB+s8à2 XrjBLx/My"ET^/̵8& 77{OotͅZ :mD'xXu ͋B/z(`aB,z\_MQGG8 ԨWR=#5*k[X`iu,iܞ r o2ؖ'߷횻ݱr?rU L3ayBAnA0ͤۧUWМ#0f_z@F7=pȵGU@/d qFFߎE82$ư#R;1=9T6R /*&u֞*8'AJs l68CPpgTK X5Y`D9S{`qA,mQNy8ȁwf =`(95#ӊ%8%Fu dN! -A cKjre k6`nnoY)4>n; ! tIde,x'PYzPMTsT6UII`=4d?͠V#MEP9LC|Q1]e.3I?P'S9AYc`Q+!w-JP9t 1<Mܪ+cҢ,3GSeR-ޞwʩa5dAd.h7`39( [Ȝ?<O4wʉGksS~I!aFNP0DN X$0DETg6m - 7KP(Q ,)lvmD06#M祇3|;:h94sQyxD 0GyjksDޝUX6d*I: [rE<& w1N "7CoDRh~{jw -"=ԏڞGlHO̷U(LbTGȦ$M5tu:3:.$" J|ib+Ș(6 !_1F;7`\M_7B*{'~{ 7m^2=S(:⃣u6 A}4GQnQ1B۾ˇ6p'^n7r]{ ADfS` ;s}`& "$TZrTivi5xF|xCqkz'K]fD_Znh4ޝ?GR_qqV8dotWq{9.)CJ_; lP} j*8ѽ#j9g Kz$X̍ x,n`x) 5j@ICJ!"23Ů.ObJ{(e"ϊ@KxB4hZN Y)gYNB'YMP۱GȞG6?eAp F=*<.Y5E8`% n&TDec<옝F/m w2I3]+0TD';xtYm]y1YP6̑s(!dP*]SX39.^J)n=C-7PU"MY^%>Y8ccV1A 12u6ӏǶ"]YHq4wB>Nz!'Xq ɂ%@UhwTۃVauEInH.aդis=mWuNi36X4 #ӴʆК87nzm})H |\>O>`S(`a{/0;x!2^RsCIXډ6 M^^,b۝gV[]2Bn%&sx\`Oi-^$Ob:+mr'3'm_i(mxp5ք+l,(w`s^۔5av) 0:kd'loGfOe==S :Ԝ`qP3zδeYR(tcuE>AM[>謦waˊa`aen¦h)z::INWl2ĥo#[:az,=SY~gp}CR %%Fhx06F&@e@f ~D+OKCr08BHQߺ-R6?roeBj-GCyfU!]qT?aeIENDB`././@LongLink0000000000000000000000000000016600000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/ScrollbarTopPressed@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/Scrollba0000644000015301777760000000320512321005637033140 0ustar pbusernogroup00000000000000PNG  IHDR#z;9tEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp A| IDATxڄUN@]ېr JRVjՇh4Wq.מ*qcΠV $ޝ욄'7?lKVx>RJ5y97A_i N nq8~Ӌ"]'0y>o_Cj^AZSf6:h6lF$v7LF9vG6}ejBqՔdfWWEI (yZJF,Z$cCT:0F>W6s8!ƅ쳭*$v-nj5OM: oȋ*za6³ҩxxŋH1՛[9XʦEkl-x;_-Rr} %fW tdЀكr bM+q M$FnYqA\K 3r]C=[%}\7 OJ@tr`H`#H8 R=wVQROv䘗s=>Qʭ:ff%l+Z AH[A&Y%n^R7 = ZݶÅ`֑h3(;w\)Jkm74O H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FAIDATxb?57Xm սBmCYhLRl 3 dus!U  f-IENDB`././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_shadow@20.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_s0000644000015301777760000000267612321005637033167 0ustar pbusernogroup00000000000000PNG  IHDRwIbKGD pHYs  tIME 0HtEXtCommentCreated with GIMPW&IDATxrEOK2EdŠ%(س"؎fRӌ\$}*ı]'gFr$nscr-o_j8Xu}&$qҁTٽ1+|&Kn SaHn[J#jsmǮ$~Dqo>8ތYC743{;-?0hOИX3tbW>Y^o~`tƌu]|X;Nc[?ғC`nQ9ƘQZ,j|+u4b ۾']&V-:,2>I">Y촂A7[,dtJLj')N9A,O٩u!`IvDXnozOj1I}ǪD5DQ;ƊIMиͥ:EaR j܎OW7 QD 5 jD 5@QD  jAQD 5@ j j5@QD 5@ j j5@QD 5 jG8T kJE \TD N'j"NԸI{52IM̸٩q;5It֏cաccvCN}#i+kcרU|:}.5_,`u:3kI^Ҏc:[?Gj,O7YE& =3zo*|ZA605oIRQ7ɉⓤovOY?B~{1DŽZg/iwt|'Vҽ?9(/Iv>Q=F}=8o$}'jwbz' Ix`%}/$:˵_IY}o#{ӽ^ LvW?]rɂ51 zg.1WKkL;ܲZC}cc2} ; x|5jmc}lI_xi8~z<%^2ư7vkn$lo_˅ׇiRdƗYĠgd*O9 cȸ]&ܟ:ZղƷm4"N_Z:aKE?1|˯uLiB^om:da7-NW*pU:|oUvZvL狛ڡ%4M PŭW֊S!W!3QZI™ ?i|)sz:EϏyO,?\G IENDB`././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/tick@30.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/tick@30.0000644000015301777760000000302312321005637032650 0ustar pbusernogroup00000000000000PNG  IHDRHHb3CugAMA asRGB cHRMz&u0`:pQ<PLTErtRNSMY dIcv. U6ZG 3,= KEt kbF#"u/(ȼ+JAL[R΃^V8S'N&C |:󅜺~}waXǬ!Q$mbKGDg pHYsHHFk>fIDATX[QyAS1,!ҢDIZL3J6,l176Dܫ0036Ϝ{ν9X,L2e ANU#8u+9B*5֝uH/׮s KALH-R-U5PPPE4 N\6+"[;"#ۺQvۢ]=1xzw ޤr`r@j_3:qqNh(hxu tK*rlB :~BX q29m1@49A:ďT}HU 9AT<~HEE4}ˬ&lbk6#;7^ uH~ ;V % ZbcHħ|_lQ%:q7gurdҷ49kbc/#4"~Lԗ4`ʔ)63ְ%tEXtdate:create2013-11-05T02:39:12-02:00V&%tEXtdate:modify2013-11-05T02:39:12-02:00NtEXtSoftwareAdobe ImageReadyqe<IENDB`././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/spinner@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/spinner@0000644000015301777760000000217012321005637033155 0ustar pbusernogroup00000000000000PNG  IHDRw=bKGD pHYs  tIME (%IDATHǥKlTe<:hg q@M4E%AKqcLnn .Lر;(U ;1b ZLg~3S@Or9shL}&끐 ŀ*/ajБv=nAYǬ  r2x"9==Vbpxrvk@# nz,Uedr g̤bij6ܾs7ysO:,+u2!(PwB]JNi^<+u7{~j^A5,dBPּIUm>`.FH(`d5}sZ94ע豉 Q=Mnk;:18qeAUU-3iŸdYŌɑCs++mw ?vRGiäN_߈1/. _ET?p6VkW`?إKU%+O,~f x!=Ԅ*2VW½G yZSXXq#}Z\X@+`YS+0KEҪs{p,"-#M'Nq'hAdLi'.SeY;l|o6wVZ7yai0A.{ \; 6WɠU'*J/\`jtWq9Ֆ|< lŰ3V߲p3@ u;N|Vӗ v dj= k@>ܼp_)q"^jʌfo`VqSA.IENDB`././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_shadow@30.sciubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_s0000644000015301777760000000025512321005637033156 0ustar pbusernogroup00000000000000border.top: 80 border.bottom: 80 border.left: 80 border.right: 80 horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch source: bubble_shadow@30.png ././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_arrow@20.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_a0000644000015301777760000000126512321005637033136 0ustar pbusernogroup00000000000000PNG  IHDR#WkbKGD pHYs  tIME -9VM4FtEXtCommentCreated with GIMPWIDATHŔMoQF۪ʂ4vcBU6H0t¸"p`m4, $\Jb@B_ 2jڞd2=}Ϲv{o8瑝Ng@wlrN8]^|RYR,SOсǟ`08HR;:`ݭV4OmG ] R^6H\~ H=S~ 2&@ۙLf+DNk% $& $e=) L|K}D)-W@J&n?f+ *YEFК( BrܛdpeK1ohB;E`E!ۖeT*c'Z~۲nEtJ[IK"hՊbD"0 'm4_;8H'Qiʀ~[;Zk)=O5͐U1' JDO^rqs$No|9JkJ1{{>O?0A@""xtԈ)Zvoxp!7oPDdֺzrrq|i sD ̌'oSRJhy]2炪sq7)筡j\@1_E$nj}VȒ^JJD :JDIyxƙO~ݻR(#"H"LÄ(HZ+81M+ u/׭w>jqq/yS@m7p_;Uα_H {C_Oq6k%DəaYNΉZ u(%SkJ-=f02 uZ:RJeGadGj)Rxq.ˍ{RxC㠾q ҰAxq^Y(IENDB`././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_arrow@30.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_a0000644000015301777760000000207012321005637033131 0ustar pbusernogroup00000000000000PNG  IHDR4~J bKGD pHYs  tIME , i5tEXtCommentCreated with GIMPWIDATX՗OHQǿog\w-tH |>cñ򢢢?<0 麾6HBTȄ`+uPw;0+o=H"x911񦽽}$KACL&T)U@ pȶk6$&ڰMPJNa~VUU-,,niZ[[[[tyyEN ۂ:RѲ`pGڝ`0xAAA #H{ggg4V" 2V5lZ )(ʉ >UU166<==8)GBTHegC1T I0,e ~Z6#1MtD:+ }(;U}m]!iV ~!S*دr$SKFȞad.3k$W@SYR䰀9au_3N5LIENDB`././@LongLink0000000000000000000000000000016500000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/ScrollbarRightIdle@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/Scrollba0000644000015301777760000000160012321005637033135 0ustar pbusernogroup00000000000000PNG  IHDR'gAMA abKGD pHYs  tIME  j9IDATH͕nE{`a#bďd &"E(faS[> '`@Ga' A$Aq;]U,zm$X;#ZU=sԩ*f8'zb9st9@^YYP[۶F>p<&ɗ7o? sJTN=NbN %qQQxԘH&4inZqӵxc10ɇD!(fDQŋs? 3 @'Ry[bhR"f8yݭ?׻(yccKxWX]]%A2e4W:7'AIPYTÃ}>\hJ) Wo/z4)ЕB"'=K 4ДJ4STu`8d)gCN~oyo#&]a8l.s H.f*jwIMo?*`9R 7\_Sb0xP'7Æ!L3lhk*"H)iKXE07סj¬Rzխ_yy 3fvpttT^oD^^~c|8Z}"*.c @p "(bmI1sФ4!{s';@R"*t)E3V UaU 㽽;|}kss׾MqO>>&\Jmh4nLg`|3L5'=4IENDB`././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/cross@30.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/cross@300000644000015301777760000000360112321005637032773 0ustar pbusernogroup00000000000000PNG  IHDR00` gAMA asRGB cHRMz&u0`:pQ<dPLTE5tRNS?&:'6;"2ñ*˨,@ΥCՠ)I(5MNڊw9QS kX fB\J`^DGcAZ iUm=Ps7K4Ծ3Fӻ0+<%ќz#.|t !pld/}L xuToR8Wg]e_ 1̴bKGD˄p pHYsHHFk>IDATH}U#TQ~IF&DcK2CYF1 eIicʤ$YKEҾkWfygr{=+E hy@I/ (}n,! NZBTBtHZ 4=ц)D\kmP OHJV;'D*8IZM%;"EKM$)Z?gd:*'79`(XT=aF8lBPicuۨ+xs%"0vP]dA۶;M%Sv4"0-KWݯՄݷ+ E}]4!E}R);H"LK`I{6+G+ |Xt)vx q S)$$t)PRaAuپ~)KK<""{hbgxͣcbR* ?E0_Vd7Ĵ#ɫ~Z+IᡛS`-l`v,R 8?cu箵kǑ U=n> 3QPv@w#~¹I3>G4V R$[yO|u<{Npz^`/W=7N\j,V/̙ٷ3ء蒍tbYSh>(8>~?g1bb#|[:Jca?;1~Uf]" &@;Wic=??:?%tEXtdate:create2013-11-05T02:39:12-02:00V&%tEXtdate:modify2013-11-05T02:39:12-02:00NtEXtSoftwareAdobe ImageReadyqe<IENDB`././@LongLink0000000000000000000000000000017600000000000011221 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/PageHeaderBaseDividerLight@18.sciubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/PageHead0000644000015301777760000000015012321005637033031 0ustar pbusernogroup00000000000000border.top: 4 border.bottom: 0 border.left: 0 border.right: 0 source: PageHeaderBaseDividerLight@18.png ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_arrow@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_a0000644000015301777760000000053312321005637033133 0ustar pbusernogroup00000000000000PNG  IHDRׅ'bKGD pHYs  tIME ,2؄܏tEXtCommentCreated with GIMPWIDATӍ `?#-©%^' B'Vi9}D?"ws _Uձ)Eٶ=B\,;[e"`^qEaL`#y_T0Mӓ+`&XI8XHP`,xOnlK!]$Դ?/VIENDB`././@LongLink0000000000000000000000000000017000000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/ScrollbarRightPressed@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/Scrollba0000644000015301777760000000157112321005637033144 0ustar pbusernogroup00000000000000PNG  IHDR'gAMA abKGD pHYs  tIME 2IDATH͕Ok^EϽhU4I-A ,;7~mDX ZPixcIhwf$ܧÅ3<9#"W;fv mPacgg p ́,[?xJ. H! .J0QD3%AT*5a;nn~5`<~8;\TsajQUU5Rq;'^]iQ,_QWV}~v~ccm߿>^㽕e5P7&G6V@fHQ͈n7ų!"BDAUXZZpuu]u1scJi$ DHi;rR.`Sb)eT3]Q9٬F7Vyx:c>&r),d2x`xιA"(Ѧ* YHQp(V+M%'T 'FPQL}߳cft}@up^UUPs`-f -gf2$gMo__(zuV搨jz8UGE*pQ$d£ߟP"kf33ܛ6N0߼V}PuRPw}/-fFD͡-ͽ7?PM{=|Qk#'pJi> Ó0RJuxKW:לLH7D6IENDB`././@LongLink0000000000000000000000000000016400000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/ScrollbarLeftIdle@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/Scrollba0000644000015301777760000000147312321005637033145 0ustar pbusernogroup00000000000000PNG  IHDR#륱gAMA abKGD pHYs  tIME +ρzgIDAT8ŕnEYN.VqMLr[ip\ q# {v0㵍TVz+Q+7brfiucfx<?mfb嶺ONN&ã'je_ZHc>(Sr&̯n Xm'Ǔr7"@Uz3vC5#ќ 7Rx*Zn5'@S質>O%]ױZutw{g~?<4bIj$M}%Es$~'=cw-9%])wlb$%EDDRB4B) wCfFAtN5BW լk_6_kua%P[H*f)"JRQg^Qܝ'"8;9"4[#wJo{ͨՖjմNP<w#i:䅪݇jb4ѾҶF#î[QJ%"X. @ӏ##IDATx}ieuީ.o~tg2ʤ([r$P,$ N0'? H8ر 81q %RHY.!gwSUat0mթ|ԩo=:P\' F ~uF} 6@t.uaPVhȎmB} 9vsy(EU aƀi|Ak2<'ĆY'LrqSx!Lڵ*aMP~K k}"o~1p76l] 8gYTLOV ^Kk+<"\ˢI3΍DVQ3}\?]Κ/ ZCC.FbK:Z+ a ԜSGFéODh51l2 kdفJ΢`6؂)@AkUE!<͚NȺͽ4AB3dE& H)FӅ!2b'I8-M Mv*0Tr 1L) Cs~[,>5|SЯ]P)Nkh=X=3O/9>E_0!?)LZsbO-~{B\5nZ*ZU=c1jhc䄜c6|?@DNWV{Ma D$xqӔ^I0*owߞnkxOOPKICnn=-gBb3Y@c<@'8#ÞÓ8]AS C>3ƁM-+xXTD- TsmhdHa~}BS&[qgDZk0xT /)+5'A8hqXyU9g:ѫ`cUQIn(8|_W#nƕa_C_wcQWs!K6OЭ_cC ,O6e#Jrݞ3FMv~~&Y?L^Hoh:!_ [/7>“h_^`Cq&tՂE)*ڕ[sުT]uPwuD2mJ84jvs Zxg ~u'Iѵ'kּ~o::g%'Ȼf_dkÀPW+ *[&#!j0B8࿖5ěT7sxBO7O}aI>-W>g5/5ݕRt߮ztZF 9xrL֚9̀- 1zZ؇O>O˗ *;܏|"l ,}FDc3hԹ4q BE f9'PoWMׂ_ /Y_Jş3 NAyQ$FP`_uZ=r>:]01!onȂ.!-sr%vbEyd r]EajߔEfMwszt@162 YH,a%LLW ѩ_~u4`bni8˄(jgP,jyti2)k~`W U꿶-rnHl7uD~C LAwLlb:A;dٸc}kQ)Tj n)f*/ O{?-Vȿ| y8;;/HY&fh=מsoznVY?F@0r*^S5JI$~RNvpT M<74>ww}6^9J 65m`R2fXh gͯ\|ZyF|{ꗸ,-iCi Q!O꣠3{Q*w*Mܱ ʫ;3Ay/J%6ܸF1o#߼GbOg𷚾ۀcaB}d\dH3ŎoN{Xq-ECUЁaJt`SqÖ(j*()eg~_9O:7~_Biz'W[rC JDfKU6Tӻ:~ٷ#-D]v/gd(^h%LڡKv=<3Je%g.5p+C5F ˇY C Y8P3q=Ȕm2IAMsؕCWE dk1PWzxazA>[`Wg ` [XP ԁFmA) #B wT2.I< x6޾PQAFC B?h$oFύ`묀rl`s5X n|(HH A~PSjU[&:\p\h#:ְʗeZ4H%*3쏪WD. T l @eu ̈>[G̶-ˍF]OXQ%茖A7:2 ˺)"eصp-2 dޏ C`UԭԘ1y"+P1276 3!{ FEܣ $Ӭd~e0=L?BCfRC* 7VR#* !I*6U/WyS%.32-ؙOǿ2kjA2wLIfcwb^\ʎ(_:hTN $**؍ѲqS8(]LXԮVh+FjxVXȱJh~X1y#%%.ۿgmA6L;*~0flmFXvn-~$J{ Tl /Njtl"M-/oqGq#fvf+WǺy#4­on_ɞ94G*>XKD Ct4B w(mRaW=lwmQ#]GnF~A܁!_%!ׁ}4&M=1IԮNJd%2@SP?`/Ena9OUDu+&#ׇ҆͞; ˍv`܇) £Lcڕ&@H2R*b5vtr^øb amd 3ڲ*Edwu$MvVm36c&ɋJqa.LupkDp*qǁ2ДͺlRVs62[ @oWrјjjBw5z bC&mıc6j<+ο癩$ %L#TGs9_j L=ɝGtdc}ɹdj>m~KBHL _DiG!,yDĝ(#nlGd>GuY:L~B(̰s:hy$Jywq "3L*@Ōҥ#hrj Br%9}OJJji5sm'BO0+9~khY![e ڔEA@ER#iY~%5ftfEԱ}hC y) %GHhm̍>h)+ K(>ʏq5>`3Lk;ՔXnYnرt^ࡁ:DJA;fU6G6v}1R2ҐSeD4ذ)vU.޴Ѵ({!9>M%5oTLԹv@X:nҥ(n 8z +iPSfv 2lɣ`L$K{NOЈZ`qI``:\<✭`4 )Ju@'ρ V &θN+X[d4H¤Y/<DsCs;vr{D,epYWvh`'t(ߎ@t37JQWKP؁Y ٹUhRڮaBKwoZJ| ^'{-mvKmJnyY}]&W|NOdKp6]Ӣ9ܩ*6itnӸ9M:d݉ۨY}$s <|`+VZte5hYqV;igk(#fQ^PZ ܐvkZ]Cd].lhĻ%*cuXə]iI#sbCt%):igN aC]Z΅Hw- : 2QcҥbvRYl%a_wy{܇ݽr3=߼2ڶLT9fek0J 8ͼe)ZBkdYSQy(A 3Tңc1ޅth6\P^,\UEGÙ=vg\vFDw=o6m7 ˯E˺)Vy؛JH[>FEm}T[V 6uq5f ~>;oxwZnL 'V~v dB\Y?ܺQ]an:ԣrD&LW?RX?·Gl|R TW}q=^vfÚCax#_@ _/TЦ+iC 5sx#P)[|5P K>y4iNwf*q[q{ў:=Y7Hb_rg[H&G沯t>)?'}ᕧ#[\7qSCXl7L~{DfxM0=$˓jR $qS_(|@A޷qi`$VԆz(.S'PS4 @P2VC$v%3g~<|kl5l毢}crv)V҆hmѪKv5(4۪iت[eR[x*+ZVR}Oxyj0Ti5x +{̝lvQ1*Q\F,-xa s~ZR`Oz+A) h?3wUO3/׏|96CFCQ oc<ł;.͸.ЙKd:^U6K!8NUQgtnI^ܟ&n houޞ_WLLƌZԮ?Ǵ[o5œktG~k=^6u/}\!@~[E )r3Y|'ڗ=۪$U%*|n P4:ʙq=3[QS7-&`CԩTVR)c Z^l;9@ ~ObKfVZ4&^vLT (Ɓ\iqKsi Wtj]Z'iތ'7N&1F&v9+[}%rtr\ <~h..EyP2N __\@1Íg>P*qͯf" Zؙ9GC6v2*:ˬFdY.Z/6hxh{V%..e%\v#On՝VM lR[P4%n`9eTFBIkӭh`Z.iFD<H)aCzTmcbV۵X_pevZϕ͎);ۚ}5ٵBצ7ߨMIjwyx*Eˉ?V&y8UW2k3H1,͛h׳znCMlmȍx">=| iو毯b^smJ F h״sI`~]Ng0Kn Fsx?ӡUv1|; NJ?]z 6y`750:!u~}X;!\ X̸] l4!gEY2 (ZCp6SnSMvNsw?JjoXd*{7gvyR5M֗a[nRm N-A dłW;UM܌bHlĝ`>7|VPaI]c+M㏊抢eK_ˊ$ 70WDs{mJSi;xz6w=,e*k|4GqKH"#5JlZh{O% v7!cRn`y[ L }lU(8U{xmf2&۩\TPdc+1[JTxMqw}R-tޡ_ )Gt9mJq6y/pv"UX -;a4nkuDe~ȟz_{Kzi>d^9{r%HEef.˻W'QpTzWcC@Θ ijV1ZP[eᄀwbs5-o׀׍<ޯ@ént3he=HUOyZ ea  7L= !We -9Lszi_Wa{#%iuyU<3Hu8‹9DAzMb|q`q!D=Sd;mIENDB`././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_shadow@8.sciubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/bubble_s0000644000015301777760000000025412321005637033155 0ustar pbusernogroup00000000000000border.top: 22 border.bottom: 22 border.left: 21 border.right: 21 horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch source: bubble_shadow@8.png ././@LongLink0000000000000000000000000000016300000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/ScrollbarTopIdle@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/Scrollba0000644000015301777760000000320312321005637033136 0ustar pbusernogroup00000000000000PNG  IHDR#z;9tEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp V(IDATxڄUMo1miPXVTJ BO(79;PUڨ!dl3c{4m6[9>>tz İxgwū7LExiF=zG1 CEQy{e)0L3 2 j-nS2CFTly)P}Kw%œs2,0x!yCgZuʁCF鵲/x5w 0+J^4M7là4흝BjGNѰ?u r(vRK@ҟD 6&s,2UB$tpK Rx"[Ds2RBMj[CwR-[™ҷWJBGfCaev ip&0TU," P(tPXȊ5gPPVAU*=dyK92_4tffT4>wd>NQjtei[͚sw6ӏgآ*9UMctRsؓ\#O!( W-kRkѸ.u wkW. 0_1AvI3GPKL=uIPC! VU Tcw?[fe|N7=*IENDB`././@LongLink0000000000000000000000000000017600000000000011221 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/PageHeaderBaseDividerLight@18.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/PageHead0000644000015301777760000000166312321005637033043 0ustar pbusernogroup00000000000000PNG  IHDR"b8tEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp %IDATxba``pf ~M F*  ewLx6IENDB`././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/clear@30.svgubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/clear@300000644000015301777760000001063012321005637032730 0ustar pbusernogroup00000000000000 image/svg+xml ././@LongLink0000000000000000000000000000016600000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/ScrollbarBottomIdle@8.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/Scrollba0000644000015301777760000000332112321005637033137 0ustar pbusernogroup00000000000000PNG  IHDR'?y/tEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp }OEIDATxڄUOOSA@ MlQPD=/~=x`BbMB4" #x]g,姏?yjw`c==<χ%(ϔ^zlee},b0FAgoP( %TWA1h}hc @\\C }.q#/,@KXb r)en(-`}th$h@+1ڌ49q >bs.xhB1hQkeQo=Zi2W3_Q3rlYJeH 0\_RȪ&NX^^06Apa̔)92fzY鉣щL(;9I&*IJєTOI&jHAK`9R;ӓu\֣wUx $ZTnYE d"dm1H6tfƑJ1H 94^9/][yxް7oAȡ `gwo[\.r9Ns|_y.upy=,XyK_>^Gr0u ҡh<g< G]4>:vxрH؞0Kx>1d0mNC{z^."q\`cwNaSYE'2qllS`ە[>^,‡ptȐm ,{{cb7] Ǧfm_}(˰;(F{]Vzc|LHuD8&0koh )uUe;fmwz2%.":60KouZ GĄ?Wn0u2C\UO4x;͇$ ld8d]&dm$WuDG>e;**WRħ}icp4MxU|[3i*t?eYDsciz_E-L4+MSG[;?gwI$+6.69]Q;>E86"~sܡSpTk F)j@j&4J<6/X*8ӻH㱫 FhG9tHMh>Rw/I߭5JF+kޞ F5uYc4}lBs(ăEC}{ʘr-Ȧ&&p-oM,y8PC˄Q^1a@es禎x]EbQlOʤp HM?ƱjAOs!iæ%L"1i۪ęx\eYM8-!(%oY\Vpq_m{"1"brJ,溨ۜ.\H[ʞw k BE'bD`pIENDB`././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/chevron@27.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/artwork/chevron@0000644000015301777760000000306012321005637033142 0ustar pbusernogroup00000000000000PNG  IHDRD}>0tEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp ́IDATxKHQǿkWmQ.\hֺa06F^D). aٻ  PEz@4[7z\?f.wKRAw%)$`7y(RXb7 ZJyF)(C|^EJ  JzqAcu8-ԶkVϔvC Pd3IDATx|UOQcHIMB? L.H iq5X0 YH=H/08I"xŵ!|Ą$"%5isj$'Mm#ř950ڀZi3S#&0$fљġTj,;hDIw)?DC0!o,"A42 8r89ZqvOE T0#S'Ue& 7%A*0c]>]b1V>r6L0U 'Ԕ \ 5z{ !ȴ P;?y1ФrxVT..YN$!dic/?ZJT^]]Z__W.v=8??<===k4tuM,$G<]]4. */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: visuals // styling properties property color color: Theme.palette.normal.overlay anchors.fill: parent Rectangle { id: background anchors.fill: parent color: visuals.color } Image { id: dropshadow anchors { left: parent.left right: parent.right bottom: background.top } source: Qt.resolvedUrl("artwork/toolbar_dropshadow.png") opacity: styledItem.opened || styledItem.animating ? 0.5 : 0.0 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } } } } ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PickerDelegateStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PickerDelegateSt0000644000015301777760000000413312321005637033066 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { property real minFade: 0.2 property real maxFade: 0.95 property bool fadingEnabled: true property bool inListView: styledItem.parent && (QuickUtils.className(styledItem.parent) !== "QQuickPathView") property Item itemList: inListView ? styledItem.ListView.view : styledItem.PathView.view property Item picker: styledItem.picker property Item highlightItem: itemList.highlightItem Binding { target: styledItem when: fadingEnabled property: "opacity" value: opacityCalc() } function opacityCalc() { if (!picker || !highlightItem || (index === itemList.currentIndex)) return 1.0; var highlightY = highlightItem.y; var delegateY = styledItem.y; if (inListView) { highlightY -= itemList.contentY; delegateY -= itemList.contentY; } var midY = delegateY + styledItem.height / 2; if (delegateY < highlightY) { return MathUtils.clamp(MathUtils.projectValue(midY, 0, highlightY, minFade, maxFade), minFade, maxFade); } var highlightH = highlightY + highlightItem.height; if (delegateY >= highlightH) { delegateY -= highlightH; midY = delegateY + styledItem.height / 2; return MathUtils.clamp(1.0 - MathUtils.projectValue(midY, 0, highlightY, minFade, maxFade), minFade, maxFade); } return 1.0; } } ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicato0000644000015301777760000000217512321005637033162 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Image { id: container anchors.fill: parent smooth: true visible: styledItem.running fillMode: Image.PreserveAspectFit horizontalAlignment: Image.AlignHCenter verticalAlignment: Image.AlignVCenter source: "artwork/spinner.png" NumberAnimation on rotation { running: styledItem.running from: 0 to: 360 loops: Animation.Infinite duration: UbuntuAnimation.SleepyDuration } } ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PopoverForegroundStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PopoverForegroun0000644000015301777760000000213012321005637033223 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 BubbleShape { property alias contentItem: content target: styledItem.target direction: styledItem.direction clipContent: styledItem.clipContent onShowCompleted: styledItem.showCompleted() onHideCompleted: styledItem.hideCompleted() Item { id: content anchors.fill: parent Connections { target: styledItem onShow: show() onHide: hide() } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PickerStyle.qml0000644000015301777760000000732412321005637032742 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 Item { id: control // style properties /*! Specifies the background color */ property color backgroundColor: "#0A000000" /*! Background color for highlight. */ property color highlightBackgroundColor: "#ffffffff" /*! Highlight color. */ property color highlightColor: UbuntuColors.orange /*! Scale of the highlight item */ property real highlightScaleFactor: 1.2 /*! Thickness of the highlight component */ property real highlightThickness: units.gu(5) /*! The content holder exposed to the Picker so tumbler list can be reparented to it. */ property alias tumblerHolder: content /*! \internal View instance listing the model */ property Item view: Item{} anchors.fill: parent // frame UbuntuShape { anchors.fill: parent radius: "medium" color: Theme.palette.normal.overlay image: shapeSource } ShaderEffectSource { id: shapeSource sourceItem: background hideSource: true // FIXME: visible: false prevents rendering so make it a nearly // transparent 1x1 pixel instead opacity: 0.01 width: 1 height: 1 } Rectangle { id: background anchors.fill: parent MouseArea { anchors.fill: parent } // background color: backgroundColor Item { id: content anchors.fill: parent } // highlight Rectangle { id: highlightItem y: (content.height - control.highlightThickness) / 2 anchors { left: content.left right: content.right } height: control.highlightThickness color: highlightBackgroundColor } ThinDivider { anchors { left: content.left right: content.right bottom: highlightItem.top } } ThinDivider { anchors { left: content.left right: content.right top: highlightItem.bottom } } ShaderEffectSource { id: effectSource visible: false sourceItem: view property real sourceRectMultiplier: 2.0 // XXX: This works because the parent of magnifier is the same as sourceItem // in this case. Otherwise coordinate transformations will be needed. sourceRect: Qt.rect(highlightItem.x, highlightItem.y, highlightItem.width, highlightItem.height) textureSize: Qt.size(highlightItem.width*sourceRectMultiplier, highlightItem.height*sourceRectMultiplier) } HighlightMagnifier { anchors.fill: highlightItem scaleFactor: control.highlightScaleFactor outputColor: control.highlightColor source: effectSource } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/SwitchStyle.qml0000644000015301777760000001140712321005637032763 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: switchStyle property real thumbPadding: units.gu(0.5) /* FIXME: setting the width and height is required because in the case no width is set on the Switch, then even though the width is set eventually to implicitWidth, it still goes through the value 0.0 which triggers an undesired animation if the Switch is checked. Example, values of width at instantiation: width = 0.0 (before SwitchStyle is loaded) width = implicitWidth (after SwitchStyle is loaded) */ width: implicitWidth height: implicitHeight implicitWidth: units.gu(8) implicitHeight: units.gu(4) opacity: styledItem.enabled ? 1.0 : 0.5 LayoutMirroring.enabled: false LayoutMirroring.childrenInherit: true UbuntuShape { id: background anchors.fill: parent color: Theme.palette.normal.base clip: true UbuntuShape { id: thumb width: (background.width - switchStyle.thumbPadding * 3.0) / 2.0 x: styledItem.checked ? rightThumbPosition.x : leftThumbPosition.x anchors { top: parent.top bottom: parent.bottom topMargin: switchStyle.thumbPadding bottomMargin: switchStyle.thumbPadding } color: styledItem.checked ? Theme.palette.selected.foreground : Theme.palette.normal.foreground Behavior on x { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration easing: UbuntuAnimation.StandardEasing } } Behavior on color { ColorAnimation { duration: UbuntuAnimation.BriskDuration easing: UbuntuAnimation.StandardEasing } } PartialColorize { anchors { verticalCenter: parent.verticalCenter right: parent.left rightMargin: switchStyle.thumbPadding * 3.0 } rightColor: Theme.palette.normal.backgroundText source: Image { source: "artwork/cross.png" } } PartialColorize { anchors { verticalCenter: parent.verticalCenter left: parent.right leftMargin: switchStyle.thumbPadding * 2.0 } rightColor: Theme.palette.normal.backgroundText source: Image { source: "artwork/tick.png" } } } Item { id: leftThumbPosition anchors { left: parent.left top: parent.top leftMargin: switchStyle.thumbPadding topMargin: switchStyle.thumbPadding } height: thumb.height width: thumb.width PartialColorize { anchors.centerIn: parent source: Image { source: "artwork/cross.png" } progress: MathUtils.clamp((thumb.x - parent.x - x) / width, 0.0, 1.0) leftColor: "transparent" rightColor: Theme.palette.selected.foregroundText } } Item { id: rightThumbPosition anchors { right: parent.right top: parent.top rightMargin: switchStyle.thumbPadding topMargin: switchStyle.thumbPadding } height: thumb.height width: thumb.width PartialColorize { anchors.centerIn: parent source: Image { source: "artwork/tick.png" } progress: MathUtils.clamp((thumb.x + thumb.width - parent.x - x) / width, 0.0, 1.0) leftColor: Theme.palette.selected.foregroundText rightColor: "transparent" } } } } ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DialerHandStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DialerHandStyle.0000644000015301777760000000377612321005637033015 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { // style API property alias handPointer: pointer function handPreset(index, property) { switch (property) { case "width" : return (index === 0) ? units.gu(0.8) : units.gu(0.5); case "height": return (index === 0) ? dialer.handSpace /2 : (index === 2) ? dialer.handSpace + units.gu(1.5) : dialer.handSpace - units.gu(1.5); case "z": return (index === 2) ? -1 : 0; case "visible": case "draggable": return true; case "toCenterItem": return false; default: return undefined; } } // style anchors.fill: parent transformOrigin: Item.Center Rectangle { id: pointer x: (parent.width - width) / 2 y: styledItem.dialer.handSpace - (styledItem.hand.toCenterItem ? 0 : styledItem.hand.height) width: styledItem.hand.width height: styledItem.hand.height radius: units.gu(1) color: styledItem.hand.visible ? Theme.palette.normal.baseText : "#00000000" antialiasing: true } Behavior on rotation { enabled: !styledItem.hand.draggable RotationAnimation { direction: RotationAnimation.Shortest } } } ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DatePickerStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/DatePickerStyle.0000644000015301777760000001141212321005637033017 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 Item { id: control // style properties /*! Specifies the background color */ property color backgroundColor: "#0A000000" /*! Background color for highlight. */ property color highlightBackgroundColor: "#ffffffff" /*! Highlight color. */ property color highlightColor: UbuntuColors.orange /*! Scale of the highlight item */ property real highlightScaleFactor: 1.2 /*! Thickness of the highlight component */ property real highlightThickness: units.gu(5) /*! The content holder exposed to the Picker so tumbler list can be reparented to it. */ property alias tumblerHolder: content /*! The property holds the separator to be shown between date and time units */ property string unitSeparator: "" property Item view: Item {} property ListModel pickerModels: ListModel{} anchors.fill: parent // frame UbuntuShape { anchors.fill: parent radius: "medium" image: shapeSource } ShaderEffectSource { id: shapeSource sourceItem: background hideSource: true // FIXME: visible: false prevents rendering so make it a nearly // transparent 1x1 pixel instead opacity: 0.01 width: 1 height: 1 } Rectangle { id: background anchors.fill: parent MouseArea { anchors.fill: parent } // background color: backgroundColor Item { id: content anchors.fill: parent } // highlight Rectangle { id: highlightItem y: (content.height - control.highlightThickness) / 2 anchors { left: content.left right: content.right } height: control.highlightThickness color: highlightBackgroundColor } ThinDivider { anchors { left: content.left right: content.right bottom: highlightItem.top } } ThinDivider { anchors { left: content.left right: content.right top: highlightItem.bottom } } ShaderEffectSource { id: effectSource visible: false sourceItem: view property real sourceRectMultiplier: 2.0 // XXX: This works because the parent of magnifier is the same as sourceItem // in this case. Otherwise coordinate transformations will be needed. sourceRect: Qt.rect(highlightItem.x, highlightItem.y, highlightItem.width, highlightItem.height) textureSize: Qt.size(highlightItem.width*sourceRectMultiplier, highlightItem.height*sourceRectMultiplier) } Row { id: magnifierRow anchors { top: highlightItem.top bottom: highlightItem.bottom horizontalCenter: highlightItem.horizontalCenter } Repeater { model: pickerModels HighlightMagnifier { anchors { top: magnifierRow.top bottom: magnifierRow.bottom } width: pickerModel.pickerWidth scaleFactor: control.highlightScaleFactor outputColor: control.highlightColor source: effectSource texCoordRange: Qt.rect((x - source.sourceRect.x) / source.sourceRect.width, 0.0, width / source.sourceRect.width, 1.0); Label { text: (index < (pickerModels.count - 1)) ? unitSeparator : "" anchors { right: parent.right verticalCenter: parent.verticalCenter } } } } } } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/CheckBoxStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/CheckBoxStyle.qm0000644000015301777760000000746612321005637033046 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: checkBoxStyle /*! The image to show inside the checkbox when it is checked. */ property url tickSource: "artwork/tick.png" opacity: enabled ? 1.0 : 0.5 implicitWidth: units.gu(4.25) implicitHeight: units.gu(4) UbuntuShape { id: background anchors.fill: parent anchors.margins: units.gu(0.5) } Image { id: tick anchors.centerIn: parent smooth: true source: tickSource visible: styledItem.checked || transitionToChecked.running || transitionToUnchecked.running } state: styledItem.checked ? "checked" : "unchecked" states: [ State { name: "checked" PropertyChanges { target: tick anchors.verticalCenterOffset: 0 } PropertyChanges { target: background color: Theme.palette.selected.foreground } }, State { name: "unchecked" PropertyChanges { target: tick anchors.verticalCenterOffset: checkBoxStyle.height } PropertyChanges { target: background color: Theme.palette.normal.foreground } } ] transitions: [ Transition { id: transitionToUnchecked to: "unchecked" ColorAnimation { target: background duration: UbuntuAnimation.BriskDuration easing: UbuntuAnimation.StandardEasingReverse } SequentialAnimation { PropertyAction { target: checkBoxStyle property: "clip" value: true } NumberAnimation { target: tick property: "anchors.verticalCenterOffset" duration: UbuntuAnimation.BriskDuration easing: UbuntuAnimation.StandardEasingReverse } PropertyAction { target: checkBoxStyle property: "clip" value: false } } }, Transition { id: transitionToChecked to: "checked" ColorAnimation { target: background duration: UbuntuAnimation.BriskDuration easing: UbuntuAnimation.StandardEasing } SequentialAnimation { PropertyAction { target: checkBoxStyle property: "clip" value: true } NumberAnimation { target: tick property: "anchors.verticalCenterOffset" duration: UbuntuAnimation.BriskDuration easing: UbuntuAnimation.StandardEasing } PropertyAction { target: checkBoxStyle property: "clip" value: false } } } ] } ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ToolbarButtonSty0000644000015301777760000000330312321005637033203 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: visuals // styling properties property int iconWidth: units.gu(2) property int iconHeight: units.gu(2) anchors.fill: parent Item { anchors.centerIn: parent height: icon.height + label.height + label.anchors.topMargin opacity: styledItem.enabled ? 1.0 : 0.3 Image { id: icon anchors { top: parent.top horizontalCenter: parent.horizontalCenter } width: iconWidth height: iconWidth source: styledItem.iconSource } Label { id: label anchors { horizontalCenter: parent.horizontalCenter top: icon.bottom topMargin: units.gu(1) } width: paintedWidth text: styledItem.text fontSize: "x-small" color: Theme.palette.normal.overlayText } } Component.onCompleted: styledItem.implicitWidth = implicitWidth } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ButtonStyle.qml0000644000015301777760000001033312321005637032772 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: buttonStyle property Button button: styledItem property real minimumWidth: units.gu(10) property real horizontalPadding: units.gu(1) property color defaultColor: UbuntuColors.orange property Gradient defaultGradient width: button.width height: button.height implicitWidth: Math.max(minimumWidth, foreground.implicitWidth + 2*horizontalPadding) implicitHeight: units.gu(4) LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true /* The proxy is necessary because Gradient.stops and GradientStop.color are non-NOTIFYable properties. They cannot be written to so it is fine but the proxy avoids the warnings. */ QtObject { id: gradientProxy property color topColor property color bottomColor function updateGradient() { if (button.gradient) { topColor = button.gradient.stops[0].color; bottomColor = button.gradient.stops[1].color; } } Component.onCompleted: { updateGradient(); button.gradientChanged.connect(updateGradient); } } // Use the gradient if it is defined and the color has not been set manually // or the gradient has been set manually property bool isGradient: button.gradient && (button.color == defaultColor || button.gradient != defaultGradient) UbuntuShape { id: background anchors.fill: parent borderSource: "radius_idle.sci" visible: color.a != 0.0 // Color properties in a JS ternary operator don't work as expected in // QML because it overwrites alpha values with 1. A workaround is to use // Qt.rgba(). For more information, see // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1197802 and // https://bugreports.qt-project.org/browse/QTBUG-32238. function colorHack(color) { return Qt.rgba(color.r, color.g, color.b, color.a); } color: isGradient ? colorHack(gradientProxy.topColor) : colorHack(button.color) gradientColor: isGradient ? colorHack(gradientProxy.bottomColor) : colorHack(button.color) } UbuntuShape { id: backgroundPressed anchors.fill: parent color: background.color gradientColor: background.gradientColor borderSource: "radius_pressed.sci" opacity: button.pressed ? 1.0 : 0.0 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration easing.type: Easing.Linear } } visible: background.visible } ButtonForeground { id: foreground width: parent.width - 2*horizontalPadding anchors.centerIn: parent text: button.text /* Pick either a clear or dark text color depending on the luminance of the background color to maintain good contrast (works in most cases) */ textColor: ColorUtils.luminance(button.color) <= 0.85 ? "#F3F3E7" : "#888888" iconSource: button.iconSource iconPosition: button.iconPosition iconSize: units.gu(3) spacing: horizontalPadding transformOrigin: Item.Top scale: button.pressed ? 0.98 : 1.0 Behavior on scale { NumberAnimation { duration: UbuntuAnimation.SnapDuration easing.type: Easing.Linear } } } } ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ProgressBarStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ProgressBarStyle0000644000015301777760000000544612321005637033171 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: progressBarStyle property ProgressBar progressBar: styledItem implicitWidth: units.gu(38) implicitHeight: units.gu(4) UbuntuShape { id: background anchors.fill: parent /* The color must be white for PartialColorizeUbuntuShape to accurately replace the white with leftColor and rightColor */ color: progressBar.indeterminate ? Theme.palette.normal.base : "white" } property real progress: progressBar.indeterminate ? 0.0 : progressBar.value / (progressBar.maximumValue - progressBar.minimumValue) /* Colorize the background with rightColor and progressively fill it with leftColor proportionally to progress */ PartialColorizeUbuntuShape { anchors.fill: background sourceItem: progressBar.indeterminate ? null : background progress: progressBarStyle.progress leftColor: Theme.palette.selected.foreground rightColor: Theme.palette.normal.base mirror: Qt.application.layoutDirection == Qt.RightToLeft } Label { id: valueLabel anchors.centerIn: background fontSize: "medium" color: Theme.palette.normal.baseText text: progressBar.indeterminate ? i18n.tr("In Progress") : "%1%".arg(Number(progressBarStyle.progress * 100.0).toFixed(0)) SequentialAnimation on opacity { loops: Animation.Infinite running: progressBar.indeterminate UbuntuNumberAnimation { to: 0.2; duration: UbuntuAnimation.BriskDuration } UbuntuNumberAnimation { to: 1.0; duration: UbuntuAnimation.BriskDuration } } } PartialColorize { anchors.fill: valueLabel sourceItem: progressBar.indeterminate ? null : valueLabel leftColor: Theme.palette.selected.foregroundText rightColor: Theme.palette.normal.baseText progress: (progressBarStyle.progress * background.width - valueLabel.x) / valueLabel.width mirror: Qt.application.layoutDirection == Qt.RightToLeft } } ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/HighlightMagnifier.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/HighlightMagnifi0000644000015301777760000000403312321005637033110 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 ShaderEffect { id: magnifier property ShaderEffectSource source property real scaleFactor: 1.2 // Everything in the sourceItem that is not transparent will be made this color // in the output, but the transparency of the input is respected. property color outputColor: "red" // Specify the region of the sourceRect that must be enlarged as // x, y, width, height in texture coordinates. (0, 0, 1, 1) is full sourceRect. property rect texCoordRange: Qt.rect(0.0, 0.0, 1.0, 1.0); vertexShader: " uniform highp vec4 texCoordRange; attribute highp vec4 qt_Vertex; attribute highp vec2 qt_MultiTexCoord0; uniform highp mat4 qt_Matrix; uniform highp float scaleFactor; varying highp vec2 qt_TexCoord0; void main() { vec2 texCoord = vec2(0.5 - 1.0 / (2.0 * scaleFactor)) + qt_MultiTexCoord0 / vec2(scaleFactor); qt_TexCoord0 = texCoordRange.xy + texCoord*texCoordRange.zw; gl_Position = qt_Matrix * qt_Vertex; }" fragmentShader: " uniform lowp float qt_Opacity; varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform highp vec4 outputColor; void main() { lowp vec4 tex = texture2D(source, qt_TexCoord0); gl_FragColor = vec4(outputColor.rgb, outputColor.a*tex.a) * qt_Opacity; }" } ././@LongLink0000000000000000000000000000016400000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ListItemOptionSelectorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ListItemOptionSe0000644000015301777760000000156412321005637033127 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: ambianceStyle property url chevron: "../../artwork/chevron_down@30.png" property url tick: "../../artwork/tick@30.png" property bool colourComponent: true } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/BubbleShape.qml0000644000015301777760000001050712321005637032655 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: bubbleShape property point target property string direction: "down" property bool clipContent: false default property alias children: content.children property alias bubbleColor: colorRect.color property alias bubbleOpacity: colorRect.opacity // FIXME: This should not be necessary. See // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1214978 property alias arrowSource: arrow.source implicitWidth: units.gu(10) implicitHeight: units.gu(8) signal showCompleted() signal hideCompleted() opacity: 0.0 function show() { hideAnimation.stop(); showAnimation.start(); } function hide() { showAnimation.stop(); hideAnimation.start(); } ParallelAnimation { id: showAnimation NumberAnimation { target: bubbleShape property: "opacity" from: 0.0 to: 1.0 duration: UbuntuAnimation.FastDuration easing: UbuntuAnimation.StandardEasing } NumberAnimation { target: scaleTransform property: (direction === "up" || direction === "down") ? "yScale" : "xScale" from: 0.91 to: 1.0 duration: UbuntuAnimation.FastDuration easing: UbuntuAnimation.StandardEasing } onStopped: showCompleted() } NumberAnimation { id: hideAnimation target: bubbleShape property: "opacity" from: 1.0 to: 0.0 duration: UbuntuAnimation.FastDuration easing: UbuntuAnimation.StandardEasing onStopped: hideCompleted() } transform: Scale { id: scaleTransform origin.x: direction === "right" ? bubbleShape.width : direction === "left" ? 0 : bubbleShape.width/2.0 origin.y: direction === "up" ? 0 : direction === "down" ? bubbleShape.height : bubbleShape.height/2.0 } BorderImage { id: shadow anchors.fill: parent anchors.margins: -units.gu(0.5) source: "artwork/bubble_shadow.sci" } UbuntuShape { anchors.fill: parent borderSource: "none" color: Theme.palette.normal.overlay image: bubbleShape.clipContent ? shapeSource : null } ShaderEffectSource { id: shapeSource visible: bubbleShape.clipContent sourceItem: bubbleShape.clipContent ? content : null hideSource: true // FIXME: visible: false prevents rendering so make it a nearly // transparent 1x1 pixel instead opacity: 0.01 width: 1 height: 1 } Item { id: content anchors.fill: parent Rectangle { id: colorRect anchors.fill: parent color: Theme.palette.normal.overlay visible: bubbleShape.clipContent } } Item { x: target.x y: target.y Image { id: arrow visible: bubbleShape.direction != "none" property var directionToRotation: {"down": 0, "up": 180, "left": 90, "right": -90, "none": 0 } x: -width / 2.0 y: -height transformOrigin: Item.Bottom rotation: directionToRotation[bubbleShape.direction] source: "artwork/bubble_arrow.png" } } } ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TextFieldStyle.q0000644000015301777760000000125512321005637033061 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 TextAreaStyle { } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/HeaderStyle.qml0000644000015301777760000000617012321005637032713 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: headerStyle /*! The height of the headercontents, which is the full height of the header minus the separators shown at the bottom of it. */ property real contentHeight: units.gu(7.5) /*! The source of the image that separates the header from the contents of a \l MainView. The separator will be drawn over the contents. */ property url separatorSource: "artwork/PageHeaderBaseDividerLight.sci" /*! The source of an additional image attached to the bottom of the separator. The contents of the \l MainView will be drawn on top of the separator bottom image. */ property url separatorBottomSource: "artwork/PageHeaderBaseDividerBottom.png" property int fontWeight: Font.Light property string fontSize: "x-large" property color textColor: Theme.palette.selected.backgroundText property real textLeftMargin: units.gu(2) implicitHeight: headerStyle.contentHeight + separator.height + separatorBottom.height BorderImage { id: separator anchors { bottom: parent.bottom left: parent.left right: parent.right } source: headerStyle.separatorSource } Image { id: separatorBottom anchors { top: separator.bottom left: parent.left right: parent.right } source: headerStyle.separatorBottomSource } Item { id: foreground anchors { left: parent.left right: parent.right top: parent.top } height: headerStyle.contentHeight Label { LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft anchors { left: parent.left verticalCenter: parent.verticalCenter leftMargin: headerStyle.textLeftMargin } text: styledItem.title font.weight: headerStyle.fontWeight visible: !styledItem.contents fontSize: headerStyle.fontSize color: headerStyle.textColor } Binding { target: styledItem.contents property: "anchors.fill" value: foreground when: styledItem.contents } Binding { target: styledItem.contents property: "parent" value: foreground when: styledItem.contents } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/SliderStyle.qml0000644000015301777760000000753512321005637032753 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /* The default slider style consists of a bar and a thumb shape. This style is themed using the following properties: - thumbSpacing: spacing between the thumb and the bar */ Item { id: sliderStyle property real thumbSpacing: units.gu(0) property Item bar: background property Item thumb: thumb implicitWidth: units.gu(38) implicitHeight: units.gu(5) UbuntuShape { id: background anchors { verticalCenter: parent.verticalCenter right: parent.right left: parent.left } height: units.dp(4) color: "white" } PartialColorizeUbuntuShape { anchors.fill: background sourceItem: background progress: thumb.x / thumb.barMinusThumbWidth leftColor: Theme.palette.selected.foreground rightColor: Theme.palette.normal.base mirror: Qt.application.layoutDirection == Qt.RightToLeft } UbuntuShape { id: thumb anchors { verticalCenter: parent.verticalCenter topMargin: thumbSpacing bottomMargin: thumbSpacing } property real barMinusThumbWidth: background.width - (thumb.width + 2.0*thumbSpacing) property real position: thumbSpacing + SliderUtils.normalizedValue(styledItem) * barMinusThumbWidth property bool pressed: SliderUtils.isPressed(styledItem) property bool positionReached: x == position x: position /* Enable the animation on x when pressing the slider. Disable it when x has reached the target position. */ onPressedChanged: if (pressed) xBehavior.enabled = true; onPositionReachedChanged: if (positionReached) xBehavior.enabled = false; Behavior on x { id: xBehavior SmoothedAnimation { duration: UbuntuAnimation.FastDuration } } width: units.gu(2) height: units.gu(2) opacity: 0.97 color: Theme.palette.normal.overlay } BubbleShape { id: bubbleShape width: units.gu(8) height: units.gu(6) // FIXME: very temporary implementation property real minX: 0.0 property real maxX: background.width - width property real pointerSize: units.dp(6) property real targetMargin: units.gu(1) property point globalTarget: Qt.point(thumb.x + thumb.width / 2.0, thumb.y - targetMargin) x: MathUtils.clamp(globalTarget.x - width / 2.0, minX, maxX) y: globalTarget.y - height - pointerSize target: Qt.point(globalTarget.x - x, globalTarget.y - y) property bool pressed: SliderUtils.isPressed(styledItem) property bool shouldShow: pressed && label.text != "" onShouldShowChanged: if (shouldShow) { show(); } else { hide(); } Label { id: label anchors.centerIn: parent text: styledItem.formatValue(SliderUtils.liveValue(styledItem)) fontSize: "large" color: Theme.palette.normal.overlayText } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml0000644000015301777760000003622312321005735032657 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: tabBarStyle // used to detect when the user is interacting with the tab bar by pressing it // or dragging the tab bar buttons. readonly property bool pressed: mouseArea.interacting // styling properties, public API property color headerTextColor: Theme.palette.normal.backgroundText property color headerTextSelectedColor: Theme.palette.selected.backgroundText // Don't start transitions because of updates to selectionMode before styledItem is completed. // This fixes bug #1246792: "Disable tabs scrolling animations at startup" property bool animate: false Binding { target: tabBarStyle property: "animate" when: styledItem.width > 0 value: styledItem.animate } property int headerTextFadeDuration: animate ? 350 : 0 property url indicatorImageSource: "artwork/chevron.png" property string headerFontSize: "x-large" property int headerTextStyle: Text.Normal property color headerTextStyleColor: Theme.palette.normal.backgroundText property int headerFontWeight: Font.Light property real headerTextLeftMargin: units.gu(2) property real headerTextRightMargin: units.gu(2) property real headerTextBottomMargin: units.gu(2) property real buttonPositioningVelocity: animate ? 1.0 : -1 // The time of inactivity before leaving selection mode automatically property int deactivateTime: 5000 /* The function assures the visuals stay on the selected tab. This can be called by the stack components holding the tabs (i.e. Tabs, ListView, etc) and only when the changes happen on the list element values, which is not reported automaytically through ListModel changes. */ function sync() { buttonView.selectButton(styledItem.selectedIndex); } property var tabsModel : styledItem ? styledItem.model : null Connections { target: styledItem onSelectionModeChanged: { if (!styledItem.selectionMode) { buttonView.selectButton(styledItem.selectedIndex); } } } Connections { target: styledItem onSelectedIndexChanged: buttonView.selectButton(styledItem.selectedIndex) } /* Prevent events that are not accepted by tab buttons or mouseArea below from passing through the TabBar. */ MouseArea { anchors.fill: parent onReleased: { mouseArea.enteringSelectionMode = false; } } Component { id: tabButtonRow Row { id: theRow anchors { top: parent.top bottom: parent.bottom } width: childrenRect.width property int rowNumber: modelData Component.onCompleted: { if (rowNumber === 0) { buttonView.buttonRow1 = theRow; } else { buttonView.buttonRow2 = theRow; } } Repeater { id: repeater model: tabsModel AbstractButton { id: button anchors { top: parent.top bottom: parent.bottom } width: text.paintedWidth + text.anchors.leftMargin + text.anchors.rightMargin // When the tab bar is in selection mode, show both buttons corresponing to // the tab index as selected, but when it is not in selection mode only one // to avoid seeing fading animations of the unselected button when switching // tabs from outside the tab bar. property bool selected: (styledItem.selectionMode && buttonView.needsScrolling) ? styledItem.selectedIndex === index : buttonView.selectedButtonIndex === button.buttonIndex property real offset: theRow.rowNumber + 1 - button.x / theRow.width; property int buttonIndex: index + theRow.rowNumber*repeater.count // Use opacity 0 to hide instead of setting visibility to false in order to // make fading work well, and not to mess up width/offset computations opacity: isVisible() ? 1.0 : 0.0 function isVisible() { if (selected) return true; if (!styledItem.selectionMode) return false; if (buttonView.needsScrolling) return true; // When we don't need scrolling, we want to avoid showing a button that is fading // while sliding in from the right side when a new button was selected var numTabs = tabsModel.count; var minimum = buttonView.selectedButtonIndex; var maximum = buttonView.selectedButtonIndex + numTabs - 1; if (MathUtils.clamp(buttonIndex, minimum, maximum) === buttonIndex) return true; // working modulus numTabs: if (buttonIndex < buttonView.selectedButtonIndex - numTabs) return true; return false; } Behavior on opacity { NumberAnimation { duration: headerTextFadeDuration easing.type: Easing.InOutQuad } } Image { id: indicatorImage source: indicatorImageSource anchors { bottom: parent.bottom bottomMargin: headerTextBottomMargin } x: button.width - width // FIXME: temporary hack for the chevron's height to match the font size height: 0.82*sourceSize.height // The indicator image must be visible after the selected tab button, when the // tab bar is not in selection mode, or after the "last" button (starting with // the selected one), when the tab bar is in selection mode. property bool isLastAfterSelected: index === (styledItem.selectedIndex === 0 ? repeater.count-1 : styledItem.selectedIndex - 1) opacity: (styledItem.selectionMode ? isLastAfterSelected : selected) ? 1 : 0 Behavior on opacity { NumberAnimation { duration: headerTextFadeDuration easing.type: Easing.InOutQuad } } } Label { id: text color: selected ? headerTextSelectedColor : headerTextColor Behavior on color { ColorAnimation { duration: headerTextFadeDuration easing.type: Easing.InOutQuad } } anchors { left: parent.left leftMargin: headerTextLeftMargin rightMargin: headerTextRightMargin baseline: parent.bottom baselineOffset: -headerTextBottomMargin } text: (model.hasOwnProperty("tab") && tab.hasOwnProperty("title")) ? tab.title : title fontSize: headerFontSize font.weight: headerFontWeight style: headerTextStyle styleColor: headerTextStyleColor } onClicked: { if (mouseArea.enteringSelectionMode) { mouseArea.enteringSelectionMode = false; } else if (opacity > 0.0) { styledItem.selectedIndex = index; if (!styledItem.alwaysSelectionMode) { styledItem.selectionMode = false; } button.select(); } } onPressedChanged: { // Catch release after a press with a delay that is too // long to make it a click, but don't unset interacting when // the user starts dragging. In that case it will be unset in // buttonView.onDragEnded. if (!pressed && !buttonView.dragging) { // unset interacting which was set in mouseArea.onPressed mouseArea.interacting = false; } } // Select this button function select() { buttonView.selectedButtonIndex = button.buttonIndex; buttonView.updateOffset(button.offset); } } } } } /*! Used by autopilot tests to determine when an animation finishes moving. \internal */ readonly property alias animating: offsetAnimation.running PathView { id: buttonView anchors { top: parent.top bottom: parent.bottom left: parent.left } width: needsScrolling ? parent.width : buttonRowWidth // set to the width of one tabButtonRow in Component.onCompleted. property real buttonRowWidth: buttonRow1 ? buttonRow1.width : 0 // set by the delegate when the components are completed. property Row buttonRow1 property Row buttonRow2 // Track which button was last clicked property int selectedButtonIndex: -1 delegate: tabButtonRow model: 2 // The second buttonRow shows the buttons that disappear on the left property bool needsScrolling: buttonRowWidth > parent.width interactive: needsScrolling clip: needsScrolling highlightRangeMode: PathView.NoHighlightRange offset: 0 path: Path { startX: -buttonView.buttonRowWidth/2 PathLine { x: buttonView.buttonRowWidth*1.5 } } // x - y (mod a), for (x - y) <= a function cyclicDistance(x, y, a) { var r = x - y; return Math.min(Math.abs(r), Math.abs(r - a)); } // Select the closest of the two buttons that represent the given tab index function selectButton(tabIndex) { if (!tabsModel || tabIndex < 0 || tabIndex >= tabsModel.count) return; if (buttonView.buttonRow1 && buttonView.buttonRow2) { var b1 = buttonView.buttonRow1.children[tabIndex]; var b2 = buttonView.buttonRow2.children[tabIndex]; // find the button with the nearest offset var d1 = cyclicDistance(b1.offset, buttonView.offset, 2); var d2 = cyclicDistance(b2.offset, buttonView.offset, 2); if (d1 < d2) { b1.select(); } else { b2.select(); } } } function updateOffset(newOffset) { if (!newOffset) return; // do not update the offset when its value is NaN if (offset - newOffset < -1) newOffset = newOffset - 2; offset = newOffset; } Behavior on offset { SmoothedAnimation { id: offsetAnimation velocity: buttonPositioningVelocity easing.type: Easing.InOutQuad } } onDragEnded: { // unset interacting which was set in mouseArea.onPressed mouseArea.interacting = false; mouseArea.enteringSelectionMode = false; } Timer { id: idleTimer interval: tabBarStyle.deactivateTime running: styledItem.selectionMode && !styledItem.alwaysSelectionMode onTriggered: styledItem.selectionMode = false function conditionalRestartOrStop() { if (Qt.application.active && styledItem.selectionMode && !styledItem.alwaysSelectionMode && !mouseArea.interacting) { idleTimer.restart(); } else { idleTimer.stop(); } } } // disable the timer when the application is not active and reset // it when the application is resumed. Connections { target: Qt.application onActiveChanged: idleTimer.conditionalRestartOrStop() } Connections { target: styledItem onSelectionModeChanged: idleTimer.conditionalRestartOrStop() } } MouseArea { // a tabBar not in selection mode can be put in selection mode by pressing id: mouseArea anchors.fill: parent // set in onPressed, and unset in button.onPressedChanged or buttonView.onDragEnded // because after not accepting the mouse, the released event will go to // the buttonView or individual buttons. property bool interacting: false onInteractingChanged: idleTimer.conditionalRestartOrStop() // When pressing to enter selection mode, a release should not be interpreted // as a click on a button to select a new tab. property bool enteringSelectionMode: false // This MouseArea is always enabled, even when the tab bar is in selection mode, // so that press events are detected and tabBarStyle.pressed is updated. onPressed: { mouseArea.interacting = true; if (!styledItem.selectionMode) { mouseArea.enteringSelectionMode = true; } styledItem.selectionMode = true; mouse.accepted = false; } } Component.onCompleted: { tabBarStyle.sync(); } } ././@LongLink0000000000000000000000000000015500000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/SelectionCursorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/SelectionCursorS0000644000015301777760000000615212321005637033160 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 EditorCursorStyle { id: cursor blinking: false property bool startPin: (styledItem.positionProperty === "selectionStart") property int cursorPosition: styledItem.editorItem[styledItem.positionProperty] visible: true function updatePosition(pos) { if (undefined === pos) return; var rect = styledItem.editorItem.positionToRectangle(pos); x = rect.x; y = rect.y; } onCursorPositionChanged: updatePosition(cursorPosition) Rectangle { id: pinBall width: cursor.pinSize height: width radius: width smooth: true color: cursor.pinColor anchors { horizontalCenter: cursor.horizontalCenter bottom: startPin ? cursor.top : undefined top: !startPin ? cursor.bottom : undefined } MouseArea { id: dragArea anchors.fill: parent anchors.margins: -cursor.pinSensingOffset drag { target: Item{} axis: Drag.XandYAxis onActiveChanged: { if (drag.active) { cursorStartX = cursor.x cursorStartY = cursor.y dragStartX = dragArea.drag.target.x dragStartY = dragArea.drag.target.y } } } property real dragStartX property real dragStartY property real cursorStartX property real cursorStartY property real dragDX: dragArea.drag.target.x - dragArea.dragStartX property real dragDY: dragArea.drag.target.y - dragArea.dragStartY onDragDXChanged: updateEditorCursorPosition() onDragDYChanged: updateEditorCursorPosition() function updateEditorCursorPosition() { var pos = styledItem.editorItem.mapFromItem(styledItem, cursor.x, cursor.y + cursor.height / 2); var dx = dragArea.cursorStartX + dragDX; var dy = dragArea.cursorStartY + dragDY; if (startPin) styledItem.editorItem.select(styledItem.editorItem.positionAt(dx, dy), styledItem.editorItem.selectionEnd); else styledItem.editorItem.select(styledItem.editorItem.selectionStart, styledItem.editorItem.positionAt(dx, dy)); } } } } ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/TextCursorStyle.0000644000015301777760000000370312321005637033132 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 Item { id: visuals /*! Cursor color */ property color color: Theme.palette.selected.foreground /*! Properties driving cursor blinking. If either of these values are 0, no blinking is provided. */ property bool blinking: true property int blinkTimeoutShown: 800 property int blinkTimeoutHidden: 400 /*! Selection mode pin styles */ property var pinSize: units.gu(1.2) property var pinSensingOffset: units.dp(4) property color pinColor: Theme.palette.selected.foreground anchors.fill: parent Rectangle { id: cursor property bool showCursor: styledItem.visible property bool timerShowCursor: true visible: showCursor && timerShowCursor color: visuals.color anchors.fill: parent Timer { interval: visuals.blinkTimeoutShown running: cursor.showCursor && (visuals.blinkTimeoutShown > 0) && (visuals.blinkTimeoutHidden > 0) && visuals.blinking repeat: true onTriggered: { interval = (interval == visuals.blinkTimeoutShown) ? visuals.blinkTimeoutHidden : visuals.blinkTimeoutShown; cursor.timerShowCursor = !cursor.timerShowCursor; } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/qmldir0000644000015301777760000000227412321005637031203 0ustar pbusernogroup00000000000000module Ubuntu.Components.Themes.Ambiance internal ActivityIndicatorStyle ActivityIndicatorStyle.qml internal ButtonStyle ButtonStyle.qml internal CheckBoxStyle CheckBoxStyle.qml internal DialogForegroundStyle DialogForegroundStyle.qml internal HeaderStyle HeaderStyle.qml MainViewStyle 0.1 MainViewStyle.qml ListItemOptionSelector 0.1 ListItemOptionSelector.qml OptionSelectorStyle 0.1 OptionSelectorStyle.qml PopoverForegroundStyle 0.1 PopoverForegroundStyle.qml internal ScrollbarStyle ScrollbarStyle.qml internal SelectionCursorStyle SelectionCursorStyle.qml internal SheetForegroundStyle SheetForegroundStyle.qml internal SliderStyle SliderStyle.qml internal SwitchStyle SwitchStyle.qml TabBarStyle 0.1 TabBarStyle.qml TextAreaStyle 0.1 TextAreaStyle.qml internal TextCursorStyle TextCursorStyle.qml TextFieldStyle 0.1 TextFieldStyle.qml internal ToolbarButtonStyle ToolbarButtonStyle.qml internal ToolbarStyle ToolbarStyle.qml internal BubbleShape BubbleShape.qml PickerStyle 0.1 PickerStyle.qml DatePickerStyle 0.1 DatePickerStyle.qml PickerDelegateStyle 0.1 PickerDelegateStyle.qml DialerStyle 0.1 DialerStyle.qml DialerHandStyle 0.1 DialerHandStyle.qml internal HighlightMagnifier HighlightMagnifier.qml ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PartialColorize.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PartialColorize.0000644000015301777760000000336712321005637033100 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 ShaderEffect { id: partialColorize implicitWidth: source.implicitWidth implicitHeight: source.implicitHeight visible: source != null && source.visible property Item sourceItem property var source: ShaderEffectSource { hideSource: true sourceItem: partialColorize.sourceItem visible: sourceItem != null } property color leftColor property color rightColor property real progress property bool mirror: false property string texCoord: mirror ? "1.0 - qt_TexCoord0.x" : "qt_TexCoord0.x" fragmentShader: " varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform lowp vec4 leftColor; uniform lowp vec4 rightColor; uniform lowp float progress; uniform lowp float qt_Opacity; void main() { lowp vec4 sourceColor = texture2D(source, qt_TexCoord0); lowp vec4 newColor = mix(leftColor, rightColor, step(progress, " + texCoord + ")); gl_FragColor = newColor * sourceColor.a * qt_Opacity; }" } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/MainViewStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/MainViewStyle.qm0000644000015301777760000000520412321005637033063 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { // styling properties anchors.fill: parent z: -1 id: mainViewStyle /*! The background texture of the main view. The image will be drawn over the background color, so if it has (semi-)transparent pixels, in those pixels the background color will be visible. */ property url backgroundSource: "artwork/background_paper.png" Gradient { id: backgroundGradient GradientStop { position: 0.0; color: styledItem.headerColor } GradientStop { position: 0.83; color: styledItem.backgroundColor } GradientStop { position: 1.0; color: styledItem.footerColor } } Rectangle { id: backgroundColor anchors.fill: parent color: styledItem.backgroundColor gradient: internals.isGradient ? backgroundGradient : null } Image { id: backgroundTexture anchors.fill: parent source: mainViewStyle.backgroundSource fillMode: Image.Tile } QtObject { id: internals property bool isGradient: styledItem.backgroundColor != styledItem.headerColor || styledItem.backgroundColor != styledItem.footerColor /* As we don't know the order the property bindings and onXXXChanged signals are evaluated we should rely only on one property when changing the theme to avoid intermediate theme changes due to properties being evaluated separately. Qt bug: https://bugreports.qt-project.org/browse/QTBUG-11712 */ property string theme: (ColorUtils.luminance(styledItem.backgroundColor) >= 0.85) ? "Ambiance" : (isGradient ? "SuruGradient" : "SuruDark") } // automatically select the appropriate theme depending on the background colors Binding { target: Theme property: "name" value: "Ubuntu.Components.Themes.%1".arg(internals.theme) when: internals.theme !== "" } } ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/OptionSelectorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/OptionSelectorSt0000644000015301777760000000200012321005637033156 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: ambianceStyle property url chevron: "../../artwork/chevron_down@30.png" property url tick: "../../artwork/tick@30.png" property bool colourComponent: true UbuntuShape { id: background width: styledItem.width height: styledItem.height radius: "medium" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/Palette.qml0000644000015301777760000000266412321005637032104 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes 0.1 Palette { normal: PaletteValues { background: "#EDEDED" backgroundText: "#81888888" base: "#1A000000" baseText: "#888888" foreground: "#888888" foregroundText: "#F3F3E7" overlay: "#FDFDFD" overlayText: "#888888" field: "#1A000000" fieldText: "#888888" } selected: PaletteValues { /* FIXME: 'background' does not come from design it is used solely in the list items for the selection highlight that will go away with the new design. */ background: "#B2E6E6E6" backgroundText: "#888888" foreground: "#DD4814" foregroundText: "#F3F3E7" field: "#FFFFFF" fieldText: "#888888" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/Ambiance.pro0000644000015301777760000000107412321005637032206 0ustar pbusernogroup00000000000000TEMPLATE = subdirs uri = Ubuntu.Components.Themes.Ambiance installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) QMLDIR_FILE = qmldir QML_FILES = *.qml ARTWORK_FILES += artwork/*.png \ artwork/*.svg \ artwork/*.sci qmldir_file.path = $$installPath qmldir_file.files = $$QMLDIR_FILE qml_files.path = $$installPath qml_files.files = $$QML_FILES artwork_files.path = $$installPath/artwork artwork_files.files = $$ARTWORK_FILES INSTALLS += qmldir_file qml_files artwork_files OTHER_FILES += $$QMLDIR_FILE $$QML_FILES $$ARTWORK_FILES ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ButtonForeground.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ButtonForeground0000644000015301777760000000676412321005637033231 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: buttonForeground property alias text: label.text property alias textColor: label.color property alias iconSource: icon.source property string iconPosition property real iconSize property real spacing property bool hasIcon: iconSource != "" property bool hasText: text != "" opacity: enabled ? 1.0 : 0.5 implicitHeight: Math.max(icon.height, label.height) state: hasIcon && hasText ? iconPosition : "center" Image { id: icon anchors.verticalCenter: parent.verticalCenter fillMode: Image.PreserveAspectFit width: iconSize height: iconSize } Label { id: label anchors { verticalCenter: parent.verticalCenter verticalCenterOffset: units.dp(-1) } fontSize: "medium" elide: Text.ElideRight } states: [ State { name: "left" AnchorChanges { target: icon anchors.left: buttonForeground.left } AnchorChanges { target: label anchors.left: icon.right } PropertyChanges { target: label anchors.leftMargin: spacing width: buttonForeground.width - icon.width - spacing } PropertyChanges { target: buttonForeground implicitWidth: icon.implicitWidth + spacing + label.implicitWidth } }, State { name: "right" AnchorChanges { target: icon anchors.right: buttonForeground.right } AnchorChanges { target: label anchors.left: buttonForeground.left } PropertyChanges { target: label width: buttonForeground.width - icon.width - spacing } PropertyChanges { target: buttonForeground implicitWidth: label.implicitWidth + spacing + icon.implicitWidth } }, State { name: "center" AnchorChanges { target: icon anchors.horizontalCenter: buttonForeground.horizontalCenter } AnchorChanges { target: label anchors.horizontalCenter: buttonForeground.horizontalCenter } PropertyChanges { target: label width: Math.min(label.implicitWidth, buttonForeground.width) } PropertyChanges { target: buttonForeground implicitWidth: hasText ? label.implicitWidth : icon.implicitWidth } } ] } ././@LongLink0000000000000000000000000000015500000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/SheetForegroundStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/SheetForegroundS0000644000015301777760000000660312321005637033141 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 Item { id: visuals // styling properties property color backgroundColor: "lightgray" property color headerColor: "darkgray" property real headerHeight: units.gu(8) property real buttonContainerWidth: units.gu(14) implicitWidth: MathUtils.clamp(styledItem.contentsWidth, styledItem.minWidth, styledItem.maxWidth) implicitHeight: header.height + containerItem.height property alias contentItem: containerItem Rectangle { id: header color: visuals.headerColor height: visuals.headerHeight anchors { top: parent.top left: parent.left right: parent.right } Label { id: headerText anchors { verticalCenter: parent.verticalCenter left: leftButtonContainer.right right: rightButtonContainer.left } width: headerText.implicitWidth + units.gu(4) elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter text: styledItem.title } Item { id: leftButtonContainer anchors { left: parent.left top: parent.top bottom: parent.bottom } width: visuals.buttonContainerWidth Component.onCompleted: header.updateButton(styledItem.leftButton, leftButtonContainer) } Item { id: rightButtonContainer anchors { right: parent.right top: parent.top bottom: parent.bottom } width: visuals.buttonContainerWidth Component.onCompleted: header.updateButton(styledItem.rightButton, rightButtonContainer) } function updateButton(button, container) { if (!button) return; button.parent = container; button.anchors.left = container.left; button.anchors.right = container.right; button.anchors.verticalCenter = container.verticalCenter; button.anchors.margins = units.gu(1); } Connections { target: styledItem onLeftButtonChanged: header.updateButton(styledItem.leftButton, leftButtonContainer) onRightButtonChanged: header.updateButton(styledItem.rightButton, rightButtonContainer) } } Rectangle { id: containerItem color: visuals.backgroundColor height: MathUtils.clamp(styledItem.contentsHeight, styledItem.minHeight - header.height, styledItem.maxHeight - header.height) anchors { top: header.bottom left: parent.left right: parent.right } } } ././@LongLink0000000000000000000000000000016300000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PartialColorizeUbuntuShape.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/PartialColorizeU0000644000015301777760000000257012321005637033142 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 PartialColorize { fragmentShader: " varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform highp vec4 leftColor; uniform highp vec4 rightColor; uniform lowp float progress; uniform lowp float qt_Opacity; void main() { lowp vec4 color = texture2D(source, qt_TexCoord0); lowp vec4 newColor = mix(leftColor, rightColor, step(progress, " + texCoord + ")); highp float opacity = (1.0 - color.r / max(1.0/256.0, color.a)); lowp vec4 result = opacity * vec4(0.0, 0.0, 0.0, 1.0) + vec4(1.0 - opacity) * newColor; gl_FragColor = vec4(result.rgb * result.a, result.a) * color.a * qt_Opacity; } " } ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ScrollbarStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Ambiance/ScrollbarStyle.q0000644000015301777760000004647712321005637033133 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 /* The visuals handle both active and passive modes. This behavior is driven yet by the styledItem's __inactive property, however should be detected upon runtime based on the device type. On active scrollbars, positioning is handled so that the logic updates the flickable's X/Y content positions, which is then synched with the contentPosition by the main element. Style properties used: - interactive: bool - drives the interactive behavior of the scrollbar - minimumSliderSize: real - specifies the minimum size of the slider * overlay - overlay: bool - true if the scrollbar is overlay type - overlayOpacityWhenHidden: opacity when hidden - overlayOpacityWhenShown: opacity when shown * animations - where duration and easing properties are used only - scrollbarFadeInAnimation: PropertyAnimation - animation used when fade in - scrollbarFadeOutAnimation: PropertyAnimation - animation used when fade out - scrollbarFadeOutPause: int - miliseconds to pause before fade out * behaviors - animations are used as declared - sliderAnimation: PropertyAnimation - animation for the slider size - thumbConnectorFading: PropertyAnimation - animation for the thumb connector - thumbFading: PropertyAnimation - animation for the thumb fading * other styling properties - color sliderColor: color for the slider - color thumbConnectorColor: thumb connector color - url forwardThumbReleased: forward thumb image when released - url forwardThumbPressed: forward thumb image when pressed - url backwardThumbReleased: backward thumb image when released - url backwardThumbPressed: backward thumb image when pressed - real scrollAreaThickness: scrollbar area thickness, the area where the slider, thumb and thumb-connector appear - real thumbConnectorMargin: margin of the thumb connector aligned to the thumb visuals */ Item { id: visuals // styling properties property bool interactive: false property real minimumSliderSize: units.gu(2) property bool overlay: true property real overlayOpacityWhenShown: 0.6 property real overlayOpacityWhenHidden: 0.0 property PropertyAnimation scrollbarFadeInAnimation: UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } property PropertyAnimation scrollbarFadeOutAnimation: UbuntuNumberAnimation { duration: UbuntuAnimation.SlowDuration } property int scrollbarFadeOutPause: 300 property PropertyAnimation sliderAnimation: UbuntuNumberAnimation {} property PropertyAnimation thumbConnectorFading: UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } property PropertyAnimation thumbFading: UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } property color sliderColor: Theme.palette.normal.base property real sliderRadius: units.gu(0.5) property color thumbConnectorColor: "white" property url forwardThumbReleased: (styledItem.align === Qt.AlignLeading || styledItem.align === Qt.AlignTrailing) ? "artwork/ScrollbarBottomIdle.png" : "artwork/ScrollbarRightIdle.png" property url forwardThumbPressed: (styledItem.align === Qt.AlignLeading || styledItem.align === Qt.AlignTrailing) ? "artwork/ScrollbarBottomPressed.png" : "artwork/ScrollbarRightPressed.png" property url backwardThumbReleased: (styledItem.align === Qt.AlignLeading || styledItem.align === Qt.AlignTrailing) ? "artwork/ScrollbarTopIdle.png" : "artwork/ScrollbarLeftIdle.png" property url backwardThumbPressed: (styledItem.align === Qt.AlignLeading || styledItem.align === Qt.AlignTrailing) ? "artwork/ScrollbarTopPressed.png" : "artwork/ScrollbarLeftPressed.png" property real scrollAreaThickness: units.gu(0.5) property real thumbConnectorMargin: units.dp(3) // helper properties to ease code readability property Flickable flickableItem: styledItem.flickableItem property bool isScrollable: styledItem.__private.scrollable && pageSize > 0.0 && contentSize > 0.0 && contentSize > pageSize property bool isVertical: ScrollbarUtils.isVertical(styledItem) property bool frontAligned: (styledItem.align === Qt.AlignLeading) property bool rearAligned: (styledItem.align === Qt.AlignTrailing) property bool topAligned: (styledItem.align === Qt.AlignTop) property bool bottomAligned: (styledItem.align === Qt.AlignBottom) property real pageSize: (isVertical) ? styledItem.height : styledItem.width property real contentSize: (isVertical) ? styledItem.flickableItem.contentHeight : styledItem.flickableItem.contentWidth /***************************************** Visuals *****************************************/ anchors.fill: parent opacity: overlayOpacityWhenHidden state: { if (!isScrollable) return ''; else if (overlay) { if (flickableItem.moving) return 'overlay'; else return 'stopped'; } else return 'shown'; } states: [ State { name: 'stopped' extend: '' PropertyChanges { target: visuals opacity: overlayOpacityWhenHidden } }, State { name: "shown" PropertyChanges { target: visuals opacity: overlayOpacityWhenShown } }, State { name: 'overlay' PropertyChanges { target: visuals opacity: overlayOpacityWhenShown } } ] transitions: [ Transition { from: '' to: 'shown' NumberAnimation { target: visuals property: "opacity" duration: scrollbarFadeInAnimation.duration easing: scrollbarFadeInAnimation.easing } }, Transition { from: '*' to: 'overlay' NumberAnimation { target: visuals property: "opacity" duration: scrollbarFadeInAnimation.duration easing: scrollbarFadeInAnimation.easing } }, Transition { from: "overlay" to: "stopped" SequentialAnimation { PauseAnimation { duration: scrollbarFadeOutPause } NumberAnimation { target: visuals property: "opacity" duration: scrollbarFadeOutAnimation.duration easing: scrollbarFadeOutAnimation.easing } } } ] function mapToPoint(map) { return Qt.point(map.x, map.y) } SmoothedAnimation { id: scrollAnimation duration: 200 easing.type: Easing.InOutQuad target: styledItem.flickableItem property: (isVertical) ? "contentY" : "contentX" } // represents the visible area of the scrollbar where slider and thumb connector are placed Item { id: scrollbarArea property real thickness: scrollAreaThickness property real proximityThickness: (isVertical) ? styledItem.width - thickness : styledItem.height - thickness anchors { fill: parent leftMargin: (!isVertical || frontAligned) ? 0 : proximityThickness rightMargin: (!isVertical || rearAligned) ? 0 : proximityThickness topMargin: (isVertical || topAligned) ? 0 : proximityThickness bottomMargin: (isVertical || bottomAligned) ? 0 : proximityThickness } } // The thumb appears whenever the mouse gets close enough to the scrollbar // and disappears after being for a long enough time far enough of it MouseArea { id: proximityArea anchors { fill: parent leftMargin: (!isVertical) ? 0 : (frontAligned ? scrollbarArea.thickness : 0) rightMargin: (!isVertical) ? 0 : (rearAligned ? scrollbarArea.thickness : 0) topMargin: (isVertical) ? 0 : (topAligned ? scrollbarArea.thickness : 0) bottomMargin: (isVertical) ? 0 : (bottomAligned ? scrollbarArea.thickness : 0) } propagateComposedEvents: true enabled: isScrollable && interactive hoverEnabled: true onEntered: thumb.show(); onPressed: mouse.accepted = false onClicked: mouse.accepted = false onReleased: mouse.accepted = false } // The slider's position represents which part of the flickable is visible. // The slider's size represents the size the visible part relative to the // total size of the flickable. Item { id: scrollCursor x: (isVertical) ? 0 : ScrollbarUtils.sliderPos(styledItem, 0.0, styledItem.width - scrollCursor.width) y: (!isVertical) ? 0 : ScrollbarUtils.sliderPos(styledItem, 0.0, styledItem.height - scrollCursor.height) width: (isVertical) ? scrollbarArea.thickness : ScrollbarUtils.sliderSize(styledItem, 0.0, flickableItem.width) height: (!isVertical) ? scrollbarArea.thickness : ScrollbarUtils.sliderSize(styledItem, 0.0, flickableItem.height) function drag() { ScrollbarUtils.dragAndClamp(styledItem, scrollCursor, contentSize, pageSize); } } Rectangle { id: slider color: visuals.sliderColor anchors { left: (isVertical) ? scrollbarArea.left : undefined right: (isVertical) ? scrollbarArea.right : undefined top: (!isVertical) ? scrollbarArea.top : undefined bottom: (!isVertical) ? scrollbarArea.bottom : undefined } x: (isVertical) ? 0 : ScrollbarUtils.sliderPos(styledItem, 0.0, styledItem.width - slider.width) y: (!isVertical) ? 0 : ScrollbarUtils.sliderPos(styledItem, 0.0, styledItem.height - slider.height) width: (isVertical) ? scrollbarArea.thickness : ScrollbarUtils.sliderSize(styledItem, minimumSliderSize, flickableItem.width) height: (!isVertical) ? scrollbarArea.thickness : ScrollbarUtils.sliderSize(styledItem, minimumSliderSize, flickableItem.height) radius: visuals.sliderRadius Behavior on width { enabled: (!isVertical) NumberAnimation { duration: visuals.sliderAnimation.duration easing: visuals.sliderAnimation.easing } } Behavior on height { enabled: (isVertical) NumberAnimation { duration: visuals.sliderAnimation.duration easing: visuals.sliderAnimation.easing } } function scroll(amount) { scrollAnimation.to = ScrollbarUtils.scrollAndClamp(styledItem, amount, 0.0, contentSize - pageSize); scrollAnimation.restart(); } } // The sliderThumbConnector ensures a visual connection between the slider and the thumb Rectangle { id: sliderThumbConnector property real thumbConnectorMargin: visuals.thumbConnectorMargin property bool isThumbAboveSlider: (isVertical) ? thumb.y < slider.y : thumb.x < slider.x anchors { left: (isVertical) ? scrollbarArea.left : (isThumbAboveSlider ? thumb.left : slider.right) right: (isVertical) ? scrollbarArea.right : (isThumbAboveSlider ? slider.left : thumb.right) top: (!isVertical) ? scrollbarArea.top : (isThumbAboveSlider ? thumb.top : slider.bottom) bottom: (!isVertical) ? scrollbarArea.bottom : (isThumbAboveSlider ? slider.top : thumb.bottom) leftMargin : (isVertical) ? 0 : (isThumbAboveSlider ? thumbConnectorMargin : 0) rightMargin : (isVertical) ? 0 : (isThumbAboveSlider ? 0 : thumbConnectorMargin) topMargin : (!isVertical) ? 0 : (isThumbAboveSlider ? thumbConnectorMargin : 0) bottomMargin : (!isVertical) ? 0 : (isThumbAboveSlider ? 0 : thumbConnectorMargin) } color: visuals.thumbConnectorColor opacity: thumb.shown ? 1.0 : 0.0 Behavior on opacity { NumberAnimation { duration: visuals.thumbConnectorFading.duration easing: visuals.thumbConnectorFading.easing } } } MouseArea { id: thumbArea property point thumbPoint: mapToPoint(thumb.mapFromItem(thumbArea, mouseX, mouseY)) property point thumbTopPoint: mapToPoint(thumbTop.mapFromItem(thumb, thumbPoint.x, thumbPoint.y)) property point thumbBottomPoint: mapToPoint(thumbBottom.mapFromItem(thumb, thumbPoint.x, thumbPoint.y)) property bool inThumbTop: thumbTop.contains(thumbTopPoint) property bool inThumbBottom: thumbBottom.contains(thumbBottomPoint) anchors { fill: scrollbarArea // set margins adding 2 dp for error area leftMargin: (!isVertical || frontAligned) ? 0 : units.dp(-2) - thumb.width rightMargin: (!isVertical || rearAligned) ? 0 : units.dp(-2) - thumb.width topMargin: (isVertical || topAligned) ? 0 : units.dp(-2) - thumb.height bottomMargin: (isVertical || bottomAligned) ? 0 : units.dp(-2) - thumb.height } enabled: isScrollable && interactive hoverEnabled: true onEntered: thumb.show() onPressed: { if (isVertical) { if (mouseY < thumb.y) { thumb.placeThumbForeUnderMouse(mouse) } else if (mouseY > (thumb.y + thumb.height)) { thumb.placeThumbRearUnderMouse(mouse) } } else { if (mouseX < thumb.x) { thumb.placeThumbForeUnderMouse(mouse) } else if (mouseX > (thumb.x + thumb.width)) { thumb.placeThumbRearUnderMouse(mouse) } } } onClicked: { if (inThumbBottom) slider.scroll(pageSize) else if (inThumbTop) slider.scroll(-pageSize) } // Dragging behaviour function resetDrag() { thumbYStart = thumb.y thumbXStart = thumb.x dragYStart = drag.target.y dragXStart = drag.target.x } property int thumbYStart property int dragYStart property int dragYAmount: thumbArea.drag.target.y - thumbArea.dragYStart property int thumbXStart property int dragXStart property int dragXAmount: thumbArea.drag.target.x - thumbArea.dragXStart drag { target: scrollCursor axis: (isVertical) ? Drag.YAxis : Drag.XAxis minimumY: 0 maximumY: flickableItem.height - scrollCursor.height minimumX: 0 maximumX: flickableItem.width - scrollCursor.width onActiveChanged: { if (drag.active) resetDrag() } } // update thumb position onDragYAmountChanged: { if (drag.active) { thumb.y = MathUtils.clamp(thumbArea.thumbYStart + thumbArea.dragYAmount, 0, thumb.maximumPos); } } onDragXAmountChanged: { if (drag.active) { thumb.x = MathUtils.clamp(thumbArea.thumbXStart + thumbArea.dragXAmount, 0, thumb.maximumPos); } } // drag slider and content to the proper position onPositionChanged: { if (pressedButtons == Qt.LeftButton) { scrollCursor.drag() } } } Timer { id: autohideTimer interval: 1000 repeat: true onTriggered: if (!proximityArea.containsMouse && !thumbArea.containsMouse && !thumbArea.pressed) thumb.hide() } Item { id: thumb enabled: interactive anchors { left: frontAligned ? slider.left : undefined right: rearAligned ? slider.right : undefined top: topAligned ? slider.top : undefined bottom: bottomAligned ? slider.bottom : undefined } width: childrenRect.width height: childrenRect.height property bool shown property int maximumPos: (isVertical) ? styledItem.height - thumb.height : styledItem.width - thumb.width /* Show the thumb as close as possible to the mouse pointer */ onShownChanged: { if (shown) { if (isVertical) { var mouseY = proximityArea.containsMouse ? proximityArea.mouseY : thumbArea.mouseY; y = MathUtils.clamp(mouseY - thumb.height / 2, 0, thumb.maximumPos); } else { var mouseX = proximityArea.containsMouse ? proximityArea.mouseX : thumbArea.mouseX; x = MathUtils.clamp(mouseX - thumb.width / 2, 0, thumb.maximumPos); } } } function show() { autohideTimer.restart(); shown = true; } function hide() { autohideTimer.stop(); shown = false; } function placeThumbForeUnderMouse(mouse) { var diff = (isVertical) ? mouse.y - height / 4 : mouse.x - width / 4; positionAnimation.to = MathUtils.clamp(diff, 0, maximumPos); positionAnimation.restart(); } function placeThumbRearUnderMouse(mouse) { var diff = (isVertical) ? mouse.y - height * 3 / 4 : mouse.x - width * 3 / 4; positionAnimation.to = MathUtils.clamp(diff, 0, maximumPos); positionAnimation.restart(); } NumberAnimation { id: positionAnimation duration: 100 easing.type: Easing.InOutQuad target: thumb property: (isVertical) ? "y" : "x" } opacity: shown ? (thumbArea.containsMouse || thumbArea.drag.active ? 1.0 : 0.5) : 0.0 Behavior on opacity { NumberAnimation { duration: visuals.thumbFading.duration easing: visuals.thumbFading.easing } } Flow { // disable mirroring as thumbs are placed in the same way no matter of RTL or LTR LayoutMirroring.enabled: false flow: (isVertical) ? Flow.TopToBottom : Flow.LeftToRight Image { id: thumbTop source: thumbArea.inThumbTop && thumbArea.pressed ? visuals.backwardThumbPressed : visuals.backwardThumbReleased } Image { id: thumbBottom source: thumbArea.inThumbBottom && thumbArea.pressed ? visuals.forwardThumbPressed : visuals.forwardThumbReleased } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/qmldir0000644000015301777760000000013412321005637027475 0ustar pbusernogroup00000000000000module Ubuntu.Components.Themes Palette 0.1 Palette.qml PaletteValues 0.1 PaletteValues.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/Palette.qml0000644000015301777760000000356212321005637030403 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Palette \inqmlmodule Ubuntu.Components.Themes 0.1 \ingroup theming \brief Palette of colors from the theme that widgets use to draw themselves. Palette provides access to colors defined by the current theme. The actual color palette to use depends on the state of the widget being drawn. A color palette (\l PaletteValues) has various roles to choose from depending on what part of the widget is being drawn (the base of the widget, the foreground, etc.). For each color there is a corresponding 'text' color that is guaranteed to provide good legibility for text or icons placed on top of a background of the corresponding color. Example of a Text on top of a background Rectangle: \qml Item { Rectangle { color: Theme.palette.normal.base } Text { color: Theme.palette.normal.baseText } } \endqml */ QtObject { /*! Color palette to use when the widget is not in any particular state. */ property PaletteValues normal /*! Color palette to use when the widget is selected, for example when a tab is the current one. */ property PaletteValues selected } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/PaletteValues.qml0000644000015301777760000000424612321005637031563 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype PaletteValues \inqmlmodule Ubuntu.Components.Themes 0.1 \ingroup theming \brief Color values used for a given widget state. */ QtObject { /*! Color applied to the background of the application. */ property color background /*! Color applied to elements placed on top of the \l background color. Typically used for labels and images. */ property color backgroundText /*! Color applied to the background of widgets. */ property color base /*! Color applied to elements placed on top of the \l base color. Typically used for labels and images. */ property color baseText /*! Color applied to widgets on top of the base colour. */ property color foreground /*! Color applied to elements placed on top of the \l foreground color. Typically used for labels and images. */ property color foregroundText /*! Color applied to the background of widgets floating over other widgets. For example: popovers, Toolbar. */ property color overlay /*! Color applied to elements placed on top of the \l overlay color. Typically used for labels and images. */ property color overlayText /*! Colour applied to the backgrouhnd of text input fields. */ property color field /*! Color applied to elements placed on top of the \l field color. Typically used for labels and images. */ property color fieldText } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/0000755000015301777760000000000012321006415030673 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/artwork/0000755000015301777760000000000012321006415032364 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/artwork/tick@30.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/artwork/tick0000644000015301777760000000743512321005637033257 0ustar pbusernogroup00000000000000PNG  IHDRZZ8AtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp IDATx PWǧgP7xDE+Phh\1 ⁂JEMJ*nX-+n$@4uA(V*7.^Ȍ0}My333گU=~_? IR"@-Z-Z-Z-Z"hZ"h8x?g zPhox,C8hO5 0%p` ld0ܻwG QptYFmh6~K c-50`ZG"F-d) >J0Uii+C~4pu2h/Gn!F4>HQ,SQ\\4>"bD_WD} L47dzZq& 3rR b[__ՇX #!h N6t.lXRx $QlMxu.^]-A2DE{$<l"/@DL̻`'٩{Q"8[3[5u+ kwb OpFEKAmMYӦŕ6 kä(D:l*+Z@WUT\3%ܝR04Y&2Hr[|CI^o0aQLI6bɐtEz(3烿1#MK[+Vb2C Q0s&nUŀ񟵴sX m YB*2d' Gߝ=;몪5f7B"Zѣw^obMXؠ0Bxzjj.(rccƼ 8c\* PкJG;Ǐۄ|8e-eho(e+-䂯^(5 HXXϷs;h`o~WFA2|8vFBB|pu6lٹs/ "zؓM"lD"ss7-Yb?e^\ddD"(_dqB rڵɄ!lr! mlQ{۰ģymhcѢ+'O~wN Bڛgfe(BplMK:$X[R%#NѼݻ'EE/Tx&%<{yh-Kҳ0Sƿq!H"[#!!HoIL= =G(vFK0,Ě_ox;'ӖG:AN-!!%AcH,<& ؂aWW_ 499y',7_%vgё[!\-,ƦCl ;/j֧}|q&g-r=-%8KK>}f hԻf)=yy4@fK|dgre\)(9r.:tpϞ*>. ; g~⢘ѣGz_Y>q &snl}ItCT*7oV-ٳ|q^Ç%Zgk2{Ɏmp!Po/_3ZݳeGh߂d_hGq֡>$Or]h0oZnq7zȈuS]ݕaa9Ҳs_p[дp:t[$vCH_rf$"_⫀4D Xa IDATx[ LG=P jE 퉩5j JUX1mF%5JJJm#[AmԚ^[QmPTۻ,!OLIvg7͛o'~]jz]?k` Xk5` XGZ7Fk tR]z,B%pZ0H"xuNXؐ2Gi:y-[ܡ6XLÇ>=#8JET=_~&^L? nنvyY19 |>_{myKJs0O6J8P߯kHHfn#3reh>bUʏ93uȉ FEΗrΝ{>YkDtʚ;„"ĬiܸFFf,;{5&Ј0gly~ҋ_]Xt{%G!_{HrHM,r6[YʴiSSl$mlUQxSw 1.EEJA?3XEyΜ9{Q% c,-))drL<1`0p~n’% QG/^b|AAދw[64Ii]./<W^n4#X_ EzI|RHRGrs:uV6tS`c2&%b-@㽥Ī,a;ZRݓ v;U 90hpV_VVZrY$Ah/HKS4f"lNXqp1 ?Vgd,>$Y`;; A5]eˆAajmmmG߷bŚp~Ha{bfH}/44$A;>/Z9I̒k$-bIӌA2NÇJKN$Ǩ\s*//8?0elXzEubU_\r @Yc[[LHsAT'BF3`" yʕ__q󆔗5{ |IɔvC99k^B.ʚu "16׵RD|IISԒDƍ[g"_V{^n.^tnUȠ2MaգT0"M4Kl⑛7fxxXdOY--NŲVXX#%`(S԰F\]lr-*R9h  x\ǎUU/][>XDUrbО''z49S!vYǏfj)]zϞm**>IIG牵RbtZȵ?aaۍ] ]OI'R "$C7J<” *Fp@0+(R]5FH@q=+IjnFe FիQς (_L']Y+Jc1`ZWڿh5` XS[IENDB`././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/artwork/chevron@27.pngubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/artwork/chev0000644000015301777760000000537312321005637033251 0ustar pbusernogroup00000000000000PNG  IHDRD}>0tEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp hVmIDATxڬYkLTG޽.oP "`ҠH)1ZF*5#`%b!ŷ шAmAIJ Vy캻ά30̲L0s}sΙ3gŢWM,{3QEh? ==t4I,rR; "uuUljn!X 䛩YLTJwʤ/臐;K^ *llR*%`kk:b…夦 &/^*$< lr#JO2||#ϟ^d<[;ygΌJھ7̒ .Rn0bX:;4t ((2~x?'OMpwwV]])#C A iijk{p7)<<ݻ+3`z)%%F pd/_NYtM);w([9X,_ lt|oܺ?m79*MST^ #Wiitjv2kצe*rW4l  [jF2T4*gAb)j5x/3'~ży HɇL`FD.wڵ{}: Śq*Ea6o Gf6> egd4j4J23SWr "`<2tt<^hMx;l;"NzYznɇ;:fO<)x4[MWxxLZbS4q1d.2~|²;(X-Z[E{|}}ڃ#u5dNP辫'i6 E´vΝ#y,q;w]"k*!GL =1E$ݡ]UDh{|7[]Kd+:ۅH@JoD[mĀ1azAwCqC9sԃvme>--Qe@(u܍N:l`<.CY<@>Z `k^$=mo- j+(ًYP` >}J>F9(G6;΀5ZQ<7ͦ_OP ,de";:#cCȭa Y YZd=uxkjj/i..4 C̡k$WGâdmr&]~9\Vt=ռ /^>MJJh>9:e+XIC WS=<:5kk׮_ڶJĦOb&?LL\QlYZKGRW^G՚5Yg㕕W#ZFCI2߬ja,:/^\YTT:[MGH^KK2*n[?HI@˅ȉ>O^ȈCRP*aJFg0BX61fgA}6s9qO໎ؒkoIENDB`././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/SuruGradient.proubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/SuruGradient0000644000015301777760000000133512321005637033241 0ustar pbusernogroup00000000000000TEMPLATE = subdirs uri = Ubuntu.Components.Themes.SuruGradient installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) PARENT_THEME_FILE = parent_theme QMLDIR_FILE = qmldir QML_FILES = *.qml ARTWORK_FILES += artwork/*.png \ artwork/*.svg \ artwork/*.sci parent_theme_file.path = $$installPath parent_theme_file.files = $$PARENT_THEME_FILE qmldir_file.path = $$installPath qmldir_file.files = $$QMLDIR_FILE qml_files.path = $$installPath qml_files.files = $$QML_FILES artwork_files.path = $$installPath/artwork artwork_files.files = $$ARTWORK_FILES INSTALLS += parent_theme_file qmldir_file qml_files artwork_files OTHER_FILES += $$PARENT_THEME_FILE $$QMLDIR_FILE $$QML_FILES $$ARTWORK_FILES ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/parent_theme0000644000015301777760000000004212321005637033272 0ustar pbusernogroup00000000000000Ubuntu.Components.Themes.Ambiance ././@LongLink0000000000000000000000000000017000000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/ListItemOptionSelectorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/ListItemOpti0000644000015301777760000000154412321005637033215 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 OptionSelectorStyle { id: suruGradientStyle chevron: "artwork/chevron_down@30.png" tick: "artwork/tick@30.png" colourComponent: false } ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/TabBarStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/TabBarStyle.0000644000015301777760000000143512321005637033060 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 as Ambiance Ambiance.TabBarStyle { indicatorImageSource: "artwork/chevron.png" } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/qmldir0000644000015301777760000000005512321005637032113 0ustar pbusernogroup00000000000000module Ubuntu.Components.Themes.SuruGradient ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/MainViewStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/MainViewStyl0000644000015301777760000000136312321005637033221 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 MainViewStyle { backgroundSource: "" } ././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/OptionSelectorStyle.qmlubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/OptionSelect0000644000015301777760000000154412321005637033237 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ import QtQuick 2.0 import Ubuntu.Components.Themes.Ambiance 0.1 OptionSelectorStyle { id: suruGradientStyle chevron: "artwork/chevron_down@30.png" tick: "artwork/tick@30.png" colourComponent: false } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Themes/SuruGradient/Palette.qml0000644000015301777760000000241712321005637033015 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components.Themes 0.1 Palette { normal: PaletteValues { background: "#5E2750" backgroundText: "#33F3F3E7" base: "#19000000" baseText: "#F3F3E7" foreground: "#888888" foregroundText: "#F3F3E7" overlay: "#F5F5F5" overlayText: "#888888" field: "#19000000" fieldText: "#7F7F7F7F" } selected: PaletteValues { background: "#88D6D6D6" // FIXME: not from design backgroundText: "#F3F3E7" foreground: "#DD4814" foregroundText: "#F3F3E7" field: "#FFFFFF" fieldText: "#888888" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Action.qml0000644000015301777760000000571412321005637026776 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Unity.Action 1.1 as UnityActions /*! \qmltype Action \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Describe an action that can be re-used in, for example a \l Button \b{This component is under heavy development.} Examples: See \l Page */ UnityActions.Action { id: action /*! The title of the action. \qmlproperty string Ubuntu.Components.Action::text */ /*! The image associated with the action. \qmlproperty url iconSource This is a URL to any image file. In order to use an icon from the Ubuntu theme, use the iconName property instead. */ // TODO: Move iconSource to unity action if possible property url iconSource: iconName ? "image://theme/" + iconName : "" /*! The icon associated with the action. \qmlproperty string iconName This is the name of the icon in the ubuntu-mobile theme. If both iconSource and iconName are defined, iconName will be ignored. Example: \qml Action { iconName: "compose" } \endqml \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folder where the icon theme is installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \endlist */ property string iconName /*! Called when the action is triggered. \qmlsignal Ubuntu.Components.Action::triggered(var property) */ /*! \deprecated \b {visible is DEPRECATED. Use \l ActionItem to specify the representation of an \l Action.} The action is visible to the user */ property bool visible: true /*! \internal */ onVisibleChanged: print("Action.visible is a DEPRECATED property. Use ActionItems to specify the representation of an Action.") /*! Enable the action. It may be visible, but disabled. \qmlproperty bool enabled */ /*! \deprecated \b {itemHint is DEPRECATED. Use \l ActionItem to specify the representation of an \l Action.} */ property Component itemHint /*! \internal */ onItemHintChanged: print("Action.itemHint is a DEPRECATED property. Use ActionItems to specify the representation of an Action.") } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ActionList.qml0000644000015301777760000000300312321005637027617 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ActionList \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief List of \l Action items */ QtObject { id: list // internal objects using nested elements, // which isn't allowed by QtObject; this fix makes this possible /*! Default property to allow adding of children. \qmlproperty list children \default */ default property alias children: list.actions /*! List of already defined actions when not defining them as children of the ActionList. Note that when you set this property, the children of the ActionList will be ignored, so do not set the list and define children. The advantage of setting actions over using the children is that the same \l Action items can be used in several sets of actions. */ property list actions } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/TextField.qml0000644000015301777760000010621712321005637027451 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Unity.Action 1.1 as UnityActions /*! \qmltype TextField \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The TextField element displays a single line of editable plain text. Input constraints can be set through validator or inputMask. Setting echoMode to an appropriate value enables TextField to be used as password input field. \b{This component is under heavy development.} \l {http://design.ubuntu.com/apps/building-blocks/text-field}{See also the Design Guidelines on the Text Field}. Example: \qml Item { TextField { placeholderText: "hint text" } TextField { placeholderText: "without clear sign" hasClearButton: false } TextField { placeholderText: "password" echoMode: TextInput.Password } TextField { placeholderText: "overlaid in front" primaryItem: Image { height: parent.height width: height source: "magnifier.png" } secondaryItem: Row { Button { height: parent.height width: height iconName: "compose" onClicked: doSomething() } Button { height: parent.height width: height iconName: "undo" onClicked: doSomething() } } } } \endqml */ ActionItem { id: control implicitWidth: units.gu(25) implicitHeight: units.gu(4) /*! The property presents whether the TextField is highlighted or not. By default the TextField gets highlighted when gets the focus, so can accept text input. This property allows to control the highlight separately from the focused behavior. */ property bool highlighted: focus /*! Text that appears when there is no focus and no content in the component. \qmlproperty string placeholderText */ property alias placeholderText: hint.text /*! Specifies whether the control has a clear button or not. */ property bool hasClearButton: true /*! \preliminary Component to be shown and used instead of the default On Screen Keyboard. */ property Component customSoftwareInputPanel /*! The property overrides the default popover of the TextField. When set, the TextField will open the given popover instead of the defaul tone defined. The popover can either be a component or a URL to be loaded. */ property var popover /*! Overlaid component that can be set for the fore side of the TextField, e.g.showing a magnifier to implement search functionality. \qmlproperty list primaryItem */ property alias primaryItem: leftPane.data /*! Overlaid component that can be set for the rear side of the TextField, e.g.showing a CAPS LOCK or NUM LOCK indication. The overlaid components will be placed right after the clear button. \qmlproperty list secondaryItem */ property alias secondaryItem: rightPane.data /*! Allows highlighting errors in the TextField. */ property bool errorHighlight: !acceptableInput // aliased properties from TextInput /*! This property is always true unless a validator or input mask has been set. If a validator or input mask has been set, this property will only be true if the current text is acceptable to the validator or input mask as a final string (not as an intermediate string). \qmlproperty bool acceptableInput */ property alias acceptableInput: editor.acceptableInput /*! Whether the TextField should gain active focus on a mouse press. By default this is set to true. \qmlproperty bool activeFocusOnPress */ property alias activeFocusOnPress: editor.activeFocusOnPress /*! Whether the TextField should scroll when the text is longer than the width. By default this is set to true. \qmlproperty bool autoScroll */ property alias autoScroll: editor.autoScroll /*! Returns true if the TextField is writable and the content of the clipboard is suitable for pasting into the TextField. \qmlproperty bool canPaste */ property alias canPaste: editor.canPaste /*! Returns true if the TextField is writable and there are undone operations that can be redone. \qmlproperty bool canRedo */ property alias canRedo: editor.canRedo /*! Returns true if the TextField is writable and there are previous operations that can be undone. \qmlproperty bool canUndo */ property alias canUndo: editor.canUndo /*! The text color. \qmlproperty color color */ property alias color: editor.color /*! Returns the height of the text, including the height past the height that is covered if the text does not fit within the set height. \qmlproperty real contentHeight */ property alias contentHeight: editor.contentHeight /*! Returns the width of the text, including the width past the width which is covered due to insufficient wrapping if wrapMode is set. \qmlproperty real contentWidth */ property alias contentWidth: editor.contentWidth /*! The delegate for the cursor in the TextField. If you set a cursorDelegate for a TextField, this delegate will be used for drawing the cursor instead of the standard cursor. An instance of the delegate will be created and managed by the TextField when a cursor is needed, and the x property of delegate instance will be set so as to be one pixel before the top left of the current character. Note that the root item of the delegate component must be a QQuickItem or QQuickItem derived item. \qmlproperty Component cursorDelegate */ property alias cursorDelegate: editor.cursorDelegate /*! The position of the cursor in the TextField. \qmlproperty int cursorPosition */ property alias cursorPosition: editor.cursorPosition /*! The rectangle where the standard text cursor is rendered within the text input. Read only. The position and height of a custom cursorDelegate are updated to follow the cursorRectangle automatically when it changes. The width of the delegate is unaffected by changes in the cursor rectangle. \qmlproperty rectangle cursorRectangle */ property alias cursorRectangle: editor.cursorRectangle /*! Set to true when the TextField shows a cursor. This property is set and unset when the TextField gets active focus, so that other properties can be bound to whether the cursor is currently showing. As it gets set and unset automatically, when you set the value yourself you must keep in mind that your value may be overwritten. It can be set directly in script, for example if a KeyProxy might forward keys to it and you desire it to look active when this happens (but without actually giving it active focus). It should not be set directly on the item, like in the below QML, as the specified value will be overridden an lost on focus changes. \qml TextField { text: "Text" cursorVisible: false } \endqml In the above snippet the cursor will still become visible when the TextField gains active focus. \qmlproperty bool cursorVisible */ property alias cursorVisible: editor.cursorVisible /*! This is the text displayed in the TextField. If echoMode is set to TextInput::Normal, this holds the same value as the \l text property. Otherwise, this property holds the text visible to the user, while the text property holds the actual entered text. \qmlproperty string displayText */ property alias displayText: editor.displayText /*! Specifies how the text should be displayed in the TextField. \list \li - TextInput.Normal - Displays the text as it is. (Default) \li - TextInput.Password - Displays asterixes instead of characters. \li - TextInput.NoEcho - Displays nothing. \li - TextInput.PasswordEchoOnEdit - Displays characters as they are entered while editing, otherwise displays asterisks. \endlist \qmlproperty enumeration echoMode */ property alias echoMode: editor.echoMode /*! Font used in the TextField. \qmlproperty font font */ property alias font: editor.font /*! Allows you to set an input mask on the TextField, restricting the text inputs. See QLineEdit::inputMask for further details, as the exact same mask strings are used by TextField. \qmlproperty string inputMask */ property alias inputMask: editor.inputMask /*! This property holds whether the TextInput has partial text input from an input method. While it is composing an input method may rely on mouse or key events from the TextField to edit or commit the partial text. This property can be used to determine when to disable events handlers that may interfere with the correct operation of an input method. \qmlproperty bool inputMethodComposing */ property alias inputMethodComposing: editor.inputMethodComposing /*! Provides hints to the input method about the expected content of the text input and how it should operate. The value is a bit-wise combination of flags, or Qt.ImhNone if no hints are set. Flags that alter behaviour are: \list \li - Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords. This is automatically set when setting echoMode to \c TextInput.Password. \li - Qt.ImhSensitiveData - Typed text should not be stored by the active input method in any persistent storage like predictive user dictionary. \li - Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case when a sentence ends. \li - Qt.ImhPreferNumbers - Numbers are preferred (but not required). \li - Qt.ImhPreferUppercase - Upper case letters are preferred (but not required). \li - Qt.ImhPreferLowercase - Lower case letters are preferred (but not required). \li - Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing. \li - Qt.ImhDate - The text editor functions as a date field. \li - Qt.ImhTime - The text editor functions as a time field. \endlist Flags that restrict input (exclusive flags) are: \list \li - Qt.ImhDigitsOnly - Only digits are allowed. \li - Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign. \li - Qt.ImhUppercaseOnly - Only upper case letter input is allowed. \li - Qt.ImhLowercaseOnly - Only lower case letter input is allowed. \li - Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed. \li - Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed. \li - Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed. \endlist Masks: \list \li - Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used. \endlist \qmlproperty enumeration inputMethodHints */ property alias inputMethodHints: editor.inputMethodHints /*! Returns the total number of characters in the TextField item. If the TextField has an inputMask the length will include mask characters and may differ from the length of the string returned by the text property. This property can be faster than querying the length the text property as it doesn't require any copying or conversion of the TextField's internal string data. \qmlproperty int length */ property alias length: editor.length /*! The maximum permitted length of the text in the TextField. If the text is too long, it is truncated at the limit. By default, this property contains a value of 32767. \qmlproperty int maximumLength */ property alias maximumLength: editor.maximumLength /*! Specifies how text should be selected using a mouse. \list \li -TextInput.SelectCharacters - The selection is updated with individual characters. (Default) \li -TextInput.SelectWords - The selection is updated with whole words. \endlist This property only applies when selectByMouse is true. \qmlproperty enumeration mouseSelectionMode */ property alias mouseSelectionMode: editor.mouseSelectionMode /*! Whether the TextField should keep its selection when it loses active focus to another item in the scene. By default this is set to false. \qmlproperty bool persistentSelection */ property alias persistentSelection: editor.persistentSelection /*! Sets whether user input can modify the contents of the TextField. If readOnly is set to true, then user input will not affect the text property. Any bindings or attempts to set the text property will still work. \qmlproperty bool readOnly */ property alias readOnly: editor.readOnly /*! Override the default rendering type for this component. Supported render types are: \list \li - Text.QtRendering - (default) \li - Text.NativeRendering \endlist Select Text.NativeRendering if you prefer text to look native on the target platform and do not require advanced features such as transformation of the text. Using such features in combination with the NativeRendering render type will lend poor and sometimes pixelated results. \qmlproperty enumeration renderType */ property alias renderType: editor.renderType /*! Defaults to true. If false, the user cannot use the mouse to select text, only can use it to focus the input. \qmlproperty bool selectByMouse \preliminary */ property alias selectByMouse: virtualKbdHandler.enabled /*! This read-only property provides the text currently selected in the text input. It is equivalent to the following snippet, but is faster and easier to use. \code myTextInput.text.toString().substring(myTextInput.selectionStart, myTextInput.selectionEnd); \endcode \qmlproperty string selectedText */ readonly property alias selectedText: editor.selectedText /*! The cursor position before the first character in the current selection. This property is read-only. To change the selection, use select(start,end), selectAll(), or selectWord(). \qmlproperty int selectionStart */ property alias selectionStart: editor.selectionStart /*! The cursor position after the last character in the current selection. This property is read-only. To change the selection, use select(start,end), selectAll(), or selectWord(). \qmlproperty int selectionEnd */ property alias selectionEnd: editor.selectionEnd /*! The text in the TextField. \qmlproperty string text */ property alias text: editor.text /*! Allows you to set a validator on the TextInput. When a validator is set the TextField will only accept input which leaves the text property in an acceptable or intermediate state. The accepted signal will only be sent if the text is in an acceptable state when enter is pressed. Currently supported validators are IntValidator, DoubleValidator and RegExpValidator. An example of using validators is shown below, which allows input of integers between 11 and 31 into the text input: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 TextField{ validator: IntValidator{bottom: 11; top: 31;} focus: true } \endqml \sa acceptableInput, inputMask \qmlproperty Validator validator */ property alias validator: editor.validator /*! Sets the horizontal alignment of the text within the item's width and height. By default, the text alignment follows the natural alignment of the text, for example text that is read from left to right will be aligned to the left. TextField does not have vertical alignment, as the natural height is exactly the height of the single line of text. If you set the height manually to something larger, TextInput will always be top aligned vertically. You can use anchors to align it however you want within another item. The valid values for horizontalAlignment are TextInput.AlignLeft, TextInput.AlignRight and TextInput.AlignHCenter. Valid values for verticalAlignment are TextInput.AlignTop (default), TextInput.AlignBottom TextInput.AlignVCenter. When using the attached property LayoutMirroring::enabled to mirror application layouts, the horizontal alignment of text will also be mirrored. However, the property horizontalAlignment will remain unchanged. To query the effective horizontal alignment of TextField, use the read-only property effectiveHorizontalAlignment. \qmlproperty enumeration horizontalAlignment */ property alias horizontalAlignment: editor.horizontalAlignment /*! \qmlproperty enumeration effectiveHorizontalAlignment See \l horizontalAlignment for details. */ property alias effectiveHorizontalAlignment: editor.effectiveHorizontalAlignment /*! \qmlproperty enumeration verticalAlignment See \l horizontalAlignment for details. */ property alias verticalAlignment: editor.verticalAlignment /*! This is the character displayed when echoMode is set to Password or PasswordEchoOnEdit. By default it is the unicode character 2022. If this property is set to a string with more than one character, the first character is used. If the string is empty, the value is ignored and the property is not set. \qmlproperty string passwordCharacter */ property alias passwordCharacter: editor.passwordCharacter /*! The text highlight color, used behind selections. \qmlproperty color selectionColor */ property alias selectionColor: editor.selectionColor /*! The highlighted text color, used in selections. \qmlproperty color selectedTextColor */ property alias selectedTextColor: editor.selectedTextColor /*! This handler is called when the Return or Enter key is pressed. Note that if there is a validator or inputMask set on the text input, the handler will only be emitted if the input is in an acceptable state. */ signal accepted() /*! \internal If used with an action or Option accepting propagates the new text. */ onAccepted: { control.triggered(control.text) } /*! Copies the currently selected text to the system clipboard. */ function copy() { editor.copy(); } /*! Moves the currently selected text to the system clipboard. */ function cut() { editor.cut(); } /*! Places the clipboard or the data given as parameter into the text input. The selected text will be replaces with the data. */ function paste(data) { if ((data !== undefined) && (typeof data === "string") && !editor.readOnly) { var selTxt = editor.selectedText; var txt = editor.text; var pos = (selTxt !== "") ? txt.indexOf(selTxt) : editor.cursorPosition if (selTxt !== "") { editor.text = txt.substring(0, pos) + data + txt.substr(pos + selTxt.length); } else { editor.text = txt.substring(0, pos) + data + txt.substr(pos); } editor.cursorPosition = pos + data.length; } else editor.paste(); } /*! Removes active text selection. */ function deselect() { editor.deselect(); } /*! Inserts \a text into the TextField at \a position. */ function insert(position, text) { editor.insert(position, text); } /*! This function returns the character position at x pixels from the left of the TextField. Position 0 is before the first character, position 1 is after the first character but before the second, and so on until position text.length, which is after all characters. This means that for all x values before the first character this function returns 0, and for all x values after the last character this function returns text.length. The cursor position type specifies how the cursor position should be resolved. \list \li - TextInput.CursorBetweenCharacters - Returns the position between characters that is nearest x. \li - TextInput.CursorOnCharacter - Returns the position before the character that is nearest x. \endlist */ function positionAt(x, position) { if (position == undefined) return editor.positionAt(x); else return editor.positionAt(x, position); } /*! This function takes a character position and returns the rectangle that the cursor would occupy, if it was placed at that character position. This is similar to setting the cursorPosition, and then querying the cursor rectangle, but the cursorPosition is not changed. */ function positionToRectangle(pos) { return editor.positionToRectangle(pos); } /*! Causes the text from start to end to be selected. If either start or end is out of range, the selection is not changed. After calling this, selectionStart will become the lesser and selectionEnd will become the greater (regardless of the order passed to this method). */ function select(start, end) { editor.select(start, end); } /*! Causes all text to be selected. */ function selectAll() { editor.selectAll(); } /*! Causes the word closest to the current cursor position to be selected. */ function selectWord() { editor.selectWord(); } /*! \internal Ensure focus propagation */ function forceActiveFocus() { internal.activateEditor(); } /*! Returns true if the natural reading direction of the editor text found between positions start and end is right to left. */ function isRightToLeft(start, end) { return editor.isRightToLeft(start, end); } /*! Moves the cursor to position and updates the selection according to the optional mode parameter. (To only move the cursor, set the cursorPosition property.) When this method is called it additionally sets either the selectionStart or the selectionEnd (whichever was at the previous cursor position) to the specified position. This allows you to easily extend and contract the selected text range. The selection mode specifies whether the selection is updated on a per character or a per word basis. If not specified the selection mode will default to TextInput.SelectCharacters. \list \li - TextInput.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at the previous cursor position) to the specified position. \li - TextInput.SelectWords - Sets the selectionStart and selectionEnd to include all words between the specified position and the previous cursor position. Words partially in the range are included. \endlist For example, take this sequence of calls: \code cursorPosition = 5 moveCursorSelection(9, TextInput.SelectCharacters) moveCursorSelection(7, TextInput.SelectCharacters) \endcode This moves the cursor to position 5, extend the selection end from 5 to 9 and then retract the selection end from 9 to 7, leaving the text from position 5 to 7 selected (the 6th and 7th characters). The same sequence with TextInput.SelectWords will extend the selection start to a word boundary before or on position 5 and extend the selection end to a word boundary on or past position 9. */ function moveCursorSelection(position, mode) { editor.moveCursorSelection(position, mode) } /*! Redoes the last operation if redo is \l {canRedo}{available}. */ function redo() { editor.redo(); } /*! Undoes the last operation if undo is \l {canUndo}{available}. Deselects any current selection, and updates the selection start to the current cursor position. */ function undo() { editor.undo(); } /*! Removes the section of text that is between the start and end positions from the TextField. */ function remove(start, end) { editor.remove(start, end); } /*! Returns the section of text that is between the start and end positions. If the TextField has an inputMask the length will include mask characters. */ function getText(start, end) { return editor.getText(start, end); } // internals opacity: enabled ? 1.0 : 0.3 /*! \internal */ onVisibleChanged: { if (!visible) control.focus = false; } LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true // grab clicks from the area between the frame and the input MouseArea { anchors.fill: parent // us it only when there is space between the frame and input enabled: internal.spacing > 0 onClicked: internal.activateEditor() } Text { id: fontHolder } //internals /*! \internal */ property alias __internal: internal QtObject { id: internal // array of borders in left, top, right, bottom order property bool textChanged: false property real spacing: control.__styleInstance.overlaySpacing property real lineSpacing: units.dp(3) property real lineSize: editor.font.pixelSize + lineSpacing //selection properties property bool selectionMode: false signal popupTriggered() property int type: action ? action.parameterType : 0 onTypeChanged: { // Don't undo explicitly specified hints if (inputMethodHints != Qt.ImhNone) return if (type == UnityActions.Action.Integer || type == UnityActions.Action.Real) inputMethodHints = Qt.ImhDigitsOnly } function activateEditor() { if (!editor.activeFocus) editor.forceActiveFocus(); else showInputPanel(); } function showInputPanel() { if (control.customSoftwareInputPanel != undefined) { // TODO implement once we have the SIP ready } else { if (!Qt.inputMethod.visible) Qt.inputMethod.show(); } textChanged = false; } function hideInputPanel() { if (control.customSoftwareInputPanel != undefined) { // TODO implement once we have the SIP ready } else { Qt.inputMethod.hide(); } // emit accepted signal if changed if (textChanged) control.accepted(); } // reset selection function resetEditorSelection(mouseX) { editor.cursorPosition = editor.positionAt(mouseX); } // positions the cursor depending on whether there is a selection active or not function positionCursor(x) { var cursorPos = control.positionAt(x); if (control.selectedText === "") { control.cursorPosition = cursorPos; } // If target cursor position is outside selection then cancel selection and move cursor else if (control.selectionStart > cursorPos || control.selectionEnd < cursorPos) { control.cursorPosition = cursorPos; } } } //left pane Item { id: leftPane anchors { left: parent.left leftMargin: internal.spacing verticalCenter: parent.verticalCenter } // the left pane width depends on its children width height: parent.height width: childrenRect.width onChildrenChanged: { // reparenting for (var i = 0; i < children.length; i++) { children[i].parent = leftPane; children[i].anchors.verticalCenter = verticalCenter; } } } // right pane Item { id: rightPane anchors { right: parent.right rightMargin: internal.spacing verticalCenter: parent.verticalCenter } // the right pane width depends on its children width height: parent.height width: childrenRect.width onChildrenChanged: { // reparenting for (var i = 0; i < children.length; i++) { children[i].parent = rightPane; children[i].anchors.verticalCenter = verticalCenter; } } } // cursor Component { id: cursor TextCursor { //FIXME: connect to root object once we have all TextInput properties exposed editorItem: editor height: internal.lineSize popover: control.popover visible: editor.cursorVisible Component.onCompleted: internal.popupTriggered.connect(openPopover) } } AbstractButton { id: clearButton objectName: "clear_button" property url iconSource: control.__styleInstance.iconSource anchors { top: parent.top right: rightPane.left bottom: parent.bottom margins: internal.spacing } width: visible ? height : 0 visible: control.hasClearButton && (control.activeFocus && ((editor.text != "") || editor.inputMethodComposing)) Image { //anchors.fill: parent anchors.verticalCenter: parent.verticalCenter width: units.gu(3) height: width smooth: true source: control.hasClearButton ? clearButton.iconSource : "" onSourceChanged: print(source) } onClicked: editor.text = "" } // hint text Label { id: hint verticalAlignment: Text.AlignVCenter horizontalAlignment: editor.horizontalAlignment anchors { left: leftPane.right right: clearButton.left top: parent.top bottom: parent.bottom margins: internal.spacing } // hint is shown till user types something in the field visible: (editor.text == "") && !editor.inputMethodComposing color: Theme.palette.normal.backgroundText fontSize: "medium" elide: Text.ElideRight } // text input TextInput { id: editor // FocusScope will forward focus to this component focus: true anchors { left: leftPane.right right: clearButton.left margins: internal.spacing verticalCenter: parent.verticalCenter } // get the control's style clip: true onTextChanged: internal.textChanged = true cursorDelegate: cursor color: control.__styleInstance.color selectedTextColor: Theme.palette.selected.foregroundText selectionColor: Theme.palette.selected.foreground font.pixelSize: FontUtils.sizeToPixels("medium") passwordCharacter: "\u2022" // forward keys to the root element so it can be captured outside of it Keys.forwardTo: [control] // handle virtual keyboard and cursor positioning, as the MouseArea overrides // those functionalities of the TextInput MouseArea { id: virtualKbdHandler anchors.fill: parent hoverEnabled: true preventStealing: true onClicked: { // activate control if (!control.activeFocus) { internal.activateEditor(); // set cursor position if no selection was previously set internal.positionCursor(mouse.x) } else if (!internal.selectionMode){ // reset selection and move cursor unde mouse click internal.resetEditorSelection(mouse.x); } else if (internal.selectionMode) { // reset selection mode (onReleased is triggered prior to onClicked // and resetting selection mode there would cause to enter in the\ // previous if-clause internal.selectionMode = false; } } onPressAndHold: { internal.activateEditor(); internal.positionCursor(mouse.x); internal.popupTriggered(); } onDoubleClicked: { // select word under doubletap if (!control.activeFocus) return; editor.selectWord(); internal.selectionMode = false; } onPressed: { // don't do anything while the control is inactive if (!control.activeFocus || (pressedButtons != Qt.LeftButton)) return; internal.activateEditor(); if (control.selectedText === "") { internal.resetEditorSelection(mouse.x); internal.selectionMode = true; } } onReleased: { if (!containsMouse) internal.selectionMode = false; } } } Component.onCompleted: { editor.accepted.connect(control.accepted); cursorPosition = 0; } style: Theme.createStyleComponent("TextFieldStyle.qml", control) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/qmldir0000644000015301777760000000266612321005637026264 0ustar pbusernogroup00000000000000module Ubuntu.Components plugin UbuntuComponents Action 0.1 Action.qml ActionItem 0.1 ActionItem.qml ActionList 0.1 ActionList.qml ToolbarItems 0.1 ToolbarItems.qml ToolbarButton 0.1 ToolbarButton.qml MainView 0.1 MainView.qml Button 0.1 Button.qml Panel 0.1 Panel.qml internal DraggingArea DraggingArea.qml Tab 0.1 Tab.qml TabBar 0.1 TabBar.qml Tabs 0.1 Tabs.qml Label 0.1 Label.qml AbstractButton 0.1 AbstractButton.qml ActivityIndicator 0.1 ActivityIndicator.qml ProgressBar 0.1 ProgressBar.qml TextField 0.1 TextField.qml TextArea 0.1 TextArea.qml Switch 0.1 Switch.qml CheckBox 0.1 CheckBox.qml Slider 0.1 Slider.qml Scrollbar 0.1 Scrollbar.qml Object 0.1 Object.qml OptionSelector 0.1 OptionSelector.qml OptionSelectorDelegate 0.1 OptionSelectorDelegate.qml Page 0.1 Page.qml internal PageTreeNode PageTreeNode.qml PageStack 0.1 PageStack.qml internal Toolbar Toolbar.qml Header 0.1 Header.qml internal AnimatedItem AnimatedItem.qml internal PageWrapper PageWrapper.qml UbuntuShape 0.1 UbuntuShape.qml CrossFadeImage 0.1 CrossFadeImage.qml Icon 0.1 Icon.qml OrientationHelper 0.1 OrientationHelper.qml MathUtils 0.1 mathUtils.js SliderUtils 0.1 sliderUtils.js ScrollbarUtils 0.1 scrollbarUtils.js UbuntuNumberAnimation 0.1 UbuntuNumberAnimation.qml StyledItem 0.1 StyledItem.qml ColorUtils 0.1 colorUtils.js DateUtils 0.1 dateUtils.js UbuntuListView 0.1 UbuntuListView.qml internal TextCursor TextCursor.qml internal TextInputPopover TextInputPopover.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/OrientationHelper.qml0000644000015301777760000001426412321005637031214 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Window 2.0 import Ubuntu.Components 0.1 as Ubuntu /*! \qmltype OrientationHelper \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The OrientationHelper automatically rotates its children following the orientation of the device. Any Item placed inside an Orientation Helper will be automatically rotated following the orientation of the device. Note that OrientationHelper is always filling its parent (anchors.parent: fill). Example: \qml Item { OrientationHelper { Label { text: "Automatically rotated" } Button { text: "Automatically rotated" } } } \endqml */ Item { id: orientationHelper /*! \preliminary Sets whether it will be automatically rotating when the device is. The default value is true. \qmlproperty bool automaticOrientation */ property bool automaticOrientation: true /*! \preliminary Sets whether the rotation transition is performed. The default value is true. \qmlproperty bool transitionEnabled */ property bool transitionEnabled: true /*! \preliminary Exposes whether the orientationTransition is running. \qmlproperty alias rotating */ property alias rotating: orientationTransition.running /*! \qmlproperty int __orientationAngle \deprecated Use orientationAngle instead. */ property alias __orientationAngle: orientationHelper.orientationAngle /*! \qmlproperty int orientationAngle Calculates the current orientation angle. */ property int orientationAngle: automaticOrientation ? Screen.angleBetween(Screen.primaryOrientation, Screen.orientation) : 0 anchors.fill: parent Component.onCompleted: orientationTransition.enabled = transitionEnabled /*! \internal */ onOrientationAngleChanged: internal.applyOrientation() /* The attached property Screen.orientation is only valid inside Item or derived components. Inside Object it evaluates to 0 with no error. Also be aware that some apps eg. webbrowser-app set window.contentOrientation and thus can hide failure to update it from this code. See http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick-window2-screen.html */ Item { id: internal /*! 'window' is defined by QML between startup and showing on the screen. There is no signal for when it becomes available and re-declaring it is not safe. http://qt-project.org/doc/qt-5.1/qtqml/qml-qtqml2-qt.html http://qt-project.org/doc/qt-5.1/qtquick/qmlmodule-qtquick-window2-qtquick-window-2.html */ property bool windowActive: typeof window != 'undefined' /*! Report the current orientation of the application via QWindow::contentOrientation. http://qt-project.org/doc/qt-5.0/qtgui/qwindow.html#contentOrientation-prop */ function applyOrientation() { if (windowActive) window.contentOrientation = Screen.orientation } onWindowActiveChanged: applyOrientation() state: orientationAngle.toString() states: [ State { name: "0" PropertyChanges { target: orientationHelper rotation: 0 } }, State { name: "180" PropertyChanges { target: orientationHelper rotation: 180 } }, State { name: "270" PropertyChanges { target: orientationHelper rotation: 270 anchors { leftMargin: (parent.width - parent.height) / 2 rightMargin: anchors.leftMargin topMargin: -anchors.leftMargin bottomMargin: anchors.topMargin } } }, State { name: "90" PropertyChanges { target: orientationHelper rotation: 90 anchors { leftMargin: (parent.width - parent.height) / 2 rightMargin: anchors.leftMargin topMargin: -anchors.leftMargin bottomMargin: anchors.topMargin } } } ] transitions: [ Transition { id: orientationTransition ParallelAnimation { SequentialAnimation { PauseAnimation { duration: 25 } PropertyAction { target: orientationHelper properties: "anchors.topMargin,anchors.bottomMargin,anchors.rightMargin,anchors.leftMargin" } } RotationAnimation { target: orientationHelper properties: "rotation" duration: Ubuntu.UbuntuAnimation.FastDuration easing: Ubuntu.UbuntuAnimation.StandardEasing direction: RotationAnimation.Shortest } } } ] } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Tab.qml0000644000015301777760000000662212321005637026266 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Tab \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Component to represent a single tab in a \l Tabs environment. Examples: See \l Tabs. */ PageTreeNode { id: tab anchors.fill: parent ? parent : undefined /*! The title that is shown on the tab button used to select this tab. */ property string title /*! \preliminary \deprecated The location of the icon that is displayed inside the button used to select this tab (optional). Either \l title or iconSource, or both must be defined. Deprecated because our new tab buttons in the header do not display an icon. */ property url iconSource /*! The contents of the page. Use a \l Page or a Loader that loads an external \l Page. */ property Item page: null /*! \qmlproperty int index \readonly The property holds the index of the tab within the Tabs. */ readonly property alias index: internal.index /*! When page is updated, set its parent to be tab. */ onPageChanged: if (page) page.parent = tab /*! The tab is active when it is the selected tab of its parent Tabs item. Setting tab to active will automatically make child nodes active. */ active: parentNode && parentNode.active && parentNode.hasOwnProperty("selectedTab") && parentNode.selectedTab === tab visible: active /*! \internal */ onTitleChanged: { if (active) { // ensure the parent node is an instance of Tabs if (parentNode.hasOwnProperty("selectedTab")) { parentNode.modelChanged(); } } } /*! \internal */ property alias __protected: internal QtObject { id: internal /* Specifies the index of the Tab in Tabs. */ property int index: -1 /* Specifies whether the Tab has already been inserted in Tabs model or not. Pre-declared tabs are added one by one automatically before Tabs component completion, therefore we need this flag to exclude adding those Tab elements again which were already added. */ property bool inserted: false /* Specifies whether the Tab was created dynamically or not. A dynamically created Tab is destroyed upon removal. */ property bool dynamic: false /* This flag is used by the Tabs to determine whether the pre-declared Tab was removed from the Tabs model or not. The flag guards adding back pre-declared tabs upon Tabs component stack (children) change. */ property bool removedFromTabs: false } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Tabs.qml0000644000015301777760000003765412321005735026461 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Tabs \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The Tabs class provides an environment where multible \l Tab children can be added, and the user is presented with a tab bar with tab buttons to select different tab pages. Tabs must be placed inside a \l MainView so that it will automatically have a header that shows the tabs that can be selected, and the toolbar which contains the tools of the \l Page in the currently selected \l Tab. \l {http://design.ubuntu.com/apps/building-blocks/tabs}{See also the Design Guidelines on Tabs}. Example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.Components.ListItems 0.1 as ListItem MainView { width: units.gu(48) height: units.gu(60) Tabs { id: tabs Tab { title: i18n.tr("Simple page") page: Page { Label { id: label anchors.centerIn: parent text: "A centered label" } tools: ToolbarItems { ToolbarButton { text: "action" onTriggered: print("action triggered") } } } } Tab { id: externalTab title: i18n.tr("External") page: Loader { parent: externalTab anchors { left: parent.left right: parent.right bottom: parent.bottom } source: (tabs.selectedTab === externalTab) ? Qt.resolvedUrl("MyCustomPage.qml") : "" } } Tab { title: i18n.tr("List view") page: Page { ListView { clip: true anchors.fill: parent model: 20 delegate: ListItem.Standard { iconName: "compose" text: "Item "+modelData } } } } } } \endqml As the example above shows, an external \l Page inside a \l Tab can be loaded using a Loader. Note that setting the top anchor or the height of the Loader would override the \l Page height. We avoid this because the \l Page automatically adapts its height to accommodate for the header. It is possible to use a Repeater to generate tabs, but when doing so, ensure that the Repeater is declared inside the Tabs at the end, because otherwise the shuffling of the order of children by the Repeater can cause incorrect ordering of the tabs. The \l {http://design.ubuntu.com/apps/global-patterns/navigation}{Navigation Patterns} specify that a tabs header should never be combined with the back button of a \l PageStack. The only way to combine Tabs and \l PageStack that avoids this is by pushing the Tabs as the first page on the \l PageStack, and pushing other pages on top of that, as is shown in the following example: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { id: mainView width: units.gu(38) height: units.gu(50) PageStack { id: pageStack Component.onCompleted: push(tabs) Tabs { id: tabs Tab { title: "Tab 1" page: Page { Button { anchors.centerIn: parent onClicked: pageStack.push(page3) text: "Press" } } } Tab { title: "Tab 2" page: Page { Label { anchors.centerIn: parent text: "Use header to navigate between tabs" } } } } Page { id: page3 visible: false title: "Page on stack" Label { anchors.centerIn: parent text: "Press back to return to the tabs" } } } } \endqml */ PageTreeNode { id: tabs anchors.fill: parent /*! \preliminary \qmlproperty int selectedTabIndex The index of the currently selected tab. The first tab is 0, and -1 means that no tab is selected. The initial value is 0 if Tabs has contents, or -1 otherwise. */ property alias selectedTabIndex: bar.selectedIndex /*! \preliminary The currently selected tab. */ readonly property Tab selectedTab: (selectedTabIndex < 0) || (tabsModel.count <= selectedTabIndex) ? null : tabsModel.get(selectedTabIndex).tab /*! The page of the currently selected tab. */ readonly property Item currentPage: selectedTab ? selectedTab.page : null /*! The \l TabBar that will be shown in the header and provides scrollable tab buttons. */ property TabBar tabBar: TabBar { id: bar model: tabsModel visible: tabs.active } /*! Children are placed in a separate item that has functionality to extract the Tab items. \qmlproperty list tabChildren */ default property alias tabChildren: tabStack.data /*! \qmlproperty int count Contains the number of tabs in the Tabs component. */ readonly property alias count: tabsModel.count /*! \deprecated Used by the tabs style to update the tabs header with the titles of all the tabs. This signal is used in an intermediate step in transitioning the tabs to a new implementation and may be removed in the future. */ signal modelChanged() /*! \internal required by TabsStyle */ ListModel { id: tabsModel function listModel(tab) { return {"title": tab.title, "tab": tab}; } function updateTabList(tabsList) { var offset = 0; var tabIndex; for (var i in tabsList) { var tab = tabsList[i]; if (internal.isTab(tab)) { tabIndex = i - offset; // make sure we have the right parent tab.parent = tabStack; if (!tab.__protected.inserted) { tab.__protected.index = tabIndex; tab.__protected.inserted = true; insert(tabIndex, listModel(tab)); } else if (!tab.__protected.removedFromTabs && tabsModel.count > tab.index) { get(tab.index).title = tab.title; } // always makes sure that tabsModel has the same order as tabsList move(tab.__protected.index, tabIndex, 1); reindex(); } else { // keep track of children that are not tabs so that we compute // the right index for actual tabs offset += 1; } } internal.sync(); } function reindex(from) { var start = 0; if (from !== undefined) { start = from + 1; } for (var i = start; i < count; i++) { var tab = get(i).tab; tab.__protected.index = i; } } } // FIXME: this component is not really needed, as it doesn't really bring any // value; should be removed in a later MR Item { anchors.fill: parent id: tabStack onChildrenChanged: { internal.connectToRepeaters(tabStack.children); tabsModel.updateTabList(tabStack.children); } } /* This timer is used when tabs are created using Repeaters. Repeater model element moves (shuffling) are causing re-stacking of the tab stack children which may not be realized at the time the rowsMoved/columnsMoved or layoutChanged signals are triggered. Therefore we use an idle timer to update the tabs model, so the tab stack is re-stacked by then. */ Timer { id: updateTimer interval: 1 running: false onTriggered: { tabsModel.updateTabList(tabStack.children); internal.sync(); } } Object { id: internal property Header header: tabs.__propagated ? tabs.__propagated.header : null Binding { target: tabBar property: "animate" when: internal.header && internal.header.hasOwnProperty("animate") value: internal.header.animate } /* List of connected Repeaters to avoid repeater "hammering" of itemAdded() signal. */ property var repeaters: [] function sync() { if (tabBar && tabBar.__styleInstance && tabBar.__styleInstance.hasOwnProperty("sync")) { tabBar.__styleInstance.sync(); } if (tabs.active && internal.header) { internal.header.show(); } // deprecated, however use it till we remove it completely tabs.modelChanged(); } function isTab(item) { if (item && item.hasOwnProperty("__isPageTreeNode") && item.__isPageTreeNode && item.hasOwnProperty("title") && item.hasOwnProperty("page")) { return true; } else { return false; } } function isRepeater(item) { return (item && item.hasOwnProperty("itemAdded")); } function connectToRepeaters(children) { for (var i = 0; i < children.length; i++) { var child = children[i]; if (internal.isRepeater(child) && (internal.repeaters.indexOf(child) < 0)) { internal.connectRepeater(child); } } } /* When inserting a delegate into its parent the Repeater does it in 3 steps: 1) sets the parent of the delegate thus inserting it in the list of children in a position that does not correspond to the position of the corresponding item in the model. At that point the childrenChanged() signal is emitted. 2) reorder the delegate to match the position of the corresponding item in the model. 3) emits the itemAdded() signal. We need to update the list of tabs (tabsModel) when the children are in the adequate order hence the workaround below. It connects to the itemAdded() signal of any repeater it finds and triggers an update of the tabsModel. Somewhat related Qt bug report: https://bugreports.qt-project.org/browse/QTBUG-32438 */ function updateTabsModel() { tabsModel.updateTabList(tabStack.children); } /* Connects a Repeater and stores it so further connects will not happen to the same repeater avoiding in this way hammering. */ function connectRepeater(repeater) { // store repeater repeaters.push(repeater); // connect destruction signal so we have a proper cleanup repeater.Component.onDestruction.connect(internal.disconnectRepeater.bind(repeater)); // connect repeater's itemAdded and itemRemoved signals repeater.itemAdded.connect(internal.updateTabsModel); repeater.itemRemoved.connect(internal.removeTabFromModel); // check if the repeater's model is set, if not, connect to modelChanged to catch that if (repeater.model === undefined) { repeater.modelChanged.connect(internal.connectRepeaterModelChanges.bind(repeater)); } else { connectRepeaterModelChanges(repeater); } } /* Disconnects the given repeater signals. */ function disconnectRepeater() { this.itemAdded.disconnect(internal.updateTabsModel); this.itemRemoved.disconnect(internal.removeTabFromModel); this.modelChanged.disconnect(internal.connectRepeaterModelChanges); } /* Connects a Repeater's model change signals so we get notified whenever those change. This can be called either by the Repeater's modelChanged() signal, in which case the parameter is undefined, or from the connectRepeater() in case the model is given for the Repeater. */ function connectRepeaterModelChanges(repeater) { if (repeater === undefined) { repeater = this; } /* Omit model types which are not derived from object (i.e. are [object Number] or [object Array] typed). JS 'instanceof' operator does not return true for all types of arrays (i.e for property var array: [....] it returns false). The safest way to detect whether the model is really an object we use the toString() prototype of the generic JS Object. Inspired from http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ */ if (Object.prototype.toString.call(repeater.model) !== "[object Object]") { return; } // other models are most likely derived from QAbstractItemModel, // therefore we can safely connect to the signals to get notified about refreshes repeater.model.rowsMoved.connect(updateTimer.restart); repeater.model.columnsMoved.connect(updateTimer.restart); repeater.model.layoutChanged.connect(updateTimer.restart); } // clean items removed trough a repeater function removeTabFromModel(index, item) { // cannot use index as that one is relative to the Repeater's model, therefore // we need to look after the Tabs models' role to find out which item to remove for (var i = 0; i < tabsModel.count; i++) { if (tabsModel.get(i).tab === item) { tabsModel.remove(i); break; } } tabsModel.reindex(); } } Binding { target: internal.header property: "contents" value: tabs.active ? tabs.tabBar: null when: internal.header && tabs.active } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/PageWrapperUtils.js0000644000015301777760000000663512321005637030645 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ //.pragma library // FIXME: cannot refer to Component.Error if I use this. // FIXME: ideally we would make this a stateless library, but that breaks applications // that rely on accessing context variables in pages that were pushed on a PageStack // by url (PageStack.push("FileName.qml")) because of a Qt bug: // https://bugreports.qt-project.org/browse/QTBUG-31347 /*! \internal Initialize pageWrapper.object. */ function __initPage(pageWrapper) { var pageComponent; if (pageWrapper.reference.createObject) { // page reference is a component pageComponent = pageWrapper.reference; } else if (typeof pageWrapper.reference == "string") { // page reference is a string (url) pageComponent = Qt.createComponent(pageWrapper.reference); } var pageObject; if (pageComponent) { if (pageComponent.status === Component.Error) { throw new Error("Error while loading page: " + pageComponent.errorString()); } else { // create the object if (pageWrapper.properties) { // initialize the object with the given properties pageObject = pageComponent.createObject(pageWrapper, pageWrapper.properties); } else { pageObject = pageComponent.createObject(pageWrapper); } pageWrapper.canDestroy = true; } } else { // page reference is an object pageObject = pageWrapper.reference; pageObject.parent = pageWrapper; pageWrapper.canDestroy = false; // copy the properties to the page object for (var prop in pageWrapper.properties) { if (pageWrapper.properties.hasOwnProperty(prop)) { pageObject[prop] = pageWrapper.properties[prop]; } } } pageWrapper.object = pageObject; return pageObject; } /*! \internal Create the page object if needed, and make the page object visible. */ function activate(pageWrapper) { if (!pageWrapper.object) { __initPage(pageWrapper); } // Having the same page pushed multiple times on a stack changes // the parent of the page object. Change it back here. pageWrapper.object.parent = pageWrapper; // Some page objects are invisible initially. Make visible. pageWrapper.object.visible = true; pageWrapper.active = true; } /*! \internal Hide page object. */ function deactivate(pageWrapper) { pageWrapper.active = false; } /*! \internal Destroy the page object if pageWrapper.canDestroy is true. Do nothing if pageWrapper.canDestroy is false. */ function destroyObject(pageWrapper) { if (pageWrapper.canDestroy) { pageWrapper.object.destroy(); pageWrapper.object = null; pageWrapper.canDestroy = false; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/0000755000015301777760000000000012321006415026330 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/alarmrequest_p.cpp0000644000015301777760000000415712321005637032074 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "alarmrequest_p.h" #include "alarmrequest_p_p.h" /*----------------------------------------------------------------------------- * Alarm request public interface */ AlarmRequestPrivate::AlarmRequestPrivate(AlarmRequest *qq, bool autoDelete) : q_ptr(qq) , status(AlarmRequest::Ready) , error(UCAlarm::NoError) , completed(true) , autoDelete(autoDelete) { } AlarmRequestPrivate::~AlarmRequestPrivate() { } void AlarmRequestPrivate::setStatus(AlarmRequest::Operation operation, AlarmRequest::Status status, int error) { if ((this->status != status) || (this->error != error)) { this->status = status; this->error = error; Q_EMIT q_func()->statusChanged(operation, status, error); } } AlarmRequest::AlarmRequest(QObject *parent) : QObject(parent) , d_ptr(createAlarmRequest(this, false)) { } AlarmRequest::AlarmRequest(bool autoDelete, QObject *parent) : QObject(parent) , d_ptr(createAlarmRequest(this, autoDelete)) { } AlarmRequest::~AlarmRequest() { } AlarmRequest::Status AlarmRequest::status() const { return d_func()->status; } int AlarmRequest::error() const { return d_func()->error; } bool AlarmRequest::save(AlarmData &alarm) { return d_func()->save(alarm); } bool AlarmRequest::remove(AlarmData &alarm) { return d_func()->remove(alarm); } bool AlarmRequest::wait(int msec) { return d_func()->wait(msec); } #include "moc_alarmrequest_p.cpp" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/quickutils.h0000644000015301777760000000324212321005637030704 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef QUICKUTILS_P_H #define QUICKUTILS_P_H #include #include #include class QQuickItem; class QQmlEngine; class QQmlComponent; class QuickUtils : public QObject { Q_OBJECT Q_PROPERTY(QQuickItem *rootObject READ rootObject NOTIFY rootObjectChanged) Q_PROPERTY(QString inputMethodProvider READ inputMethodProvider) public: static QuickUtils& instance() { static QuickUtils instance; return instance; } QQuickItem *rootObject(); Q_INVOKABLE QQuickItem *rootItem(QObject *object); QString inputMethodProvider() const; Q_INVOKABLE static QString className(QObject *item); QObject* createQmlObject(const QUrl &url, QQmlEngine *engine); Q_SIGNALS: void rootObjectChanged(); void activated(); void deactivated(); protected: bool eventFilter(QObject *, QEvent *); private: explicit QuickUtils(QObject *parent = 0); QPointer m_rootView; void lookupQuickView(); }; #endif // QUICKUTILS_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/i18n.h0000644000015301777760000000370412321005637027271 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Tim Peeters */ #ifndef UBUNTU_COMPONENTS_I18N_H #define UBUNTU_COMPONENTS_I18N_H #include class QQmlContext; class QQmlEngine; class UbuntuI18n : public QObject { Q_OBJECT Q_PROPERTY(QString domain READ domain WRITE setDomain NOTIFY domainChanged) Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged) private: Q_DISABLE_COPY(UbuntuI18n) explicit UbuntuI18n(QObject* parent = 0); public: static UbuntuI18n& instance() { static UbuntuI18n instance; return instance; } Q_INVOKABLE void bindtextdomain(const QString& domain_name, const QString& dir_name); Q_INVOKABLE QString tr(const QString& text); Q_INVOKABLE QString tr(const QString& singular, const QString& plural, int n); Q_INVOKABLE QString dtr(const QString& domain, const QString& text); Q_INVOKABLE QString dtr(const QString& domain, const QString& singular, const QString& plural, int n); // getter QString domain() const; QString language() const; // setter void setDomain(const QString& domain); void setLanguage(const QString& lang); Q_SIGNALS: void domainChanged(); void languageChanged(); private: QString m_domain; QString m_language; }; #endif // UBUNTU_COMPONENTS_I18N_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucarguments.h0000644000015301777760000000707512321005637031054 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UCARGUMENTS_H #define UCARGUMENTS_H #include "ucargument.h" #include #include #include #include #include #include #include class UCArguments : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(UCArgument* defaultArgument READ defaultArgument WRITE setDefaultArgument NOTIFY defaultArgumentChanged) Q_PROPERTY(QQmlListProperty arguments READ arguments) Q_CLASSINFO("DefaultProperty", "arguments") Q_PROPERTY(QQmlPropertyMap* values READ values CONSTANT) Q_PROPERTY(bool error READ error NOTIFY errorChanged) Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) public: explicit UCArguments(QObject *parent = 0); UCArgument* defaultArgument() const; void setDefaultArgument(UCArgument* argument); QQmlPropertyMap* values() const; bool error() const; QString errorMessage() const; Q_INVOKABLE void printUsage(); Q_INVOKABLE void quitWithError(const QString& errorMessage = QString()); // inherited from QQmlParserStatus void classBegin(); void componentComplete(); // methods necessary for implementing property QQmlListProperty arguments void appendArguments(UCArgument* argument); UCArgument* atArguments(int index); int countArguments(); void clearArguments(); QQmlListProperty arguments(); Q_SIGNALS: void defaultArgumentChanged(); void errorChanged(); void errorMessageChanged(); protected: void parseAndExposeArguments(); void setValuesOnArguments(const QHash& argumentsValues); QHash buildExpectedArguments(const QList& declaredArguments); QHash parseRawArguments(const QStringList& rawArguments, const QHash& expectedArguments); QStringList collectArgumentValues(QStringList::const_iterator& i, QStringList::const_iterator end, int nValues); bool usageRequested(const QStringList& argumentNames); bool requiredArgumentsProvided(const QHash& argumentsValues, QString& error); bool requiredDefaultArgumentProvided(const QHash& argumentsValues, QString& error); void exposeArgumentsAsProperties(const QHash& argumentsValues); QString usage(); void setErrorMessage(const QString& errorMessage); void quitApplication(); protected Q_SLOTS: void warningArgumentPropertyChanged(); private: bool m_completed; UCArgument* m_defaultArgument; QList m_arguments; QStringList m_rawArguments; QString m_applicationBinary; QQmlPropertyMap* m_values; bool m_error; QString m_errorMessage; }; #endif // UCARGUMENTS_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucurihandler.h0000644000015301777760000000237312321005637031200 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Loïc Molinari */ #include class UCUriHandler; class UriHandlerObject : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Application") public: UriHandlerObject(UCUriHandler* uriHandler); public Q_SLOTS: void Open(const QStringList& uris, const QHash& platformData); private: UCUriHandler* m_uriHandler; }; class UCUriHandler : public QObject { Q_OBJECT public: UCUriHandler(); Q_SIGNALS: void opened(const QStringList& uris); private: UriHandlerObject m_uriHandlerObject; }; ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/plugin.h0000644000015301777760000000267212321005637030013 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #ifndef UBUNTU_COMPONENTS_PLUGIN_H #define UBUNTU_COMPONENTS_PLUGIN_H #include #include class QWindow; class UbuntuComponentsPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri); void initializeEngine(QQmlEngine *engine, const char *uri); static QUrl baseUrl(const QStringList& importPathList, const char* uri); static QObject *registerQmlSingletonType(QQmlEngine *engine, const char* uri, const char* qmlFile); private Q_SLOTS: void registerWindowContextProperty(); void setWindowContextProperty(QWindow* focusWindow); }; #endif // UBUNTU_COMPONENTS_PLUGIN_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/statesaverbackend_p.h0000644000015301777760000000352412321005637032522 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef STATESAVERBACKEND_P_H #define STATESAVERBACKEND_P_H #include #include #include #include #include #include class StateSaverBackend : public QObject { Q_OBJECT public: ~StateSaverBackend(); static StateSaverBackend &instance() { static StateSaverBackend instance; return instance; } bool enabled() const; void setEnabled(bool enabled); bool registerId(const QString &id); void removeId(const QString &id); int load(const QString &id, QObject *item, const QStringList &properties); int save(const QString &id, QObject *item, const QStringList &properties); public Q_SLOTS: bool reset(); Q_SIGNALS: void enabledChanged(bool enabled); void initiateStateSaving(); protected: explicit StateSaverBackend(QObject *parent = 0); private Q_SLOTS: void initialize(); void cleanup(); void signalHandler(int type); private: QPointer m_archive; QSet m_register; QStack m_groupStack; bool m_globalEnabled; }; #endif // STATESAVERBACKEND_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/listener.h0000644000015301777760000000206512321005637030336 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef UBUNTU_COMPONENTS_LISTENER_H #define UBUNTU_COMPONENTS_LISTENER_H #include class QQmlContext; class ContextPropertyChangeListener : public QObject { Q_OBJECT public: explicit ContextPropertyChangeListener(QQmlContext* context, const QString& contextProperty); Q_SLOT void updateContextProperty(); QQmlContext* m_context; QString m_contextProperty; }; #endif // UBUNTU_COMPONENTS_PLUGIN_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/uctheme.cpp0000644000015301777760000001763512321005637030507 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Zsombor Egri * Florian Boucault */ #include "uctheme.h" #include "listener.h" #include "quickutils.h" #include "i18n.h" #include #include #include #include #include #include #include #include #include #include /*! \qmltype Theme \instantiates UCTheme \inqmlmodule Ubuntu.Components 0.1 \ingroup theming \brief The Theme class provides facilities to interact with the current theme. A global instance is exposed as the \b Theme context property. The theme defines the visual aspect of the Ubuntu components. Example changing the current theme: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Item { Button { onClicked: Theme.name = "Ubuntu.Components.Themes.Ambiance" } } \endqml Example creating a style component: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 StyledItem { id: myItem style: Theme.createStyleComponent("MyItemStyle.qml", myItem) } \endqml \sa {StyledItem} */ const QString THEME_FOLDER_FORMAT("%1/%2/"); const QString PARENT_THEME_FILE("parent_theme"); const char *ENV_PATH = "UBUNTU_UI_TOOLKIT_THEMES_PATH"; QStringList themeSearchPath() { QString envPath = QLatin1String(getenv("UBUNTU_UI_TOOLKIT_THEMES_PATH")); QStringList pathList = envPath.split(':', QString::SkipEmptyParts); if (pathList.isEmpty()) { // get the default path list from generic data location, which contains // ~/.local/share and XDG_DATA_DIRS pathList << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); } // fix folders QStringList result; Q_FOREACH(const QString &path, pathList) { if (QDir(path).exists()) { result << path + '/'; } } // append standard QML2_IMPORT_PATH value result << QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); return result; } UCTheme::UCTheme(QObject *parent) : QObject(parent), m_palette(NULL), m_engine(NULL), m_engineUpdated(false) { m_name = m_themeSettings.themeName(); QObject::connect(&m_themeSettings, &UCThemeSettings::themeNameChanged, this, &UCTheme::onThemeNameChanged); updateThemePaths(); QObject::connect(this, SIGNAL(nameChanged()), this, SLOT(loadPalette()), Qt::UniqueConnection); } void UCTheme::updateEnginePaths() { if (!m_engine || m_engineUpdated) { return; } QStringList paths = themeSearchPath(); Q_FOREACH(const QString &path, paths) { if (QDir(path).exists()) { m_engine->addImportPath(path); } } m_engineUpdated = true; } void UCTheme::onThemeNameChanged() { if (m_themeSettings.themeName() != m_name) { m_name = m_themeSettings.themeName(); updateThemePaths(); Q_EMIT nameChanged(); } } QUrl UCTheme::pathFromThemeName(QString themeName) { themeName.replace('.', '/'); QStringList pathList = themeSearchPath(); Q_FOREACH(const QString &path, pathList) { QString themeFolder = THEME_FOLDER_FORMAT.arg(path, themeName); // QUrl needs a trailing slash to understand it's a directory QString absoluteThemeFolder = QDir(themeFolder).absolutePath().append('/'); if (QDir(absoluteThemeFolder).exists()) { return QUrl::fromLocalFile(absoluteThemeFolder); } } return QUrl(); } void UCTheme::updateThemePaths() { m_themePaths.clear(); QString themeName = m_name; while (!themeName.isEmpty()) { QUrl themePath = pathFromThemeName(themeName); if (themePath.isValid()) { m_themePaths.append(themePath); } themeName = parentThemeName(themeName); } } /*! \qmlproperty string Theme::name The name of the current theme. */ QString UCTheme::name() const { return m_name; } void UCTheme::setName(const QString& name) { if (name != m_name) { QObject::disconnect(&m_themeSettings, &UCThemeSettings::themeNameChanged, this, &UCTheme::onThemeNameChanged); m_name = name; updateThemePaths(); Q_EMIT nameChanged(); } } /*! \qmlproperty Palette Theme::palette The palette of the current theme. */ QObject* UCTheme::palette() { if (!m_palette) { loadPalette(false); } return m_palette; } QUrl UCTheme::styleUrl(const QString& styleName) { Q_FOREACH (const QUrl& themePath, m_themePaths) { QUrl styleUrl = themePath.resolved(styleName); if (styleUrl.isValid() && QFile::exists(styleUrl.toLocalFile())) { return styleUrl; } } return QUrl(); } QString UCTheme::parentThemeName(const QString& themeName) { QString parentTheme; QUrl themePath = pathFromThemeName(themeName); if (!themePath.isValid()) { qWarning() << UbuntuI18n::instance().tr("Theme not found: ") << themeName; } else { QFile file(themePath.resolved(PARENT_THEME_FILE).toLocalFile()); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); parentTheme = in.readLine(); } } return parentTheme; } /*! \qmlmethod Component Theme::createStyleComponent(string styleName, object parent) Returns an instance of the style component named \a styleName. */ QQmlComponent* UCTheme::createStyleComponent(const QString& styleName, QObject* parent) { QQmlComponent *component = NULL; if (parent != NULL) { QQmlEngine* engine = qmlEngine(parent); if (engine != m_engine && !m_engine) { m_engine = engine; updateEnginePaths(); } // make sure we have the paths if (engine != NULL) { QUrl url = styleUrl(styleName); if (url.isValid()) { component = new QQmlComponent(engine, url, QQmlComponent::PreferSynchronous, parent); if (component->isError()) { qmlInfo(parent) << component->errorString(); delete component; component = NULL; } } else { qmlInfo(parent) << UbuntuI18n::instance().tr(QString("Warning: Style %1 not found in theme %2").arg(styleName).arg(m_name)); } } } return component; } void UCTheme::registerToContext(QQmlContext* context) { // add paths to engine search folder m_engine = context->engine(); updateEnginePaths(); // register Theme context->setContextProperty("Theme", this); ContextPropertyChangeListener *themeChangeListener = new ContextPropertyChangeListener(context, "Theme"); QObject::connect(this, SIGNAL(nameChanged()), themeChangeListener, SLOT(updateContextProperty())); } void UCTheme::loadPalette(bool notify) { if (!m_engine) { return; } if (m_palette != NULL) { delete m_palette; } m_palette = QuickUtils::instance().createQmlObject(styleUrl("Palette.qml"), m_engine); if (notify) { Q_EMIT paletteChanged(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/qquickclipboard.h0000644000015301777760000000265112321005637031667 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef QQUICKCLIPBOARD_H #define QQUICKCLIPBOARD_H #include #include #include class QQuickMimeData; class QQmlEngine; class QJSEngine; class QQuickClipboardPrivate; class QQuickClipboard : public QObject { Q_OBJECT Q_PROPERTY(QQuickMimeData *data READ data NOTIFY dataChanged) public: explicit QQuickClipboard(QObject *parent = 0); Q_INVOKABLE QQuickMimeData *newData(); private: //getter/setter QQuickMimeData *data(); Q_SIGNALS: void dataChanged(); public Q_SLOTS: void push(const QVariant& data); void clear(); private: Q_DECLARE_PRIVATE(QQuickClipboard) QScopedPointer d_ptr; }; #endif // QQUICKCLIPBOARD_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucstatesaver_p.h0000644000015301777760000000247112321005637031542 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef UCSTATESAVER_P_H #define UCSTATESAVER_P_H #include "ucstatesaver.h" #include class UCStateSaverAttachedPrivate { Q_DECLARE_PUBLIC(UCStateSaverAttached) public: UCStateSaverAttachedPrivate(UCStateSaverAttached *qq, QObject *attachee); UCStateSaverAttached *q_ptr; QObject *m_attachee; bool m_enabled:1; QString m_id; QString m_absoluteId; QStringList m_properties; QString absoluteId(const QString &id); void restore(); void watchComponent(bool watch); void _q_init(); void _q_save(); void _q_globalEnableChanged(bool); }; #endif // UCSTATESAVER_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/qquickclipboard_p.h0000644000015301777760000000216512321005637032206 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef QQUICKCLIPBOARD_P_H #define QQUICKCLIPBOARD_P_H #include "qquickclipboard.h" #include class QQuickMimeData; class QQuickClipboardPrivate { Q_DECLARE_PUBLIC(QQuickClipboard) public: QQuickClipboardPrivate(QQuickClipboard *qq); QQuickClipboard *q_ptr; QClipboard *clipboard; QClipboard::Mode mode; QQuickMimeData *mimeData; void updateMimeData(); }; #endif // QQUICKCLIPBOARD_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/shapeitem.cpp0000644000015301777760000010054012321005637031020 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Loïc Molinari */ #include "shapeitem.h" #include "shapeitemtexture.h" #include "ucunits.h" #include #include #include #include // Retrieves the size of an array at compile time. #define ARRAY_SIZE(a) \ ((sizeof(a) / sizeof(*(a))) / static_cast(!(sizeof(a) % sizeof(*(a))))) // Threshold in grid unit defining the texture quality to be used. const float lowHighTextureThreshold = 11.0f; static const char* const shapeVertexShader = "uniform lowp mat4 matrix; \n" "attribute lowp vec4 positionAttrib; \n" "attribute lowp vec2 shapeCoordAttrib; \n" "attribute lowp vec2 imageCoordAttrib; \n" "varying lowp vec2 shapeCoord; \n" "varying lowp vec2 imageCoord; \n" "void main() \n" "{ \n" " shapeCoord = shapeCoordAttrib; \n" " imageCoord = imageCoordAttrib; \n" " gl_Position = matrix * positionAttrib; \n" "}"; static const char* const shapeTexturedFragmentShader = "uniform lowp float opacity; \n" "uniform sampler2D shapeTexture; \n" "uniform sampler2D imageTexture; \n" "varying lowp vec2 shapeCoord; \n" "varying lowp vec2 imageCoord; \n" "void main() \n" "{ \n" " lowp vec4 shapeData = texture2D(shapeTexture, shapeCoord); \n" " lowp vec4 color = texture2D(imageTexture, imageCoord) * vec4(shapeData.b); \n" " lowp vec4 blend = shapeData.gggr + vec4(1.0 - shapeData.r) * color; \n" " gl_FragColor = blend * vec4(opacity); \n" "}"; static const char* const shapeColoredFragmentShader = "uniform lowp float opacity; \n" "uniform sampler2D shapeTexture; \n" "uniform lowp vec4 color; \n" "uniform lowp vec4 gradientColor; \n" "varying lowp vec2 shapeCoord; \n" "varying lowp vec2 imageCoord; \n" "void main(void) \n" "{ \n" " lowp vec4 shapeData = texture2D(shapeTexture, shapeCoord); \n" " lowp vec4 result = mix(color, gradientColor, imageCoord.t) * vec4(shapeData.b); \n" " lowp vec4 blend = shapeData.gggr + vec4(1.0 - shapeData.r) * result; \n" " gl_FragColor = blend * vec4(opacity); \n" "}"; static const unsigned short shapeMeshIndices[] __attribute__((aligned(16))) = { 0, 4, 1, 5, 2, 6, 3, 7, // Triangles 1 to 6. 7, 4, // Degenerate triangles. 4, 8, 5, 9, 6, 10, 7, 11, // Triangles 7 to 12. 11, 8, // Degenerate triangles. 8, 12, 9, 13, 10, 14, 11, 15 // Triangles 13 to 18 }; static const struct { const unsigned short* const indices; int indexCount; // Number of indices. int vertexCount; // Number of vertices. int attributeCount; // Number of attributes. int stride; // Offset in bytes from one vertex to the other. int positionCount; // Number of components per position. int positionType; // OpenGL type of the position components. int shapeCoordCount; // Number of components per shape texture coordinate. int shapeCoordType; // OpenGL type of the shape texture coordinate components. int imageCoordCount; // Number of components per image texture coordinate. int imageCoordType; // OpenGL type of the image texture coordinate components. int indexType; // OpenGL type of the indices. } shapeMesh = { shapeMeshIndices, ARRAY_SIZE(shapeMeshIndices), 16, 3, sizeof(ShapeNode::Vertex), 2, GL_FLOAT, 2, GL_FLOAT, 2, GL_FLOAT, GL_UNSIGNED_SHORT }; static const QSGGeometry::AttributeSet& getAttributes() { static QSGGeometry::Attribute data[] = { QSGGeometry::Attribute::create(0, shapeMesh.positionCount, shapeMesh.positionType, true), QSGGeometry::Attribute::create(1, shapeMesh.shapeCoordCount, shapeMesh.shapeCoordType), QSGGeometry::Attribute::create(2, shapeMesh.imageCoordCount, shapeMesh.imageCoordType) }; static QSGGeometry::AttributeSet attributes = { shapeMesh.attributeCount, shapeMesh.stride, data }; return attributes; } // Gets the size in bytes of an OpenGL type in the range [GL_BYTE, GL_DOUBLE]. static int sizeOfType(GLenum type) { static int sizes[] = { sizeof(char), sizeof(unsigned char), sizeof(short), sizeof(unsigned short), sizeof(int), sizeof(unsigned int), sizeof(float), 2, 3, 4, sizeof(double) }; Q_ASSERT(type >= 0x1400 && type <= 0x140a); return sizes[type - 0x1400]; } // --- QtQuick item --- ShapeItem::ShapeItem(QQuickItem* parent) : QQuickItem(parent) , color_(0.0, 0.0, 0.0, 0.0) , gradientColor_(0.0, 0.0, 0.0, 0.0) , gradientColorSet_(false) , radiusString_("small") , radius_(ShapeItem::SmallRadius) , border_(ShapeItem::IdleBorder) , image_(NULL) , stretched_(true) , hAlignment_(ShapeItem::AlignHCenter) , vAlignment_(ShapeItem::AlignVCenter) , gridUnit_(UCUnits::instance().gridUnit()) , geometry_() , dirtyFlags_(ShapeItem::DirtyAll) { setFlag(ItemHasContents); QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), this, SLOT(gridUnitChanged())); setImplicitWidth(8 * gridUnit_); setImplicitHeight(8 * gridUnit_); update(); } void ShapeItem::setColor(const QColor& color) { if (color_ != color) { color_ = color; dirtyFlags_ |= ShapeItem::DirtyColor; // gradientColor has the same value as color unless it was manually set if (!gradientColorSet_) { gradientColor_ = color; dirtyFlags_ |= ShapeItem::DirtyGradientColor; Q_EMIT gradientColorChanged(); } update(); Q_EMIT colorChanged(); } } void ShapeItem::setGradientColor(const QColor& gradientColor) { gradientColorSet_ = true; if (gradientColor_ != gradientColor) { gradientColor_ = gradientColor; dirtyFlags_ |= ShapeItem::DirtyGradientColor; update(); Q_EMIT gradientColorChanged(); } } void ShapeItem::setRadius(const QString& radius) { if (radiusString_ != radius) { radiusString_ = radius; radius_ = (radius == "medium") ? ShapeItem::MediumRadius : ShapeItem::SmallRadius; dirtyFlags_ |= ShapeItem::DirtyRadius; update(); Q_EMIT radiusChanged(); } } void ShapeItem::setBorderSource(const QString& borderSource) { if (borderSource_ != borderSource) { if (borderSource.endsWith(QString("radius_idle.sci"))) border_ = ShapeItem::IdleBorder; else if (borderSource.endsWith(QString("radius_pressed.sci"))) border_ = ShapeItem::PressedBorder; else border_ = ShapeItem::RawBorder; borderSource_ = borderSource; dirtyFlags_ |= ShapeItem::DirtyBorder; update(); Q_EMIT borderSourceChanged(); } } void ShapeItem::setImage(const QVariant& image) { QQuickItem* newImage = qobject_cast(qvariant_cast(image)); if (image_ != newImage) { image_ = newImage; // update values of properties that depend on properties of the image QObject::disconnect(image_); if (newImage != NULL) { updateFromImageProperties(newImage); connectToImageProperties(newImage); } if (image_ && !image_->parentItem()) { // Inlined images need a parent and must not be visible. image_->setParentItem(this); image_->setVisible(false); } dirtyFlags_ |= ShapeItem::DirtyImage; update(); Q_EMIT imageChanged(); } } void ShapeItem::updateFromImageProperties(QQuickItem* image) { int alignment; // ShapeItem::stretched depends on image::fillMode QQuickImage::FillMode fillMode = (QQuickImage::FillMode)image->property("fillMode").toInt(); if (fillMode == QQuickImage::PreserveAspectCrop) { setStretched(false); } else { setStretched(true); } // ShapeItem::horizontalAlignment depends on image::horizontalAlignment int imageHorizontalAlignment = image->property("horizontalAlignment").toInt(); if (imageHorizontalAlignment == Qt::AlignLeft) { alignment = ShapeItem::AlignLeft; } else if (imageHorizontalAlignment == Qt::AlignRight) { alignment = ShapeItem::AlignRight; } else { alignment = ShapeItem::AlignHCenter; } setHorizontalAlignment(static_cast(alignment)); // ShapeItem::verticalAlignment depends on image::verticalAlignment int imageVerticalAlignment = image->property("verticalAlignment").toInt(); if (imageVerticalAlignment == Qt::AlignTop) { alignment = ShapeItem::AlignTop; } else if (imageVerticalAlignment == Qt::AlignBottom) { alignment = ShapeItem::AlignBottom; } else { alignment = ShapeItem::AlignVCenter; } setVerticalAlignment(static_cast(alignment)); } void ShapeItem::connectToPropertyChange(QObject* sender, const char* property, QObject* receiver, const char* slot) { int propertyIndex = sender->metaObject()->indexOfProperty(property); if (propertyIndex != -1) { QMetaMethod changeSignal = sender->metaObject()->property(propertyIndex).notifySignal(); int slotIndex = receiver->metaObject()->indexOfSlot(slot); QMetaMethod updateSlot = receiver->metaObject()->method(slotIndex); QObject::connect(sender, changeSignal, receiver, updateSlot); } } void ShapeItem::connectToImageProperties(QQuickItem* image) { connectToPropertyChange(image, "fillMode", this, "onImagePropertiesChanged()"); connectToPropertyChange(image, "horizontalAlignment", this, "onImagePropertiesChanged()"); connectToPropertyChange(image, "verticalAlignment", this, "onImagePropertiesChanged()"); } void ShapeItem::onImagePropertiesChanged() { QQuickItem* image = qobject_cast(sender()); updateFromImageProperties(image); } void ShapeItem::setStretched(bool stretched) { if (stretched_ != stretched) { stretched_ = stretched; dirtyFlags_ |= ShapeItem::DirtyStretched; update(); Q_EMIT stretchedChanged(); } } void ShapeItem::setHorizontalAlignment(HAlignment hAlignment) { if (hAlignment_ != hAlignment) { hAlignment_ = hAlignment; dirtyFlags_ |= ShapeItem::DirtyHAlignment; update(); Q_EMIT horizontalAlignmentChanged(); } } void ShapeItem::setVerticalAlignment(VAlignment vAlignment) { if (vAlignment_ != vAlignment) { vAlignment_ = vAlignment; dirtyFlags_ |= ShapeItem::DirtyVAlignment; update(); Q_EMIT verticalAlignmentChanged(); } } void ShapeItem::gridUnitChanged() { gridUnit_ = UCUnits::instance().gridUnit(); setImplicitWidth(8 * gridUnit_); setImplicitHeight(8 * gridUnit_); dirtyFlags_ |= ShapeItem::DirtyGridUnit; update(); } void ShapeItem::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) { QQuickItem::geometryChanged(newGeometry, oldGeometry); geometry_ = newGeometry; dirtyFlags_ |= ShapeItem::DirtyGeometry; update(); } QSGNode* ShapeItem::updatePaintNode(QSGNode* old_node, UpdatePaintNodeData* data) { Q_UNUSED(data); // FIXME(loicm) Shape textures are stored in the read-only data section of the plugin as it // avoids having to deal with paths for now. It should preferably be loaded from a file. /* Textures created with QWindow::createTextureFromImage() become invalid * when the window is destroyed; therefore, we must keep track of which * window was used to create them and be ready to re-create them if that * window goes away. */ static QPointer textureOwner = 0; if (!textureOwner) { shapeTextureHigh.texture = window()->createTextureFromImage( QImage(shapeTextureHigh.data, shapeTextureHigh.width, shapeTextureHigh.height, QImage::Format_ARGB32_Premultiplied)); shapeTextureLow.texture = window()->createTextureFromImage( QImage(shapeTextureLow.data, shapeTextureLow.width, shapeTextureLow.height, QImage::Format_ARGB32_Premultiplied)); textureOwner = window(); } // The image item sets its texture in its updatePaintNode() method when QtQuick iterates through // the list of dirty items. When we're notified the image item has been changed through // setImage(), we mark the shape item as dirty by requesting an update. But sometimes it leads // to have the shape item being queued in the dirty list before the image item. That case can be // detected when the texture provider exists but not the texture itself. When that's the case we // push the shape item in the dirty list to be handled next frame and we tell QtQuick not to // render the item for the current frame. const QSGTextureProvider* provider = image_ ? image_->textureProvider() : NULL; const QSGTexture* texture = provider ? provider->texture() : NULL; if (provider && !texture) { update(); delete old_node; return NULL; } ShapeNode* node = static_cast(old_node); if (!node) { node = new ShapeNode(this); } ShapeTexturedMaterial* texturedMaterial = node->texturedMaterial(); ShapeColoredMaterial* coloredMaterial = node->coloredMaterial(); TextureData* textureData = (gridUnit_ > lowHighTextureThreshold) ? &shapeTextureHigh : &shapeTextureLow; // Set the shape texture to be used by the materials depending on current grid unit. The radius // is set considering the current grid unit and the texture raster grid unit. When the item size // is less than 2 radii, the radius is scaled down anyhow. float radius = (radius_ == ShapeItem::SmallRadius) ? textureData->smallRadius : textureData->mediumRadius; const float scaleFactor = gridUnit_ / textureData->gridUnit; radius *= scaleFactor; int scaledDown = 0; if (scaleFactor != 1.0f) { scaledDown |= 1; } const float halfMinWidthHeight = qMin(geometry_.width(), geometry_.height()) * 0.5f; if (radius > halfMinWidthHeight) { radius = halfMinWidthHeight; scaledDown |= 1; } coloredMaterial->setShapeTexture(textureData->texture, !!scaledDown); texturedMaterial->setShapeTexture(textureData->texture, !!scaledDown); // Update the other material properties. coloredMaterial->setColor(color_); coloredMaterial->setGradientColor(gradientColor_); texturedMaterial->setImage(image_); // Update node vertices and type. int index = (border_ == ShapeItem::RawBorder) ? 0 : (border_ == ShapeItem::IdleBorder) ? 1 : 2; if (radius_ == ShapeItem::SmallRadius) index += 3; node->setVertices(geometry_, radius, image_, stretched_, hAlignment_, vAlignment_, textureData->coordinate[index]); node->setMaterialType(image_ ? ShapeNode::TexturedMaterial : ShapeNode::ColoredMaterial); return node; } // --- Scene graph geometry node --- ShapeNode::ShapeNode(ShapeItem* item) : QSGGeometryNode() , item_(item) , geometry_(getAttributes(), shapeMesh.vertexCount, shapeMesh.indexCount, shapeMesh.indexType) , texturedMaterial_() , coloredMaterial_() , currentMaterial_(ShapeNode::ColoredMaterial) { memcpy(geometry_.indexData(), shapeMesh.indices, shapeMesh.indexCount * sizeOfType(shapeMesh.indexType)); geometry_.setDrawingMode(GL_TRIANGLE_STRIP); geometry_.setIndexDataPattern(QSGGeometry::StaticPattern); geometry_.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); setGeometry(&geometry_); setMaterial(&coloredMaterial_); setFlag(UsePreprocess, false); } void ShapeNode::setVertices(const QRectF& geometry, float radius, QQuickItem* image, bool stretched, ShapeItem::HAlignment hAlignment, ShapeItem::VAlignment vAlignment, float shapeCoordinate[][2]) { ShapeNode::Vertex* vertices = reinterpret_cast(geometry_.vertexData()); const QSGTextureProvider* provider = image ? image->textureProvider() : NULL; const QSGTexture* texture = provider ? provider->texture() : NULL; const float width = geometry.width(); const float height = geometry.height(); float topCoordinate; float bottomCoordinate; float leftCoordinate; float rightCoordinate; float radiusCoordinateWidth; float radiusCoordinateHeight; // FIXME(loicm) With a NxM image, a preserve aspect crop fill mode and a width // component size of N (or a height component size of M), changing the the // height (or width) breaks the 1:1 texel/pixel mapping for odd values. if (!stretched && texture) { // Preserve source image aspect ratio cropping areas exceeding destination rectangle. const float factors[3] = { 0.0f, 0.5f, 1.0f }; const QSize srcSize = texture->textureSize(); const float srcRatio = static_cast(srcSize.width()) / srcSize.height(); const float dstRatio = static_cast(width) / height; if (dstRatio <= srcRatio) { const float inCoordinateSize = dstRatio / srcRatio; const float outCoordinateSize = 1.0f - inCoordinateSize; topCoordinate = 0.0f; bottomCoordinate = 1.0f; leftCoordinate = outCoordinateSize * factors[hAlignment]; rightCoordinate = 1.0f - (outCoordinateSize * (1.0f - factors[hAlignment])); radiusCoordinateHeight = radius / height; radiusCoordinateWidth = (radius / width) * inCoordinateSize; } else { const float inCoordinateSize = srcRatio / dstRatio; const float outCoordinateSize = 1.0f - inCoordinateSize; topCoordinate = outCoordinateSize * factors[vAlignment]; bottomCoordinate = 1.0f - (outCoordinateSize * (1.0f - factors[vAlignment])); leftCoordinate = 0.0f; rightCoordinate = 1.0f; radiusCoordinateHeight = (radius / height) * inCoordinateSize; radiusCoordinateWidth = radius / width; } } else { // Don't preserve source image aspect ratio stretching it in destination rectangle. topCoordinate = 0.0f; bottomCoordinate = 1.0f; leftCoordinate = 0.0f; rightCoordinate = 1.0f; radiusCoordinateHeight = radius / height; radiusCoordinateWidth = radius / width; } // Scale and translate coordinates of textures packed in an atlas. if (texture && texture->isAtlasTexture()) { const QRectF srcSubRect = texture->normalizedTextureSubRect(); topCoordinate = topCoordinate * srcSubRect.height() + srcSubRect.y(); bottomCoordinate = bottomCoordinate * srcSubRect.height() + srcSubRect.y(); leftCoordinate = leftCoordinate * srcSubRect.width() + srcSubRect.x(); rightCoordinate = rightCoordinate * srcSubRect.width() + srcSubRect.x(); radiusCoordinateHeight = radiusCoordinateHeight * srcSubRect.height(); radiusCoordinateWidth = radiusCoordinateWidth * srcSubRect.width(); } // Set top row of 4 vertices. vertices[0].position[0] = 0.0f; vertices[0].position[1] = 0.0f; vertices[0].shapeCoordinate[0] = shapeCoordinate[0][0]; vertices[0].shapeCoordinate[1] = shapeCoordinate[0][1]; vertices[0].imageCoordinate[0] = leftCoordinate; vertices[0].imageCoordinate[1] = topCoordinate; vertices[1].position[0] = radius; vertices[1].position[1] = 0.0f; vertices[1].shapeCoordinate[0] = shapeCoordinate[1][0]; vertices[1].shapeCoordinate[1] = shapeCoordinate[1][1]; vertices[1].imageCoordinate[0] = leftCoordinate + radiusCoordinateWidth; vertices[1].imageCoordinate[1] = topCoordinate; vertices[2].position[0] = width - radius; vertices[2].position[1] = 0.0f; vertices[2].shapeCoordinate[0] = shapeCoordinate[2][0]; vertices[2].shapeCoordinate[1] = shapeCoordinate[2][1]; vertices[2].imageCoordinate[0] = rightCoordinate - radiusCoordinateWidth; vertices[2].imageCoordinate[1] = topCoordinate; vertices[3].position[0] = width; vertices[3].position[1] = 0.0f; vertices[3].shapeCoordinate[0] = shapeCoordinate[3][0]; vertices[3].shapeCoordinate[1] = shapeCoordinate[3][1]; vertices[3].imageCoordinate[0] = rightCoordinate; vertices[3].imageCoordinate[1] = topCoordinate; // Set middle-top row of 4 vertices. vertices[4].position[0] = 0.0f; vertices[4].position[1] = radius; vertices[4].shapeCoordinate[0] = shapeCoordinate[4][0]; vertices[4].shapeCoordinate[1] = shapeCoordinate[4][1]; vertices[4].imageCoordinate[0] = leftCoordinate; vertices[4].imageCoordinate[1] = topCoordinate + radiusCoordinateHeight; vertices[5].position[0] = radius; vertices[5].position[1] = radius; vertices[5].shapeCoordinate[0] = shapeCoordinate[5][0]; vertices[5].shapeCoordinate[1] = shapeCoordinate[5][1]; vertices[5].imageCoordinate[0] = leftCoordinate + radiusCoordinateWidth; vertices[5].imageCoordinate[1] = topCoordinate + radiusCoordinateHeight; vertices[6].position[0] = width - radius; vertices[6].position[1] = radius; vertices[6].shapeCoordinate[0] = shapeCoordinate[6][0]; vertices[6].shapeCoordinate[1] = shapeCoordinate[6][1]; vertices[6].imageCoordinate[0] = rightCoordinate - radiusCoordinateWidth; vertices[6].imageCoordinate[1] = topCoordinate + radiusCoordinateHeight; vertices[7].position[0] = width; vertices[7].position[1] = radius; vertices[7].shapeCoordinate[0] = shapeCoordinate[7][0]; vertices[7].shapeCoordinate[1] = shapeCoordinate[7][1]; vertices[7].imageCoordinate[0] = rightCoordinate; vertices[7].imageCoordinate[1] = topCoordinate + radiusCoordinateHeight; // Set middle-bottom row of 4 vertices. vertices[8].position[0] = 0.0f; vertices[8].position[1] = height - radius; vertices[8].shapeCoordinate[0] = shapeCoordinate[8][0]; vertices[8].shapeCoordinate[1] = shapeCoordinate[8][1]; vertices[8].imageCoordinate[0] = leftCoordinate; vertices[8].imageCoordinate[1] = bottomCoordinate - radiusCoordinateHeight; vertices[9].position[0] = radius; vertices[9].position[1] = height - radius; vertices[9].shapeCoordinate[0] = shapeCoordinate[9][0]; vertices[9].shapeCoordinate[1] = shapeCoordinate[9][1]; vertices[9].imageCoordinate[0] = leftCoordinate + radiusCoordinateWidth; vertices[9].imageCoordinate[1] = bottomCoordinate - radiusCoordinateHeight; vertices[10].position[0] = width - radius; vertices[10].position[1] = height - radius; vertices[10].shapeCoordinate[0] = shapeCoordinate[10][0]; vertices[10].shapeCoordinate[1] = shapeCoordinate[10][1]; vertices[10].imageCoordinate[0] = rightCoordinate - radiusCoordinateWidth; vertices[10].imageCoordinate[1] = bottomCoordinate - radiusCoordinateHeight; vertices[11].position[0] = width; vertices[11].position[1] = height - radius; vertices[11].shapeCoordinate[0] = shapeCoordinate[11][0]; vertices[11].shapeCoordinate[1] = shapeCoordinate[11][1]; vertices[11].imageCoordinate[0] = rightCoordinate; vertices[11].imageCoordinate[1] = bottomCoordinate - radiusCoordinateHeight; // Set bottom row of 4 vertices. vertices[12].position[0] = 0.0f; vertices[12].position[1] = height; vertices[12].shapeCoordinate[0] = shapeCoordinate[12][0]; vertices[12].shapeCoordinate[1] = shapeCoordinate[12][1]; vertices[12].imageCoordinate[0] = leftCoordinate; vertices[12].imageCoordinate[1] = bottomCoordinate; vertices[13].position[0] = radius; vertices[13].position[1] = height; vertices[13].shapeCoordinate[0] = shapeCoordinate[13][0]; vertices[13].shapeCoordinate[1] = shapeCoordinate[13][1]; vertices[13].imageCoordinate[0] = leftCoordinate + radiusCoordinateWidth; vertices[13].imageCoordinate[1] = bottomCoordinate; vertices[14].position[0] = width - radius; vertices[14].position[1] = height; vertices[14].shapeCoordinate[0] = shapeCoordinate[14][0]; vertices[14].shapeCoordinate[1] = shapeCoordinate[14][1]; vertices[14].imageCoordinate[0] = rightCoordinate - radiusCoordinateWidth; vertices[14].imageCoordinate[1] = bottomCoordinate; vertices[15].position[0] = width; vertices[15].position[1] = height; vertices[15].shapeCoordinate[0] = shapeCoordinate[15][0]; vertices[15].shapeCoordinate[1] = shapeCoordinate[15][1]; vertices[15].imageCoordinate[0] = rightCoordinate; vertices[15].imageCoordinate[1] = bottomCoordinate; markDirty(DirtyGeometry); } void ShapeNode::setMaterialType(ShapeNode::MaterialType material) { if (currentMaterial_ != material) { if (material == ShapeNode::ColoredMaterial) setMaterial(&coloredMaterial_); else setMaterial(&texturedMaterial_); currentMaterial_ = material; markDirty(DirtyMaterial); } } // --- Scene graph textured material --- ShapeTexturedMaterial::ShapeTexturedMaterial() : imageTextureProvider_(NULL) , shapeTexture_(NULL) , filtering_(QSGTexture::Nearest) { setFlag(Blending); } QSGMaterialType* ShapeTexturedMaterial::type() const { static QSGMaterialType type; return &type; } QSGMaterialShader* ShapeTexturedMaterial::createShader() const { return new ShapeTexturedShader; } void ShapeTexturedMaterial::setImage(QQuickItem* image) { imageTextureProvider_ = image ? image->textureProvider() : NULL; } QSGTextureProvider* ShapeTexturedMaterial::imageTextureProvider() const { return imageTextureProvider_; } void ShapeTexturedMaterial::setShapeTexture(QSGTexture* texture, bool scaledDown) { shapeTexture_ = texture; filtering_ = scaledDown ? QSGTexture::Linear : QSGTexture::Nearest; } // -- Scene graph textured material shader --- const char *ShapeTexturedShader::vertexShader() const { return shapeVertexShader; } const char* ShapeTexturedShader::fragmentShader() const { return shapeTexturedFragmentShader; } char const* const* ShapeTexturedShader::attributeNames() const { static char const* const attributes[] = { "positionAttrib", "shapeCoordAttrib", "imageCoordAttrib", 0 }; return attributes; } void ShapeTexturedShader::initialize() { QSGMaterialShader::initialize(); program()->bind(); program()->setUniformValue("shapeTexture", 0); program()->setUniformValue("imageTexture", 1); matrixId_ = program()->uniformLocation("matrix"); opacityId_ = program()->uniformLocation("opacity"); glFuncs_ = QOpenGLContext::currentContext()->functions(); } void ShapeTexturedShader::updateState(const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) { Q_UNUSED(oldEffect); ShapeTexturedMaterial* material = static_cast(newEffect); // Bind textures. glFuncs_->glActiveTexture(GL_TEXTURE1); QSGTextureProvider* provider = material->imageTextureProvider(); QSGTexture* texture = provider ? provider->texture() : NULL; if (texture) texture->bind(); else glBindTexture(GL_TEXTURE_2D, 0); glFuncs_->glActiveTexture(GL_TEXTURE0); QSGTexture* shapeTexture = material->shapeTexture(); if (shapeTexture) { shapeTexture->setFiltering(material->filtering()); shapeTexture->setHorizontalWrapMode(QSGTexture::ClampToEdge); shapeTexture->setVerticalWrapMode(QSGTexture::ClampToEdge); shapeTexture->bind(); } else { glBindTexture(GL_TEXTURE_2D, 0); } // Bind uniforms. if (state.isMatrixDirty()) program()->setUniformValue(matrixId_, state.combinedMatrix()); if (state.isOpacityDirty()) program()->setUniformValue(opacityId_, state.opacity()); } // --- Scene graph colored material --- ShapeColoredMaterial::ShapeColoredMaterial() : color_(0.0, 0.0, 0.0, 0.0) , gradientColor_(0.0, 0.0, 0.0, 0.0) , shapeTexture_(NULL) , filtering_(QSGTexture::Nearest) { setFlag(Blending); } QSGMaterialType* ShapeColoredMaterial::type() const { static QSGMaterialType type; return &type; } QSGMaterialShader* ShapeColoredMaterial::createShader() const { return new ShapeColoredShader; } void ShapeColoredMaterial::setColor(const QColor& color) { // Premultiply color components by alpha. const float alpha = color.alphaF(); color_ = QVector4D(color.redF() * alpha, color.greenF() * alpha, color.blueF() * alpha, alpha); } void ShapeColoredMaterial::setGradientColor(const QColor& gradientColor) { // Premultiply color components by alpha. const float alpha = gradientColor.alphaF(); gradientColor_ = QVector4D(gradientColor.redF() * alpha, gradientColor.greenF() * alpha, gradientColor.blueF() * alpha, alpha); } void ShapeColoredMaterial::setShapeTexture(QSGTexture* texture, bool scaledDown) { shapeTexture_ = texture; filtering_ = scaledDown ? QSGTexture::Linear : QSGTexture::Nearest; } // -- Scene graph colored material shader --- const char *ShapeColoredShader::vertexShader() const { return shapeVertexShader; } const char* ShapeColoredShader::fragmentShader() const { return shapeColoredFragmentShader; } char const* const* ShapeColoredShader::attributeNames() const { static char const* const attributes[] = { "positionAttrib", "shapeCoordAttrib", "imageCoordAttrib", 0 }; return attributes; } void ShapeColoredShader::initialize() { QSGMaterialShader::initialize(); program()->bind(); program()->setUniformValue("shapeTexture", 0); matrixId_ = program()->uniformLocation("matrix"); opacityId_ = program()->uniformLocation("opacity"); colorId_ = program()->uniformLocation("color"); gradientColorId_ = program()->uniformLocation("gradientColor"); } void ShapeColoredShader::updateState(const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) { Q_UNUSED(oldEffect); ShapeColoredMaterial* material = static_cast(newEffect); // Bind texture. QSGTexture* shapeTexture = material->shapeTexture(); if (shapeTexture) { shapeTexture->setFiltering(material->filtering()); shapeTexture->setHorizontalWrapMode(QSGTexture::ClampToEdge); shapeTexture->setVerticalWrapMode(QSGTexture::ClampToEdge); shapeTexture->bind(); } else { glBindTexture(GL_TEXTURE_2D, 0); } // Bind uniforms. if (state.isMatrixDirty()) program()->setUniformValue(matrixId_, state.combinedMatrix()); if (state.isOpacityDirty()) program()->setUniformValue(opacityId_, state.opacity()); program()->setUniformValue(colorId_, material->color()); program()->setUniformValue(gradientColorId_, material->gradientColor()); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucalarm.h0000644000015301777760000000752112321005637030137 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef UCALARM_H #define UCALARM_H #include #include #include class UCAlarmPrivate; class UCAlarm : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) Q_PROPERTY(QDateTime date READ date WRITE setDate NOTIFY dateChanged) Q_PROPERTY(AlarmType type READ type WRITE setType NOTIFY typeChanged) Q_PROPERTY(DaysOfWeek daysOfWeek READ daysOfWeek WRITE setDaysOfWeek NOTIFY daysOfWeekChanged) Q_PROPERTY(QUrl sound READ sound WRITE setSound NOTIFY soundChanged) Q_PROPERTY(int error READ error NOTIFY errorChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_ENUMS(Status Operation Error AlarmType DayOfWeek) Q_FLAGS(DaysOfWeek) public: // enums enum Status { // keep values in sync with AlarmRequest::Status Ready = 1, InProgress, Fail }; enum Operation { // keep values in sync with AlarmRequest::Operation NoOperation, Saving, Canceling, Reseting }; enum Error { NoError = 0, InvalidDate = 1, EarlyDate = 2, NoDaysOfWeek = 3, OneTimeOnMoreDays = 4, InvalidEvent = 5, OperationPending = 6, AdaptationError = 100 }; enum AlarmType { OneTime, Repeating // more to be added }; enum DayOfWeek { Monday = 0x01, Tuesday = 0x02, Wednesday = 0x04, Thursday = 0x08, Friday = 0x10, Saturday = 0x20, Sunday = 0x40, Daily = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday, AutoDetect = 0x80 }; Q_DECLARE_FLAGS(DaysOfWeek, DayOfWeek) public: explicit UCAlarm(QObject *parent = 0); UCAlarm(const QDateTime &dt, const QString &message = QString(), QObject *parent = 0); UCAlarm(const QDateTime &dt, DaysOfWeek days = AutoDetect, const QString &message = QString(), QObject *parent = 0); ~UCAlarm(); public: // getter/setter bool enabled() const; void setEnabled(bool enabled); QDateTime date() const; void setDate(const QDateTime &date); QString message() const; void setMessage(const QString &message); AlarmType type() const; void setType(AlarmType type); DaysOfWeek daysOfWeek() const; void setDaysOfWeek(DaysOfWeek days); QUrl sound() const; void setSound(const QUrl &sound); int error() const; Status status() const; Q_SIGNALS: void enabledChanged(); void messageChanged(); void dateChanged(); void typeChanged(); void daysOfWeekChanged(); void soundChanged(); void errorChanged(); void statusChanged(Operation operation); public Q_SLOTS: void save(); void cancel(); void reset(); private: Q_DISABLE_COPY(UCAlarm) Q_DECLARE_PRIVATE(UCAlarm) QScopedPointer d_ptr; Q_PRIVATE_SLOT(d_func(), void _q_syncStatus(int operation, int status, int error)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(UCAlarm::DaysOfWeek) #endif // UUALARM_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucmousefilters.cpp0000644000015301777760000007532212321005637032123 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "ucmouse.h" #include "ucinversemouse.h" #include #include #include #include #include #include "inversemouseareatype.h" #include "i18n.h" #include "quickutils.h" #include "ucunits.h" // keep in sync with QQuickMouseArea PressAndHoldDelay const int DefaultPressAndHoldDelay = 800; /* * Attached filter instantiator template */ template T *createAttachedFilter(QObject *owner, const QString &qmlName) { QQuickItem *item = qobject_cast(owner); if (!item) { qmlInfo(owner) << UbuntuI18n::instance(). tr(QString("Warning: %1 filter can only be attached to Items.").arg(qmlName)); } T *filter = new T(owner); filter->setEnabled(true); return filter; } /*! \qmltype Mouse \instantiates UCMouse \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Attached property filtering mouse events occured inside the owner. Sometimes we need to provide additional functionality on mouse events beside a QML element's default behavior. Placing a MouseArea over a component however will grab the mouse events from the component underneath, no matter if we set \a preventStealing to false or not. Setting mouse.accepted to false in \a onPressed would result in having the event forwarded to the MouseArea's parent, however MouseArea will no longer receive other mouse events. \qml import QtQuick 2.0 TextInput { width: 100 height: 20 MouseArea { anchors.fill: parent preventStealing: false // do not accept event so it gets propagated to the parent item onPressed: mouse.accepted = false; onReleased: console.log("this will not be printed") } } \endqml Ubuntu UI Toolkit declares filter components similar to Keys, which can be attached to any visual primitve. Mouse filter however will have effect only when attached to items handling mouse events. Events are handled through signals, where the event data is presented through the \a mouse parameter. Events should be accepted if the propagation of those to the owner is not wanted. This is not valid to \l onClicked, \l onPressAndHold composed events. The previous code sample using Mouse filter, which will print the pressed and released mouse buttons would look as follows: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { width: 100 height: 20 // do not accept event so it gets propagated to the parent item Mouse.onPressed: console.log("mouse button pressed: " + mouse.button) Mouse.onReleased: console.log("mouse button released: " + mouse.button) } \endqml The event details are reported in the \a mouse parameter, of MouseEvent type, which extends QtQuick's MouseEvent with additional properties. The filter will accept the same mouse buttons the owner accepts, and will accept hover events if the owner does. However it is not possible to alter these settings through the filter. If button handling other than the default ones specified for the primitive is required, MouseAreas can be declared to handle those events. Example of handling right button clicks over a TextInput: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { width: 100 height: 20 MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton onClicked: console.log("right button clicked") } } \endqml In this example left and middle mouse button clicks will reach TextInput as MouseArea only grabs right button events. Mouse filter can be used in combination with MouseArea, where the filter brings additional functionality on top of existing primitive functionality, and MouseArea add new functionality to the primitive. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { width: 100 height: 20 // do not accept event so it gets propagated to the parent item Mouse.onPressed: { if (mouse.button === Qt.LeftButton) { // do something } } MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton Mouse.onPressed: console.log("right button clicked") } } \endqml As mentioned, mouse filters can be attached to any visual item. Attaching it to items that do not handle any mouse events will not have any effect. However child items which handle mouse events can forward the events they handle to their parent. In this way mouse events will land in these items too, and mouse filter attached to those can also handle the event. This is useful when creating custom types where the mouse handling item is nested into a non-mouse handling one, and we want to provide additional filtering possibility to the user. \qml Item { id: top width: 100 height: 50 Mouse.onPressed: console.log("mouse received from input") TextItem { anchors.fill: parent Mouse.forvardTo: [top] Mouse.onPressed: console.log("pressed over input") Mouse.onPressAndHold: console.log("longpress handled here") } } \endqml In this example the mouse press is first handled by the mouse filter attached to TextInput, then it is forwarded to the top item and finally to the TextInput. Accepting the mouse event will stop propagation to the top item as well as to the TextInput. An interesting feature that can be achieved using Mouse filter is the event "transparency" towards the MouseArea lying behind the items which handle mouse events. This means for example that by forwarding mouse events occurred on a TextInput to a MouseArea that stays behind it in the item hierarchy, the MouseArea will also get all the events occurred on the area covered by the TextInput, acting like it would be above the TextInput. However, due to the nature of the MouseArea event acceptance policy (all events are accepted by default) TextInput will not get these mouse events unless we set the \a accepted field of the mouse event to false in MouseArea. This normally leads to the MouseArea no longer getting further mouse events. However, Mouse filter will continue to forward other mouse events to the MouseArea, so setting \a accepted to false in \a onPressed, \a onReleased will not have the default effect. This is only valid to press and release events, double-click or mouse position change will be blocked by the MouseArea still. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MouseArea { id: topArea width: units.gu(50) height: units.gu(10) onPressed: { console.log("forwarded pressed") mouse.accepted = false } onReleased: { console.log("released") mouse.accepted = false } TextInput { width: units.gu(40) height: units.gu(5) anchors.centerIn: parent Mouse.forwardTo: [topArea] Mouse.onPressed: console.log("input pressed") Mouse.onReleased: console.log("input released") } } \endqml Mouse filter provides ability to control the order of the event dispatching. The filter can receive the events prior the owner or after the owner. This can be controlled through the \l priority property. In the following example we make sure the TextInput always receives the events before the filter: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { id: input width: units.gu(40) height: units.gu(5) activeFocusOnPress: true Mouse.prority: Mouse.AfterItem Mouse.onPressed: if (input.activeFocus) console.log("Text input already handled it") } \endqml Another feature of the mouse filters is the ability to restrict when the composed events like \l onClicked and \l onPressAndHold should be triggered. By default these events are triggered no matter what is the distance between the mouse pressed position and the current position after a certain timeout (for \l onPressAndHold) or upon mouse release (for \l onClicked). In this way the \l onClicked will be emitted even if the user presses the mouse at the left-top edge of the component, then moves it to the right-bottom corner and releases it. This may not be the preferred behavior on certain components (like TextInput). Therefore MouseFilter provides a property which can alter this behavior, the \l clickAndHoldThreshold. This property specifies the radius of the area the up-mentioned composed events are emitted during a mouse move. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 TextInput { width: units.gu(40) height: units.gu(5) activeFocusOnPress: true selectByMouse: true // emit composed events only if the mouse moves within 2 GU radius area Mouse.clickAndHoldThreshold: units.gu(2) Mouse.onClicked: console.log("click happened within threshold value") Mouse.onPressAndHold: console.log("pressAndHold happened within threshold value") } \endqml Similar functionality for the case when the mouse event occurs outside of the owner is brought by the \l InverseMouse attached property. */ UCMouse::UCMouse(QObject *parent) : QObject(parent) , m_owner(qobject_cast(parent)) , m_pressedButtons(Qt::NoButton) , m_priority(BeforeItem) , m_moveThreshold(0.0) , m_enabled(false) , m_moved(false) , m_longPress(false) , m_hovered(false) , m_doubleClicked(false) { // if owner is MouseArea or InverseMouseArea, connect to the acceptedButtons // and hoverEnabled change signals QQuickMouseArea* mouseOwner = qobject_cast(m_owner); if (mouseOwner) { connect(mouseOwner, SIGNAL(acceptedButtonsChanged()), this, SIGNAL(acceptedButtonsChanged())); connect(mouseOwner, SIGNAL(hoverEnabledChanged()), this, SIGNAL(hoverEnabledChanged())); } } UCMouse *UCMouse::qmlAttachedProperties(QObject *owner) { return createAttachedFilter(owner, "Mouse"); } bool UCMouse::eventFilter(QObject *target, QEvent *event) { QEvent::Type type = event->type(); bool mouseEvent = isMouseEvent(type); bool hoverEvent = isHoverEvent(type); if (mouseEvent || hoverEvent) { static bool forwardLock = false; if (forwardLock) { return QObject::eventFilter(target, event); } if (m_priority == AfterItem) { // send the event first to the owner, but lock out ourself to avoid // getting into infinite recurence forwardLock = true; QCoreApplication::sendEvent(m_owner, event); forwardLock = false; } if (mouseEvent) { return mouseEvents(target, static_cast(event)); } else { return hoverEvents(target, static_cast(event)); } } return QObject::eventFilter(target, event); } void UCMouse::timerEvent(QTimerEvent *event) { if (isEnabled() && (event->timerId() == m_pressAndHoldTimer.timerId())) { m_pressAndHoldTimer.stop(); if (m_pressedButtons && m_hovered) { m_longPress = true; QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, false, m_longPress); mev.setAccepted(false); Q_EMIT pressAndHold(&mev); // if the event wasn't handled, allow click if (!mev.isAccepted()) { m_longPress = false; } event->setAccepted(mev.isAccepted()); } } else { QObject::timerEvent(event); } } bool UCMouse::mouseEvents(QObject *target, QMouseEvent *event) { bool result = false; Q_UNUSED(target); switch (event->type()) { case QEvent::MouseButtonPress: { result = mousePressed(event); } break; case QEvent::MouseButtonRelease: { result = mouseReleased(event); } break; case QEvent::MouseButtonDblClick: { result = mouseDblClick(event); } break; case QEvent::MouseMove: { result = mouseMoved(event); } break; default: break; } forwardEvent(event); return result || event->isAccepted(); } bool UCMouse::hoverEvents(QObject *target, QHoverEvent *event) { bool result = false; Q_UNUSED(target) switch (event->type()) { case QEvent::HoverEnter: { result = hoverEntered(event); } break; case QEvent::HoverMove: { result = hoverMoved(event); } break; case QEvent::HoverLeave: { result = hoverExited(event); } break; default: break; } forwardEvent(event); return result || event->isAccepted(); } bool UCMouse::hasAttachedFilter(QQuickItem *item) { return (qmlAttachedPropertiesObject(item, false) != 0); } void UCMouse::setHovered(bool hovered) { if (m_hovered != hovered) { m_hovered = hovered; QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, false, false); mev.setAccepted(false); if (m_hovered) { Q_EMIT entered(&mev); } else { Q_EMIT exited(&mev); } } } bool UCMouse::mousePressed(QMouseEvent *event) { m_moved = false; if (event->button() & m_owner->acceptedMouseButtons()) { saveEvent(event); m_pressedButtons |= m_lastButton; m_longPress = m_doubleClicked = false; setHovered(true); QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, false, m_longPress); mev.setAccepted(false); Q_EMIT pressed(&mev); event->setAccepted(mev.isAccepted()); // start long press timer m_pressAndHoldTimer.start(DefaultPressAndHoldDelay, this); return mev.isAccepted(); } event->ignore(); return false; } bool UCMouse::mouseMoved(QMouseEvent *event) { if (m_pressedButtons) { saveEvent(event); // check if we should stop pressAndHold if (!m_toleranceArea.contains(m_lastPos)) { m_pressAndHoldTimer.stop(); } setHovered(true); m_moved = true; m_doubleClicked = false; QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, false, m_longPress); mev.setAccepted(false); Q_EMIT positionChanged(&mev); event->setAccepted(mev.isAccepted()); return mev.isAccepted(); } event->ignore(); return false; } bool UCMouse::mouseReleased(QMouseEvent *event) { if (m_pressedButtons) { saveEvent(event); // stop long press timer event m_pressAndHoldTimer.stop(); bool isClicked = (m_pressedButtons & m_lastButton) && !m_longPress && !m_doubleClicked && ((m_moveThreshold <= 0.0) || m_toleranceArea.contains(m_lastPos)); QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, isClicked, m_longPress); mev.setAccepted(false); Q_EMIT released(&mev); event->setAccepted(mev.isAccepted()); // remove button from press m_pressedButtons &= ~m_lastButton; if (isClicked) { // emit clicked Q_EMIT clicked(&mev); } if (!m_pressedButtons && !m_owner->acceptHoverEvents()) { setHovered(false); } return mev.isAccepted(); } event->ignore(); return false; } bool UCMouse::mouseDblClick(QMouseEvent *event) { if (m_pressedButtons) { saveEvent(event); // if double click connected, suppress release() and click() signals if (isDoubleClickConnected()) { QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, true, m_longPress); mev.setAccepted(false); Q_EMIT doubleClicked(&mev); event->setAccepted(mev.isAccepted()); m_doubleClicked = true; } else { // set accepted to false still event->setAccepted(false); } return event->isAccepted(); } event->ignore(); return false; } bool UCMouse::hoverEntered(QHoverEvent *event) { m_lastPos = event->posF(); m_lastModifiers = event->modifiers(); setHovered(true); return false; } bool UCMouse::hoverMoved(QHoverEvent *event) { m_lastPos = event->posF(); m_lastModifiers = event->modifiers(); QQuickMouseEvent mev(m_lastPos.x(), m_lastPos.y(), m_lastButton, m_lastButtons, m_lastModifiers, false, m_longPress); mev.setAccepted(false); Q_EMIT positionChanged(&mev); forwardEvent(event); return false; } bool UCMouse::hoverExited(QHoverEvent *event) { m_lastPos = event->posF(); m_lastModifiers = event->modifiers(); setHovered(false); return false; } void UCMouse::saveEvent(QMouseEvent *event) { m_lastPos = event->localPos(); m_lastScenePos = event->windowPos(); m_lastButton = event->button(); m_lastButtons = event->buttons(); m_lastModifiers = event->modifiers(); if ((event->type() == QEvent::MouseButtonPress) && (m_moveThreshold > 0.0)) { m_toleranceArea.setX(m_lastPos.x() - m_moveThreshold); m_toleranceArea.setY(m_lastPos.y() - m_moveThreshold); m_toleranceArea.setWidth(2 * m_moveThreshold); m_toleranceArea.setHeight(2 * m_moveThreshold); } } bool UCMouse::isDoubleClickConnected() { IS_SIGNAL_CONNECTED(this, UCMouse, doubleClicked, (QQuickMouseEvent*)); } bool UCMouse::isMouseEvent(QEvent::Type type) { return (type == QEvent::MouseButtonPress) || (type == QEvent::MouseButtonRelease) || (type == QEvent::MouseButtonDblClick) || (type == QEvent::MouseMove); } bool UCMouse::isHoverEvent(QEvent::Type type) { return (type == QEvent::HoverEnter) || (type == QEvent::HoverMove) || (type == QEvent::HoverLeave); } // forwards the events to the listed items; only mouse and hover events qualify void UCMouse::forwardEvent(QEvent *event) { /* * alter acceptedButtons and hoverEnabled for the time the event is delivered * exclude MouseArea and InverseMouseArea!! */ Q_FOREACH(QQuickItem *item, m_forwardList) { if (event->isAccepted()) { // the event got accepted, therefore should not be forwarded return; } // skip InverseMouseArea otherwise those will get the event twice if (qobject_cast(item)) { continue; } /* * temporarily enable mouse buttons and hover for items which have Mouse or InverseMouse * filter attached, but exclude targets which is MouseArea or InverseMouseArea */ Qt::MouseButtons acceptedButtons = item->acceptedMouseButtons(); bool hoverEnabled = item->acceptHoverEvents(); if (!qobject_cast(item) && hasAttachedFilter(item)) { // set accepted buttons and hover temporarily item->setAcceptedMouseButtons(m_owner->acceptedMouseButtons()); item->setAcceptHoverEvents(m_owner->acceptHoverEvents()); } // forward events bool accepted = false; if (isMouseEvent(event->type())) { QMouseEvent *mouse = static_cast(event); QPointF itemPos = item->mapFromScene(m_owner->mapToScene(mouse->pos())); QMouseEvent me = QMouseEvent(event->type(), itemPos, mouse->button(), mouse->buttons(), mouse->modifiers()); QGuiApplication::sendEvent(item, &me); accepted = me.isAccepted(); } else { QHoverEvent *hover = static_cast(event); QPointF itemPos = item->mapFromScene(m_owner->mapToScene(hover->pos())); QPointF itemOldPos = item->mapFromScene(m_owner->mapToScene(hover->oldPos())); QHoverEvent he = QHoverEvent(event->type(), itemPos, itemOldPos, hover->modifiers()); QGuiApplication::sendEvent(item, &he); accepted = he.isAccepted(); } event->setAccepted(accepted); // restore acceptedButtons and hover item->setAcceptedMouseButtons(acceptedButtons); item->setAcceptHoverEvents(hoverEnabled); } } /*! \qmlproperty bool Mouse::enabled */ bool UCMouse::isEnabled() const { return m_enabled; } void UCMouse::setEnabled(bool enabled) { if ((enabled != m_enabled) && m_owner) { m_enabled = enabled; if (m_enabled) { m_owner->installEventFilter(this); } else { m_owner->removeEventFilter(this); } Q_EMIT enabledChanged(); } } /*! \qmlproperty Qt::MouseButtons Mouse::acceptedButtons \readonly The property holds the accepted mouse buttons of the owner. */ Qt::MouseButtons UCMouse::acceptedButtons() const { return m_owner ? m_owner->acceptedMouseButtons() : Qt::NoButton; } /*! \qmlproperty bool Mouse::hoverEnabled \readonly The property reports whether the owner accepts hover events or not. When events are accepted \l onEntered, \l onPositionChanged and \l onExited signals containing the mouse cursor position. */ bool UCMouse::hoverEnabled() const { return m_owner ? m_owner->acceptHoverEvents() : false; } /*! \qmlproperty int Mouse::clickAndHoldThreshold The property holds the radius of the tolerance area the mouse can move in both x and y axis when the mouse is pressed, during which the composed events such as \l onClicked and \l onPressAndHold will still be emitted. If the mouse is moved out of this area while the button is pressed, no composed events will be emitted. When this value is 0, the signals will be emitted as in MouseArea, meaning the composed events will come until the mouse is moved inside the owner's area. The default value is 0. */ int UCMouse::clickAndHoldThreshold() const { return m_moveThreshold; } void UCMouse::setClickAndHoldThreshold(int threshold) { if (m_moveThreshold != threshold) { m_moveThreshold = threshold; Q_EMIT clickAndHoldThresholdChanged(); } } /*! \qmlproperty list Mouse::forwardTo The property provides a way to forward mouse presses, releases, moves and double click events to other items. This can be useful when you want other items to handle different parts of the same mouse event or to handle other mouse events. The items listed will receive the event only if the mouse event falls into their area. Once an item that has forwarded mouse events accepts the event, that will no longer be delivered to the rest of the items in the list. This rule is also applied on the owner when the priority is set to \a BeforeItem. */ QQmlListProperty UCMouse::forwardTo() { return QQmlListProperty(this, m_forwardList); } /*! \qmlproperty enumeration Mouse::priority The property specifies the event dispach relation between the filter, the elements the event is forwarded to and the owner. Similar to Keys' \a priority property, the event dispach is performed in two ways: berfore (\a BeforeItem) or after (\a AfterItem) the owner receives the events. When \a BeforeItem is set the event dispach happens based as follows: \list i \li the event is handled by the mouse filter \li if there are items listed in \l forwardTo property, the event will be forwarded to those items \li the event is handed over the owner. \endlist \raw HTML
    \endraw When \a AfterItem is set the event dispach happens based as follows: \list i \li the event is handed over the owner; \li the event is handled by the mouse filter; \li if there are items listed in \l forwardTo property, the event will be forwarded to those items. \endlist The default value is \a BeforeItem. */ UCMouse::Priority UCMouse::priority() const { return m_priority; } void UCMouse::setPriority(Priority priority) { if (priority != m_priority) { m_priority = priority; Q_EMIT priorityChanged(); } } /*! \qmlsignal Mouse::onPressed(MouseEvent event) The signal reports the mouse press. */ /*! \qmlsignal Mouse::onReleased(MouseEvent event) The signal reports the mouse release. */ /*! \qmlsignal Mouse::onClicked(MouseEvent event) The signal reports the mouse click. The signal is not emitted if the onPressAndHold got triggered or if onDoubleClicked is handled (a slot is connected to it). */ /*! \qmlsignal Mouse::onPressAndHold(MouseEvent event) The signal reports the mouse press and hold. */ /*! \qmlsignal Mouse::onDoubleClicked(MouseEvent event) The signal reports mouse double click. */ /*! \qmlsignal Mouse::onPositionChanged(MouseEvent event) The signal reports the mouse pointer position change. If the hover events are enabled for the owner, the signal will come continuously. Otherwise the position chanes are reported when one of the accepted mouse buttons are being kept pressed. */ /*! \qmlsignal Mouse::onEntered(MouseEvent event) The signal reports that the mouse has entered into the area. The signal is emitted when the hover events are enabled and the mouse enters the area or when one of the accepted mouse button is pressed. */ /*! \qmlsignal Mouse::onExited(MouseEvent event) The signal reports that the mouse has left the area. The signal is emitted when the hover events are enabled for the owner or if not, when one of the accepted button is released. */ /****************************************************************************** **/ /*! \qmltype InverseMouse \instantiates UCInverseMouse \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Attached object filtering mouse events occured outside the owner. Similar to Mouse filter attached property, provides mouse event filtering capabilities but for events occurring outside of the owner's area, excluding the input method area. Being derived from Mouse filter element, provides the same behavior as the Mouse filter, except that all the signals are emitted when the mouse event occurs outside the owner's area. Note that accepting composed mouse events does not have any effect on event propagation. Altering \a priority property has no effect on inverse mouse filter as mouse events captured by the filter are not forwarded to the owner, hence forwarding those events first to the owner will not have any effect. */ UCInverseMouse::UCInverseMouse(QObject *parent) : UCMouse(parent) { } UCInverseMouse *UCInverseMouse::qmlAttachedProperties(QObject *owner) { return createAttachedFilter(owner, "InverseMouse"); } QMouseEvent UCInverseMouse::mapMouseToOwner(QObject *target, QMouseEvent* event) { QQuickItem *item = qobject_cast(target); QPointF localPos = (target != m_owner) ? m_owner->mapFromItem(item, event->localPos()) : event->localPos(); QPointF windowPos = (target != m_owner) ? m_owner->mapFromItem(item, event->windowPos()) : event->windowPos(); return QMouseEvent(event->type(), localPos, windowPos, event->screenPos(), event->button(), event->buttons(), event->modifiers()); } QHoverEvent UCInverseMouse::mapHoverToOwner(QObject *target, QHoverEvent *event) { QQuickItem *item = qobject_cast(target); QPointF pos = (target != m_owner) ? m_owner->mapFromItem(item, event->posF()) : event->posF(); QPointF oldPos = (target != m_owner) ? m_owner->mapFromItem(item, event->oldPosF()) : event->oldPosF(); return QHoverEvent(event->type(), pos, oldPos, event->modifiers()); } bool UCInverseMouse::eventFilter(QObject *target, QEvent *event) { // exclude MouseArea and InverseMouseArea targets; InverseMosueArea casts to QQuickMouseArea if ((target != m_owner) && !qobject_cast(target)) { return UCMouse::eventFilter(target, event); } return QObject::eventFilter(target, event); } bool UCInverseMouse::mouseEvents(QObject *target, QMouseEvent *event) { QMouseEvent mouse(mapMouseToOwner(target, event)); if (!contains(&mouse)) { // do not handle mouse event if it's inside the owner return false; } // call base handler return UCMouse::mouseEvents(target, &mouse); } bool UCInverseMouse::hoverEvents(QObject *target, QHoverEvent *event) { QHoverEvent hover(mapHoverToOwner(target, event)); return UCMouse::hoverEvents(target, &hover); } bool UCInverseMouse::hasAttachedFilter(QQuickItem *item) { return UCMouse::hasAttachedFilter(item) || (qmlAttachedPropertiesObject(item, false) != 0); } // check whether the mouse point is in OSK area bool UCInverseMouse::pointInOSK(const QPointF &point) { QPointF scenePoint = m_owner->mapToScene(point); QRectF oskRect = QGuiApplication::inputMethod()->keyboardRectangle(); return oskRect.contains(scenePoint); } // returns true if the point is in the inverse area bool UCInverseMouse::contains(QMouseEvent *mouse) { QPointF localPos = mouse->localPos(); return !m_owner->contains(localPos) && !pointInOSK(localPos); } void UCInverseMouse::setEnabled(bool enabled) { if ((m_enabled != enabled) && m_owner) { m_enabled = enabled; if (m_enabled) { // FIXME: use application's main till we don't get touch events // forwarded to the QQuickItem QGuiApplication::instance()->installEventFilter(this); } else { QGuiApplication::instance()->removeEventFilter(this); } Q_EMIT enabledChanged(); } } void UCInverseMouse::setPriority(Priority priority) { if (priority != m_priority) { qmlInfo(m_owner) << UbuntuI18n::instance().tr("Ignoring AfterItem priority for InverseMouse filters."); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/inversemouseareatype.cpp0000644000015301777760000004412612321005637033327 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "inversemouseareatype.h" #include #include "quickutils.h" /*! \qmltype InverseMouseArea \instantiates InverseMouseAreaType \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The InverseMouseArea captures mouse events happening outside of a given area. A typical use case is hiding of a popup or tooltip when the user presses or taps outside of the popup or tooltip area. The following example illustrates the use of InverseMouseArea in a Popup. Popup.qml \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { anchors.centerIn: parent width: 200; height: 200 color: "darkgray" radius: 10 InverseMouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton onPressed: parent.destroy() } } \endqml In the Popup above the mouse presses happening outside the area will cause closing and destroying the popup. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: 640 height: 480 Button { id: button text: "Press me" onClicked: { var component = Qt.createComponent("Popup.qml"); var obj = component.create(parent); obj.visible = true; } } } \endqml By default the InverseMouseArea sensing area (the area from which the mouse clicks will be taken) is the application's root component, or the Window in which the topmost parent component of the mouse area resides. This area can be however altered to a different area by setting the \l sensingArea property to a component which is either a parent of the mouse area or a sibling of it. \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(40) height: units.gu(71) MouseArea { anchors.fill: parent onClicked: console.log("clicked on the root component") } Rectangle { id: blueRect width: units.gu(30) height: units.gu(51) anchors.centerIn: parent color: "blue" Rectangle { width: units.gu(20) height: units.gu(20) anchors.centerIn: parent color: "red" InverseMouseArea { anchors.fill: parent sensingArea: blueRect onClicked: console.log("clicked on the blue rect") } } } } \endqml In this example the inverse mouse area will get mouse presses only when those happen on the blue rectangle area. When clicked outside of the blue rectangle or inside the red rectangle, the mouse area covering the root item will get click signals. InverseMouseArea, being derived from MouseArea respects the stacking and z-order of the components. This should be taken into account when combining it with MouseAreas within the same level of the component hierarchy or when combined with MouseArea siblings. In these cases it is recommended to have the InverseMouseArea declared as last component, having it in this way as last one oin the component stack. \qml Item { id: page width: units.gu(40) height: units.gu(71) Rectangle { id: label anchors { horizontalCenter: parent.horizontalCenter top: parent.top } height: units.gu(5) width: parent.width color: "red" MouseArea { anchors.fill: parent z: 1 onPressed: console.log("red band") } } Rectangle { anchors { top: label.bottom topMargin: units.gu(2) horizontalCenter: parent.horizontalCenter } height: units.gu(10) width: parent.width color: "green" Button { id: button anchors.centerIn: parent text: "I'm a button, I do nothing." } MouseArea { anchors.fill: parent onPressed: console.log("green band") } InverseMouseArea { anchors.fill: button onPressed: console.log("all over except button") } } } \endqml When this is not enough, and you want to grab all the mouse events that have been sent to the sensingArea, you can use \l topmostItem to place the mouse area above all the components that were instantiated under the sensing area. Beware that setting this property will no longer consider neither the z-order nor the component stack order anymore, as it will steal all the mouse events from the component set as \l sensingArea. \qml Item { width: units.gu(40) height: units.gu(71) Rectangle { id: firstRect anchors { left: parent.left top: parent.top leftMargin: units.gu(10) topMargin: units.gu(10) } width: units.gu(15) height: width color: "blue" InverseMouseArea { anchors.fill: parent objectName: "IMA" topmostItem: true onPressed: print("IMA") } } Rectangle { anchors { left: firstRect.right top: firstRect.bottom } width: units.gu(10) height: width color: "red" MouseArea { anchors.fill: parent objectName: "MA" onPressed: print("MA") } } } \endqml */ /*! \internal */ InverseMouseAreaType::InverseMouseAreaType(QQuickItem *parent) : QQuickMouseArea(parent), m_ready(false), m_topmostItem(false), m_sensingArea(QuickUtils::instance().rootItem(this)) { /* * QQuickMouseArea overrides enabledChanged() signal, therefore we must make sure * we connect to the proper signal. */ QObject::connect(this, &QQuickMouseArea::enabledChanged, this, &InverseMouseAreaType::update); QObject::connect(this, &QQuickMouseArea::visibleChanged, this, &InverseMouseAreaType::update); /* * Also connect to windowChanged() to get the proper window to filter */ QObject::connect(this, &QQuickMouseArea::windowChanged, this, &InverseMouseAreaType::resetFilterOnWindowUpdate); if (!m_sensingArea) { // get sensing area upon parent change QObject::connect(this, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(update())); } } InverseMouseAreaType::~InverseMouseAreaType() { } void InverseMouseAreaType::updateEventFilter(bool enable) { m_filteredEvent = false; if (!enable && m_filterHost) { m_filterHost->removeEventFilter(this); m_filterHost.clear(); } else if (enable) { QQuickWindow *currentWindow = window(); if (!currentWindow || (m_filterHost == currentWindow)) { return; } if (m_filterHost) { m_filterHost->removeEventFilter(this); } currentWindow->installEventFilter(this); m_filterHost = currentWindow; } } /*! \internal Slot connected to enabledChanged signal to update the state of the handler. */ void InverseMouseAreaType::update() { if (!m_ready) { return; } // update sensing area if (!m_sensingArea) { m_sensingArea = QuickUtils::instance().rootItem(this); } updateEventFilter(isEnabled() && isVisible() && m_topmostItem); } /*! \internal Slot connected to windowChanged signal to refresh filter host. */ void InverseMouseAreaType::resetFilterOnWindowUpdate(QQuickWindow *win) { Q_UNUSED(win); updateEventFilter(m_topmostItem); } void InverseMouseAreaType::componentComplete() { QQuickMouseArea::componentComplete(); // by now the parents should have been resolved so we can look after the // topmost component for the sensingArea in case it has not been set yet m_ready = true; update(); } /* * Translate mouse, wheel and hover event positions to component's local coordinates. */ QEvent *InverseMouseAreaType::mapEventToArea(QObject *target, QEvent *event, QPoint &point) { QQuickItem *targetItem = qobject_cast(target); // target can be the QQuickView or QQuickWindow, then we need to get the root item from it if (!targetItem) { QQuickView *view = qobject_cast(target); if (view) { targetItem = view->rootObject(); } else { QQuickWindow *window = qobject_cast(target); if (window) { targetItem = window->contentItem(); } } } Q_ASSERT(target); m_filteredEvent = true; switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: if (targetItem != this) { // translate coordinates to local QMouseEvent *ev = static_cast(event); QMouseEvent *mev = new QMouseEvent(ev->type(), mapFromScene(ev->windowPos()), ev->windowPos(), ev->screenPos(), ev->button(), ev->buttons(), ev->modifiers()); point = mev->pos(); return mev; } break; case QEvent::Wheel: if (targetItem != this) { QWheelEvent *ev = static_cast(event); QWheelEvent *wev = new QWheelEvent(mapFromScene(ev->globalPos()), ev->globalPos(), ev->delta(), ev->buttons(), ev->modifiers(), ev->orientation()); point = wev->pos(); return wev; } break; case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: { if (targetItem && targetItem != this) { QHoverEvent *ev = static_cast(event); QPointF spos = targetItem->mapToScene(ev->posF()); QPointF sopos = targetItem->mapToScene(ev->oldPosF()); QHoverEvent *hev = new QHoverEvent(ev->type(), mapFromScene(spos), mapFromScene(sopos), ev->modifiers()); point = hev->pos(); return hev; } } break; // convert touch events into mouse events and continue handling as such case QEvent::TouchBegin: { QTouchEvent *tev = static_cast(event); QList points = tev->touchPoints(); const QTouchEvent::TouchPoint &primaryPoint = points.first(); m_touchId = primaryPoint.id(); QPointF pos = targetItem->mapToScene(primaryPoint.pos()); QMouseEvent *mev = new QMouseEvent(QEvent::MouseButtonPress, mapFromScene(pos), primaryPoint.scenePos(), primaryPoint.screenPos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); point = mev->pos(); return mev; } break; case QEvent::TouchUpdate: { QTouchEvent *tev = static_cast(event); QList points = tev->touchPoints(); const QTouchEvent::TouchPoint &primaryPoint = points.first(); QPointF pos = targetItem->mapToScene(primaryPoint.pos()); QMouseEvent *mev = new QMouseEvent(QEvent::MouseMove, mapFromScene(pos), primaryPoint.scenePos(), primaryPoint.screenPos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); point = mev->pos(); return mev; } break; case QEvent::TouchEnd: { QMouseEvent *mev = 0; QTouchEvent *tev = static_cast(event); QList points = tev->touchPoints(); for (int i = 0; i < points.count(); i++) { const QTouchEvent::TouchPoint &point = points.at(i); if (point.id() != m_touchId) { continue; } QPointF pos = targetItem->mapToScene(point.pos()); mev = new QMouseEvent(QEvent::MouseButtonRelease, mapFromScene(pos), point.scenePos(), point.screenPos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); break; } point = mev->pos(); return mev; } break; default: m_filteredEvent = false; point = QPoint(); break; } return event; } bool InverseMouseAreaType::eventFilter(QObject *object, QEvent *event) { if (object != this) { bool captured = true; QPoint point; QEvent *mappedEvent = mapEventToArea(object, event, point); switch (mappedEvent->type()) { case QEvent::MouseButtonPress: mousePressEvent(static_cast(mappedEvent)); break; case QEvent::MouseButtonRelease: mouseReleaseEvent(static_cast(mappedEvent)); break; case QEvent::MouseButtonDblClick: mouseDoubleClickEvent(static_cast(mappedEvent)); break; case QEvent::MouseMove: mouseMoveEvent(static_cast(mappedEvent)); break; case QEvent::Wheel: wheelEvent(static_cast(mappedEvent)); break; case QEvent::HoverEnter: hoverEnterEvent(static_cast(mappedEvent)); break; case QEvent::HoverLeave: hoverLeaveEvent(static_cast(mappedEvent)); break; case QEvent::HoverMove: hoverMoveEvent(static_cast(mappedEvent)); break; default: captured = false; break; } if (mappedEvent != event) { event->setAccepted(mappedEvent->isAccepted()); delete mappedEvent; } m_filteredEvent = false; if (captured && event->isAccepted() && contains(point)) { // consume the event return true; } } return false; } void InverseMouseAreaType::mousePressEvent(QMouseEvent *event) { // overload QQuickMouseArea mousePress event as the original one sets containsMouse // to true automatically, however ion our case this can be false in case the press // happens inside the "hole" if (!m_topmostItem || (m_topmostItem && m_filteredEvent && contains(event->localPos()))) { QQuickMouseArea::mousePressEvent(event); } else { // we do not consume the mouse event // this is not the same as setting the accepted flag in the signal handler // as in this way we only tell to the event handling that the event can be // propagated to other filters event->setAccepted(false); } } void InverseMouseAreaType::mouseDoubleClickEvent(QMouseEvent *event) { // same as with mousePressEvent if (!m_topmostItem || (m_topmostItem && m_filteredEvent && contains(event->localPos()))) { QQuickMouseArea::mouseDoubleClickEvent(event); } else { // we do not consume the mouse event // this is not the same as setting the accepted flag in the signal handler // as in this way we only tell to the event handling that the event can be // propagated to other filters event->setAccepted(false); } } /*! \qmlproperty Item InverseMouseArea::sensingArea This property holds the sensing area of the inverse mouse area. By default it is the root item but it can be set to any other area. The area can be reset to the root item by setting null to the property. */ QQuickItem *InverseMouseAreaType::sensingArea() const { return m_sensingArea; } void InverseMouseAreaType::setSensingArea(QQuickItem *sensing) { if (!sensing) sensing = QuickUtils::instance().rootItem(this); if (sensing != m_sensingArea) { // clear previous filter updateEventFilter(false); m_sensingArea = sensing; updateEventFilter(m_topmostItem); Q_EMIT sensingAreaChanged(); } } /*! \qmlproperty bool InverseMouseArea::topmostItem The property specifies whether the InverseMouseArea should be above all components taking all mouse, wheel and hover events from the application's or from the area specified by the \l sensingArea (true), or only from the siblings (false). The default value is false. */ bool InverseMouseAreaType::topmostItem() const { return m_topmostItem; } void InverseMouseAreaType::setTopmostItem(bool value) { if (m_topmostItem != value) { m_topmostItem = value; updateEventFilter(m_topmostItem); Q_EMIT topmostItemChanged(); } } /* * Overrides QQuickItem's contains method. Point is in local coordinates. */ bool InverseMouseAreaType::contains(const QPointF &point) const { QPointF scenePos = mapToScene(point); QRectF oskRect = QGuiApplication::inputMethod()->keyboardRectangle(); bool pointInArea = QQuickMouseArea::contains(point); bool pointInOSK = oskRect.contains(scenePos); bool pointOutArea = (m_sensingArea && m_sensingArea->contains(m_sensingArea->mapFromScene(scenePos))); return !pointInArea && !pointInOSK && pointOutArea; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/listener.cpp0000644000015301777760000000210612321005637030665 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "listener.h" #include ContextPropertyChangeListener::ContextPropertyChangeListener(QQmlContext *context, const QString &contextProperty) : QObject(context), m_context(context), m_contextProperty(contextProperty) { } void ContextPropertyChangeListener::updateContextProperty() { QVariant value = m_context->contextProperty(m_contextProperty); m_context->setContextProperty(m_contextProperty, value); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/uctheme.h0000644000015301777760000000405412321005637030143 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Zsombor Egri * Florian Boucault */ #ifndef UCTHEME_H #define UCTHEME_H #include #include #include #include #include "ucthemesettings.h" class UCTheme : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QObject* palette READ palette NOTIFY paletteChanged) public: static UCTheme& instance() { static UCTheme instance; return instance; } explicit UCTheme(QObject *parent = 0); // getter/setters QString name() const; void setName(const QString& name); QObject* palette(); Q_INVOKABLE QQmlComponent* createStyleComponent(const QString& styleName, QObject* parent); void registerToContext(QQmlContext* context); Q_SIGNALS: void nameChanged(); void paletteChanged(); private Q_SLOTS: void updateEnginePaths(); void onThemeNameChanged(); QUrl pathFromThemeName(QString themeName); void updateThemePaths(); QUrl styleUrl(const QString& styleName); QString parentThemeName(const QString& themeName); void loadPalette(bool notify = true); private: QString m_name; QObject* m_palette; QQmlEngine *m_engine; QList m_themePaths; UCThemeSettings m_themeSettings; bool m_engineUpdated; }; #endif // UCTHEME_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucqquickimageextension.h0000644000015301777760000000341512321005637033276 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef QQUICKIMAGEEXTENSION_H #define QQUICKIMAGEEXTENSION_H #include #include #include #include #include #include class QQuickImageBase; class UCQQuickImageExtension : public QObject { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) public: explicit UCQQuickImageExtension(QObject *parent = 0); QUrl source() const; virtual void setSource(const QUrl& url); Q_SIGNALS: void sourceChanged(const QUrl &); protected Q_SLOTS: void reloadSource(); protected: bool rewriteSciFile(const QString &sciFilePath, const QString &scaleFactor, QTextStream& output); QString scaledBorder(const QString &border, const QString &scaleFactor); QString scaledSource(QString source, const QString &sciFilePath, const QString &scaleFactor); private: QQuickImageBase* m_image; QUrl m_source; static QHash > s_rewrittenSciFiles; }; #endif // QQUICKIMAGEEXTENSION_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/quickutils.cpp0000644000015301777760000001154012321005637031237 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "quickutils.h" #include #include #include #include #include #include #include #include #include #include #include QuickUtils::QuickUtils(QObject *parent) : QObject(parent), m_rootView(0) { QGuiApplication::instance()->installEventFilter(this); } /*! * \internal * Filter events to catch ChildAdded, when the the application gets the topmost * window assigned. Need to check the topmost windows each time as widgets added * to the application are not signaled in any other way. */ bool QuickUtils::eventFilter(QObject *obj, QEvent *event) { if (!m_rootView && (event->type() == QEvent::ApplicationActivate)) { lookupQuickView(); Q_EMIT activated(); } if (event->type() == QEvent::ApplicationDeactivate) { Q_EMIT deactivated(); } return QObject::eventFilter(obj, event); } /*! * \internal * \deprecated * Returns the current root object. */ QQuickItem *QuickUtils::rootObject() { qmlInfo(this) << "WARNING: QuickUtils.rootObject property is deprecated: Use QuickUtils::rootItem() function instead."; if (!m_rootView) lookupQuickView(); return (m_rootView) ? m_rootView->rootObject() : 0; } /*! * \internal * Returns the root item of a given item. In case there is a QQuickWindow (Window) * found in the hierarchy, the function will return the contentItem of the window. */ QQuickItem *QuickUtils::rootItem(QObject *object) { // make sure we have the m_rootView updated lookupQuickView(); if (!object) { return (m_rootView) ? m_rootView->rootObject() : 0; } QQuickItem *item = qobject_cast(object); // the given object may be a non-visual element (QtObject or QQmlComponent) // therefore those objects' parent object should be considered QQuickItem *parentItem = item ? item->parentItem() : qobject_cast(object->parent()); while (parentItem && parentItem->parentItem()) { parentItem = parentItem->parentItem(); } if (m_rootView && (m_rootView->contentItem() == parentItem)) { // when traversing visual parents of an element from the application, // we reach QQuickView's contentItem, whose size is invalid. Therefore // we need to return the QQuickView's rootObject() instead of the topmost // item found return m_rootView->rootObject(); } return parentItem; } QString QuickUtils::inputMethodProvider() const { return QString(getenv("QT_IM_MODULE")); } /*! * \internal * Returns the class name (type) of a QtQuick item. */ QString QuickUtils::className(QObject *item) { if (!item) { return QString("(null)"); } QString result = item->metaObject()->className(); return result.left(result.indexOf("_QML")); } /*! * \internal * Get QQuickView from the application's window list and connect its status change * signal as the root element is set after the root element completion. */ void QuickUtils::lookupQuickView() { if (m_rootView) return; Q_FOREACH (QWindow *w, QGuiApplication::topLevelWindows()) { m_rootView = qobject_cast(w); if (m_rootView) { // connect in case we get the root object changed QObject::connect(m_rootView, SIGNAL(statusChanged(QQuickView::Status)), this, SIGNAL(rootObjectChanged())); // emit changed signal so we update the eventual bindings if (m_rootView->rootObject()) Q_EMIT rootObjectChanged(); break; } } } QObject* QuickUtils::createQmlObject(const QUrl &url, QQmlEngine *engine) { /* FIXME: if the directory pointed to by url contains a qmldir file that declares a JavaScript module then QQmlComponent::create() fails with the error "QQmlComponent: Component is not ready". */ QQmlComponent *component = new QQmlComponent(engine, url, QQmlComponent::PreferSynchronous); QObject* result = component->create(); delete component; return result; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/unitythemeiconprovider.h0000644000015301777760000000176412321005637033335 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Lars Uebernickel */ #ifndef UNITY_THEME_ICON_PROVIDER_H #define UNITY_THEME_ICON_PROVIDER_H #include class UnityThemeIconProvider: public QQuickImageProvider { public: UnityThemeIconProvider(); QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize); }; #endif ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucapplication.cpp0000644000015301777760000000461112321005637031676 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #include "ucapplication.h" #include #include #include #include #include /*! * \qmltype UbuntuApplication * \instantiates UCApplication * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief UbuntuApplication is a QML binding for a subset of QCoreApplication. * * UbuntuApplication is a context property in QML. */ UCApplication::UCApplication(QObject* parent) : QObject(parent), m_context(0) { } void UCApplication::setContext(QQmlContext* context) { m_context = context; } /*! * \qmlproperty string Application::applicationName * \internal * The name of the application, see QCoreApplication::applicationName */ QString UCApplication::applicationName() { return QCoreApplication::applicationName(); } void UCApplication::setApplicationName(const QString& applicationName) { /* QStandardPaths uses the name to build folder names. This works across platforms. For confinement we rely on the fact that the folders are whitelisted based on the app name. Similar to how Unity uses it to distinguish running applications. */ QCoreApplication::setApplicationName(applicationName); // Unset organization to skip an extra folder component QCoreApplication::setOrganizationName(QString()); /* Ensure that LocalStorage and WebKit use the same location Docs are ambiguous: in practise applicationName is ignored by default */ QQmlEngine* engine(m_context->engine()); QString dataFolder(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); engine->setOfflineStoragePath(dataFolder); Q_EMIT applicationNameChanged(); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/unixsignalhandler_p.cpp0000644000015301777760000000505312321005637033102 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "unixsignalhandler_p.h" #include #include #include #include UnixSignalHandler::UnixSignalHandler(QObject *parent) : QObject(parent) { } void UnixSignalHandler::connectSignal(SignalType type) { if (notifiers.contains(type)) { return; } HandlerType handler = createHandler((int)type); notifiers.insert(type, handler); socketRegister.insert(handler.first[1], type); } UnixSignalHandler::HandlerType UnixSignalHandler::createHandler(int signal) { struct sigaction sigAction; sigAction.sa_handler = signalHook; ::sigemptyset(&sigAction.sa_mask); sigAction.sa_flags = SA_RESTART; if (::sigaction(signal, &sigAction, 0) > 0) { qFatal("UNIX signal registration error"); } HandlerType handler; if (::socketpair(AF_UNIX, SOCK_STREAM, 0, handler.first)) { qFatal("Cannot create signal socketpair"); } handler.second = new QSocketNotifier(handler.first[1], QSocketNotifier::Read, this); QObject::connect(handler.second, SIGNAL(activated(int)), this, SLOT(notifierActivated(int))); return handler; } void UnixSignalHandler::signalHook(int signal) { HandlerType handler = UnixSignalHandler::instance().notifiers.value((SignalType)signal); char value = 1; ssize_t size = ::write(handler.first[0], &value, sizeof(value)); // this is needed to suppress write return value warning Q_UNUSED(size) } void UnixSignalHandler::notifierActivated(int socket) { // get the socket from the hash SignalType signal = socketRegister.value(socket); HandlerType handler = notifiers.value(signal); handler.second->setEnabled(false); char value; ssize_t size = ::read(handler.first[1], &value, sizeof(value)); // this is needed to suppress read return value warning Q_UNUSED(size) Q_EMIT signalTriggered(signal); handler.second->setEnabled(true); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucmouse.h0000644000015301777760000000756712321005637030205 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef UCMOUSE_H #define UCMOUSE_H #include #include #include #include class QQuickItem; class UCMouse : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons NOTIFY acceptedButtonsChanged) Q_PROPERTY(bool hoverEnabled READ hoverEnabled NOTIFY hoverEnabledChanged) Q_PROPERTY(int clickAndHoldThreshold READ clickAndHoldThreshold WRITE setClickAndHoldThreshold NOTIFY clickAndHoldThresholdChanged) Q_PROPERTY(QQmlListProperty forwardTo READ forwardTo) Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged) Q_ENUMS(Priority) public: enum Priority { BeforeItem, AfterItem }; explicit UCMouse(QObject *parent = 0); static UCMouse *qmlAttachedProperties(QObject *owner); bool isEnabled() const; virtual void setEnabled(bool enabled); Qt::MouseButtons acceptedButtons() const; bool hoverEnabled() const; int clickAndHoldThreshold() const; void setClickAndHoldThreshold(int threshold); QQmlListProperty forwardTo(); Priority priority() const; virtual void setPriority(Priority priority); Q_SIGNALS: void enabledChanged(); void acceptedButtonsChanged(); void hoverEnabledChanged(); void clickAndHoldThresholdChanged(); void priorityChanged(); void pressed(QQuickMouseEvent *mouse); void released(QQuickMouseEvent *mouse); void clicked(QQuickMouseEvent *mouse); void pressAndHold(QQuickMouseEvent *mouse); void doubleClicked(QQuickMouseEvent *mouse); void positionChanged(QQuickMouseEvent *mouse); void entered(QQuickMouseEvent *event); void exited(QQuickMouseEvent *event); protected: virtual bool eventFilter(QObject *, QEvent *); virtual void timerEvent(QTimerEvent *event); virtual bool mouseEvents(QObject *target, QMouseEvent *event); virtual bool hoverEvents(QObject *target, QHoverEvent *event); virtual bool hasAttachedFilter(QQuickItem *item); void setHovered(bool hovered); bool mousePressed(QMouseEvent *event); bool mouseReleased(QMouseEvent *event); bool mouseDblClick(QMouseEvent *event); bool mouseMoved(QMouseEvent *event); bool hoverEntered(QHoverEvent *event); bool hoverMoved(QHoverEvent *event); bool hoverExited(QHoverEvent *event); virtual void saveEvent(QMouseEvent *event); bool isDoubleClickConnected(); bool isMouseEvent(QEvent::Type type); bool isHoverEvent(QEvent::Type type); void forwardEvent(QEvent *event); protected: QQuickItem *m_owner; QList m_forwardList; QBasicTimer m_pressAndHoldTimer; QRectF m_toleranceArea; QPointF m_lastPos; QPointF m_lastScenePos; Qt::MouseButton m_lastButton; Qt::MouseButtons m_lastButtons; Qt::KeyboardModifiers m_lastModifiers; Qt::MouseButtons m_pressedButtons; Priority m_priority; int m_moveThreshold; bool m_enabled: 1; bool m_moved:1; bool m_longPress:1; bool m_hovered:1; bool m_doubleClicked:1; }; QML_DECLARE_TYPEINFO(UCMouse, QML_HAS_ATTACHED_PROPERTIES) #endif // UCMOUSE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucthemesettings.h0000644000015301777760000000264412321005637031727 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Zsombor Egri * Florian Boucault */ #ifndef UCTHEMESETTINGS_H #define UCTHEMESETTINGS_H #include #include #include class UCThemeSettings : public QObject { Q_OBJECT Q_PROPERTY(QString themeName READ themeName WRITE setThemeName NOTIFY themeNameChanged) public: explicit UCThemeSettings(QObject *parent = 0); // getter/setters QString themeName() const; void setThemeName(const QString &themeName); Q_SIGNALS: void themeNameChanged(); private Q_SLOTS: void reloadSettings(); private: QFileSystemWatcher m_settingsFileWatcher; QSettings m_settings; QString m_themeName; }; #endif // UCTHEMESETTINGS_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucunits.h0000644000015301777760000000305312321005637030201 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UBUNTU_COMPONENTS_UNITS_H #define UBUNTU_COMPONENTS_UNITS_H #include #include #include class UCUnits : public QObject { Q_OBJECT Q_PROPERTY(float gridUnit READ gridUnit WRITE setGridUnit NOTIFY gridUnitChanged) public: static UCUnits& instance() { static UCUnits instance; return instance; } explicit UCUnits(QObject *parent = 0); Q_INVOKABLE float dp(float value); Q_INVOKABLE float gu(float value); QString resolveResource(const QUrl& url); // getters float gridUnit(); // setters void setGridUnit(float gridUnit); Q_SIGNALS: void gridUnitChanged(); protected: QString suffixForGridUnit(float gridUnit); float gridUnitSuffixFromFileName(const QString &fileName); private: float m_gridUnit; }; #endif // UBUNTU_COMPONENTS_UNITS_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/inversemouseareatype.h0000644000015301777760000000411112321005637032762 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef INVERSEMOUSEAREATYPE_H #define INVERSEMOUSEAREATYPE_H #include #include class QQuickItem; class InverseMouseAreaType : public QQuickMouseArea { Q_OBJECT Q_PROPERTY(QQuickItem *sensingArea READ sensingArea WRITE setSensingArea NOTIFY sensingAreaChanged) Q_PROPERTY(bool topmostItem READ topmostItem WRITE setTopmostItem NOTIFY topmostItemChanged) public: explicit InverseMouseAreaType(QQuickItem *parent = 0); ~InverseMouseAreaType(); Q_INVOKABLE virtual bool contains(const QPointF &point) const; protected: void componentComplete(); bool eventFilter(QObject *, QEvent *); // override mouse events void mousePressEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); private: // getter/setter QQuickItem *sensingArea() const; void setSensingArea(QQuickItem *sensing); bool topmostItem() const; void setTopmostItem(bool value); QEvent * mapEventToArea(QObject *target, QEvent *event, QPoint &point); Q_SIGNALS: void sensingAreaChanged(); void topmostItemChanged(); private Q_SLOTS: void update(); void resetFilterOnWindowUpdate(QQuickWindow *win); private: bool m_ready:1; bool m_topmostItem:1; bool m_filteredEvent:1; QPointer m_filterHost; QPointer m_sensingArea; int m_touchId; void updateEventFilter(bool enable); }; #endif // INVERSEMOUSEAREATYPE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucfontutils.h0000644000015301777760000000211512321005637031064 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef UCFONTUTILS_H #define UCFONTUTILS_H #include class UCFontUtils : public QObject { Q_OBJECT public: static UCFontUtils& instance() { static UCFontUtils instance; return instance; } explicit UCFontUtils(QObject *parent = 0) : QObject(parent) {} Q_INVOKABLE qreal sizeToPixels(const QString &size); Q_INVOKABLE qreal modularScale(const QString &size); }; #endif // UCFONTUTILS_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucargument.cpp0000644000015301777760000001151412321005637031215 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "ucargument.h" /*! * \qmltype Argument * \instantiates UCArgument * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu-commandline * \brief The Argument class specifies what type a given command line parameter should be. * * \b Important: Argument is not used on its own but must be a child of \l Arguments. * * An Argument is defined by its \l name and \l valueNames properties which correspond * to a command line parameter (e.g. \e{--target}) and the values passed to it * (e.g. \e{--target=http://myaddress}). * * For example, the following code allows to retrieve parameters on the * command line of the form \e{--target=URL}: * * \qml * Argument { * name: "target" * help: "address of the resource to retrieve" * required: true * valueNames: ["URL"] * } * \endqml * * To retrieve a value passed to the parameter knowing its position, use the \l at * method. * * \sa Arguments * */ UCArgument::UCArgument(QObject *parent) : QObject(parent), m_required(true) { } /*! * \qmlproperty string Argument::name * * Name identifying the command line argument. * * For example 'target' corrsesponds to the \e{'--target'} command line argument. * */ QString UCArgument::name() const { return m_name; } void UCArgument::setName(const QString &name) { m_name = name; Q_EMIT(nameChanged()); } /*! * \qmlproperty string Argument::help * * Help displayed when launching the application with --usage. * */ QString UCArgument::help() const { return m_help; } void UCArgument::setHelp(const QString &help) { m_help = help; Q_EMIT(helpChanged()); } /*! * \qmlproperty bool Argument::required * * Whether or not this argument needs to be passed on the command line when * launching the application. * */ bool UCArgument::required() const { return m_required; } void UCArgument::setRequired(bool required) { m_required = required; Q_EMIT(requiredChanged()); } /*! * \qmlproperty list Argument::valueNames * * Names given to the values of this argument. They are used when displaying the * expected command line arguments of the application. * * Typically all capital letters (e.g. URL). * */ QStringList UCArgument::valueNames() const { return m_valueNames; } void UCArgument::setValueNames(const QStringList &valueNames) { m_valueNames = valueNames; Q_EMIT(valueNamesChanged()); } QString UCArgument::syntax() const { QString syntax; if (!m_name.isEmpty()) { // for named argument: --name=value1 value2 syntax.append("--"); syntax.append(m_name); if (!m_valueNames.empty()) { syntax.append('='); Q_FOREACH (const QString &valueName, m_valueNames) { syntax.append(valueName); if (valueName != m_valueNames.last()) { syntax.append(' '); } } } } else { // for unnamed required argument: value1 value2 // for unnamed optional argument: [value1] [value2] if (!m_valueNames.empty()) { Q_FOREACH (const QString &valueName, m_valueNames) { QString outputName = valueName; if (!m_required) { outputName.prepend('[').append(']'); } syntax.append(outputName); if (valueName != m_valueNames.last()) { syntax.append(' '); } } } } return syntax; } QString UCArgument::usage() const { // ensure that the help string for the arguments are aligned vertically QString usage; usage.append(syntax().leftJustified(20, ' ', true)); usage.append(' ').append(m_help); return usage; } QStringList UCArgument::values() const { return m_values; } void UCArgument::setValues(const QStringList &values) { m_values = values; } /*! * \qmlmethod string Argument::at(int i) * * Returns the \e{i}th value of the argument. * Values are counted from 0. * */ QVariant UCArgument::at(int i) const { if (i >= 0 && i < m_values.size()) { return QVariant(m_values.at(i)); } else { return QVariant(); } } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucscalingimageprovider.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucscalingimageprovider.cp0000644000015301777760000000455212321005637033415 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "ucscalingimageprovider.h" #include #include /*! \internal The UCScalingImageProvider class loads and scales images. It responds to URLs of the form "image://scaling/scale/path" where: - 'scale' is the scaling factor applied to the image - 'path' is the full path of the image on the filesystem Example: * image://scaling/0.5/arrow.png */ UCScalingImageProvider::UCScalingImageProvider() : QQuickImageProvider(QQuickImageProvider::Image) { } QImage UCScalingImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { int separatorPosition = id.indexOf("/"); float scaleFactor = id.left(separatorPosition).toFloat(); QString path = id.mid(separatorPosition+1); QFile file(path); if (file.open(QIODevice::ReadOnly)) { QImage image; QImageReader imageReader(&file); QSize realSize = imageReader.size(); QSize scaledSize = realSize; QSize constrainedSize; if (!qFuzzyCompare(scaleFactor, (float)1.0)) { scaledSize = realSize * scaleFactor; } if (requestedSize.isValid() && (requestedSize.width() < realSize.width() || requestedSize.height() < realSize.height())) { constrainedSize = scaledSize.scaled(requestedSize, Qt::KeepAspectRatio); } if (constrainedSize.isValid()) { imageReader.setScaledSize(constrainedSize); } else if (scaledSize != realSize) { imageReader.setScaledSize(scaledSize); } imageReader.read(&image); *size = scaledSize; return image; } else { return QImage(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/alarmrequest_p.h0000644000015301777760000000321012321005637031526 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ALARMREQUEST_P_H #define ALARMREQUEST_P_H #include #include "alarmmanager_p.h" class AlarmRequestPrivate; class AlarmRequest : public QObject { Q_OBJECT public: enum Status { Ready = 1, InProgress, Fail }; enum Operation { NoOperation, Saving, Canceling, Fetching = 100 // this is an operation which is not reflected to QML Alarm }; explicit AlarmRequest(QObject *parent = 0); AlarmRequest(bool autoDelete, QObject *parent = 0); ~AlarmRequest(); Status status() const; int error() const; bool save(AlarmData &alarm); bool remove(AlarmData &alarm); protected: bool wait(int msec = 0); Q_SIGNALS: void statusChanged(int operation, int status, int error); private: Q_DECLARE_PRIVATE(AlarmRequest) QScopedPointer d_ptr; Q_PRIVATE_SLOT(d_func(), void _q_updateProgress()) }; #endif // ALARMREQUEST_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/shapeitem.h0000644000015301777760000002031412321005637030465 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Loïc Molinari */ #ifndef UBUNTU_COMPONENTS_SHAPE_H #define UBUNTU_COMPONENTS_SHAPE_H #include #include #include #include #include // QtQuick item. class ShapeItem : public QQuickItem { Q_OBJECT Q_ENUMS(HAlignment) Q_ENUMS(VAlignment) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(QColor gradientColor READ gradientColor WRITE setGradientColor NOTIFY gradientColorChanged) Q_PROPERTY(QString radius READ radius WRITE setRadius NOTIFY radiusChanged) Q_PROPERTY(QVariant image READ image WRITE setImage NOTIFY imageChanged) Q_PROPERTY(bool stretched READ stretched WRITE setStretched NOTIFY stretchedChanged) Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged) Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged) Q_PROPERTY(QString borderSource READ borderSource WRITE setBorderSource NOTIFY borderSourceChanged) public: ShapeItem(QQuickItem* parent=0); enum Radius { SmallRadius, MediumRadius }; enum Border { RawBorder, IdleBorder, PressedBorder }; enum HAlignment { AlignLeft = 0, AlignHCenter = 1, AlignRight = 2 }; enum VAlignment { AlignTop = 0, AlignVCenter = 1, AlignBottom = 2 }; QColor color() const { return color_; } void setColor(const QColor& color); QColor gradientColor() const { return gradientColor_; } void setGradientColor(const QColor& gradientColor); QString radius() const { return radiusString_; } void setRadius(const QString& radius); QString borderSource() const { return borderSource_; } void setBorderSource(const QString& borderSource); QVariant image() const { return QVariant::fromValue(image_); } void setImage(const QVariant& image); bool stretched() const { return stretched_; } void setStretched(bool stretched); HAlignment horizontalAlignment() const { return hAlignment_; } void setHorizontalAlignment(HAlignment horizontalAlignment); VAlignment verticalAlignment() const { return vAlignment_; } void setVerticalAlignment(VAlignment verticalAlignment); Q_SLOT void gridUnitChanged(); Q_SIGNALS: void colorChanged(); void gradientColorChanged(); void radiusChanged(); void borderChanged(); void imageChanged(); void stretchedChanged(); void horizontalAlignmentChanged(); void verticalAlignmentChanged(); void borderSourceChanged(); protected: virtual void geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry); virtual QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*); private: void updateFromImageProperties(QQuickItem* image); void connectToPropertyChange(QObject* sender, const char* property, QObject* receiver, const char* slot); void connectToImageProperties(QQuickItem* image); private Q_SLOTS: void onImagePropertiesChanged(); private: enum DirtyFlags { NotDirty = 0, DirtyColor = (1 << 0), DirtyGradientColor = (1 << 1), DirtyRadius = (1 << 2), DirtyBorder = (1 << 3), DirtyImage = (1 << 4), DirtyStretched = (1 << 5), DirtyHAlignment = (1 << 6), DirtyVAlignment = (1 << 7), DirtyGridUnit = (1 << 8), DirtyGeometry = (1 << 9), DirtyAll = (DirtyColor | DirtyGradientColor | DirtyRadius | DirtyBorder | DirtyImage | DirtyStretched | DirtyHAlignment | DirtyVAlignment | DirtyGridUnit | DirtyGeometry) }; QColor color_; QColor gradientColor_; bool gradientColorSet_; QString radiusString_; Radius radius_; QString borderSource_; Border border_; QQuickItem* image_; bool stretched_; HAlignment hAlignment_; VAlignment vAlignment_; float gridUnit_; QRectF geometry_; QFlags dirtyFlags_; Q_DISABLE_COPY(ShapeItem) }; // Scene graph textured material. class ShapeTexturedMaterial : public QSGMaterial { public: ShapeTexturedMaterial(); virtual QSGMaterialType* type() const; virtual QSGMaterialShader* createShader() const; QSGTextureProvider* imageTextureProvider() const; void setImage(QQuickItem* image); QSGTexture* shapeTexture() const { return shapeTexture_; } QSGTexture::Filtering filtering() const { return filtering_; } void setShapeTexture(QSGTexture* shapeTexture, bool scaledDown); private: QSGTextureProvider* imageTextureProvider_; QSGTexture* shapeTexture_; QSGTexture::Filtering filtering_; }; // Scene graph textured material shader. class ShapeTexturedShader : public QSGMaterialShader { public: virtual char const* const* attributeNames() const; virtual void initialize(); virtual void updateState( const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect); private: virtual const char* vertexShader() const; virtual const char* fragmentShader() const; int matrixId_; int opacityId_; QOpenGLFunctions* glFuncs_; }; // Scene graph colored material. class ShapeColoredMaterial : public QSGMaterial { public: ShapeColoredMaterial(); virtual QSGMaterialType* type() const; virtual QSGMaterialShader* createShader() const; const QVector4D& color() const { return color_; } void setColor(const QColor& color); const QVector4D& gradientColor() const { return gradientColor_; } void setGradientColor(const QColor& gradientColor); QSGTexture* shapeTexture() const { return shapeTexture_; } QSGTexture::Filtering filtering() const { return filtering_; } void setShapeTexture(QSGTexture* shapeTexture, bool scaledDown); private: QVector4D color_; QVector4D gradientColor_; QSGTexture* shapeTexture_; QSGTexture::Filtering filtering_; }; // Scene graph colored material shader. class ShapeColoredShader : public QSGMaterialShader { public: virtual char const* const* attributeNames() const; virtual void initialize(); virtual void updateState( const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect); private: virtual const char* vertexShader() const; virtual const char* fragmentShader() const; int matrixId_; int opacityId_; int colorId_; int gradientColorId_; }; // Scene graph node. struct TextureData; class ShapeNode : public QObject, public QSGGeometryNode { Q_OBJECT public: struct Vertex { float position[2]; float shapeCoordinate[2]; float imageCoordinate[2]; float padding[2]; // Ensure a 32 bytes stride. }; enum MaterialType { TexturedMaterial, ColoredMaterial }; ShapeNode(ShapeItem* item); ShapeTexturedMaterial* texturedMaterial() { return &texturedMaterial_; } ShapeColoredMaterial* coloredMaterial() { return &coloredMaterial_; } void setVertices(const QRectF& geometry, float radius, QQuickItem* image, bool stretched, ShapeItem::HAlignment hAlignment, ShapeItem::VAlignment vAlignment, float shapeCoordinate[][2]); void setMaterialType(MaterialType material); private: ShapeItem* item_; QSGGeometry geometry_; ShapeTexturedMaterial texturedMaterial_; ShapeColoredMaterial coloredMaterial_; MaterialType currentMaterial_; }; QML_DECLARE_TYPE(ShapeItem) #endif // UBUNTU_COMPONENTS_SHAPE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/alarmmanager_p.cpp0000644000015301777760000000301412321005637032005 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "alarmmanager_p.h" #include "alarmmanager_p_p.h" #include "ucalarm.h" #include "ucalarm_p.h" AlarmManagerPrivate::AlarmManagerPrivate(AlarmManager *qq) : q_ptr(qq) , completed(false) { } AlarmManagerPrivate::~AlarmManagerPrivate() { } /*----------------------------------------------------------------------------- * Alarm Manager public interface */ AlarmManager::AlarmManager(QObject *parent) : QObject(parent) , d_ptr(createAlarmsAdapter(this)) { } AlarmManager::~AlarmManager() { } AlarmManager &AlarmManager::instance() { static AlarmManager instance; if (!instance.d_func()->completed) { instance.d_func()->fetchAlarms(); } return instance; } QList AlarmManager::alarms() const { Q_D(const AlarmManager); return d->alarmList; } #include "moc_alarmmanager_p.cpp" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucubuntuanimation.cpp0000644000015301777760000000672512321005637032625 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "ucubuntuanimation.h" #include /*! * \qmltype UbuntuAnimation * \instantiates UCUbuntuAnimation * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief Singleton defining standard Ubuntu durations and easing for animations * that should be used to ensure that Ubuntu applications are consistent * in their animations. * * Example of use: * * \qml * RotationAnimation { * duration: UbuntuAnimation.SlowDuration * easing: UbuntuAnimation.StandardEasing * } * \endqml * * Animation durations should be selected depending on the frequency and * disruptiveness of the animation. The more frequent an animation is, the * faster it should be. The more disruptive an animation is, the slower it should * be. Rule of thumb to select durations: * \list * \li SnapDuration: very frequent, non-disruptive. * \li FastDuration: frequent, non-disruptive. * \li SlowDuration: less frequent, non-disruptive. * \li SleepyDuration: disruptive. * \endlist * * Note that \l UbuntuNumberAnimation provides a standard NumberAnimation for * Ubuntu applications. * */ UCUbuntuAnimation::UCUbuntuAnimation(QObject *parent) : QObject(parent), m_standardEasing(QEasingCurve::OutQuad), m_StandardEasingReverse(QEasingCurve::InQuad) { } /*! * \qmlproperty int UbuntuAnimation::SnapDuration * Used for very frequent and non-disruptive transitions on small objects. * The user would perceive the change as instant but smooth. * * The value is 100ms. */ /*! * \qmlproperty int UbuntuAnimation::FastDuration * Used for frequent and non-disruptive transitions. * * The value is 165ms. */ /*! * \qmlproperty int UbuntuAnimation::BriskDuration * Used for frequent and non-disruptive transitions. * Used when objects have more distance to travel or when they are larger in size. * * The value is 333ms. */ /*! * \qmlproperty int UbuntuAnimation::SlowDuration * Used for delay after key press and for less frequent and non-disruptive * transitions. * * The value is 500ms. */ /*! * \qmlproperty int UbuntuAnimation::SleepyDuration * Used for disruptive transitions. * * The value is 1000ms. */ /*! * \qmlproperty QEasingCurve UbuntuAnimation::StandardEasing * Used for animations trigerred by user actions. */ /*! * \qmlproperty QEasingCurve UbuntuAnimation::StandardEasingReverse * * StandardEasingReverse is mainly used in combination with StandardEasing. * For example, if animating an object that bounces, you will want the object * to slow down as it reaches the apex of its bounce and slowly speed back up * as it descends. * * StandardEasingReverse should not be used to introduce a new object or screen * to the user. * In general, it should only be used if StandardEasing is visually inappropriate * and even so, will usually be proceeded by StandardEasing. */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/qquickclipboard.cpp0000644000015301777760000001243112321005637032217 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include #include #include "qquickclipboard.h" #include "qquickclipboard_p.h" #include "qquickmimedata.h" /*! * \qmltype Clipboard * \instantiates QQuickClipboard * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief This is a singleton type providing access to the system clipboard. * * Clipboard data can be retrieved through data property, which returns an object * of MimeData type. The actual content of the clipboard can be accessed through * this object. Data can be pushed to the clipboard using push() function. * * The clipboard data cannot be modified through the type returned by the data * property, for this a new instance of MimeData type must be used. This instance * can be either a standalone MimeDala component or an object created using newData() * function. Remember that standalone MimeData types duplicate the clipboard data * which may cause extensive memory use. * * Examples of use: * * 1. Using standard MimeType component - the following example copies the selected * text from the text area into the clipboard pushing also a color * \qml * Item { * TextArea { * id: editor * } * * MimeData { * id: mimeData * color: "green" * text: editor.text * } * * Button { * text: "Copy" * onClicked: Clipboard.push(mimeData) * } * } * \endqml * * 2. Pushing data straight to clipboard * \qml * Item { * TextArea { * id: editor * } * * Button { * text: "Copy" * onClicked: { * Clipboard.push(editor.text); * Clipboard.push(["application/x-color", "green"]); * } * } * } * \endqml * * 3. Pushing data using MimeData object * \qml * Item { * TextArea { * id: editor * } * * Button { * text: "Copy" * onClicked: { * var mimeData = Clipboard.newData(); * mimeData.text = editor.text; * mimeData.color = "green"; * Clipboard.push(mimeData); * } * } * } * \endqml * */ /*! * \qmlsignal Clipboard::dataChanged() * The signal is triggered when clipboard content gets changed. */ QQuickClipboardPrivate::QQuickClipboardPrivate(QQuickClipboard *qq) : q_ptr(qq), clipboard(QGuiApplication::clipboard()), mode(QClipboard::Clipboard), mimeData(0) { // connect to the system clipboard's dataChanged signal so we get update QObject::connect(clipboard, SIGNAL(dataChanged()), q_ptr, SIGNAL(dataChanged())); } void QQuickClipboardPrivate::updateMimeData() { const QMimeData *data = clipboard->mimeData(mode); if (!mimeData) mimeData = new QQuickMimeData(clipboard->mimeData(mode), true, q_ptr); else mimeData->fromMimeData(data); } QQuickClipboard::QQuickClipboard(QObject *parent) : QObject(parent), d_ptr(new QQuickClipboardPrivate(this)) { } /*! * \qmlproperty MimeData Clipboard::data * Provides access to the Clipboard's current data. */ QQuickMimeData *QQuickClipboard::data() { Q_D(QQuickClipboard); d->updateMimeData(); return d->mimeData; } /*! * \qmlmethod MimeData Clipboard::newData() * The function returns a new MimeData object that can be used in Java script code * to push pultiple MIME types at the same time. */ QQuickMimeData *QQuickClipboard::newData() { // create it so that we give a QMimeData instance so it won't create a new // instance of that when data is pushed to clipboard return new QQuickMimeData(new QMimeData, false, this); } /*! * \qmlmethod Clipboard::push(var data) * The function copies data provided as parameter to the clipboard. The parameter * can be a MimeData instance or object created using newData() beside * the ones listed at MimeData::data. * * When MimeData instance or object is given, the entire object content will be * pushed to the clipboard. * */ void QQuickClipboard::push(const QVariant& data) { if (!data.isValid()) return; Q_D(QQuickClipboard); // check whether we have a MimeData to push QQuickMimeData *mimeData = qvariant_cast(data); if (mimeData) d->clipboard->setMimeData(mimeData->toMimeData(), d->mode); else { QQuickMimeData newData(new QMimeData, false); newData.setMimeData(data); d->clipboard->setMimeData(newData.m_mimeData, d->mode); } } /*! * \qmlmethod Clipboard::clear() * The function clears the clipboard content. */ void QQuickClipboard::clear() { Q_D(QQuickClipboard); d->clipboard->clear(d->mode); } #include "moc_qquickclipboard.cpp" ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/unitythemeiconprovider.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/unitythemeiconprovider.cp0000644000015301777760000000330212321005637033476 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Lars Uebernickel */ #include "unitythemeiconprovider.h" #include UnityThemeIconProvider::UnityThemeIconProvider(): QQuickImageProvider(QQuickImageProvider::Pixmap) { QIcon::setThemeName("ubuntu-mobile"); } QPixmap UnityThemeIconProvider::requestPixmap(const QString &id, QSize *realSize, const QSize &requestedSize) { QIcon icon; Q_FOREACH (const QString &name, id.split(",", QString::SkipEmptyParts)) { icon = QIcon::fromTheme(name); if (!icon.isNull()) { if (requestedSize.isValid()) { *realSize =requestedSize; return icon.pixmap(requestedSize); } else { QList sizes = icon.availableSizes(); if (sizes.count() > 0 && sizes.last().isValid()) { *realSize = sizes.last(); } else { *realSize = QSize(32,32); } return icon.pixmap(*realSize); } break; } } return QPixmap(); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/alarmmanager_p.h0000644000015301777760000000677312321005637031471 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ALARMMANAGER_H #define ALARMMANAGER_H #include #include #include #include "ucalarm.h" class AlarmData { public: enum Change { NoChange = 0, Enabled = 0x0001, Date = 0x0002, Message = 0x0004, Sound = 0x0008, Type = 0x0010, Days = 0x0020, AllFields = 0x00FF }; AlarmData() : changes(0) , type(UCAlarm::OneTime) , days(UCAlarm::AutoDetect) , enabled(true) { } AlarmData(const AlarmData &other) : changes(0) , cookie(other.cookie) , date(other.date) , message(other.message) , type(other.type) , days(other.days) , enabled(other.enabled) { } bool compare(const AlarmData &other) { // cookie, sound, and enabled do not count on alarm equality return date == other.date && message == other.message && type == other.type && days == other.days; } bool operator==(const AlarmData &other) { return compare(other); } static QHash roles() { QHash hash; int i = 0; hash.insert(i++, QByteArray("message")); hash.insert(i++, QByteArray("date")); hash.insert(i++, QByteArray("type")); hash.insert(i++, QByteArray("daysOfWeek")); hash.insert(i++, QByteArray("sound")); hash.insert(i++, QByteArray("enabled")); return hash; } QVariant roleData(int role) const { switch (role) { case 0: return message; case 1: return date; case 2: return type; case 3: return static_cast(days); case 4: return sound; case 5: return enabled; default: return QVariant(); } } static QDateTime normalizeDate(const QDateTime &dt) { QTime time = dt.time(); time.setHMS(time.hour(), time.minute(), time.second()); return QDateTime(dt.date(), time, dt.timeSpec()); } unsigned int changes; QVariant cookie; // data members QDateTime date; QString message; QUrl sound; UCAlarm::AlarmType type; UCAlarm::DaysOfWeek days; bool enabled; }; class AlarmRequest; class AlarmManagerPrivate; class AlarmManager : public QObject { Q_OBJECT public: enum Status { Ready = 1, Progress, Error }; ~AlarmManager(); static AlarmManager &instance(); QList alarms() const; Q_SIGNALS: void alarmsChanged(); private: explicit AlarmManager(QObject *parent = 0); Q_DISABLE_COPY(AlarmManager) Q_DECLARE_PRIVATE(AlarmManager) QScopedPointer d_ptr; }; #endif // ALARMMANAGER_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/statesaverbackend_p.cpp0000644000015301777760000001433112321005637033053 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "statesaverbackend_p.h" #include "ucapplication.h" #include #include #include #include #include #include #include #include "i18n.h" #include "quickutils.h" #include #include "unixsignalhandler_p.h" StateSaverBackend::StateSaverBackend(QObject *parent) : QObject(parent) , m_archive(0) , m_globalEnabled(true) { // connect to application quit signal so when that is called, we can clean the states saved QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &StateSaverBackend::cleanup); QObject::connect(&QuickUtils::instance(), &QuickUtils::activated, this, &StateSaverBackend::reset); QObject::connect(&QuickUtils::instance(), &QuickUtils::deactivated, this, &StateSaverBackend::initiateStateSaving); if (!qgetenv("APP_ID").isEmpty() || !UCApplication::instance().applicationName().isEmpty()) { initialize(); } else { QObject::connect(&UCApplication::instance(), &UCApplication::applicationNameChanged, this, &StateSaverBackend::initialize); } UnixSignalHandler::instance().connectSignal(UnixSignalHandler::Terminate); UnixSignalHandler::instance().connectSignal(UnixSignalHandler::Interrupt); QObject::connect(&UnixSignalHandler::instance(), SIGNAL(signalTriggered(int)), this, SLOT(signalHandler(int))); } StateSaverBackend::~StateSaverBackend() { if (m_archive) { delete m_archive; } } void StateSaverBackend::initialize() { QString applicationName(qgetenv("APP_ID")); if (applicationName.isEmpty()) { applicationName = UCApplication::instance().applicationName(); } m_archive = new QSettings(QString("%1/%2.state") .arg(QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0]) .arg(applicationName), QSettings::NativeFormat); m_archive->setFallbacksEnabled(false); } void StateSaverBackend::cleanup() { reset(); m_archive.clear(); } void StateSaverBackend::signalHandler(int type) { if (type == UnixSignalHandler::Interrupt) { Q_EMIT initiateStateSaving(); // disconnect aboutToQuit() so the state file doesn't get wiped upon quit QObject::disconnect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &StateSaverBackend::cleanup); } QCoreApplication::quit(); } bool StateSaverBackend::enabled() const { return m_globalEnabled; } void StateSaverBackend::setEnabled(bool enabled) { if (m_globalEnabled != enabled) { m_globalEnabled = enabled; Q_EMIT enabledChanged(m_globalEnabled); if (!m_globalEnabled) { reset(); } } } bool StateSaverBackend::registerId(const QString &id) { if (m_register.contains(id)) { return false; } m_register.insert(id); return true; } void StateSaverBackend::removeId(const QString &id) { m_register.remove(id); } int StateSaverBackend::load(const QString &id, QObject *item, const QStringList &properties) { if (m_archive.isNull()) { return 0; } int result = 0; // save the previous group bool restorePreviousGroup = !m_archive->group().isEmpty(); if (restorePreviousGroup) { m_groupStack.push(m_archive->group()); // leave the group so we can read the next one m_archive->endGroup(); } m_archive.data()->beginGroup(id); QStringList propertyNames = m_archive.data()->childKeys(); Q_FOREACH(const QString &propertyName, propertyNames) { QVariant value = m_archive.data()->value(propertyName); if (!properties.contains(propertyName)) { // skip the property continue; } QQmlProperty qmlProperty(item, propertyName.toLocal8Bit().constData(), qmlContext(item)); if (qmlProperty.isValid() && qmlProperty.isWritable()) { qmlProperty.write(value); result++; } else { qmlInfo(item) << UbuntuI18n::instance().tr("property \"%1\" does not exist or is not writable for object %2") .arg(propertyName).arg(qmlContext(item)->nameForObject(item)); } } m_archive.data()->endGroup(); // restore leaved group if needed if (restorePreviousGroup) { m_archive->beginGroup(m_groupStack.pop()); } return result; } int StateSaverBackend::save(const QString &id, QObject *item, const QStringList &properties) { if (m_archive.isNull()) { return 0; } m_archive.data()->beginGroup(id); int result = 0; Q_FOREACH(const QString &propertyName, properties) { QQmlProperty qmlProperty(item, propertyName.toLocal8Bit().constData()); if (qmlProperty.isValid()) { QVariant value = qmlProperty.read(); if (static_cast(value.type()) != QMetaType::QObjectStar) { m_archive.data()->setValue(propertyName, value); result++; } } } m_archive.data()->endGroup(); m_archive.data()->sync(); return result; } /* * The method resets the register and the state archive for the application. */ bool StateSaverBackend::reset() { m_register.clear(); if (m_archive) { QFile archiveFile(m_archive.data()->fileName()); return archiveFile.remove(); } return true; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucthemesettings.cpp0000644000015301777760000000444712321005637032265 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Zsombor Egri * Florian Boucault */ #include "ucthemesettings.h" #include #include /* User theme settings are stored in $HOME/.config/ubuntu-ui-toolkit/theme.ini file, which contains the current global theme name. */ const QString SETTINGS_FILE_FORMAT("%1/.config/ubuntu-ui-toolkit/theme.ini"); const QString THEME_KEY("theme"); const QString DEFAULT_THEME("Ubuntu.Components.Themes.Ambiance"); UCThemeSettings::UCThemeSettings(QObject *parent) : QObject(parent), m_settings(SETTINGS_FILE_FORMAT.arg(QDir::homePath()), QSettings::IniFormat) { // check if there is a theme settings file, if not, create one if (!QFile::exists(m_settings.fileName())) { // create the file by writing the default theme m_settings.setValue(THEME_KEY, DEFAULT_THEME); m_settings.sync(); } QObject::connect(&m_settingsFileWatcher, &QFileSystemWatcher::fileChanged, this, &UCThemeSettings::reloadSettings); reloadSettings(); } void UCThemeSettings::reloadSettings() { m_settings.sync(); m_settingsFileWatcher.addPath(m_settings.fileName()); QString themeName = m_settings.value(THEME_KEY).toString(); if (themeName != m_themeName) { m_themeName = themeName; Q_EMIT themeNameChanged(); } } QString UCThemeSettings::themeName() const { return m_themeName; } void UCThemeSettings::setThemeName(const QString &themeName) { if (themeName != m_themeName) { m_themeName = themeName; m_settings.setValue(THEME_KEY, themeName); Q_EMIT themeNameChanged(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucalarmmodel.h0000644000015301777760000000275312321005637031162 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef UCALARMSMODEL_H #define UCALARMSMODEL_H #include #include "ucalarm.h" class UCAlarm; class UCAlarmModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit UCAlarmModel(QObject *parent = 0); ~UCAlarmModel(); int rowCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QHash roleNames() const; // invokables Q_INVOKABLE UCAlarm *get(int index); // property getters int count() const; Q_SIGNALS: void countChanged(); private Q_SLOTS: void refresh(); private: bool m_ready; QHash m_roles; QList m_alarms; void clear(); }; #endif // UCALARMSMODEL_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucubuntuanimation.h0000644000015301777760000000353712321005637032270 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef UCUBUNTUANIMATION_H #define UCUBUNTUANIMATION_H #include #include class UCUbuntuAnimation : public QObject { Q_OBJECT Q_PROPERTY(int SnapDuration READ SnapDuration CONSTANT) Q_PROPERTY(int FastDuration READ FastDuration CONSTANT) Q_PROPERTY(int BriskDuration READ BriskDuration CONSTANT) Q_PROPERTY(int SlowDuration READ SlowDuration CONSTANT) Q_PROPERTY(int SleepyDuration READ SleepyDuration CONSTANT) Q_PROPERTY(QEasingCurve StandardEasing READ StandardEasing CONSTANT) Q_PROPERTY(QEasingCurve StandardEasingReverse READ StandardEasingReverse CONSTANT) public: explicit UCUbuntuAnimation(QObject *parent = 0); int SnapDuration() const { return 100; } int FastDuration() const { return 165; } int BriskDuration() const { return 333; } int SlowDuration() const { return 500; } int SleepyDuration() const { return 1000; } const QEasingCurve& StandardEasing() const { return m_standardEasing; } const QEasingCurve& StandardEasingReverse() const { return m_StandardEasingReverse; } private: QEasingCurve m_standardEasing; QEasingCurve m_StandardEasingReverse; }; #endif // UCUBUNTUANIMATION_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/unixsignalhandler_p.h0000644000015301777760000000303712321005637032547 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef UNIXSIGNALHANDLER_P_H #define UNIXSIGNALHANDLER_P_H #include #include #include class QSocketNotifier; class UnixSignalHandler : public QObject { Q_OBJECT public: enum SignalType { Invalid = 0, Interrupt = SIGINT, Terminate = SIGTERM }; typedef QPair HandlerType; static UnixSignalHandler &instance() { static UnixSignalHandler instance; return instance; } void connectSignal(SignalType type); Q_SIGNALS: void signalTriggered(int type); private Q_SLOTS: void notifierActivated(int socket); private: explicit UnixSignalHandler(QObject *parent = 0); static void signalHook(int); HandlerType createHandler(int signal); QHash notifiers; QHash socketRegister; }; #endif // UNIXSIGNALHANDLER_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucalarm.cpp0000644000015301777760000004746112321005637030501 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ucalarm.h" #include "ucalarm_p.h" #include "alarmmanager_p.h" #include "alarmrequest_p.h" #include "i18n.h" #include UCAlarmPrivate::UCAlarmPrivate(UCAlarm *qq) : q_ptr(qq) , request(0) , error(UCAlarm::NoError) , status(UCAlarm::Ready) { setDefaults(); } UCAlarmPrivate::~UCAlarmPrivate() { } void UCAlarmPrivate::setDefaults() { rawData.date = QDateTime::currentDateTime(); rawData.message = UbuntuI18n::instance().tr("Alarm"); rawData.days = dayOfWeek(rawData.date); } bool UCAlarmPrivate::createRequest() { if (request) { return true; } request = new AlarmRequest(q_ptr); if (!request) { return false; } QObject::connect(request, SIGNAL(statusChanged(int,int,int)), q_ptr, SLOT(_q_syncStatus(int,int,int))); return true; } void UCAlarmPrivate::_q_syncStatus(int operation, int status, int error) { UCAlarm::Status alarmStatus = static_cast(status); if (this->status != alarmStatus || this->error != error) { this->status = alarmStatus; this->error = error; if (this->status == UCAlarm::Ready) { // sync field changes occured during operation if (rawData.changes & AlarmData::Enabled) Q_EMIT q_ptr->enabledChanged(); if (rawData.changes & AlarmData::Date) Q_EMIT q_ptr->dateChanged(); if (rawData.changes & AlarmData::Message) Q_EMIT q_ptr->messageChanged(); if (rawData.changes & AlarmData::Sound) Q_EMIT q_ptr->soundChanged(); if (rawData.changes & AlarmData::Type) Q_EMIT q_ptr->typeChanged(); if (rawData.changes & AlarmData::Days) Q_EMIT q_ptr->daysOfWeekChanged(); rawData.changes = 0; } Q_EMIT q_func()->statusChanged(static_cast(operation)); Q_EMIT q_func()->errorChanged(); } } UCAlarm::DayOfWeek UCAlarmPrivate::dayOfWeek(const QDateTime &dt) { return (UCAlarm::DayOfWeek)(1 << (dt.date().dayOfWeek() - 1)); } int UCAlarmPrivate::firstDayOfWeek(UCAlarm::DaysOfWeek days) { for (int d = Qt::Monday; d <= Qt::Sunday; d++) { if ((1 << (d - 1)) & days) { return d; } } return 0; } int UCAlarmPrivate::nextDayOfWeek(UCAlarm::DaysOfWeek days, int fromDay) { if (fromDay <= 0) { fromDay = Qt::Monday; } for (int d = fromDay; d <= Qt::Sunday; d++) { if ((1 << (d - 1)) & days) { return d; } } return 0; } // checks whether the given num has more than one bit set bool UCAlarmPrivate::multipleDaysSet(UCAlarm::DaysOfWeek days) { unsigned bits; int num = static_cast(days); for (bits = 0; num; bits++) { num &= num - 1; // clears the least significant bit } return (bits > 1); } UCAlarm::Error UCAlarmPrivate::checkAlarm() { if (rawData.message.isEmpty()) { rawData.message = UbuntuI18n::instance().tr("Alarm"); rawData.changes |= AlarmData::Message; } if (!rawData.date.isValid()) { return UCAlarm::InvalidDate; } rawData.date = rawData.normalizeDate(rawData.date); // check type first as it may alter start day if (rawData.type == UCAlarm::OneTime) { return checkOneTime(); } else if (rawData.type == UCAlarm::Repeating) { return checkRepeatingWeekly(); } return UCAlarm::NoError; } UCAlarm::Error UCAlarmPrivate::checkDow() { if (!rawData.days) { return UCAlarm::NoDaysOfWeek; } else if (rawData.days == UCAlarm::AutoDetect) { rawData.days = dayOfWeek(rawData.date); rawData.changes |= AlarmData::Days; } else if (rawData.days != UCAlarm::Daily) { int alarmDay = firstDayOfWeek(rawData.days); int dayOfWeek = rawData.date.date().dayOfWeek(); if (alarmDay < dayOfWeek) { rawData.date = rawData.date.addDays(7 - dayOfWeek + alarmDay); rawData.changes |= AlarmData::Date; } else if (alarmDay > dayOfWeek) { rawData.date = rawData.date.addDays(alarmDay - dayOfWeek); rawData.changes |= AlarmData::Date; } } return UCAlarm::NoError; } UCAlarm::Error UCAlarmPrivate::checkOneTime() { // check days, days can be set for only one day in this case if (multipleDaysSet(rawData.days)) { return UCAlarm::OneTimeOnMoreDays; } // adjust start date and/or dayOfWeek according to their values UCAlarm::Error result = checkDow(); if (result != UCAlarm::NoError) { return result; } // start date should be later then the current date/time if (rawData.date <= AlarmData::normalizeDate(QDateTime::currentDateTime())) { return UCAlarm::EarlyDate; } return UCAlarm::NoError; } UCAlarm::Error UCAlarmPrivate::checkRepeatingWeekly() { // start date is adjusted depending on the days value; // start date can be set to be the current time, as scheduling will move // it to the first occurence. UCAlarm::Error result = checkDow(); if (result != UCAlarm::NoError) { return result; } // move start time to the first occurence if needed int dayOfWeek = rawData.date.date().dayOfWeek(); if (!isDaySet(dayOfWeek, rawData.days) || (rawData.date <= QDateTime::currentDateTime())) { // check the next occurence of the alarm int nextOccurence = nextDayOfWeek(rawData.days, dayOfWeek); if (nextOccurence <= 0) { // the starting date should be moved to the next week nextOccurence = firstDayOfWeek(rawData.days); rawData.date.addDays(7 - dayOfWeek + nextOccurence); } else { // the starting date is still this week rawData.date.addDays(nextOccurence - dayOfWeek); } rawData.changes |= AlarmData::Date; } return UCAlarm::NoError; } /*! * \qmltype Alarm * \instantiates UCAlarm * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu-services * \brief Alarm component is a representation of an alarm event. * * The Alarm element encapsulates alarm event data. Supports one time and repeating * alarms, where repeating can be either daily or weekly on one or several selected * days. * * The alarm data is validated upon \l save operation, which can be used to save * a new alarm or update existing alarm's properties. * * During data validation the alarm properties may suffer changes. These changes * will be reported back to each changed property. See what changes can occurr at * \l save function documentation. * * Example usage: * \qml * import QtQuick 2.0 * import Ubuntu.Components 0.1 * * Rectangle { * width: units.gu(40) * height: units.gu(20) * * Alarm{ * id: alarm * } * Column { * spacing: units.gu(1) * Row { * spacing: units.gu(1) * Label { * id: date * text: "Date:" * anchors.verticalCenter: parent.verticalCenter * } * TextField { * text: alarm.date.toString() * onAccepted: alarm.date = new Date(text) * } * } * Row { * spacing: units.gu(1) * Label { * id: msg * text: "Message:" * anchors.verticalCenter: parent.verticalCenter * } * TextField { * text: alarm.message * onAccepted: alarm.message = text * } * } * Button { * text: "Save" * onClicked: { * alarm.save(); * if (alarm.error != Alarm.NoError) * print("Error saving alarm, code: " + alarm.error); * } * } * } * } * \endqml * * An alarm can be cancelled using \l cancel function but only if the event has * previously been stored in the alarm collection. * * The \l reset function clears the properties of the alarm bringing them to the * default values. In this way the same alarm component can be used to save several * alarms at the same time. */ UCAlarm::UCAlarm(QObject *parent) : QObject(parent) , d_ptr(new UCAlarmPrivate(this)) { } UCAlarm::UCAlarm(const QDateTime &dt, const QString &message, QObject *parent) : QObject(parent) , d_ptr(new UCAlarmPrivate(this)) { d_ptr->rawData.date = dt; if (!message.isEmpty()) { d_ptr->rawData.message = message; } d_ptr->rawData.days = UCAlarmPrivate::dayOfWeek(d_ptr->rawData.date); } UCAlarm::UCAlarm(const QDateTime &dt, DaysOfWeek days, const QString &message, QObject *parent) : QObject(parent) , d_ptr(new UCAlarmPrivate(this)) { d_ptr->rawData.date = dt; d_ptr->rawData.type = Repeating; d_ptr->rawData.days = days; if (!message.isEmpty()) { d_ptr->rawData.message = message; } if (d_ptr->rawData.days == AutoDetect) { d_ptr->rawData.days = UCAlarmPrivate::dayOfWeek(d_ptr->rawData.date); } } UCAlarm::~UCAlarm() { } /*! * \qmlproperty bool Alarm::enabled * The property specifies whether the alarm is enabled or not. Disable dalarms * are not scheduled. * The default value is true; */ bool UCAlarm::enabled() const { Q_D(const UCAlarm); return d->rawData.enabled; } void UCAlarm::setEnabled(bool enabled) { Q_D(UCAlarm); if (d->rawData.enabled == enabled) { return; } d->rawData.enabled = enabled; d->rawData.changes |= AlarmData::Enabled; Q_EMIT enabledChanged(); } /*! * \qmlproperty Date Alarm::date * The property holds the date the alarm will be triggered. The default * value is the current date and time the alarm object was created. Further * \l reset calls will bring the value back to the time the \l reset was called. */ QDateTime UCAlarm::date() const { Q_D(const UCAlarm); return d->rawData.date; } void UCAlarm::setDate(const QDateTime &date) { Q_D(UCAlarm); if (d->rawData.date == date) { return; } d->rawData.date = date; d->rawData.changes |= AlarmData::Date; Q_EMIT dateChanged(); } /*! * \qmlproperty string Alarm::message * The property holds the message string which will be displayed when the alarm * is triggered. The default value is the localized "Alarm" text. */ QString UCAlarm::message() const { Q_D(const UCAlarm); return d->rawData.message; } void UCAlarm::setMessage(const QString &message) { Q_D(UCAlarm); if (d->rawData.message == message) { return; } d->rawData.message = message; d->rawData.changes |= AlarmData::Message; Q_EMIT messageChanged(); } /*! * \qmlproperty AlarmType Alarm::type * The property holds the type of the alarm, which can have one of the * following values: * \table * \header * \li {2, 1} Alarm.AlarmType enum: * \header * \li Type * \li Description * \row * \li Alarm.OneTime * \li The alarm occurs only once. * \row * \li Alarm.Repeating * \li The alarm is a repeating one, either daily, weekly on a given day or on * selected days. * \endtable * *The default value is Alarm.OneTime. */ UCAlarm::AlarmType UCAlarm::type() const { Q_D(const UCAlarm); return d->rawData.type; } void UCAlarm::setType(UCAlarm::AlarmType type) { Q_D(UCAlarm); if (d->rawData.type == type) { return; } d->rawData.type = type; d->rawData.changes |= AlarmData::Type; Q_EMIT typeChanged(); } /*! * \qmlproperty DaysOfWeek Alarm::daysOfWeek * The property holds the days of the week the alarm is scheduled. This property * can have only one day set for one time alarms and multiple days for repeating * alarms. * The following flags can be set: * \table * \header * \li {3, 1} Alarm.DayOfWeek enum: * \header * \li Type * \li Value * \li Description * \row * \li Alarm.Monday * \li 0x01 * \li The alarm will kick on Mondays. * \row * \li Alarm.Tuesday * \li 0x02 * \li The alarm will kick on Tuesdays. * \row * \li Alarm.Wednesday * \li 0x04 * \li The alarm will kick on Wednesdays. * \row * \li Alarm.Thursday * \li 0x08 * \li The alarm will kick on Thursdays. * \row * \li Alarm.Friday * \li 0x10 * \li The alarm will kick on Fridays. * \row * \li Alarm.Saturday * \li 0x20 * \li The alarm will kick on Saturdays. * \row * \li Alarm.Sunday * \li 0x40 * \li The alarm will kick on Sundays. * \row * \li Alarm.AutoDetect * \li 0x80 * \li The alarm day will be detected from the alarm date. * \endtable * * The default value is Alarm.AutoDetect. */ UCAlarm::DaysOfWeek UCAlarm::daysOfWeek() const { Q_D(const UCAlarm); return d->rawData.days; } void UCAlarm::setDaysOfWeek(UCAlarm::DaysOfWeek days) { Q_D(UCAlarm); if (d->rawData.days == days) { return; } d->rawData.days = days; d->rawData.changes |= AlarmData::Days; Q_EMIT daysOfWeekChanged(); } /*! * \qmlproperty url Alarm::sound * The property holds the alarm's sound to be played when the alarm is triggered. * An empty url will mean to play the default sound. * * The defaul tvalue is an empty url. */ QUrl UCAlarm::sound() const { Q_D(const UCAlarm); return d->rawData.sound; } void UCAlarm::setSound(const QUrl &sound) { Q_D(UCAlarm); if (d->rawData.sound == sound) { return; } d->rawData.sound = sound; d->rawData.changes |= AlarmData::Sound; Q_EMIT soundChanged(); } /*! * \qmlproperty Error Alarm::error * The property holds the error code occurred during the last performed operation. * * \table * \header * \li Error code * \li Value * \li Description * \row * \li NoError * \li 0 * \li Successful operation completion. * \row * \li InvalidDate * \li 1 * \li The date specified for the alarm was invalid. * \row * \li EarlyDate * \li 2 * \li The date specified for the alarm is an earlier date than the current one. * \row * \li NoDaysOfWeek * \li 3 * \li The daysOfWeek parameter of the alarm was not specified. * \row * \li OneTimeOnMoreDays * \li 4 * \li The one-time alarm was set to be kicked in several days. * \row * \li InvalidEvent * \li 5 * \li The alarm event is invalid. * \row * \li AdaptationError * \li 100 * \li The error occurred in alarm adaptation layer. Adaptations may define * additional behind this value. * \endtable */ int UCAlarm::error() const { Q_D(const UCAlarm); return d->error; } /*! * \qmlproperty Status Alarm::status * The property holds the status of the last performed operation. It can take one * of the following values: * \table * \header * \li Status code * \li Value * \li Description * \row * \li Ready * \li 1 * \li Specifies either that the Alarm object is ready to perform any operation * or that the previous operation has been successfully completed. * \row * \li InProgress * \li 2 * \li Specifies that there is an operation pending on Alarm object. * \row * \li Fail * \li 3 * \li Specifies that the last alarm operation has failed. The failure code is * set in \l error property. * \endtable * * The notification signal has a parameter specifying the \a operation the status * refers to. The operation can take the following values: * \table * \header * \li Operation code * \li Description * \row * \li NoOperation * \li There is no operation pending. This may be set when an error occured * in the alarm adapters and the operation cannot be determined. * \row * \li Saving * \li The status reported refers to an operation requested through save(). * \row * \li Canceling * \li The status reported refers to an operation requested through cancel(). * \row * \li Reseting * \li The status reported refers to an operation requested through reset(). * \endtable * * For example an implementation which resets the alarm data whenever * the save or cancel operations succeed would look as follows: * * \qml * Alarm { * onStatusChanged: { * if (status !== Alarm.Ready) * return; * if ((operation > Alarm.NoOperation) && (operation < Alarm.Reseting)) { * reset(); * } * } * } * \endqml */ UCAlarm::Status UCAlarm::status() const { Q_D(const UCAlarm); return d->status; } /*! * \qmlmethod Alarm::save() * Updates or adds an alarm to the alarm collection. The operation aligns properties * according to the following rules: * \list * \li - the \l daysOfWeek will be set to the alarm day if the daysOfWeek was set * to Alarm.AutoDetect. * \li - if the \l daysOfWeek is set to a day other than the one specified in the \l date * field, the \l date will be moved ahead to match the day from the \l daysOfWeek. * \endlist * * The function will fail if * \list * \li - the \l date property is invalid * \li - for one time alarm, the \l date property falue is earlier than the current time * \li - the \l daysOfWeek property is set to multiple days for one time alarm * \endlist * * The operation is asynchronous, and its status is reported through the \l status * property. Further operations should wait till the previous operation is completed. * The operation result is stored in the \l error property. */ void UCAlarm::save() { Q_D(UCAlarm); if (d->status == InProgress) { qmlInfo(this) << UbuntuI18n::instance().tr("Alarm has a pending operation."); return; } d->error = NoError; d->status = Ready; UCAlarm::Error result = d->checkAlarm(); if (result != UCAlarm::NoError) { d->_q_syncStatus(Saving, Fail, result); } else { if (d->createRequest()) { d->request->save(d->rawData); } } } /*! * \qmlmethod Alarm::cancel() * The function removes the alarm from the collection. The function will fail * for alarms which are not yet registered to the collection. * * The operation is asynchronous, and its status is reported through the \l status * property. Further operations should wait till the previous operation is completed. * The operation result is stored in the \l error property. */ void UCAlarm::cancel() { Q_D(UCAlarm); if (d->status == InProgress) { qmlInfo(this) << UbuntuI18n::instance().tr("Alarm has a pending operation."); return; } d->error = NoError; d->status = Ready; if (d->createRequest()) { d->request->remove(d->rawData); } } /*! * \qmlmethod Alarm::reset() * The function resets the alarm properties to its defaults. After this call the * object can be used to create a new alarm event. * * \b Note: do not call this function on alarm objects retrieved from AlarmModel, as * calling it will result in the model being out of sync from the alarm database. */ void UCAlarm::reset() { Q_D(UCAlarm); d->_q_syncStatus(Reseting, InProgress, NoError); d->rawData = AlarmData(); d->setDefaults(); d->rawData.changes = AlarmData::AllFields; d->_q_syncStatus(Reseting, Ready, NoError); } #include "moc_ucalarm.cpp" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucstatesaver.h0000644000015301777760000000361612321005637031225 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef UCSTATESAVER_H #define UCSTATESAVER_H #include #include class UCStateSaverAttachedPrivate; class UCStateSaverAttached : public QObject { Q_OBJECT Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged) public: UCStateSaverAttached(QObject *attachee); ~UCStateSaverAttached(); // getter/setter bool enabled() const; void setEnabled(bool v); QString properties() const; void setProperties(const QString &list); Q_SIGNALS: void enabledChanged(); void propertiesChanged(); private: Q_DECLARE_PRIVATE(UCStateSaverAttached) QScopedPointer d_ptr; Q_PRIVATE_SLOT(d_func(), void _q_init()) Q_PRIVATE_SLOT(d_func(), void _q_save()) Q_PRIVATE_SLOT(d_func(), void _q_globalEnableChanged(bool)) }; class UCStateSaver : public QObject { Q_OBJECT public: static UCStateSaverAttached *qmlAttachedProperties(QObject *attachee) { return new UCStateSaverAttached(attachee); } }; QML_DECLARE_TYPEINFO(UCStateSaver, QML_HAS_ATTACHED_PROPERTIES) #endif // UCSTATESAVER_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/qquickmimedata.cpp0000644000015301777760000002011312321005637032035 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include #include #include #include #include #include "qquickmimedata.h" #include /*! * \qmltype MimeData * \instantiates QQuickMimeData * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief MimeData type provides interface to access and store data to the * Clipboard. * */ QQuickMimeData::QQuickMimeData(QObject *parent) : QObject(parent), m_refData(false), m_mimeData(new QMimeData) { } QQuickMimeData::QQuickMimeData(const QMimeData *mimeData, bool refData, QObject *parent) : QObject(parent), m_refData(refData), m_mimeData(const_cast(mimeData)) { } QQuickMimeData::~QQuickMimeData() { // if the clipboard doesn't own the MimeData yet, delete it if (QGuiApplication::clipboard()->mimeData(QClipboard::Clipboard) != m_mimeData) delete m_mimeData; m_mimeData = 0; } /*! * \internal * Updates the internal MIME data from the clipboard. */ void QQuickMimeData::fromMimeData(const QMimeData *data) { // copy if (!data || (m_mimeData == data)) return; if (!m_refData) delete m_mimeData; m_mimeData = const_cast(data); } /* * This function is called when a standalone MimeData instance is passed as parameter to push() */ QMimeData *QQuickMimeData::toMimeData() { QMimeData *ret = m_mimeData; if (!m_refData) { m_mimeData = new QMimeData; // copy data so we keep the properties as they were Q_FOREACH(const QString &format, ret->formats()) { m_mimeData->setData(format, ret->data(format)); } // set teh color separately m_mimeData->setColorData(ret->colorData()); } return ret; } /*! * \qmlproperty list MimeData::format * Returns a list of formats supported by the object. This is a list of MIME * types for which the object can return suitable data. The formats in the list * are in a priority order. * * \sa data */ QStringList QQuickMimeData::formats() const { return (m_mimeData) ? m_mimeData->formats() : QStringList(); } /*! * \qmlproperty string MimeData::text * Contains a plain text (MIME type text/plain) representation of the data. */ QString QQuickMimeData::text() const { return m_mimeData ? m_mimeData->text() : QString(); } void QQuickMimeData::setText(const QString &text) { if (!m_refData) { m_mimeData->setText(text); Q_EMIT textChanged(); } } /*! * \qmlproperty string MimeData::html * Contains a string if the data stored in the object is HTML (MIME type text/html); * otherwise contains an empty string. */ QString QQuickMimeData::html() const { return m_mimeData ? m_mimeData->html() : QString(); } void QQuickMimeData::setHtml(const QString &html) { if (!m_refData) { m_mimeData->setHtml(html); Q_EMIT htmlChanged(); } } /*! * \qmlproperty list MimeData::urls * Contains a list of URLs contained within the MIME data object. URLs correspond * to the MIME type text/uri-list. */ QList QQuickMimeData::urls() const { return m_mimeData ? m_mimeData->urls() : QList(); } void QQuickMimeData::setUrls(const QList &urls) { if (!m_refData) { m_mimeData->setUrls(urls); Q_EMIT urlsChanged(); } } /*! * \qmlproperty color MimeData::color */ QColor QQuickMimeData::color() const { return (m_mimeData) ? qvariant_cast(m_mimeData->colorData()) : QColor(); } void QQuickMimeData::setColor(const QColor &color) { if (!m_refData) { m_mimeData->setColorData(color); Q_EMIT colorChanged(); } } /*! * \qmlproperty var MimeData::data * Reading the property returns a list of MIME type and data pairs representing * the data stored in the object. Users can set custom MIME types which are not * covered by the other properties. * * When setting the property value can take one of the following types: * \list * \li - string - the data will be set as \c{text/plain} MIME type, or * as \c{text/html} in case HTML tags are detected * \li - color - the data will be set as \c{application/x-color} MIME type * \li - list - the data will be set as \c{text/uri-list} * \li - list - the data will be set as \c{text/uri-list} in case the * first element of the list is a valid URL with scheme; otherwise if the list * size is even, the list will be set as pairs of (MIME type,data) * \li - list - same as list or list * \endlist */ QVariant QQuickMimeData::mimeData() const { if (!m_mimeData) return QVariant(); QVariantList ret; Q_FOREACH(const QString &format, formats()) { ret << format; ret << QVariant(m_mimeData->data(format)); } return QVariant::fromValue(ret); } static bool setMimeType(QMimeData *mimeData, QVariantList &mlist) { bool ret = false; QMimeDatabase db; for (int i = 0; i < mlist.length() / 2; i++) { QString type = mlist[2 * i].toString(); if (db.mimeTypeForName(type).isValid() || type == "application/x-color") { QByteArray data = mlist[2 * i + 1].toByteArray(); mimeData->setData(type, data); ret = true; } else if (type == "application/x-color") { // for some reason colors are not taken in other way... mimeData->setColorData(mlist[2 * i + 1]); ret = true; } } return ret; } void QQuickMimeData::setMimeData(const QVariant &mimeData) { if (m_refData) return; QMimeDatabase db; bool emitSignal = false; if (mimeData.type() == QVariant::List) { // the list can be a list of URLs or a list of (type, data) pairs or a // plain list formatted so that every 2k element describes a type and // every 2k+1 defines the data QVariantList mlist= mimeData.toList(); if (mlist[0].type() == QVariant::List) { Q_FOREACH(const QVariant &item, mlist) { // should not have more than two elements QVariantList block = item.toList(); if (setMimeType(m_mimeData, block)) emitSignal = true; } } else { QUrl url(mlist[0].toUrl()); if (!url.scheme().isEmpty()) { // we have a list or URLs, push them QList ulist; Q_FOREACH(const QVariant &v, mlist) { ulist << v.toUrl(); } setUrls(ulist); emitSignal = true; } else if (!(mlist.length() % 2)) { // the count of the list is a pair number, so we might have the // mime (type,data) pairs emitSignal = setMimeType(m_mimeData, mlist); } } } else if (mimeData.type() == QVariant::Color){ // color must e handled separately m_mimeData->setColorData(mimeData); emitSignal = true; } else { // try to detect the mime data within the variant // text/plain, text/html and application/x-color types QByteArray data = mimeData.toByteArray(); QMimeType type = db.mimeTypeForData(mimeData.toByteArray()); if (type.isValid()) { m_mimeData->setData(type.name(), data); emitSignal = true; } else { qWarning() << "UNHANDLED" << mimeData; } } if (emitSignal) Q_EMIT dataChanged(); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/plugin.cpp0000644000015301777760000002247512321005637030351 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Juhapekka Piiroinen */ #include #include #include #include #include "plugin.h" #include "uctheme.h" #include #include "i18n.h" #include "listener.h" #include "ucunits.h" #include "ucscalingimageprovider.h" #include "ucqquickimageextension.h" #include "quickutils.h" #include "shapeitem.h" #include "inversemouseareatype.h" #include "qquickclipboard.h" #include "qquickmimedata.h" #include "thumbnailgenerator.h" #include "ucubuntuanimation.h" #include "ucfontutils.h" #include "ucarguments.h" #include "ucargument.h" #include "ucapplication.h" #include "ucalarm.h" #include "ucalarmmodel.h" #include "unitythemeiconprovider.h" #include "ucstatesaver.h" #include "ucurihandler.h" #include "ucmouse.h" #include "ucinversemouse.h" #include #include #include // Needed for unit tests Q_DECLARE_METATYPE(QList) /* * Type registration functions. */ static QObject *registerPickerPanel(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(scriptEngine) return UbuntuComponentsPlugin::registerQmlSingletonType(engine, "Ubuntu.Components", "Pickers/PickerPanel.qml"); } static QObject *registerClipboard(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) QQuickClipboard *clipboard = new QQuickClipboard; return clipboard; } static QObject *registerUCUbuntuAnimation(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) UCUbuntuAnimation *animation = new UCUbuntuAnimation(); return animation; } static QObject *registerUriHandler(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) UCUriHandler *uriHandler = new UCUriHandler(); return uriHandler; } static QObject *registerUbuntuColors(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(scriptEngine) return UbuntuComponentsPlugin::registerQmlSingletonType(engine, "Ubuntu.Components", "Colors/UbuntuColors.qml"); } QUrl UbuntuComponentsPlugin::baseUrl(const QStringList& importPathList, const char* uri) { /* FIXME: remove when migrating to Qt 5.1 and use QQmlExtensionPlugin::baseUrl() http://doc-snapshot.qt-project.org/qt5-stable/qtqml/qqmlextensionplugin.html#baseUrl */ QString pluginRelativePath = QString::fromUtf8(uri).replace(".", "/").prepend("/").append("/"); QString pluginPath; Q_FOREACH (QString importPath, importPathList) { pluginPath = importPath.append(pluginRelativePath); /* We verify that the directory ending in Ubuntu/Components contains the file libUbuntuComponents.so therefore proving it's the right directory. Ref.: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1197293 */ if (QFile(pluginPath + "libUbuntuComponents.so").exists()) { return QUrl::fromLocalFile(pluginPath); } } return QUrl(); } QObject *UbuntuComponentsPlugin::registerQmlSingletonType(QQmlEngine *engine, const char* uri, const char* qmlFile) { QUrl url = baseUrl(engine->importPathList(), uri).resolved(QUrl::fromLocalFile(qmlFile)); return QuickUtils::instance().createQmlObject(url, engine); } void UbuntuComponentsPlugin::registerWindowContextProperty() { setWindowContextProperty(QGuiApplication::focusWindow()); // listen to QGuiApplication::focusWindowChanged /* Ensure that setWindowContextProperty is called in the same thread (the main thread) otherwise it segfaults. Reference: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1205556 */ QGuiApplication* application = static_cast(QCoreApplication::instance()); QObject::connect(application, SIGNAL(focusWindowChanged(QWindow*)), this, SLOT(setWindowContextProperty(QWindow*)), Qt::ConnectionType(Qt::DirectConnection | Qt::UniqueConnection)); } void UbuntuComponentsPlugin::setWindowContextProperty(QWindow* focusWindow) { QQuickView* view = qobject_cast(focusWindow); if (view != NULL) { view->rootContext()->setContextProperty("window", view); } } void UbuntuComponentsPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("Ubuntu.Components")); qmlRegisterSingletonType(uri, 0, 1, "UbuntuColors", registerUbuntuColors); qmlRegisterUncreatableType(uri, 0, 1, "i18n", "Singleton object"); qmlRegisterExtendedType(uri, 0, 1, "QQuickImageBase"); qmlRegisterUncreatableType(uri, 0, 1, "UCUnits", "Not instantiable"); qmlRegisterType(uri, 0, 1, "Shape"); qmlRegisterType(uri, 0, 1, "InverseMouseArea"); qmlRegisterType(uri, 0, 1, "MimeData"); qmlRegisterSingletonType(uri, 0, 1, "Clipboard", registerClipboard); qmlRegisterSingletonType(uri, 0, 1, "UbuntuAnimation", registerUCUbuntuAnimation); qmlRegisterType(uri, 0, 1, "Arguments"); qmlRegisterType(uri, 0, 1, "Argument"); qmlRegisterType(); qmlRegisterType(uri, 0, 1, "Alarm"); qmlRegisterType(uri, 0, 1, "AlarmModel"); qmlRegisterType(uri, 0, 1, "StateSaver"); qmlRegisterType(); qmlRegisterSingletonType(uri, 0, 1, "UriHandler", registerUriHandler); qmlRegisterType(uri, 0, 1, "Mouse"); qmlRegisterType(uri, 0, 1, "InverseMouse"); // Needed for unit tests qRegisterMetaType >(); // register QML singletons qmlRegisterSingletonType(uri, 0, 1, "PickerPanel", registerPickerPanel); } void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { QQmlExtensionPlugin::initializeEngine(engine, uri); QQmlContext* context = engine->rootContext(); // register root object watcher that sets a global property with the root object // that can be accessed from any object context->setContextProperty("QuickUtils", &QuickUtils::instance()); UCTheme::instance().registerToContext(context); context->setContextProperty("i18n", &UbuntuI18n::instance()); ContextPropertyChangeListener *i18nChangeListener = new ContextPropertyChangeListener(context, "i18n"); QObject::connect(&UbuntuI18n::instance(), SIGNAL(domainChanged()), i18nChangeListener, SLOT(updateContextProperty())); QObject::connect(&UbuntuI18n::instance(), SIGNAL(languageChanged()), i18nChangeListener, SLOT(updateContextProperty())); // We can't use 'Application' because it exists (undocumented) context->setContextProperty("UbuntuApplication", &UCApplication::instance()); ContextPropertyChangeListener *applicationChangeListener = new ContextPropertyChangeListener(context, "UbuntuApplication"); QObject::connect(&UCApplication::instance(), SIGNAL(applicationNameChanged()), applicationChangeListener, SLOT(updateContextProperty())); // Give the application object access to the engine UCApplication::instance().setContext(context); context->setContextProperty("units", &UCUnits::instance()); ContextPropertyChangeListener *unitsChangeListener = new ContextPropertyChangeListener(context, "units"); QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), unitsChangeListener, SLOT(updateContextProperty())); // register FontUtils context->setContextProperty("FontUtils", &UCFontUtils::instance()); ContextPropertyChangeListener *fontUtilsListener = new ContextPropertyChangeListener(context, "FontUtils"); QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), fontUtilsListener, SLOT(updateContextProperty())); engine->addImageProvider(QLatin1String("scaling"), new UCScalingImageProvider); // register icon provider engine->addImageProvider(QLatin1String("theme"), new UnityThemeIconProvider); try { engine->addImageProvider(QLatin1String("thumbnailer"), new ThumbnailGenerator); } catch(std::runtime_error &e) { qDebug() << "Could not create thumbnailer: " << e.what(); } // Necessary for Screen.orientation (from import QtQuick.Window 2.0) to work QGuiApplication::primaryScreen()->setOrientationUpdateMask( Qt::PortraitOrientation | Qt::LandscapeOrientation | Qt::InvertedPortraitOrientation | Qt::InvertedLandscapeOrientation); registerWindowContextProperty(); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucfontutils.cpp0000644000015301777760000000555612321005637031433 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "ucfontutils.h" #include "ucunits.h" /*! * \qmltype FontUtils * \instantiates UCFontUtils * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief FontUtils is a \l {http://qt-project.org/doc/qt-5.0/qtqml/qqmlcontext.html#details} {context property}, * which provides utility functions for font manipulations. * * FontUtils cannot be instantiated and it is already available as a context * property, i.e. 'FontUtils' is an instance that can be used from anywhere in * the code. * * Example of a Label implementation which uses the default base scale for the font * size: * \qml * import QtQuick 2.0 * import Ubuntu.Components 0.1 * * Text { * property string fontSize: "medium" * font.pixelSize: FontUtils.sizeToPixels(fontSize) * } * \endqml * * Another example of a custom text input component exposing a fontSize property and a base * font unit size to scale its font: * \qml * import QtQuick 2.0 * import Ubuntu.Components 0.1 * * TextInput { * property string fontSize: "small" * property int baseFontUnits: units.dp(20) * font.pixelSize: FontUtils.modularScale(fontSize) * units.dp(baseFontUnits) * } * \endqml * */ /*! * \qmlmethod real FontUtils::sizeToPixels(string size) * The function calculates the pixel size of a given scale. The size scale can be * one of the strings specified at modularScale function. On failure returns 0. */ qreal UCFontUtils::sizeToPixels(const QString &size) { return modularScale(size) * UCUnits::instance().dp(14); } /*! * \qmlmethod real FontUtils::modularScale(string size) * The function returns the number interpretation of a given font scale. The scale * can have one of the following values: * \list * \li \b{xx-small} * \li \b{x-small} * \li \b{small} * \li \b{medium} * \li \b{large} * \li \b{x-large} * \endlist */ qreal UCFontUtils::modularScale(const QString &size) { if (size == "xx-small") { return 0.606; } else if (size == "x-small") { return 0.707; } else if (size == "small") { return 0.857; } else if (size == "medium") { return 1.0; } else if (size == "large") { return 1.414; } else if (size == "x-large") { return 1.905; } return 0.0; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/i18n.cpp0000644000015301777760000001462112321005637027624 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Tim Peeters */ #include "i18n.h" #include #include namespace C { #include } #include #include /*! * \qmltype i18n * \instantiates UbuntuI18n * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief i18n is a context property that provides internationalization support. * * i18n cannot be instantiated, and is already available as a context property. * It is based on \l {https://www.gnu.org/software/gettext/} {gettext}, and thus the standard gettext tools can be used for translating * a project. Example: * \qml * import QtQuick 2.0 * import Ubunut.Components 0.1 * * Item { * width: units.gu(40) * height: units.gu(50) * * Button { * anchors.centerIn: parent * text: i18n.tr("Press me") * } * } * \endqml */ UbuntuI18n::UbuntuI18n(QObject* parent) : QObject(parent) { /* * setlocale * category = LC_ALL: All types of i18n: LC_MESSAGES, LC_NUMERIC, LC_TIME * locale = "": Lookup the environment for $LC_ALL, $LC_* and $LANG in that order * Returns: for example en_US.utf8, da_DK or POSIX * * Note: $LANGUAGE is implicitly respected by gettext() calls and * defines the order of multiple locales */ m_language = setlocale(LC_ALL, ""); } /*! * \qmlproperty string i18n::domain * The gettext domain to be used for the translation. The default domain * is the applicationName specified in the application's \l MainView, or the empty string "" if * no applicationName was given or no \l MainView is used. * Use dtr() functions instead of tr() to use a different domain for a single translation * that ignores i18n.domain. */ QString UbuntuI18n::domain() const { return m_domain; } /*! * \qmlproperty string i18n::language * The language that is used for the translation. The default value is * the user's locale dending on $LC_ALL, $LC_MESSAGES and $LANG at the time * of running the application. See the gettext manual for details. */ QString UbuntuI18n::language() const { return m_language; } /** * \qmlmethod void i18n::bindtextdomain(string domain_name, string dir_name) * Specify that the domain_name message catalog can be found * in dir_name rather than in the system locale data base. */ void UbuntuI18n::bindtextdomain(const QString& domain_name, const QString& dir_name) { C::bindtextdomain(domain_name.toUtf8(), dir_name.toUtf8()); Q_EMIT domainChanged(); } void UbuntuI18n::setDomain(const QString &domain) { m_domain = domain; C::textdomain(domain.toUtf8()); /* Look for locale folder as per XDG basedir spec The default is /usr/share/locale if we don't set a folder We look for share/domain to pick correctly among multiple prefixes */ QString dataPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation, domain, QStandardPaths::LocateDirectory)); if (!dataPath.isEmpty()) { QDir dataDir(dataPath); if (dataDir.cdUp() && dataDir.cd("locale")) { QString localePath(dataDir.path()); C::bindtextdomain(domain.toUtf8(), localePath.toUtf8()); } } Q_EMIT domainChanged(); } void UbuntuI18n::setLanguage(const QString &lang) { m_language = lang; /* This is needed for LP: #1263163. LANGUAGE may be set to one or more languages for example "fi" or "sv:de". gettext prioritizes LANGUAGE over LC_ALL, LC_*, and LANG, so if the session has already set LANGUAGE, calls to gettext will only use that. We must override it here so that future calls to gettext are done in the new language. This only affects the current process. It does not override the user's session LANGUAGE. */ setenv("LANGUAGE", lang.toUtf8().constData(), 1); /* The inverse form of setlocale as used in the constructor, passing a valid locale string updates all category type defaults. */ setlocale(LC_ALL, lang.toUtf8()); Q_EMIT languageChanged(); } /*! * \qmlmethod string i18n::tr(string text) * Translate \a text using gettext and return the translation. */ QString UbuntuI18n::tr(const QString& text) { return QString::fromUtf8(C::gettext(text.toUtf8())); } /*! * \qmlmethod string i18n::tr(string singular, string plural, int n) * Translate the given input string \a singular or \a plural (depending on the number of items \a n) * using gettext. Should be called like this: * tr("%n file", "%n files", count) */ QString UbuntuI18n::tr(const QString &singular, const QString &plural, int n) { return QString::fromUtf8(C::ngettext(singular.toUtf8(), plural.toUtf8(), n)); } /*! * \qmlmethod string i18n::dtr(string domain, string text) * Translate \a text using gettext. Uses the specified domain \a domain instead of i18n.domain. */ QString UbuntuI18n::dtr(const QString& domain, const QString& text) { if (domain.isNull()) { return QString::fromUtf8(C::dgettext(NULL, text.toUtf8())); } else { return QString::fromUtf8(C::dgettext(domain.toUtf8(), text.toUtf8())); } } /*! * \qmlmethod string i18n::dtr(string domain, string singular, string plural, int n) * Translate the given text using gettext. Should be called like this: * tr(domain, "%n file", "%n files", count) * Uses \a domain for the domain instead of i18n.domain, and \a singular or \a plural * as input for the translation depending on the number of items \a n. */ QString UbuntuI18n::dtr(const QString& domain, const QString& singular, const QString& plural, int n) { if (domain.isNull()) { return QString::fromUtf8(C::dngettext(NULL, singular.toUtf8(), plural.toUtf8(), n)); } else { return QString::fromUtf8(C::dngettext(domain.toUtf8(), singular.toUtf8(), plural.toUtf8(), n)); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucalarm_p.h0000644000015301777760000000367312321005637030462 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef UCALARM_P_H #define UCALARM_P_H #include "ucalarm.h" #include "alarmmanager_p.h" #include #include class UCAlarmPrivate { Q_DECLARE_PUBLIC(UCAlarm) public: UCAlarmPrivate(UCAlarm *qq); ~UCAlarmPrivate(); static UCAlarmPrivate *get(UCAlarm *alarm) { return alarm->d_func(); } void setDefaults(); UCAlarm* q_ptr; AlarmRequest *request; AlarmData rawData; int error; UCAlarm::Status status; // utility functions static UCAlarm::DayOfWeek dayOfWeek(const QDateTime &dt); static inline bool isDaySet(int dayNumber, UCAlarm::DaysOfWeek days); static int firstDayOfWeek(UCAlarm::DaysOfWeek days); static int nextDayOfWeek(UCAlarm::DaysOfWeek days, int fromDay); static bool multipleDaysSet(UCAlarm::DaysOfWeek days); UCAlarm::Error checkAlarm(); UCAlarm::Error checkDow(); UCAlarm::Error checkOneTime(); UCAlarm::Error checkRepeatingWeekly(); bool createRequest(); // private slots void _q_syncStatus(int operation, int status, int error); }; inline bool UCAlarmPrivate::isDaySet(int dayNumber, UCAlarm::DaysOfWeek days) { return (days & (1 << (dayNumber - 1))) == (1 << (dayNumber - 1)); } #endif // UUALARM_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucunits.cpp0000644000015301777760000001325612321005637030542 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "ucunits.h" #include #include #include #include #include #include #define ENV_GRID_UNIT_PX "GRID_UNIT_PX" #define DEFAULT_GRID_UNIT_PX 8 static float getenvFloat(const char* name, float defaultValue) { QByteArray stringValue = qgetenv(name); bool ok; float value = stringValue.toFloat(&ok); return ok ? value : defaultValue; } /*! \qmltype Units \instantiates UCUnits \inqmlmodule Ubuntu.Components 0.1 \ingroup resolution-independence \brief Units of measurement for sizes, spacing, margin, etc. Units provides facilities for measuring UI elements in a variety of units other than just pixels. A global instance of Units is exposed as the \b{units} context property. Example usage: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 Item { width: units.gu(2) height: units.gu(5) } \endqml \sa {Resolution Independence} */ UCUnits::UCUnits(QObject *parent) : QObject(parent) { m_gridUnit = getenvFloat(ENV_GRID_UNIT_PX, DEFAULT_GRID_UNIT_PX); } /*! \qmlproperty real Units::gridUnit The number of pixels 1 grid unit corresponds to. */ float UCUnits::gridUnit() { return m_gridUnit; } void UCUnits::setGridUnit(float gridUnit) { m_gridUnit = gridUnit; Q_EMIT gridUnitChanged(); } /*! \qmlmethod real Units::dp(real value) Returns the number of pixels \a value density independent pixels correspond to. */ float UCUnits::dp(float value) { const float ratio = m_gridUnit / DEFAULT_GRID_UNIT_PX; if (value <= 2.0) { // for values under 2dp, return only multiples of the value return qRound(value * qFloor(ratio)); } else { return qRound(value * ratio); } } /*! \qmlmethod real Units::gu(real value) Returns the number of pixels \a value grid units correspond to. */ float UCUnits::gu(float value) { return qRound(value * m_gridUnit); } QString UCUnits::resolveResource(const QUrl& url) { if (url.isEmpty()) { return QString(); } QString path = QQmlFile::urlToLocalFileOrQrc(url); if (path.isEmpty()) { return QString(); } QFileInfo fileInfo(path); if (fileInfo.exists() && !fileInfo.isFile()) { return QString(); } QString prefix = fileInfo.dir().absolutePath() + QDir::separator() + fileInfo.baseName(); QString suffix = "." + fileInfo.completeSuffix(); /* Use file with expected grid unit suffix if it exists. For example, if m_gridUnit = 10, look for resource@10.png. */ path = prefix + suffixForGridUnit(m_gridUnit) + suffix; if (QFile::exists(path)) { return QString("1") + "/" + path; } /* No file with expected grid unit suffix exists. List all the files of the form fileBaseName@[0-9]*.fileSuffix and select the most appropriate one privileging downscaling high resolution assets over upscaling low resolution assets. The most appropriate file has a grid unit suffix greater than the target grid unit (m_gridUnit) yet as small as possible. If no file with a grid unit suffix greater than the target grid unit exists, then select one with a grid unit suffix as close as possible to the target grid unit. For example, if m_gridUnit = 10 and the available files are resource@9.png, resource@14.png and resource@18.png, the most appropriate file would be resource@14.png since it is above 10 and smaller than resource@18.png. */ QStringList nameFilters; nameFilters << fileInfo.baseName() + "@[0-9]*" + suffix; QStringList files = fileInfo.dir().entryList(nameFilters, QDir::Files); if (!files.empty()) { float selectedGridUnitSuffix = gridUnitSuffixFromFileName(files.first()); Q_FOREACH (const QString& fileName, files) { float gridUnitSuffix = gridUnitSuffixFromFileName(fileName); if ((selectedGridUnitSuffix >= m_gridUnit && gridUnitSuffix >= m_gridUnit && gridUnitSuffix < selectedGridUnitSuffix) || (selectedGridUnitSuffix < m_gridUnit && gridUnitSuffix > selectedGridUnitSuffix)) { selectedGridUnitSuffix = gridUnitSuffix; } } path = prefix + suffixForGridUnit(selectedGridUnitSuffix) + suffix; float scaleFactor = m_gridUnit / selectedGridUnitSuffix; return QString::number(scaleFactor) + "/" + path; } path = prefix + suffix; if (QFile::exists(path)) { return QString("1") + "/" + path; } return QString(); } QString UCUnits::suffixForGridUnit(float gridUnit) { return "@" + QString::number(gridUnit); } float UCUnits::gridUnitSuffixFromFileName(const QString& fileName) { QRegularExpression re("^.*@([0-9]*).*$"); QRegularExpressionMatch match = re.match(fileName); if (match.hasMatch()) { return match.captured(1).toFloat(); } else { return 0; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/plugin.pro0000644000015301777760000000433112321005637030356 0ustar pbusernogroup00000000000000unix { CONFIG += link_pkgconfig PKGCONFIG += gio-2.0 thumbnailer dbus-1 libnih-dbus } TEMPLATE = lib TARGET = ../UbuntuComponents QT += core-private qml qml-private quick quick-private dbus equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { QT += v8-private } CONFIG += qt plugin no_keywords QMAKE_CXXFLAGS += -Werror # QOrganizer QT += organizer #comment in the following line to disable traces #DEFINES += QT_NO_DEBUG_OUTPUT TARGET = $$qtLibraryTarget($$TARGET) uri = Ubuntu.Components HEADERS += plugin.h \ uctheme.h \ ucthemesettings.h \ i18n.h \ listener.h \ ucscalingimageprovider.h \ ucunits.h \ ucqquickimageextension.h \ quickutils.h \ shapeitemtexture.h \ shapeitem.h \ inversemouseareatype.h \ qquickclipboard.h \ qquickmimedata.h \ qquickclipboard_p.h \ ucubuntuanimation.h \ ucfontutils.h \ ucapplication.h \ ucarguments.h \ ucargument.h \ ucalarm.h \ ucalarm_p.h \ alarmmanager_p_p.h \ alarmmanager_p.h \ ucalarmmodel.h \ unitythemeiconprovider.h \ thumbnailgenerator.h \ alarmrequest_p.h \ alarmrequest_p_p.h \ adapters/alarmsadapter_p.h \ ucstatesaver.h \ statesaverbackend_p.h \ ucstatesaver_p.h \ ucurihandler.h \ ucinversemouse.h \ ucmouse.h \ unixsignalhandler_p.h SOURCES += plugin.cpp \ uctheme.cpp \ ucthemesettings.cpp \ i18n.cpp \ listener.cpp \ ucscalingimageprovider.cpp \ ucunits.cpp \ ucqquickimageextension.cpp \ quickutils.cpp \ shapeitem.cpp \ inversemouseareatype.cpp \ qquickclipboard.cpp \ qquickmimedata.cpp \ ucubuntuanimation.cpp \ ucfontutils.cpp \ ucapplication.cpp \ ucarguments.cpp \ ucargument.cpp \ ucalarm.cpp \ alarmmanager_p.cpp \ ucalarmmodel.cpp \ unitythemeiconprovider.cpp \ thumbnailgenerator.cpp \ alarmrequest_p.cpp \ ucstatesaver.cpp \ statesaverbackend_p.cpp \ ucurihandler.cpp \ ucmousefilters.cpp \ unixsignalhandler_p.cpp # adapters SOURCES += adapters/alarmsadapter_organizer.cpp # deployment rules for the plugin installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) target.path = $$installPath INSTALLS += target ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/shapeitemtexture.h0000644000015301777760000175734012321005637032127 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Loïc Molinari */ class QSGTexture; struct TextureData { const unsigned char* const data; QSGTexture* texture; int width; int height; int bytesPerPixel; float smallRadius; float mediumRadius; float gridUnit; float coordinate[6][16][2]; }; static const unsigned char shapeTextureHighData[256 * 128 * 4 + 1] = "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\1\0\0\377\31\0\0\3778\0\0\377" "T\0\0\377n\0\0\377\202\0\0\377\226\0\0\377\252\0\0\377\272\0\0\377\311\0" "\0\377\321\0\0\377\335\0\0\377\337\0\0\377\356\0\0\377\356\0\0\377\356\0" "\0\377\366\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\1\0\0\377\31\0\13\3778\0\30\377T\0$\377n\0/\377" "\202\0""8\377\226\0@\377\252\0H\377\272\0O\377\311\0U\377\321\0Y\377\335" "\0^\377\337\0^\377\356\0d\377\356\0d\377\356\0d\377\366\0g\377\377\0k\377" "\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0" "k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377" "\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377\377\0k\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\1\0\1\377\31\0\15\3778\0\35" "\377T\0,\377n\0""9\377\202\0D\377\226\0N\377\252\0Y\377\272\0a\377\311\0" "i\377\321\0m\377\335\0s\377\337\0t\377\356\0|\377\356\0|\377\356\0|\377\366" "\0\200\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0" "\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205" "\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377" "\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377" "\0\205\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\5\0\0\377\36\0\0\3772\0\0\377D\0\0\377U\0\0\377f\0\0\377" "f\0\0\377f\0\0\377u\0\0\377w\0\0\377w\0\0\377w\0\0\377w\0\0\377w\0\0\377" "w\0\0\377w\0\0\377w\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\5\0\2\377\36\0\15\3772\0\26\377D\0\35\377" "U\0%\377f\0,\377f\0,\377f\0,\377u\0""2\377w\0""3\377w\0""3\377w\0""3\377" "w\0""3\377w\0""3\377w\0""3\377w\0""3\377w\0""3\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\16\0\0\377A\0\0\377w\0\0\377" "\246\0\0\377\316\0\0\377\365\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\16\0\6\377A\0\34\377w\0""3\377\246" "\0F\377\316\0W\377\365\0g\377\377\0j\377\377\0j\377\377\0i\377\377\0h\377" "\377\0h\377\377\0g\377\377\0f\377\377\0f\377\377\0e\377\377\0e\377\377\0" "e\377\377\0d\377\377\0d\377\377\0d\377\377\0d\377\377\0c\377\377\0c\377\377" "\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377" "\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0" "c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\377\0c\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\16\0\7\377" "A\0\"\377w\0>\377\246\0W\377\316\0k\377\365\0\200\377\377\0\205\377\377\0" "\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205" "\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377" "\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377" "\0\205\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0" "\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204" "\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377" "\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\11\0\0\377>\0\0\377}\0\0\377\265\0\0\377\337\0\0\377\374\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\11\0\4\377>\0\33\377}\0""5\377\265\0M\377\337\0]\377\374\0h\377\377" "\0g\377\377\0e\377\377\0c\377\377\0a\377\377\0_\377\377\0^\377\377\0^\377" "\377\0]\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377\377" "\0\\\377\377\0\\\377\377\0\\\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\3776\0\0" "\377\203\0\0\377\310\0\0\377\374\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\3776\0\27\377\203\0""8\377\310\0U\377\374\0j\377\377\0i\377\377\0h\377\377" "\0g\377\377\0e\377\377\0c\377\377\0b\377\377\0`\377\377\0^\377\377\0\\\377" "\377\0Z\377\377\0Y\377\377\0W\377\377\0V\377\377\0T\377\377\0S\377\377\0" "R\377\377\0Q\377\377\0P\377\377\0P\377\377\0O\377\377\0O\377\377\0N\377\377" "\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377" "\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0" "N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\377\0N\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\3776\0\34\377\203\0D\377\310\0h\377\374\0" "\203\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\205\377\377\0\204" "\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377" "\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377" "\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0" "\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204" "\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377" "\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377" "\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0" "\204\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\3776\0\0\377\231\0\0\377\363\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\3776\0\27\377\231\0A\377\363\0d\377\377\0c\377\377\0[\377" "\377\0Q\377\377\0F\377\377\0=\377\377\0""7\377\377\0""3\377\377\0/\377\377" "\0+\377\377\0)\377\377\0(\377\377\0'\377\377\0%\377\377\0$\377\377\0$\377" "\377\0$\377\377\0$\377\377\0$\377\377\0$\377\377\0$\377\377\0$\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\30" "\0\0\377\177\0\0\377\334\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\30\0\12\377\177\0""6\377\334\0\\\377\377\0j\377\377\0h\377" "\377\0e\377\377\0b\377\377\0_\377\377\0\\\377\377\0X\377\377\0T\377\377\0" "P\377\377\0L\377\377\0I\377\377\0F\377\377\0C\377\377\0A\377\377\0>\377\377" "\0<\377\377\0:\377\377\0""8\377\377\0""6\377\377\0""5\377\377\0""4\377\377" "\0""3\377\377\0""3\377\377\0""2\377\377\0""1\377\377\0""1\377\377\0""0\377" "\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0" "\377\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377\377" "\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377\377\0""0\377" "\377\0""0\377\377\0""0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\30\0\15\377\177\0B\377\334\0s\377\377\0\205" "\377\377\0\205\377\377\0\205\377\377\0\204\377\377\0\204\377\377\0\204\377" "\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\203\377\377" "\0\203\377\377\0\203\377\377\0\203\377\377\0\203\377\377\0\202\377\377\0" "\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202" "\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377" "\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377" "\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0" "\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\202" "\377\377\0\202\377\377\0\202\377\377\0\202\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\0\377\251\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\14\377\251\0G\377\377\0" "d\377\377\0V\377\377\0B\377\377\0""1\377\377\0#\377\377\0\26\377\377\0\12" "\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\36\0\0\377\233\0\0\377\370" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\36\0\15" "\377\233\0B\377\370\0g\377\377\0h\377\377\0d\377\377\0`\377\377\0[\377\377" "\0U\377\377\0O\377\377\0H\377\377\0C\377\377\0=\377\377\0""8\377\377\0""3" "\377\377\0/\377\377\0+\377\377\0(\377\377\0$\377\377\0\"\377\377\0\40\377" "\377\0\35\377\377\0\33\377\377\0\31\377\377\0\30\377\377\0\27\377\377\0\26" "\377\377\0\25\377\377\0\24\377\377\0\23\377\377\0\23\377\377\0\22\377\377" "\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377" "\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22" "\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\377" "\0\22\377\377\0\22\377\377\0\22\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\36\0\20\377\233\0Q\377\370\0\201\377\377\0\205\377\377" "\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0" "\203\377\377\0\203\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\201" "\377\377\0\201\377\377\0\201\377\377\0\200\377\377\0\200\377\377\0\177\377" "\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377" "\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0" "\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177" "\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377" "\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377" "\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\377\0\177\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377>\0\0\377\357\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377>\0\33\377\357\1b\377" "\377\0T\377\377\0""8\377\377\0\34\377\377\0\11\377\377\0\1\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\5\0\0\377\177\0\0\377" "\366\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\5\0\2\377\177\0""6\377\366\0f\377\377\0g\377\377\0b\377\377\0[\377\377\0" "S\377\377\0K\377\377\0B\377\377\0:\377\377\0""2\377\377\0+\377\377\0$\377" "\377\0\36\377\377\0\31\377\377\0\25\377\377\0\21\377\377\0\16\377\377\0\14" "\377\377\0\13\377\377\0\11\377\377\0\7\377\377\0\6\377\377\0\5\377\377\0" "\4\377\377\0\4\377\377\0\3\377\377\0\2\377\377\0\2\377\377\0\1\377\377\0" "\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\5\0\3\377\177\0B\377\366\0\200\377\377\0\204\377\377\0" "\204\377\377\0\204\377\377\0\204\377\377\0\203\377\377\0\203\377\377\0\202" "\377\377\0\202\377\377\0\201\377\377\0\200\377\377\0\177\377\377\0\177\377" "\377\0\177\377\377\0~\377\377\0~\377\377\0}\377\377\0|\377\377\0|\377\377" "\0{\377\377\0{\377\377\0z\377\377\0z\377\377\0y\377\377\0y\377\377\0y\377" "\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0" "y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377" "\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377" "\377\0y\377\377\0y\377\377\0y\377\377\0y\377\377\0y\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377E\0\0\377\366\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377E\0\35\377\366\1`\377\377\0E\377\377\0\35\377" "\377\0\6\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377$\0\0\377\316\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377$\0\17\377\316\0V\377\377" "\0g\377\377\0b\377\377\0Z\377\377\0O\377\377\0D\377\377\0""9\377\377\0.\377" "\377\0$\377\377\0\33\377\377\0\24\377\377\0\16\377\377\0\12\377\377\0\7\377" "\377\0\4\377\377\0\2\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377$\0\23\377" "\316\0k\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\203\377\377\0" "\203\377\377\0\202\377\377\0\201\377\377\0\200\377\377\0\177\377\377\0\177" "\377\377\0}\377\377\0|\377\377\0{\377\377\0y\377\377\0y\377\377\0x\377\377" "\0v\377\377\0u\377\377\0t\377\377\0s\377\377\0s\377\377\0q\377\377\0p\377" "\377\0p\377\377\0o\377\377\0n\377\377\0n\377\377\0m\377\377\0m\377\377\0" "m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377" "\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377" "\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0m\377\377\0" "m\377\377\0m\377\377\0m\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\0\377\360" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\34\0\14\377\360\2^\377\377\0>\377\377\0\21\377\377\0\1\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "A\0\0\377\355\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377A\0\34\377\355\0b\377\377\0d\377\377\0\\\377\377" "\0P\377\377\0B\377\377\0""4\377\377\0&\377\377\0\33\377\377\0\22\377\377" "\0\13\377\377\0\6\377\377\0\3\377\377\0\1\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377A\0\"\377\355\0{\377\377" "\0\204\377\377\0\204\377\377\0\203\377\377\0\202\377\377\0\201\377\377\0" "\200\377\377\0\177\377\377\0~\377\377\0|\377\377\0z\377\377\0y\377\377\0" "v\377\377\0s\377\377\0r\377\377\0p\377\377\0m\377\377\0l\377\377\0j\377\377" "\0h\377\377\0g\377\377\0e\377\377\0d\377\377\0c\377\377\0b\377\377\0a\377" "\377\0a\377\377\0`\377\377\0_\377\377\0^\377\377\0^\377\377\0]\377\377\0" "]\377\377\0]\377\377\0]\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377" "\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377" "\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377\377\0\\\377" "\377\0\\\377\377\0\\\377\377\0\\\377\0\0\0\377\0\0\0\377\0\0\0\377\255\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\255\4I\377\377\0D\377\377\0\20\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377A\0\0\377\365\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377A\0\34\377\365\0d\377\377\0b\377\377\0V\377" "\377\0G\377\377\0""6\377\377\0%\377\377\0\27\377\377\0\15\377\377\0\7\377" "\377\0\3\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377A\0\"\377\365\0\177" "\377\377\0\204\377\377\0\203\377\377\0\202\377\377\0\201\377\377\0\177\377" "\377\0~\377\377\0|\377\377\0y\377\377\0w\377\377\0s\377\377\0p\377\377\0" "m\377\377\0j\377\377\0g\377\377\0c\377\377\0a\377\377\0^\377\377\0\\\377" "\377\0Z\377\377\0X\377\377\0W\377\377\0U\377\377\0S\377\377\0R\377\377\0" "Q\377\377\0P\377\377\0O\377\377\0N\377\377\0N\377\377\0M\377\377\0L\377\377" "\0L\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377" "\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0" "K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377\0K\377\377" "\0K\377\377\0K\377\377\0K\377\0\0\0\377\0\0\0\3771\0\0\377\376\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\3771\0\25\377" "\376\0T\377\377\0\35\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377.\0\0\377\365\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377.\0\23\377\365\0d\377\377\0`\377\377\0R\377\377\0@\377\377" "\0,\377\377\0\32\377\377\0\16\377\377\0\6\377\377\0\2\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377.\0\30\377\365\0\177\377\377\0\204" "\377\377\0\203\377\377\0\202\377\377\0\177\377\377\0~\377\377\0{\377\377" "\0x\377\377\0t\377\377\0p\377\377\0l\377\377\0g\377\377\0b\377\377\0^\377" "\377\0Z\377\377\0W\377\377\0S\377\377\0P\377\377\0M\377\377\0K\377\377\0" "H\377\377\0F\377\377\0E\377\377\0C\377\377\0B\377\377\0@\377\377\0@\377\377" "\0?\377\377\0>\377\377\0=\377\377\0<\377\377\0;\377\377\0;\377\377\0;\377" "\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0" ":\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377" "\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377\377\0:\377" "\377\0:\377\377\0:\377\0\0\0\377\0\0\0\377\233\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\233\10E\377" "\377\0""8\377\377\0\6\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\20\0\0\377\334\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\20\0\7\377\334\0Z\377\377\0_\377\377\0P\377\377\0<\377\377\0%\377" "\377\0\23\377\377\0\10\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\20\0\10\377\334\0r\377\377\0\204\377" "\377\0\202\377\377\0\200\377\377\0\177\377\377\0|\377\377\0x\377\377\0s\377" "\377\0m\377\377\0h\377\377\0b\377\377\0\\\377\377\0W\377\377\0Q\377\377\0" "M\377\377\0I\377\377\0E\377\377\0B\377\377\0?\377\377\0<\377\377\0:\377\377" "\0""8\377\377\0""6\377\377\0""5\377\377\0""4\377\377\0""2\377\377\0""2\377" "\377\0""1\377\377\0""0\377\377\0/\377\377\0/\377\377\0/\377\377\0/\377\377" "\0.\377\377\0.\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377" "\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377\0" "-\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377\0-\377\377" "\0-\377\377\0-\377\377\0-\377\377\0-\377\0\0\0\377\5\0\0\377\357\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\5" "\0\2\377\357\4V\377\377\0\35\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\234" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\234\0@\377\377\0a\377\377\0Q\377\377\0;\377" "\377\0#\377\377\0\20\377\377\0\6\377\377\0\2\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\234\0Q\377\377" "\0\203\377\377\0\202\377\377\0\200\377\377\0~\377\377\0y\377\377\0t\377\377" "\0n\377\377\0h\377\377\0`\377\377\0Y\377\377\0Q\377\377\0K\377\377\0E\377" "\377\0@\377\377\0<\377\377\0""9\377\377\0""5\377\377\0""3\377\377\0""0\377" "\377\0/\377\377\0-\377\377\0,\377\377\0+\377\377\0*\377\377\0)\377\377\0" ")\377\377\0)\377\377\0(\377\377\0(\377\377\0(\377\377\0'\377\377\0'\377\377" "\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377>\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377>\2\34\377\377\0C\377\377\0\11\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377>\0\0\377" "\376\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377>\0\32\377\376\0c\377\377\0T\377\377\0>\377\377" "\0$\377\377\0\17\377\377\0\5\377\377\0\1\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377>\0\40\377\376" "\0\202\377\377\0\202\377\377\0\177\377\377\0|\377\377\0x\377\377\0r\377\377" "\0j\377\377\0b\377\377\0X\377\377\0P\377\377\0H\377\377\0A\377\377\0;\377" "\377\0""6\377\377\0""2\377\377\0/\377\377\0,\377\377\0*\377\377\0)\377\377" "\0(\377\377\0'\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377v\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\0\0\0\377v\16<\377\377\0""2\377\377\0\1\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\305\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\305\0O\377\377\0Z\377\377\0D\377\377" "\0)\377\377\0\22\377\377\0\5\377\377\0\1\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\305" "\0f\377\377\0\202\377\377\0\177\377\377\0|\377\377\0w\377\377\0p\377\377" "\0g\377\377\0\\\377\377\0R\377\377\0H\377\377\0@\377\377\0""9\377\377\0""3" "\377\377\0/\377\377\0,\377\377\0)\377\377\0(\377\377\0'\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0" "\0\0\377\251\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\251\21N\377\377\0$\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377F\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377F\0\35\377\377\0`\377\377\0M" "\377\377\0""2\377\377\0\27\377\377\0\7\377\377\0\1\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377F\0$\377\377\0\202\377\377\0\177\377\377\0|\377\377\0w\377\377" "\0o\377\377\0e\377\377\0Y\377\377\0M\377\377\0B\377\377\0""9\377\377\0""2" "\377\377\0.\377\377\0*\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\0\0\0\377\332\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\332\12Q\377\377\0\30\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\261\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\261" "\0F\377\377\0V\377\377\0>\377\377\0!\377\377\0\13\377\377\0\2\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\261\0Z\377\377\0\200\377\377\0}\377\377\0" "x\377\377\0o\377\377\0d\377\377\0W\377\377\0K\377\377\0?\377\377\0""5\377" "\377\0/\377\377\0+\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\4\0\0\377\373\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\4\0\2\377\373" "\1H\377\377\0\13\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\0\377\375\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\34\0\14\377\375\0^\377\377\0K\377\377\0/\377\377\0\23\377\377\0\4" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\16\377\375\0\200\377" "\377\0\177\377\377\0y\377\377\0q\377\377\0f\377\377\0X\377\377\0K\377\377" "\0=\377\377\0""4\377\377\0-\377\377\0)\377\377\0(\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\37\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\37\2\17\377\377\0=\377\377\0\3\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377q\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377q\0-\377\377\0W\377\377\0>\377\377\0!\377\377" "\0\12\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377q\0:\377\377" "\0\177\377\377\0{\377\377\0s\377\377\0i\377\377\0[\377\377\0L\377\377\0>" "\377\377\0""3\377\377\0,\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\3779\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\3779\12!\377\377\0""6\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\306\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\306\3O\377\377\0N\377\377\0""2" "\377\377\0\25\377\377\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\306\3g\377\377\0}\377\377\0w\377\377\0m\377\377\0`\377\377\0Q" "\377\377\0A\377\377\0""4\377\377\0-\377\377\0)\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377O\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377O\20/\377\377\0""1\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\22\0\0\377\375\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\22\0\7\377\375\0" "[\377\377\0E\377\377\0&\377\377\0\15\377\377\0\1\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\0\0\0\377\0\0\0\377\22\0\11\377\375\0~\377\377\0z\377\377\0r\377\377" "\0e\377\377\0W\377\377\0E\377\377\0""8\377\377\0.\377\377\0)\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377_\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377_\25" ":\377\377\0-\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377R\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377R\0\40\377\377\0V\377\377\0:\377\377\0\35\377\377\0\7\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377R\0)\377\377\0}\377\377\0v\377" "\377\0l\377\377\0]\377\377\0M\377\377\0=\377\377\0""1\377\377\0*\377\377" "\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377o\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377o\26?\377\377\0)\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\220\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\0\0\0\377\0\0\0\377\220\3:\377\377\0N\377\377\0""1\377\377\0\24\377" "\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\220" "\3K\377\377\0z\377\377\0r\377\377\0e\377\377\0V\377\377\0E\377\377\0""5\377" "\377\0,\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\177\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\177\27E\377\377\0&\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "\0\0\0\377\307\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\307\7P\377\377\0G\377" "\377\0)\377\377\0\16\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\307\7i\377\377\0x\377\377\0m\377\377\0_\377\377\0N\377" "\377\0>\377\377\0""0\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\207\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\207" "\30H\377\377\0#\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\0\0\377\4\0\0\377\366\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\4" "\0\2\377\366\2Y\377\377\0@\377\377\0!\377\377\0\11\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\0\0\0\377\4\0\2\377\366\2z\377\377\0t\377" "\377\0h\377\377\0X\377\377\0G\377\377\0""8\377\377\0-\377\377\0(\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\222\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\222\30K\377\377\0\40\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377)\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377)\0\20\377\377\0U\377\377\0""9\377\377\0\33" "\377\377\0\5\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" ")\0\24\377\377\0z\377\377\0q\377\377\0c\377\377\0R\377\377\0A\377\377\0""3" "\377\377\0*\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\226\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\226\31L\377\377" "\0\36\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377R\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377R\1!\377\377\0" "O\377\377\0""3\377\377\0\25\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\0\0\377R\1*\377\377\0x\377\377\0m\377\377\0^\377\377" "\0M\377\377\0<\377\377\0/\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\242\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\242\27N\377\377\0\34\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377z\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\0\0\0\377z\11""7\377\377\0K\377\377\0-\377\377\0\20\377\377\0\1\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377z\11E\377\377\0" "v\377\377\0i\377\377\0Y\377\377\0H\377\377\0""8\377\377\0,\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\30N\377\377\0\32\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0" "\377\234\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\234\15G\377\377\0F\377" "\377\0(\377\377\0\15\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377\234\15Y\377\377\0s\377\377\0f\377\377\0U\377\377\0" "D\377\377\0""4\377\377\0*\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\245\30N\377\377\0\31\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\275\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\275\15P\377\377\0B\377\377\0#\377\377\0\12\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\275\15g\377" "\377\0p\377\377\0b\377\377\0Q\377\377\0@\377\377\0""1\377\377\0)\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\30N\377\377\0\31\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\332\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\332\11T\377\377\0" "=\377\377\0\37\377\377\0\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\0\0\377\332\11p\377\377\0m\377\377\0^\377\377\0M\377" "\377\0<\377\377\0/\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\245\30N\377\377\0\31\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\366\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\366\3U\377\377\0:\377\377\0\33\377\377\0\5\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\366\3v\377" "\377\0k\377\377\0\\\377\377\0J\377\377\0""9\377\377\0-\377\377\0'\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\30N\377\377\0\31\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\14\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\14\0\5\377\377\0R\377\377\0" """6\377\377\0\27\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\14\0\6\377\377\0u\377\377\0h\377\377\0X\377\377\0G\377" "\377\0""7\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\245\30N\377\377\0\31\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377%\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377%\0\17\377\377\0O\377\377\0""3\377\377\0\24\377\377\0\2\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377%\0\22\377\377\0" "s\377\377\0g\377\377\0V\377\377\0E\377\377\0""4\377\377\0*\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\31N\377\377\0\27" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\3777\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\3777\4\31\377\377\0M\377\377" "\0/\377\377\0\22\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\3777\4\37\377\377\0r\377\377\0d\377\377\0S\377\377\0B\377" "\377\0""2\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\245\30N\377\377\0\31\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377E\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377E\13%\377\377\0K\377\377\0-\377\377\0\20\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377E\13,\377\377\0p" "\377\377\0b\377\377\0Q\377\377\0@\377\377\0""1\377\377\0)\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\30N\377\377\0\31" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377T\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377T\17/\377\377\0I\377\377" "\0+\377\377\0\16\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377T\17""7\377\377\0o\377\377\0`\377\377\0O\377\377\0>\377" "\377\0/\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\245\30N\377\377\0\31\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377b\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377b\21""6\377\377\0G\377\377\0)\377\377\0\15\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377b\21@\377\377\0m\377" "\377\0^\377\377\0M\377\377\0;\377\377\0/\377\377\0'\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\30N\377\377\0\31\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377q\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377q\23=\377\377\0E\377\377\0'\377\377" "\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377q\23H\377\377\0l\377\377\0\\\377\377\0K\377\377\0:\377\377\0-\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\245\30N\377\377\0\31\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\177\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\177\24B\377\377\0D\377\377\0%\377\377\0\13\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\177\24O\377\377\0k\377\377\0" "[\377\377\0J\377\377\0""9\377\377\0,\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\233\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\233\33N\377\377\0\31\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\216\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\216\25H\377\377\0B\377\377\0$" "\377\377\0\12\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\216\25W\377\377\0i\377\377\0Z\377\377\0H\377\377\0""8\377" "\377\0,\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\226\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\226\32L\377\377\0\33\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\226\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\226\25J\377\377\0A\377\377\0\"\377\377\0\11\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\226\25Z\377" "\377\0h\377\377\0X\377\377\0G\377\377\0""6\377\377\0+\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\212\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\212\34K\377" "\377\0\35\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\242\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\242\25N\377" "\377\0?\377\377\0!\377\377\0\10\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\242\25_\377\377\0h\377\377\0W\377\377\0" "E\377\377\0""5\377\377\0*\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\207\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\207\33J\377\377\0\37\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\245\26P\377\377\0>\377\377\0\37\377\377\0" "\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\245\26a\377\377\0g\377\377\0W\377\377\0E\377\377\0""5\377\377\0*\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377v\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "v\36H\377\377\0!\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\255\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\255" "\26R\377\377\0=\377\377\0\36\377\377\0\7\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\255\26d\377\377\0f\377\377\0" "V\377\377\0D\377\377\0""4\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377f\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377f\35B\377\377\0$\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\264\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\264\24Q\377\377\0<\377\377\0\35\377\377" "\0\6\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\264\24e\377\377\0e\377\377\0U\377\377\0C\377\377\0""4\377\377\0" ")\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377V\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377V\34<\377\377\0(\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\270\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\270\24S\377\377\0;\377\377\0\35\377\377\0\6\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\270\24g\377\377\0d\377\377" "\0T\377\377\0B\377\377\0""3\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377E\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377E\32""4\377\377\0+\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\303\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\303\21S\377\377\0:\377\377\0\34\377\377" "\0\5\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\303\21h\377\377\0d\377\377\0S\377\377\0B\377\377\0""2\377\377\0" ")\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377(\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377(\30(\377\377\0/\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\303\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\303\22S\377\377\0:\377\377\0\33\377\377\0\5\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\303\22i\377\377\0c\377\377" "\0R\377\377\0A\377\377\0""2\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\12\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\12\17\23\377\377\0""5\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\16S\377\377\0""9\377\377\0" "\32\377\377\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\322\16k\377\377\0c\377\377\0Q\377\377\0@\377\377\0""2" "\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\377\352\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\4\4\377\352\11?\377\377\0\1\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\322\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\322\16S\377\377\0""8\377\377\0\31\377\377\0\4\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\16k\377" "\377\0b\377\377\0Q\377\377\0@\377\377\0""1\377\377\0)\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\275\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\275" "\31K\377\377\0\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\322\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\17S\377\377" "\0""7\377\377\0\31\377\377\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\322\17k\377\377\0b\377\377\0Q\377\377\0" "@\377\377\0""1\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\377\213\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\0\0\0\377\213#N\377\377\0\22\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\322\17S\377\377\0""6\377\377\0\30\377\377\0\4\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\322\17k\377\377\0b\377\377\0Q\377\377\0?\377\377\0""0\377\377\0(\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377V\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377V&D\377\377\0\37\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\322\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\17S\377" "\377\0""6\377\377\0\30\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\322\17k\377\377\0a\377\377\0P\377\377" "\0?\377\377\0""0\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\377\22\0\0\377\374\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\0\0\0\377\22!(\377\374\1,\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\322\17S\377\377\0""6\377\377\0\30\377\377\0\3\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322" "\17k\377\377\0a\377\377\0P\377\377\0>\377\377\0/\377\377\0(\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\272\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\7\7\377\272\34H\377\377\0\5\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\330\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\330\15S\377\377" "\0""6\377\377\0\27\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\330\15k\377\377\0a\377\377\0O\377\377\0" ">\377\377\0/\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\377\0\0\0\377V\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377V3N\377\377\0\26\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\341\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\341\12R\377\377\0""6\377\377\0\27\377\377\0\3\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\12l\377" "\377\0`\377\377\0O\377\377\0>\377\377\0/\377\377\0(\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\3\0\0\377\323\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\3#$" "\377\323\22""9\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\12R\377\377\0""5\377\377\0" "\27\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\341\12l\377\377\0`\377\377\0O\377\377\0=\377\377\0/\377" "\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377" "\0\0\0\377\0\0\0\377<\0\0\377\374\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\0\0\0\377\0\0\0\377\0\1\1\377\377\300\32(\377\343\14\23\377\375\1\3" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\341\13R\377\377\0""4\377\377\0\26\377\377\0" "\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\341\13l\377\377\0_\377\377\0N\377\377\0<\377\377\0/\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\7\0\0\377$\0\0\377" "6\0\0\377F\0\0\377W\0\0\377f\0\0\377f\0\0\377f\0\0\377t\0\0\377w\0\0\377" "w\0\0\377w\0\0\377w\0\0\377w\0\0\377w\0\0\377w\0\0\377w\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\11\11\377\0%%\377\0<<\377\0OO\377\0]]\377\7eg\377$Z" "b\3776S^\377FLY\377WET\377f?O\377f?O\377f?O\377t9J\377w8I\377w8I\377w8I\377" "w8I\377w8I\377w8I\377w8I\377w8I\377\341\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\341\13R\377\377\0""4\377\377\0\26\377\377\0\2\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\13l\377\377" "\0_\377\377\0N\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\3\3\377" "\0\17\17\377\0\26\26\377\0\35\35\377\0$$\377\0**\377\0**\377\0**\377\0""0" "0\377\0""11\377\0""11\377\0""11\377\0""11\377\0""11\377\0""11\377\0""11\377" "\0""11\377\341\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\13R\377\377" "\0""4\377\377\0\26\377\377\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\341\13k\377\377\0_\377\377\0M\377\377\0" "<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\5\0\3\377\36\0\20\3772\0\32\377D\0#\377U\0,\377f\0""5\377f\0""5" "\377f\0""5\377u\0=\377w\0>\377w\0>\377w\0>\377w\0>\377w\0>\377w\0>\377w\0" ">\377w\0>\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\341\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\341\13R\377\377\0""4\377\377\0\26\377\377\0" "\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\341\13k\377\377\0_\377\377\0M\377\377\0<\377\377\0/\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\11\0\5\377>\0\40\377}\0A\377\265\0^\377\337\0t\377\374\0\203\377\377" "\0\205\377\377\0\205\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0" "\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204" "\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\341\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\341\13R\377\377\0""4\377\377\0\26\377\377\0\2\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\13" "k\377\377\0_\377\377\0M\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\3776\0\34\377\231\0P\377\363\0" "\177\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\203" "\377\377\0\202\377\377\0\202\377\377\0\202\377\377\0\201\377\377\0\201\377" "\377\0\201\377\377\0\200\377\377\0\200\377\377\0\200\377\377\0\200\377\377" "\0\200\377\377\0\200\377\377\0\200\377\377\0\200\377\377\0\200\377\377\0" "\200\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\341\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\341\13R\377\377\0""4\377\377\0\26\377\377\0\2\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\341\13k\377\377\0_\377\377\0M\377\377\0<\377\377\0/\377\377\0'\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\34\0\17\377\251\0X\377\377\0\204\377\377\0" "\204\377\377\0\203\377\377\0\202\377\377\0\200\377\377\0\177\377\377\0~\377" "\377\0|\377\377\0z\377\377\0y\377\377\0x\377\377\0w\377\377\0v\377\377\0" "u\377\377\0u\377\377\0t\377\377\0t\377\377\0s\377\377\0s\377\377\0s\377\377" "\0s\377\377\0s\377\377\0s\377\377\0s\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\341\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\13R\377\377" "\0""4\377\377\0\26\377\377\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\341\13k\377\377\0_\377\377\0M\377\377\0" "<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377>\0\40\377\357\1}" "\377\377\0\204\377\377\0\202\377\377\0\177\377\377\0|\377\377\0y\377\377" "\0s\377\377\0n\377\377\0i\377\377\0d\377\377\0a\377\377\0^\377\377\0\\\377" "\377\0Z\377\377\0Y\377\377\0W\377\377\0W\377\377\0W\377\377\0V\377\377\0" "V\377\377\0V\377\377\0V\377\377\0V\377\377\0V\377\377\0V\377\377\0V\377\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\341\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\341\13R\377\377\0""4\377\377\0\26\377\377\0\2\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\13k\377" "\377\0_\377\377\0M\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "E\0$\377\366\1\200\377\377\0\202\377\377\0\177\377\377\0y\377\377\0q\377" "\377\0h\377\377\0^\377\377\0V\377\377\0N\377\377\0G\377\377\0B\377\377\0" ">\377\377\0;\377\377\0:\377\377\0""8\377\377\0""7\377\377\0""6\377\377\0" """5\377\377\0""5\377\377\0""4\377\377\0""4\377\377\0""4\377\377\0""4\377" "\377\0""4\377\377\0""4\377\377\0""4\377\377\0""4\377\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\341\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341" "\13R\377\377\0""4\377\377\0\26\377\377\0\2\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\13k\377\377\0_\377\377\0" "M\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\17\377\360\2~\377\377" "\0\201\377\377\0{\377\377\0q\377\377\0b\377\377\0S\377\377\0F\377\377\0<" "\377\377\0""4\377\377\0/\377\377\0*\377\377\0(\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\331\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\331\16S\377\377\0""5\377\377\0\26\377\377\0\2\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\331" "\16k\377\377\0_\377\377\0M\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\255" "\4^\377\377\0\200\377\377\0y\377\377\0i\377\377\0U\377\377\0A\377\377\0""4" "\377\377\0+\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\322\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\20T\377\377\0""5\377\377\0" "\26\377\377\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\322\20j\377\377\0_\377\377\0M\377\377\0<\377\377\0/\377" "\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377" "\0\0\0\3771\0\31\377\376\0\200\377\377\0y\377\377\0g\377\377\0M\377\377\0" """7\377\377\0+\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\322\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\20" "T\377\377\0""5\377\377\0\27\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\20k\377\377\0_\377\377\0M" "\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\377\0\0\0\377\233\10W\377\377\0{\377\377\0i\377\377" "\0L\377\377\0""4\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\322\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\322\17S\377\377\0""6\377\377\0\27\377\377\0\3\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\17" "j\377\377\0_\377\377\0N\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\5\0\3\377\357\4{\377\377" "\0q\377\377\0U\377\377\0""6\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\322\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\322\17S\377\377\0""6\377\377\0\27\377" "\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\322\17j\377\377\0_\377\377\0N\377\377\0<\377\377\0/\377\377" "\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377>\2" "\"\377\377\0y\377\377\0b\377\377\0A\377\377\0+\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\322\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\17S\377" "\377\0""6\377\377\0\30\377\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\322\17j\377\377\0_\377\377\0N\377\377" "\0<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\377v\16I\377\377\0r\377\377\0T\377\377\0""4\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\322\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\322\17S\377\377\0""6\377\377\0\30\377\377\0\3\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\17j\377\377" "\0_\377\377\0N\377\377\0<\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\0\0\0\377\251\21c\377\377\0h\377\377\0F\377" "\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\304\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\304\24T\377\377\0""6\377\377\0\30\377\377" "\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\304\24i\377\377\0`\377\377\0N\377\377\0=\377\377\0/\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\332\12q\377" "\377\0_\377\377\0<\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\303\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\303\24S\377\377\0" """7\377\377\0\31\377\377\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\303\24h\377\377\0`\377\377\0N\377\377\0" "=\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\4\0\2\377\373\1s\377\377\0W\377\377\0""5\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\271\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\271\26S\377\377\0""8\377\377\0\31\377\377\0\4\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\271\26g\377\377" "\0`\377\377\0N\377\377\0=\377\377\0/\377\377\0'\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\37\2\21\377\377\0o\377\377\0O\377\377\0/\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\264\30S\377\377\0""9\377\377\0\32\377\377" "\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\264\30f\377\377\0`\377\377\0O\377\377\0=\377\377\0/\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\3779\12&\377\377\0i\377\377" "\0H\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\256\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\256\30R\377\377\0:\377\377" "\0\33\377\377\0\5\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\256\30d\377\377\0`\377\377\0O\377\377\0>\377\377\0/" "\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377O\20""6" "\377\377\0e\377\377\0B\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\32" "R\377\377\0:\377\377\0\34\377\377\0\5\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\245\32b\377\377\0a\377\377\0O\377" "\377\0>\377\377\0/\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377_\25B\377\377\0a\377\377\0>\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\243\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\243\32R\377\377\0;\377\377\0\35\377\377\0\6\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\243\32b\377\377" "\0a\377\377\0P\377\377\0>\377\377\0/\377\377\0(\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377o\26K\377\377\0]\377\377\0;\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\226\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\226\34O\377\377\0<\377\377\0\35\377\377\0\6\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\226\34^\377\377\0a\377\377\0P\377\377\0?\377\377\0""0\377\377\0(\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\177\27S\377\377\0[\377" "\377\0""9\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\217\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\217\35N\377\377" "\0=\377\377\0\36\377\377\0\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\217\35\\\377\377\0b\377\377\0Q\377\377\0" "?\377\377\0""0\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\207\30V\377\377\0Y\377\377\0""7\377\377\0&\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\200\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\200\37L\377\377\0>\377\377\0\37\377\377\0\7\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\200\37W\377" "\377\0b\377\377\0Q\377\377\0@\377\377\0""1\377\377\0(\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\222\30Z\377\377\0W\377\377\0""5\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0r\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377r!I\377\377\0?\377\377\0!\377\377\0\10" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377r!T\377\377\0b\377\377\0Q\377\377\0@\377\377\0""1\377\377\0)\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\226\31]\377\377\0U\377" "\377\0""4\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0c\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377c\40C\377\377\0A\377" "\377\0\"\377\377\0\11\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377c\40L\377\377\0c\377\377\0Q\377\377\0@\377\377\0" """2\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\242" "\27`\377\377\0T\377\377\0""3\377\377\0&\377\377\0&\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "U\37=\377\377\0B\377\377\0$\377\377\0\12\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377U\37E\377\377\0c\377\377\0R\377" "\377\0A\377\377\0""2\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\245\30b\377\377\0R\377\377\0""2\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0F\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377F\36""8\377\377\0D\377\377\0%\377\377\0\13\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377F\36=\377\377" "\0d\377\377\0S\377\377\0B\377\377\0""2\377\377\0)\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\245\30`\377\377\0Q\377\377\0""1\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\3778\33""0\377\377\0E\377\377\0'\377\377\0\14" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\3778\33""4\377\377\0d\377\377\0T\377\377\0B\377\377\0""3\377\377\0)\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\30`\377\377\0P\377" "\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0&\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377&\31'\377\377\0G\377" "\377\0(\377\377\0\15\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377&\31*\377\377\0e\377\377\0U\377\377\0C\377\377\0" """4\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245" "\30`\377\377\0P\377\377\0/\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\16\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\16\26" "\33\377\377\0I\377\377\0+\377\377\0\16\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\16\26\34\377\377\0f\377\377\0" "V\377\377\0D\377\377\0""4\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\245\30`\377\377\0O\377\377\0/\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\367\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\20\20\377\367\3L\377\377\0-\377\377\0\20\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\20\20" "\377\367\3g\377\377\0W\377\377\0E\377\377\0""5\377\377\0*\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\245\30`\377\377\0O\377\377\0/\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\377\334\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\0\6\6\377\334\16P\377\377\0/\377" "\377\0\22\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\6\6\377\334\16h\377\377\0W\377\377\0E\377\377\0""5\377\377" "\0*\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\245\31`\377" "\377\0M\377\377\0/\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\377\277\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\277" "\32U\377\377\0""2\377\377\0\24\377\377\0\2\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\277\32h\377\377\0X\377\377\0G" "\377\377\0""6\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\245\30_\377\377\0M\377\377\0/\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\237\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\237\"U\377\377\0""6\377\377\0\27\377\377\0\3\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\237\"c\377" "\377\0Z\377\377\0H\377\377\0""8\377\377\0,\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\245\30_\377\377\0N\377\377\0/\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377|\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377|)R\377\377\0:\377\377\0\33\377\377\0\5" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "|)]\377\377\0[\377\377\0J\377\377\0""9\377\377\0,\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\245\30`\377\377\0O\377\377\0/\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377U\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377U+H\377\377\0=\377\377\0\37\377\377\0\7" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "U+O\377\377\0\\\377\377\0K\377\377\0:\377\377\0-\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\245\30`\377\377\0O\377\377\0/\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377,*:\377\377\0A\377\377\0#\377\377\0\12" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" ",*=\377\377\0^\377\377\0L\377\377\0;\377\377\0/\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\245\30`\377\377\0O\377\377\0/\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\5\0\0" "\377\370\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\0\0\0\377\5\"$\377\370\3G\377\377\0(\377\377" "\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\5\"$\377\370\3`\377\377\0N\377\377\0=\377\377\0/\377\377\0(\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\233\33^\377\377\0O\377\377\0/\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\377\0\0\0\377\312\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\22\22\377\312\26Q\377\377" "\0-\377\377\0\20\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\22\22\377\312\26d\377\377\0Q\377\377\0?\377\377\0""1" "\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\226\32[\377\377\0" "O\377\377\0/\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\377\0\0\0\377\224\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\2\2\377" "\224+Y\377\377\0""3\377\377\0\25\377\377\0\3\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377\0\2\2\377\224+d\377\377\0S\377\377\0A" "\377\377\0""2\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\212" "\34Y\377\377\0P\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377W\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377W7T\377\377\0""9\377\377\0\32\377\377\0\5\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377W7Z\377\377\0V\377" "\377\0D\377\377\0""4\377\377\0*\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\207\33V\377\377\0Q\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\25\0\0\377\376\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\0\0\0\377\0\0\0\377\25""8?\377\376\0?\377\377\0!\377\377\0\10\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\25""8A\377" "\376\0X\377\377\0F\377\377\0""6\377\377\0+\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377v\36R\377\377\0Q\377\377\0""1\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\313" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0$$\377\313\25N\377\377\0(\377\377\0\15\377" "\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0$$" "\377\313\25]\377\377\0J\377\377\0""9\377\377\0-\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377f\35K\377\377\0S\377\377\0""2\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" "w\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\11\11\377w8\\\377\377\0""1\377\377\0\24\377" "\377\0\3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\11" "\11\377w8d\377\377\0M\377\377\0<\377\377\0/\377\377\0(\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377V\34C\377\377\0T\377\377\0""3\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377!\0" "\0\377\375\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377!IT\377\375\1;\377\377\0\34\377\377\0" "\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "!IV\377\375\1Q\377\377\0@\377\377\0""1\377\377\0)\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377E\32""9\377\377\0V\377\377\0""4\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\270\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0""11\377\270\35N\377\377\0&\377\377\0\14" "\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" """11\377\270\35Z\377\377\0C\377\377\0""4\377\377\0*\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377(\30*\377\377\0W\377\377\0""6\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377M\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\16\16\377MIa\377\377\0""1\377\377\0\25\377" "\377\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\16\16" "\377MId\377\377\0H\377\377\0""8\377\377\0,\377\377\0'\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\12\17\24\377\377\0Z\377\377\0""8\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\1\0\0\377\315\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\1LL\377\315\25F\377\377\0\40\377\377" "\0\11\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\1LL\377\315\25R\377\377\0<\377\377\0/\377\377\0)\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0" "\4\4\377\352\11]\377\377\0:\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "F\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\40\40\377FL`\377\377\0-\377\377\0\22\377\377\0" "\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\40\40\377FL" "c\377\377\0A\377\377\0""3\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\275" "\31`\377\377\0<\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\247\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0TT\377\247$L\377\377\0\40\377\377\0\13\377\377" "\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0TT\377\247$R" "\377\377\0""7\377\377\0,\377\377\0(\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\213#Y\377\377" "\0@\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\25\0\0\377\343" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\35\35\377\25`f\377\343\14""8\377\377\0\26\377\377\0\7\377\377" "\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\35\35\377\25`f\377\343\14" "B\377\377\0""0\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377V&I\377\377\0E\377\377\0" ")\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\3778\0\0\377\371\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0EE\3778Ra\377\371\2)\377\377\0\21\377\377\0\5\377\377\0\1\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0EE\3778Ra\377\371\2""6\377\377\0,\377\377" "\0(\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\377\22!)\377\374\1L\377\377\0.\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377N\0\0\377\371\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\11\11\377\0]]\377NI\\\377" "\371\2$\377\377\0\16\377\377\0\4\377\377\0\1\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\11\11\377\0]]\377NI[\377\371\2""1\377\377\0)\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\7\7\377\272" "\34Y\377\377\0""3\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377M\0\0\377\363\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\27\27\377\0gg\377MI[\377\363\5$\377\377" "\0\17\377\377\0\5\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\27\27\377\0gg\377" "MIZ\377\363\5""1\377\377\0)\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\0\0\0\377\0\0\0\377V3R\377\377\0:\377\377\0'\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377/\0\0\377" "\332\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\40" "\40\377\0gg\377/Va\377\332\17.\377\377\0\22\377\377\0\7\377\377\0\3\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\40\40\377\0gg\377/V`\377\332\17""5\377\377\0)\377\377" "\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\3#$\377" "\323\22I\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\12\0\0\377\217\0\0\377\373\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\40\40\377\0dd\377\12eg\377\217.F\377" "\373\2\33\377\377\0\14\377\377\0\5\377\377\0\2\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\40\40\377\0dd\377" "\12eg\377\217.G\377\373\2*\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0" "\377\0\0\0\377\0\1\1\377\377\375\1(\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\31\31\377u8T\377\377\0)\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377$\0\0\377\220\0\0\377\352\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\4\4\377\0;;\377\0gg\377\0ii\377$Za\377\220.B\377\352\11\40\377" "\377\0\20\377\377\0\12\377\377\0\5\377\377\0\2\377\377\0\1\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\4\4\377\0;;\377\0gg\377\0ii\377$Z`\377\220.E\377\352\11" "-\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0""00\377t9P\377\374\1)\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\3\0\0\377F\0\0\377\223\0\0\377\330" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\21\21\377\0GG\377\0hh\377\0ii\377\3hi\377FLX\377\223,@\377\330\20" "%\377\377\0\22\377\377\0\15\377\377\0\11\377\377\0\6\377\377\0\4\377\377" "\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\21\21\377\0GG\377\0hh\377\0ii\377\3hh\377FLW\377\223,B\377\330\20" """0\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0""00\377?NZ\377\325\21""2\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\34\0\0\377R\0\0\377\210" "\0\0\377\267\0\0\377\337\0\0\377\376\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\17\17\377" "\0;;\377\0``\377\0ii\377\0ii\377\0ii\377\34]b\377RGT\377\2101C\377\267\36" """2\377\337\15!\377\376\0\23\377\377\0\20\377\377\0\15\377\377\0\13\377\377" "\0\11\377\377\0\10\377\377\0\6\377\377\0\5\377\377\0\4\377\377\0\3\377\377" "\0\2\377\377\0\1\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\17\17\377\0;;\377\0``" "\377\0ii\377\0ii\377\0ii\377\34]a\377RGT\377\2101E\377\267\36""9\377\337" "\15.\377\376\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\32\32\377\3WX\377TFT\377" "\265\36""9\377\374\1'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\11\0\0\377*\0\0\377I\0\0" "\377e\0\0\377\177\0\0\377\223\0\0\377\247\0\0\377\273\0\0\377\313\0\0\377" "\331\0\0\377\342\0\0\377\356\0\0\377\356\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\1\1\377\0\35\35\377\0==\377\0YY\377\0ii\377\0ii\377\0ii" "\377\0ii\377\0ii\377\11eg\377*X_\377IKW\377e?N\377\1775F\377\223,>\377\247" "$7\377\273\34""0\377\313\25)\377\331\20$\377\342\14\37\377\356\7\33\377\356" "\7\31\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\21\377\377\0\21\377" "\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21" "\377\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377\377" "\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377\377\0\21\377" "\377\0\21\377\377\0\21\377\377\0\21\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\1\1\377" "\0\35\35\377\0==\377\0YY\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\11e" "f\377*X^\377IKV\377e?N\377\1775H\377\223,B\377\247$=\377\273\34""8\377\313" "\25""3\377\331\20""0\377\342\14.\377\356\7*\377\356\7*\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\1\1\377\0##\377\0KK\377\26_c\377" "YDR\377\222-C\377\300\32""7\377\343\14.\377\375\1'\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\21\0\0\377\21\0\0\377\21\0" "\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377" "\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0" "\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\21\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\14\14\377\0\"\"\377" "\0""88\377\0KK\377\0\\\\\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii" "\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii" "\377\0ii\377\0ii\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377" "\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377" "\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\14\14\377\0\"" "\"\377\0""88\377\0KK\377\0\\\\\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377" "\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377" "\0ii\377\0ii\377\0ii\377\21be\377\21be\377\21be\377\21be\377\21be\377\21" "be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21" "be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\21be\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\11\11\377\0%%\377\0<<\377\0OO\377\0]]\377\7ef" "\377$Z_\3776S[\377FLV\377WER\377f?N\377f?N\377f?N\377t9J\377w8J\377w8J\377" "w8J\377w8J\377w8J\377w8J\377w8J\377w8J\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\4\4\377\0\21\21\377\0\36\36\377" "\0**\377\0""44\377\0==\377\0EE\377\0MM\377\0TT\377\0YY\377\0]]\377\0bb\377" "\0bb\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377" "\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377" "\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\4\4\377\0\21\21\377\0\36\36\377\0**" "\377\0""44\377\0==\377\0EE\377\0MM\377\0TT\377\0YY\377\0]]\377\0bb\377\0" "bb\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0" "ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0" "ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0ii\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\3" "\3\377\0\17\17\377\0\26\26\377\0\35\35\377\0$$\377\0**\377\0**\377\0**\377" "\0""00\377\0""11\377\0""11\377\0""11\377\0""11\377\0""11\377\0""11\377\0" """11\377\0""11\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; // Half a high texture pixel in texture coordinate space [0, 1]. const float hh = 1.0f / 512.0f; // High resolution shape texture. TextureData shapeTextureHigh __attribute__((aligned(16))) = { shapeTextureHighData, NULL, 256, 128, 4, 32.0f, 64.0f, 18.0f, { { // Medium raw coords. { hh, 0.0f }, { 0.25f-hh, 0.0f }, { 0.25f-hh, 0.0f }, { hh, 0.0f }, { hh, 0.5f }, { 0.25f-hh, 0.5f }, { 0.25f-hh, 0.5f }, { hh, 0.5f }, { hh, 0.5f }, { 0.25f-hh, 0.5f }, { 0.25f-hh, 0.5f }, { hh, 0.5f }, { hh, 1.0f }, { 0.25f-hh, 1.0f }, { 0.25f-hh, 1.0f }, { hh, 1.0f } }, { // Medium idle coords. { 0.25f+hh, 0.0f }, { 0.5f-hh, 0.0f }, { 0.5f-hh, 0.0f }, { 0.25f+hh, 0.0f }, { 0.25f+hh, 0.5f }, { 0.5f-hh, 0.5f }, { 0.5f-hh, 0.5f }, { 0.25f+hh, 0.5f }, { 0.25f+hh, 0.5f }, { 0.5f-hh, 0.5f }, { 0.5f-hh, 0.5f }, { 0.25f+hh, 0.5f }, { 0.25f+hh, 1.0f }, { 0.5f-hh, 1.0f }, { 0.5f-hh, 1.0f }, { 0.25f+hh, 1.0f } }, { // Medium pressed coords. { 0.5f+hh, 0.0f }, { 0.75f-hh, 0.0f }, { 0.75f-hh, 0.0f }, { 0.5f+hh, 0.0f }, { 0.5f+hh, 0.5f }, { 0.75f-hh, 0.5f }, { 0.75f-hh, 0.5f }, { 0.5f+hh, 0.5f }, { 0.5f+hh, 0.5f }, { 0.75f-hh, 0.5f }, { 0.75f-hh, 0.5f }, { 0.5f+hh, 0.5f }, { 0.5f+hh, 1.0f }, { 0.75f-hh, 1.0f }, { 0.75f-hh, 1.0f }, { 0.5f+hh, 1.0f } }, { // Small raw coords. { 0.75f+hh, 0.0f+hh }, { 0.875f-hh, 0.0f+hh }, { 0.875f-hh, 0.0f+hh }, { 0.75f+hh, 0.0f+hh }, { 0.75f+hh, 0.25f-hh }, { 0.875f-hh, 0.25f-hh }, { 0.875f-hh, 0.25f-hh }, { 0.75f+hh, 0.25f-hh }, { 0.75f+hh, 0.25f+hh }, { 0.875f-hh, 0.25f+hh }, { 0.875f-hh, 0.25f+hh }, { 0.75f+hh, 0.25f+hh }, { 0.75f+hh, 0.5f-hh }, { 0.875f-hh, 0.5f-hh }, { 0.875f-hh, 0.5f-hh }, { 0.75f+hh, 0.5f-hh } }, { // Small idle coords. { 0.875f+hh, 0.0f+hh }, { 1.0f-hh, 0.0f+hh }, { 1.0f-hh, 0.0f+hh }, { 0.875f+hh, 0.0f+hh }, { 0.875f+hh, 0.25f-hh }, { 1.0f-hh, 0.25f-hh }, { 1.0f-hh, 0.25f-hh }, { 0.875f+hh, 0.25f-hh }, { 0.875f+hh, 0.25f+hh }, { 1.0f-hh, 0.25f+hh }, { 1.0f-hh, 0.25f+hh }, { 0.875f+hh, 0.25f+hh }, { 0.875f+hh, 0.5f-hh }, { 1.0f-hh, 0.5f-hh }, { 1.0f-hh, 0.5f-hh }, { 0.875f+hh, 0.5f-hh } }, { // Small pressed coords. { 0.75f+hh, 0.5f+hh }, { 0.875f-hh, 0.5f+hh }, { 0.875f-hh, 0.5f+hh }, { 0.75f+hh, 0.5f+hh }, { 0.75f+hh, 0.75f-hh }, { 0.875f-hh, 0.75f-hh }, { 0.875f-hh, 0.75f-hh }, { 0.75f+hh, 0.75f-hh }, { 0.75f+hh, 0.75f+hh }, { 0.875f-hh, 0.75f+hh }, { 0.875f-hh, 0.75f+hh }, { 0.75f+hh, 0.75f+hh }, { 0.75f+hh, 1.0f-hh }, { 0.875f-hh, 1.0f-hh }, { 0.875f-hh, 1.0f-hh }, { 0.75f+hh, 1.0f-hh } } } }; static const unsigned char shapeTextureLowData[128 * 64 * 4 + 1] = "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\3\0\0\377.\0\0\377]\0\0\377\203\0\0\377\242" "\0\0\377\273\0\0\377\317\0\0\377\340\0\0\377\353\0\0\377\362\0\0\377\366" "\0\0\377\374\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\3\0\1\377.\0\23\377]\0'\377\203\0""7\377\242\0C" "\377\273\0M\377\317\0U\377\340\0[\377\353\0`\377\362\0b\377\366\0d\377\374" "\0f\377\377\0g\377\377\0g\377\377\0g\377\377\0g\377\377\0g\377\377\0g\377" "\377\0g\377\377\0g\377\377\0g\377\377\0g\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\3" "\0\1\377.\0\30\377]\0""0\377\203\0D\377\242\0T\377\273\0a\377\317\0l\377" "\340\0u\377\353\0z\377\362\0~\377\366\0\200\377\374\0\203\377\377\0\204\377" "\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\377" "\0\204\377\377\0\204\377\377\0\204\377\377\0\204\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\21\0\0\377L\0\0\377x\0\0\377\223\0\0\377\245" "\0\0\377\262\0\0\377\266\0\0\377\273\0\0\377\273\0\0\377\273\0\0\377\273" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\21\0\7\377L\0" "\40\377x\0""1\377\223\0;\377\245\0A\377\262\0E\377\266\0F\377\273\0G\377" "\273\0G\377\273\0G\377\273\0G\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\6\0\0\377V\0\0\377\255\0\0\377\360\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\6\0\2\377V\0$\377\255\0H\377\360\0a\377" "\377\0c\377\377\0^\377\377\0X\377\377\0S\377\377\0N\377\377\0J\377\377\0" "G\377\377\0D\377\377\0B\377\377\0A\377\377\0?\377\377\0?\377\377\0?\377\377" "\0?\377\377\0?\377\377\0?\377\377\0?\377\377\0?\377\377\0?\377\377\0?\377" "\377\0?\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\6\0\3\377V\0-\377\255\0Z\377\360\0}\377\377\0\204\377\377\0\204" "\377\377\0\204\377\377\0\203\377\377\0\203\377\377\0\203\377\377\0\203\377" "\377\0\203\377\377\0\203\377\377\0\203\377\377\0\203\377\377\0\203\377\377" "\0\203\377\377\0\203\377\377\0\203\377\377\0\203\377\377\0\203\377\377\0" "\203\377\377\0\203\377\377\0\203\377\377\0\203\377\0\0\0\377\0\0\0\377\0" "\0\0\3771\0\0\377\263\0\0\377\374\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\3771\0\24\377\263\0D\377\374\0" "N\377\377\0""9\377\377\0$\377\377\0\32\377\377\0\26\377\377\0\24\377\377" "\0\23\377\377\0\22\377\377\0\22\377\377\0\22\377\377\0\22\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\1\0\0\377d\0\0\377\344\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\1\0\0\377d\0*\377\344\0\\" "\377\377\0^\377\377\0R\377\377\0D\377\377\0""6\377\377\0+\377\377\0\"\377" "\377\0\33\377\377\0\26\377\377\0\22\377\377\0\17\377\377\0\15\377\377\0\13" "\377\377\0\12\377\377\0\11\377\377\0\11\377\377\0\11\377\377\0\11\377\377" "\0\11\377\377\0\11\377\377\0\11\377\377\0\11\377\377\0\11\377\377\0\11\377" "\377\0\11\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\1\0\0\377" "d\0""4\377\344\0v\377\377\0\204\377\377\0\203\377\377\0\203\377\377\0\201" "\377\377\0\200\377\377\0\200\377\377\0\177\377\377\0~\377\377\0}\377\377" "\0|\377\377\0|\377\377\0|\377\377\0|\377\377\0|\377\377\0|\377\377\0|\377" "\377\0|\377\377\0|\377\377\0|\377\377\0|\377\377\0|\377\377\0|\377\377\0" "|\377\377\0|\377\0\0\0\377\0\0\0\377^\0\0\377\373\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0" "\377^\0&\377\373\0F\377\377\0\26\377\377\0\2\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\20\0\0\377" "\267\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\20\0\7\377\267\0J\377\377\0]\377\377\0G\377\377\0/\377\377\0\33\377" "\377\0\16\377\377\0\6\377\377\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\20\0\10\377\267\0_\377\377\0\203\377\377\0\202\377\377\0" "\201\377\377\0~\377\377\0|\377\377\0x\377\377\0u\377\377\0r\377\377\0o\377" "\377\0l\377\377\0j\377\377\0h\377\377\0g\377\377\0f\377\377\0e\377\377\0" "e\377\377\0d\377\377\0d\377\377\0d\377\377\0d\377\377\0d\377\377\0d\377\377" "\0d\377\377\0d\377\377\0d\377\377\0d\377\0\0\0\3772\0\0\377\373\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\3772\1\25\377\373\0<\377\377\0\4\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\13\0\0\377\312\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\13\0\4\377\312\0Q\377\377\0R\377\377\0""0\377\377\0" "\24\377\377\0\5\377\377\0\1\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\13\0\6\377\312\0i\377\377\0\203\377" "\377\0\200\377\377\0|\377\377\0v\377\377\0o\377\377\0g\377\377\0`\377\377" "\0Y\377\377\0T\377\377\0P\377\377\0M\377\377\0I\377\377\0H\377\377\0F\377" "\377\0D\377\377\0C\377\377\0B\377\377\0B\377\377\0B\377\377\0B\377\377\0" "B\377\377\0B\377\377\0B\377\377\0B\377\377\0B\377\377\0B\377\377\0B\377\0" "\0\0\377\262\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\262\2""9\377\377\0" "\11\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\241\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\241\0" "@\377\377\0N\377\377\0%\377\377\0\10\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\241\0S\377\377\0\202\377\377\0}\377\377\0u\377\377\0j\377\377" "\0]\377\377\0P\377\377\0F\377\377\0?\377\377\0""9\377\377\0""4\377\377\0" """1\377\377\0/\377\377\0-\377\377\0,\377\377\0+\377\377\0+\377\377\0*\377" "\377\0)\377\377\0)\377\377\0)\377\377\0)\377\377\0)\377\377\0)\377\377\0" ")\377\377\0)\377\377\0)\377\377\0)\377\377\0)\377\20\0\0\377\373\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\20\0\7\377\373\1/\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377@\0\0\377\376\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377\0\0\0\377@\0\32\377\376\0U\377\377\0'\377\377\0\6" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377@\0!\377\376\0\201\377\377" "\0{\377\377\0p\377\377\0^\377\377\0L\377\377\0=\377\377\0""3\377\377\0,\377" "\377\0(\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377G\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377G\7\"\377\377\0\25" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\275\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\275" "\0F\377\377\0""7\377\377\0\12\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377\0\0\0\377\275\0`\377\377\0|\377\377\0n\377\377\0X\377\377\0@\377\377" "\0""1\377\377\0*\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377v\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377v\2&\377\377\0\10\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377#\0\0\377\376\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\0\0\0\377#\0\16\377\376\0O\377\377\0\33\377\377\0\1\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377#\0\22\377\376\0~\377\377\0q\377" "\377\0Y\377\377\0>\377\377\0-\377\377\0'\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\225\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\225\3(\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377u\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377u\0,\377" "\377\0:\377\377\0\11\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377u\0;\377\377\0x\377\377\0b\377\377\0C\377\377\0.\377\377\0'\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\253\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\253\11""1\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\270\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\0\0\0\377\270\0?\377\377\0'\377\377\0\2\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\270\0Z\377\377" "\0n\377\377\0Q\377\377\0""3\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\273\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\273\13""4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\1\0\0\377\356\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\1\0\0\377\356\2L\377\377\0\30\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\1\0\0\377\356\2s\377\377\0c\377\377\0B\377\377" "\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\305\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\305\14""5\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\36\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\36\0\14\377\377\0" "D\377\377\0\16\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\36\0\17\377\377\0t\377\377\0X\377\377\0""7\377\377\0(\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\315\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\315\14""5\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377E\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377E\5\37\377\377\0""9\377\377\0\7\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377E\5'\377\377" "\0n\377\377\0N\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\322\14""3\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377e\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377e\5)\377\377\0""0\377\377\0\4\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377e\5""5\377\377\0g\377\377\0F\377\377" "\0,\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\322\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322" "\14""3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\200\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\200" "\0+\377\377\0(\377\377\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\200\0<\377\377\0a\377\377\0@\377\377\0)\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\322\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\14""3\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\226\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\226\1""1\377\377\0" "\"\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\226\1E\377\377\0]\377\377\0;\377\377\0'\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\322\14""3\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\245\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245\6:\377\377\0\35\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\245" "\6P\377\377\0X\377\377\0""7\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\322\14""3\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\264\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\264\11?\377\377\0\32\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\264\11X\377\377" "\0T\377\377\0""4\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\322\14""3\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\302" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\302\12D\377\377\0\27\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\302\12^\377\377\0Q\377\377\0" """2\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\313\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\313\15""3\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\315\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\315\12F\377\377\0\25\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\315\12b\377\377\0N\377\377\0""0\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\303\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\303" "\15""4\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\324\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\324" "\13G\377\377\0\22\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\324\13d\377\377\0M\377\377\0/\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\266\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\266\16""3\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\332\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\332\12F\377\377" "\0\21\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\332\12e\377\377\0K\377\377\0.\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\246\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\246\15""0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\341\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\10F\377\377\0\20\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341" "\10f\377\377\0J\377\377\0-\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\214\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\214\11'\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\350\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\350\7E\377\377\0\16\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350\7f\377\377\0H" "\377\377\0-\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377i\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377i\11#\377\377\0\2\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\350\7D\377\377\0\16\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\350\7f\377\377\0H\377\377\0,\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\3778\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\3778\22$\377\377" "\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\350\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350\7D\377\377\0" "\15\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\350\7f\377\377\0G\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\4\0\0" "\377\355\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\4\12\13\377\355\7\36\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\355\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\355\5D\377\377\0\15\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\355\5f\377" "\377\0F\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\212\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\212\32""0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\360\5C\377\377\0\14\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360\5f\377\377\0E\377\377\0" "+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\0\0\0\377\17\0\0\377\333\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\17\27\33\377\333\16\34\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\360\5C\377\377\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\360\5f\377\377\0E\377\377\0+\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\377\0\0\0\377\35\0\0\377\303\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377" "\35&,\377\303\30\"\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\360\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360\5C\377\377\0\14\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360" "\5e\377\377\0E\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377B\0\0\377\232\0\0\377\324\0\0\377\367\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\34\34\377B4<\377\232)/\377" "\324\21\31\377\367\3\5\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\360\5C\377\377\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\360\5e\377\377\0E\377\377\0+\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\1\0\0\377\26\0\0\377'\0\0\3773\0\0\3776\0\0\377;\0\0\377;\0\0\377" ";\0\0\377;\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\13" "\13\377\0\"\"\377\1""11\377\26""49\377'4;\37734<\37764<\377;4=\377;4=\377" ";4=\377;4=\377\360\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\360\5C\377\377\0\14\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360\5e\377\377" "\0D\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\21\0\11\377L\0'\377x\0>\377\223\0M\377\245\0U\377\262" "\0\\\377\266\0^\377\273\0a\377\273\0a\377\273\0a\377\273\0a\377\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\360\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360" "\5C\377\377\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\360\5e\377\377\0D\377\377\0+\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\377\0\0\0\377\0\0\0\3771\0\31\377\263\0]\377\374\0\202\377\377" "\0\201\377\377\0\200\377\377\0}\377\377\0|\377\377\0{\377\377\0z\377\377" "\0y\377\377\0y\377\377\0y\377\377\0y\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\360\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\360\5C\377\377\0\14\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\360\5e\377\377\0D\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\377\0" "\0\0\377^\0""1\377\373\0\200\377\377\0z\377\377\0n\377\377\0a\377\377\0U" "\377\377\0N\377\377\0J\377\377\0G\377\377\0F\377\377\0E\377\377\0E\377\377" "\0E\377\377\0E\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\356\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\356\6C\377\377\0\14\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\356\6e\377\377\0D\377\377" "\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\3772\1\33\377\373\0~\377\377\0j\377" "\377\0J\377\377\0""5\377\377\0+\377\377\0'\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\350\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350" "\10D\377\377\0\14\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\350\10d\377\377\0D\377\377\0+\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\377\262\2Z\377\377\0e\377\377\0""8\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\350\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350\7D\377\377\0\15\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350" "\7d\377\377\0E\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\20\0\11\377\373\1" "q\377\377\0=\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\350\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\350\7D\377\377\0\15\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\350\7d\377\377\0E\377\377\0+\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377G\7+\377\377\0]\377\377\0+\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\341\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\341\12E\377" "\377\0\16\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\341\12d\377\377\0E\377\377\0+\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "v\2""9\377\377\0I\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&" "\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\332\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\332\13E\377\377\0\16\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\332\13c\377" "\377\0E\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\225\3C\377\377\0<\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\324\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\324\14F\377\377\0\20\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\324\14a\377\377\0F\377\377\0+\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\253\11O\377\377\0""3\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\315\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\315\15F\377" "\377\0\21\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\315\15`\377\377\0G\377\377\0+\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\273\13U\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\303\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\303\17E\377\377\0\22\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\303\17]" "\377\377\0H\377\377\0,\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\305\14X\377\377\0.\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\264\20C\377\377\0\25\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\264\20Y\377\377\0H\377\377\0-\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\315\14Y\377\377\0,\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\246\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\246\17>\377\377" "\0\27\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\246\17R\377\377\0J\377\377\0-\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\14" "Y\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\227\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\227\15""8\377\377\0\32\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\227\15I\377\377" "\0K\377\377\0.\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\14X\377\377\0*\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\201\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\201\12""0\377\377\0\35\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\201\12>\377\377\0M\377\377\0/\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\322\14W\377\377\0*\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0f\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377f\13*\377\377\0!\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "f\13""5\377\377\0N\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\322\14V\377" "\377\0*\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0F\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377F\22)\377\377\0(\377\377\0\2\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377F\22""0\377\377\0Q\377\377\0""2\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\322\14W\377\377\0*\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\40\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\40\25" "\40\377\377\0""0\377\377\0\4\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\40\25#\377\377\0T\377\377\0""4\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\322\14W\377\377\0*\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\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\0\0\377\360\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\1\15\15\377\360\6;\377\377\0" "\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\1\15\15" "\377\360\6X\377\377\0""7\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\313\15U\377\377\0" "*\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\377\272\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\0\0\0\377\272\30F\377\377\0\15\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\272\30Y\377\377\0:\377\377" "\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\303\15T\377\377\0+\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377w\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377w\34<\377\377" "\0\27\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0" "\0\377w\34F\377\377\0?\377\377\0)\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\266\16P\377\377\0+\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" "&\0\0\377\376\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377&\".\377\376\0'\377\377\0\2\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\0\0\0\377&\"0\377\376\0F\377\377\0,\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\246\15I\377\377\0,\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\300\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\17\17\377\300\31A" "\377\377\0\11\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0" "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377" "\0\17\17\377\300\31R\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\214\11;\377\377\0.\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" "\0\0\0\377E\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0" "\0\377\0\0\0\377\0\0\0\377E3D\377\377\0\32\377\377\0\1\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377E3H\377\377\0""7\377\377\0'\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "i\11""0\377\377\0""0\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\247\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\34\34\377\247$B\377" "\377\0\12\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\34" "\34\377\247$L\377\377\0+\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\3778\22(\377\377\0""5\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" "\377\16\0\0\377\317\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\16?C\377\317\23.\377\377\0\6\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\16?C\377\317\23;\377\377\0'\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\4\12\14\377\355\7" "A\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\23\0\0\377\276\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\5\5\377\23MR\377\276\32""0\377\377" "\0\7\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\5\5\377\23MR\377\276" "\32;\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377" "\0\0\0\377\212\32>\377\377\0'\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377" "\0&\377\377\0&\377\377\0&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\2\0\0\377" "l\0\0\377\351\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377" "\0\0\377\377\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\10\10\377" "\2MN\377l\377\232)@\377\324\21""1\377\367\3(\377\377\0&\377" "\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0&\377\377\0" "&\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\4\0\0\377\10\0\0\377" "\10\0\0\377\10\0\0\377\10\0\0\377\10\0\0\377\10\0\0\377\10\0\0\377\10\0\0" "\377\10\0\0\377\10\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\3\3\377\0\26\26" "\377\0))\377\0""99\377\0FF\377\0PP\377\0YY\377\0__\377\0dd\377\0gg\377\0" "ii\377\4gh\377\10eg\377\10eg\377\10eg\377\10eg\377\10eg\377\10eg\377\10e" "g\377\10eg\377\10eg\377\10eg\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\3\3\377\0" "\26\26\377\0))\377\0""99\377\0FF\377\0PP\377\0YY\377\0__\377\0dd\377\0gg" "\377\0ii\377\4gh\377\10eg\377\10eg\377\10eg\377\10eg\377\10eg\377\10eg\377" "\10eg\377\10eg\377\10eg\377\10eg\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\13\13\377\0\"\"\377\1""11\377\26""47\377'4:\37734<\3776" "4<\377;4=\377;4=\377;4=\377;4=\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0"; // Half a low texture pixel in texture coordinate space [0, 1]. const float hl = 1.0f / 256.0f; // Low resolution shape texture. TextureData shapeTextureLow __attribute__((aligned(16))) = { shapeTextureLowData, NULL, 128, 64, 4, 16.0f, 32.0f, 9.0f, { { // Medium raw coords. { hl, 0.0f }, { 0.25f-hl, 0.0f }, { 0.25f-hl, 0.0f }, { hl, 0.0f }, { hl, 0.5f }, { 0.25f-hl, 0.5f }, { 0.25f-hl, 0.5f }, { hl, 0.5f }, { hl, 0.5f }, { 0.25f-hl, 0.5f }, { 0.25f-hl, 0.5f }, { hl, 0.5f }, { hl, 1.0f }, { 0.25f-hl, 1.0f }, { 0.25f-hl, 1.0f }, { hl, 1.0f } }, { // Medium idle coords. { 0.25f+hl, 0.0f }, { 0.5f-hl, 0.0f }, { 0.5f-hl, 0.0f }, { 0.25f+hl, 0.0f }, { 0.25f+hl, 0.5f }, { 0.5f-hl, 0.5f }, { 0.5f-hl, 0.5f }, { 0.25f+hl, 0.5f }, { 0.25f+hl, 0.5f }, { 0.5f-hl, 0.5f }, { 0.5f-hl, 0.5f }, { 0.25f+hl, 0.5f }, { 0.25f+hl, 1.0f }, { 0.5f-hl, 1.0f }, { 0.5f-hl, 1.0f }, { 0.25f+hl, 1.0f } }, { // Medium pressed coords. { 0.5f+hl, 0.0f }, { 0.75f-hl, 0.0f }, { 0.75f-hl, 0.0f }, { 0.5f+hl, 0.0f }, { 0.5f+hl, 0.5f }, { 0.75f-hl, 0.5f }, { 0.75f-hl, 0.5f }, { 0.5f+hl, 0.5f }, { 0.5f+hl, 0.5f }, { 0.75f-hl, 0.5f }, { 0.75f-hl, 0.5f }, { 0.5f+hl, 0.5f }, { 0.5f+hl, 1.0f }, { 0.75f-hl, 1.0f }, { 0.75f-hl, 1.0f }, { 0.5f+hl, 1.0f } }, { // Small raw coords. { 0.75f+hl, 0.0f+hl }, { 0.875f-hl, 0.0f+hl }, { 0.875f-hl, 0.0f+hl }, { 0.75f+hl, 0.0f+hl }, { 0.75f+hl, 0.25f-hl }, { 0.875f-hl, 0.25f-hl }, { 0.875f-hl, 0.25f-hl }, { 0.75f+hl, 0.25f-hl }, { 0.75f+hl, 0.25f+hl }, { 0.875f-hl, 0.25f+hl }, { 0.875f-hl, 0.25f+hl }, { 0.75f+hl, 0.25f+hl }, { 0.75f+hl, 0.5f-hl }, { 0.875f-hl, 0.5f-hl }, { 0.875f-hl, 0.5f-hl }, { 0.75f+hl, 0.5f-hl } }, { // Small idle coords. { 0.875f+hl, 0.0f+hl }, { 1.0f-hl, 0.0f+hl }, { 1.0f-hl, 0.0f+hl }, { 0.875f+hl, 0.0f+hl }, { 0.875f+hl, 0.25f-hl }, { 1.0f-hl, 0.25f-hl }, { 1.0f-hl, 0.25f-hl }, { 0.875f+hl, 0.25f-hl }, { 0.875f+hl, 0.25f+hl }, { 1.0f-hl, 0.25f+hl }, { 1.0f-hl, 0.25f+hl }, { 0.875f+hl, 0.25f+hl }, { 0.875f+hl, 0.5f-hl }, { 1.0f-hl, 0.5f-hl }, { 1.0f-hl, 0.5f-hl }, { 0.875f+hl, 0.5f-hl } }, { // Small pressed coords. { 0.75f+hl, 0.5f+hl }, { 0.875f-hl, 0.5f+hl }, { 0.875f-hl, 0.5f+hl }, { 0.75f+hl, 0.5f+hl }, { 0.75f+hl, 0.75f-hl }, { 0.875f-hl, 0.75f-hl }, { 0.875f-hl, 0.75f-hl }, { 0.75f+hl, 0.75f-hl }, { 0.75f+hl, 0.75f+hl }, { 0.875f-hl, 0.75f+hl }, { 0.875f-hl, 0.75f+hl }, { 0.75f+hl, 0.75f+hl }, { 0.75f+hl, 1.0f-hl }, { 0.875f-hl, 1.0f-hl }, { 0.875f-hl, 1.0f-hl }, { 0.75f+hl, 1.0f-hl } } } }; ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucurihandler.cpp0000644000015301777760000000567312321005637031541 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Loïc Molinari */ #include "ucurihandler.h" #include #include #include #include "statesaverbackend_p.h" UriHandlerObject::UriHandlerObject(UCUriHandler* uriHandler) : m_uriHandler(uriHandler) { } void UriHandlerObject::Open(const QStringList& uris, const QHash& platformData) { Q_UNUSED(platformData); Q_EMIT m_uriHandler->opened(uris); } /*! * \qmltype UriHandler * \instantiates UCUriHandler * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu * \brief Singleton signalling for opened URIs. * * UriHandler is a singleton handling opened URIs. The application can be signalled of opened URIs * through the opened signal. The content of the "APP_ID" environment variable is used to determine * the object path. If the D-Bus session bus is not connected or the "APP_ID" variable is not set or * empty, the handler stays uninitialized. * * Example of use: * * \qml * Connections { * target: UriHandler * onOpened: print(uris) * } * \endqml */ UCUriHandler::UCUriHandler() : m_uriHandlerObject(this) { QString objectPath; if (!QDBusConnection::sessionBus().isConnected()) { qWarning() << "UCUriHandler: D-Bus session bus is not connected, ignoring."; return; } // Get the object path based on the "APP_ID" environment variable. QByteArray applicationId = qgetenv("APP_ID"); if (applicationId.isEmpty()) { qWarning() << "UCUriHandler: Empty \"APP_ID\" environment variable, ignoring."; return; } char* path = nih_dbus_path(NULL, "", applicationId.constData(), NULL); objectPath = QString(path); nih_free(path); // Ensure handler is running on the main thread. QCoreApplication* instance = QCoreApplication::instance(); if (instance) { moveToThread(instance->thread()); } else { qWarning() << "UCUriHandler: Created before QCoreApplication, application may misbehave."; } QDBusConnection::sessionBus().registerObject( objectPath, &m_uriHandlerObject, QDBusConnection::ExportAllSlots); QDBusConnection::sessionBus().registerService("org.freedesktop.Application"); } /*! * \qmlsignal UriHandler::onOpened(list uris) * * The signal is triggered when URIs are opened. */ ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucapplication.h0000644000015301777760000000276312321005637031351 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #ifndef UBUNTU_COMPONENTS_APPLICATION_H #define UBUNTU_COMPONENTS_APPLICATION_H #include class QQmlContext; class QQmlEngine; class UCApplication : public QObject { Q_OBJECT Q_PROPERTY(QString applicationName READ applicationName WRITE setApplicationName NOTIFY applicationNameChanged) private: Q_DISABLE_COPY(UCApplication) explicit UCApplication(QObject* parent = 0); public: static UCApplication& instance() { static UCApplication instance; return instance; } // getter QString applicationName(); // setter void setContext(QQmlContext* context); void setApplicationName(const QString& applicationName); private: QQmlContext* m_context; Q_SIGNALS: void applicationNameChanged(); }; #endif // UBUNTU_COMPONENTS_I18N_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucstatesaver.cpp0000644000015301777760000002374212321005637031562 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ucstatesaver.h" #include "ucstatesaver_p.h" #include "statesaverbackend_p.h" #include "i18n.h" #include "quickutils.h" #include #include #include #include #include "private/qqmldata_p.h" #include "private/qqmlcontext_p.h" #include UCStateSaverAttachedPrivate::UCStateSaverAttachedPrivate(UCStateSaverAttached *qq, QObject *attachee) : q_ptr(qq) , m_attachee(attachee) , m_enabled(false) { } /* * Initializer slot. */ void UCStateSaverAttachedPrivate::_q_init() { m_id = qmlContext(m_attachee)->nameForObject(m_attachee); if (m_id.isEmpty()) { qmlInfo(m_attachee) << UbuntuI18n::instance().tr("Warning: attachee must have an ID. State will not be saved."); q_func()->setEnabled(false); return; } m_absoluteId = absoluteId(m_id); if (m_absoluteId.isEmpty()) { q_func()->setEnabled(false); return; } if (!StateSaverBackend::instance().registerId(m_absoluteId)) { qmlInfo(m_attachee) << UbuntuI18n::instance().tr("Warning: attachee's UUID is already registered, state won't be saved: %1").arg(m_absoluteId); m_absoluteId.clear(); q_func()->setEnabled(false); return; } restore(); } /* * Force state saver slot. */ void UCStateSaverAttachedPrivate::_q_save() { if (m_enabled && StateSaverBackend::instance().enabled() && !m_properties.isEmpty() && !m_absoluteId.isEmpty()) { StateSaverBackend::instance().save(m_absoluteId, m_attachee, m_properties); } } void UCStateSaverAttachedPrivate::_q_globalEnableChanged(bool enabled) { // sync component watchers signals watchComponent(enabled); } QString UCStateSaverAttachedPrivate::absoluteId(const QString &id) { QQmlContext *attacheeContext = qmlContext(m_attachee); QQmlContextData *cdata = QQmlContextData::get(attacheeContext); QQmlData *ddata = QQmlData::get(m_attachee); QString path = cdata->url.path().replace('/', '_') + ':' + QString::number(ddata->lineNumber) + ':' + QString::number(ddata->columnNumber) + ':' + id; QObject *parent = m_attachee->parent(); // check whether we have an "index" context property defined QVariant indexValue = attacheeContext->contextProperty("index"); if (indexValue.isValid() && (indexValue.type() == QVariant::Int)) { path += indexValue.toString(); } while (parent) { QString parentId = qmlContext(parent)->nameForObject(parent); QString className = QuickUtils::instance().className(parent); if (!parentId.isEmpty()) { path.prepend(className + '-' + parentId + ":"); } else { qmlInfo(parent) << UbuntuI18n::instance().tr("All the parents must have an id.\nState saving disabled for %1, class %2"). arg(path).arg(className); return QString(); } parent = parent->parent(); } return path; } void UCStateSaverAttachedPrivate::restore() { if (m_enabled && !m_absoluteId.isEmpty() && !m_properties.isEmpty()) { // load group StateSaverBackend::instance().load(m_absoluteId, m_attachee, m_properties); } } /* * */ void UCStateSaverAttachedPrivate::watchComponent(bool watch) { Q_Q(UCStateSaverAttached); if (!watch) { // disconnect to save processing time if no state save is needed QQmlComponentAttached *componentAttached = QQmlComponent::qmlAttachedProperties(m_attachee); QObject::disconnect(componentAttached, SIGNAL(completed()), q, SLOT(_q_init())); QObject::disconnect(&StateSaverBackend::instance(), SIGNAL(initiateStateSaving()), q, SLOT(_q_save())); } else { // re-connect to proceed with saving QQmlComponentAttached *componentAttached = QQmlComponent::qmlAttachedProperties(m_attachee); QObject::connect(componentAttached, SIGNAL(completed()), q, SLOT(_q_init())); QObject::connect(&StateSaverBackend::instance(), SIGNAL(initiateStateSaving()), q, SLOT(_q_save())); } } /*! * \qmltype StateSaver * \instantiates UCStateSaverAttached * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu-services * \brief Attached propertyes to save component property states. * * StateSaver attached object provides the ability to save component property values * that can be restored after an inproper application close. The properties subject * of serialization must be given in the \l properties as a string, separated with * commas. The serialization will happen automatically on component's completion * time, as well as when the application is deactivated. Automatic serialization * of a component can be turned off by simply setting false to \l enabled property. * * States saved are discarded when the application is closed properly. The state * loading is ignored (but not discarded) when the application is launched through * UriHandler. * * Example: * \qml * import QtQuick 2.0 * import Ubuntu.Components 0.1 * * TextField { * id: input * StateSaver.properties: "text" * StateSaver.enabled: input.enabled * } * \endqml * * In this example the state saver is synchronized with the attachee's one. * * Group properties can also be serialized by specifying the path to their individual * properties. * \qml * Rectangle { * id: rect * color: "gray" * border { * color: "blue" * width: units.gu(1) * } * StateSaver.properties: "color, border.color, border.width" * } * \endqml * * StateSaver computes a unique identifier for the attachee using the component's * and all its parents' \a{id}. Therefore attachee component as well as all its * parents must have a valid ID set. * * The following example will give error for the \a input, as the root component * has no id specified: * \qml * Item { * //[...] * Item { * id: parent * //[...] * TextField { * id: input * StateSaver.properties: "text" * } * } * } * \endqml * but the following example will successfully save the text field content * \qml * Item { * id: root * //[...] * Item { * id: parent * //[...] * TextField { * id: input * StateSaver.properties: "text" * } * } * } * \endqml * * When used with Repeater, each created item from the Repeater's delegate will * be saved separately. Note that due to the way Repeater works, Repeaters do not * need to have id specified. * * \qml * Item { * id: root * // [...] * Repeater { * model: 10 * Rectangle { * id: rect * width: 50; height: 50 * StateSaver.properties: "width, height" * } * } * // [...] * } * \endqml * * It can be used in the same way in ListView or GridView, except that both ListView * and GridView must have an id set. * * The StateSaver can save all \l{http://qt-project.org/doc/qt-5.0/qtqml/qtqml-typesystem-basictypes.html}{QML base types}, * Objects, list of objects or variants containing any of these cannot be saved. */ UCStateSaverAttached::UCStateSaverAttached(QObject *attachee) : QObject(attachee) , d_ptr(new UCStateSaverAttachedPrivate(this, attachee)) { setEnabled(true); // connect to StateSaverBackend's enabledChanged signal to sync when the state saver is globally disabled/enabled connect(&StateSaverBackend::instance(), SIGNAL(enabledChanged(bool)), this, SLOT(_q_globalEnableChanged(bool))); } UCStateSaverAttached::~UCStateSaverAttached() { StateSaverBackend::instance().removeId(d_func()->m_absoluteId); } // getter/setter /*! * \qmlproperty bool StateSaver::enabled * The property drives the automatic state saving. When disabled, state saving * will not happen on properties. * * The default value is true. */ bool UCStateSaverAttached::enabled() const { return d_func()->m_enabled; } void UCStateSaverAttached::setEnabled(bool v) { Q_D(UCStateSaverAttached); if (d->m_enabled != v) { d->m_enabled = v; // make sure next time we sync properties if (StateSaverBackend::instance().enabled()) { d->watchComponent(d->m_enabled); } Q_EMIT enabledChanged(); } } /*! * \qmlproperty string StateSaver::properties * List of properties to be serialized, separated with commas. Properties must be * writable and can only be \l{http://qt-project.org/doc/qt-5.0/qtqml/qtqml-typesystem-basictypes.html}{QML base types}. * * A custom singl eline input which saves the text, polaceholderText, font and color would look as follows: * \qml * TextField { * id: input * StateSaver.properties: "text, placeholderText, font, color" * } * \endqml */ QString UCStateSaverAttached::properties() const { return d_func()->m_properties.join(','); } void UCStateSaverAttached::setProperties(const QString &list) { QStringList propertyList = list.split(',', QString::SkipEmptyParts); for (int i = 0; i < propertyList.count(); i++) { propertyList[i] = propertyList.at(i).trimmed(); } Q_D(UCStateSaverAttached); if (d->m_properties != propertyList) { d->m_properties = propertyList; Q_EMIT propertiesChanged(); d->restore(); } } #include "moc_ucstatesaver.cpp" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/qquickmimedata.h0000644000015301777760000000443512321005637031513 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef QQUICKMIMEDATA_H #define QQUICKMIMEDATA_H #include #include #include #include #include "qquickclipboard.h" class QQuickMimeData : public QObject { Q_OBJECT Q_PROPERTY(QStringList formats READ formats NOTIFY formatsChanged) Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QString html READ html WRITE setHtml NOTIFY htmlChanged) Q_PROPERTY(QList urls READ urls WRITE setUrls NOTIFY urlsChanged) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(QVariant data READ mimeData WRITE setMimeData NOTIFY dataChanged) public: explicit QQuickMimeData(QObject *parent = 0); QQuickMimeData(const QMimeData *refData, bool localData = true, QObject *parent = 0); ~QQuickMimeData(); QStringList formats() const; QString text() const; void setText(const QString &text); QString html() const; void setHtml(const QString &html); QList urls() const; void setUrls(const QList &urls); QColor color() const; void setColor(const QColor &color); QVariant mimeData() const; void setMimeData(const QVariant &mimeData); void fromMimeData(const QMimeData *data); QMimeData *toMimeData(); Q_SIGNALS: void formatsChanged(); void textChanged(); void htmlChanged(); void urlsChanged(); void colorChanged(); void typeChanged(); void dataChanged(); private: friend class QQuickClipboard; bool m_refData; QMimeData *m_mimeData; }; #endif // QQUICKMIMEDATA_H ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucqquickimageextension.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucqquickimageextension.cp0000644000015301777760000001325112321005637033450 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include #include #include #include "ucqquickimageextension.h" #include "ucunits.h" QHash > UCQQuickImageExtension::s_rewrittenSciFiles; /*! \internal The UCQQuickImageExtension class makes sure that for images loaded via QQuickImageBase the right version is loaded and that they are scaled appropriately. It does so by overriding the QQuickImageBase's 'source' property. */ UCQQuickImageExtension::UCQQuickImageExtension(QObject *parent) : QObject(parent), m_image(static_cast(parent)) { QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), this, SLOT(reloadSource()), Qt::UniqueConnection); } QUrl UCQQuickImageExtension::source() const { return m_source; } void UCQQuickImageExtension::setSource(const QUrl& url) { if (url != m_source) { m_source = url; reloadSource(); Q_EMIT sourceChanged(m_source); } } void UCQQuickImageExtension::reloadSource() { if (m_source.isEmpty()) { m_image->setSource(m_source); return; } QString resolved = UCUnits::instance().resolveResource(m_source); if (resolved.isEmpty()) { m_image->setSource(m_source); return; } int separatorPosition = resolved.indexOf("/"); QString scaleFactor = resolved.left(separatorPosition); QString selectedFilePath = resolved.mid(separatorPosition+1); if (scaleFactor == "1") { // No scaling. Just pass the file as is. m_image->setSource(QUrl::fromLocalFile(selectedFilePath)); } else { // Prepend "image://scaling" for the image to be loaded by UCScalingImageProvider. if (!m_source.path().endsWith(".sci")) { // Regular image file m_image->setSource(QUrl("image://scaling/" + resolved)); } else { // .sci image file. Rewrite the .sci file into a temporary file. bool rewritten = true; QTemporaryFile* rewrittenSciFile; /* Ensure that only one temporary rewritten .sci file is created for each source .sci file by storing the path to the temporary file in a global hash. */ rewrittenSciFile = UCQQuickImageExtension::s_rewrittenSciFiles.value(m_source).data(); if (rewrittenSciFile == NULL) { rewrittenSciFile = new QTemporaryFile; rewrittenSciFile->setFileTemplate(QDir::tempPath() + QDir::separator() + "XXXXXX.sci"); rewrittenSciFile->open(); QTextStream output(rewrittenSciFile); rewritten = rewriteSciFile(selectedFilePath, scaleFactor, output); rewrittenSciFile->close(); s_rewrittenSciFiles.insert(m_source, QSharedPointer(rewrittenSciFile)); } if (rewritten) { m_image->setSource(QUrl::fromLocalFile(rewrittenSciFile->fileName())); } else { m_image->setSource(m_source); } } } } bool UCQQuickImageExtension::rewriteSciFile(const QString &sciFilePath, const QString &scaleFactor, QTextStream& output) { QFile sciFile(sciFilePath); if (sciFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream sciStream(&sciFile); while (!sciStream.atEnd()) { QString line = sciStream.readLine(); if (line.startsWith("border")) { output << scaledBorder(line, scaleFactor) << endl; } else if (line.startsWith("source")) { output << scaledSource(line, sciFilePath, scaleFactor) << endl; } else { output << line << endl; } } return true; } else { return false; } } QString UCQQuickImageExtension::scaledBorder(const QString &border, const QString &scaleFactor) { // Rewrite the border line with a scaled border value QStringList parts = border.split(":"); float scaledValue = parts[1].toFloat() * scaleFactor.toFloat(); return parts[0] + ": " + QString::number(qRound(scaledValue)); } QString UCQQuickImageExtension::scaledSource(QString source, const QString &sciFilePath, const QString &scaleFactor) { // Rewrite the source line by prepending "image://scaling" to the source value QString sciDirectory = QFileInfo(sciFilePath).dir().path() + QDir::separator(); QString baseUrl = "image://scaling/" + scaleFactor + "/" + sciDirectory; // If the source url is between quotes "", remove them const QChar quote = '"'; const int quoteFirstIndex = source.indexOf(quote); if (quoteFirstIndex != -1) { source.remove(quoteFirstIndex, 1); } const int quoteLastIndex = source.lastIndexOf(quote); if (quoteLastIndex != -1) { source.remove(quoteLastIndex, 1); } return source.replace("source: ", "source: " + QString(quote) + baseUrl).append(quote); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucscalingimageprovider.h0000644000015301777760000000205312321005637033234 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef SCALINGIMAGEPROVIDER_H #define SCALINGIMAGEPROVIDER_H #include #include class UCScalingImageProvider : public QQuickImageProvider { public: explicit UCScalingImageProvider(); QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize); }; #endif // SCALINGIMAGEPROVIDER_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucinversemouse.h0000644000015301777760000000323312321005637031563 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef UCINVERSEMOUSE_H #define UCINVERSEMOUSE_H #include "ucmouse.h" #include class UCInverseMouse : public UCMouse { Q_OBJECT public: explicit UCInverseMouse(QObject *parent = 0); static UCInverseMouse *qmlAttachedProperties(QObject *owner); virtual void setEnabled(bool enabled); virtual void setPriority(Priority priority); bool excludeInputArea() const; void setExcludeInputArea(bool value); protected: QMouseEvent mapMouseToOwner(QObject *target, QMouseEvent* event); QHoverEvent mapHoverToOwner(QObject *target, QHoverEvent *event); virtual bool eventFilter(QObject *, QEvent *); virtual bool mouseEvents(QObject *target, QMouseEvent *event); virtual bool hoverEvents(QObject *target, QHoverEvent *event); virtual bool hasAttachedFilter(QQuickItem *item); bool pointInOSK(const QPointF &point); bool contains(QMouseEvent *mouse); }; QML_DECLARE_TYPE(UCInverseMouse) QML_DECLARE_TYPEINFO(UCInverseMouse, QML_HAS_ATTACHED_PROPERTIES) #endif // UCINVERSEMOUSE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/alarmrequest_p_p.h0000644000015301777760000000305412321005637032053 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ALARMREQUEST_P_P_H #define ALARMREQUEST_P_P_H #include "alarmrequest_p.h" class AlarmRequestPrivate { Q_DECLARE_PUBLIC(AlarmRequest) public: AlarmRequestPrivate(AlarmRequest *qq, bool autoDelete); virtual ~AlarmRequestPrivate(); AlarmRequest *q_ptr; AlarmRequest::Status status; int error; bool completed:1; bool autoDelete:1; static AlarmRequestPrivate *get(AlarmRequest *instance) { return instance->d_func(); } void setStatus(AlarmRequest::Operation operation, AlarmRequest::Status status, int error = UCAlarm::NoError); virtual bool save(AlarmData &alarm) = 0; virtual bool remove(AlarmData &alarm) = 0; virtual bool wait(int msec) = 0; virtual void _q_updateProgress() = 0; }; AlarmRequestPrivate * createAlarmRequest(AlarmRequest *request, bool autoDelete); #endif // ALARMREQUEST_P_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucarguments.cpp0000644000015301777760000004102112321005637031374 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "ucarguments.h" #include "i18n.h" #include #include #include #include #include #include /*! * \qmltype Arguments * \instantiates UCArguments * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu-commandline * \brief The Arguments class provides a way to declare what command line * parameters are expected by the application. * * Example of use: * * \qml * Arguments { * id: args * * defaultArgument.help: "Expects URL of the media to play." * defaultArgument.valueNames: ["URL"] * * Argument { * name: "fullscreen" * help: "whether or not the media will be played fullscreen" * required: false * } * * Argument { * name: "volume" * help: "level to which to set the volume" * required: false * valueNames: ["VOLUME_LEVEL"] * } * } * \endqml * * The code above ensures that at least one argument is passed on the command * line which will then be available in QML via the defaultArgument property. * Optionally two other arguments can be passed: * * \e --fullscreen that will be exposed as a boolean property: \l{values}.fullscreen * * \e --volume that will be exposed as a string property: \l{values}.volume * * \qml * Item { * Label { * text: "volume = " + args.values.volume * } * * Label { * text: "fullscreen = " + args.values.fullscreen * } * * Label { * text: "URL = " + args.defaultArgument.at(0) * } * } * \endqml * * If the application is launched with the incorrect arguments or with the * \e --usage argument an help will be outputted on the command line and the * application will exit: * * \code * Usage: application [--fullscreen] [--volume=VOLUME_LEVEL] URL * Options: * --fullscreen whether or not the media will be played fullscreen * --volume=VOLUME_LEVE level to which to set the volume * * Expects URL of the media to play. * \endcode * * \sa Argument */ UCArguments::UCArguments(QObject *parent) : QObject(parent), m_completed(false), m_defaultArgument(NULL), m_values(new QQmlPropertyMap(this)), m_error(false) { m_rawArguments = QCoreApplication::arguments(); m_applicationBinary = QFileInfo(m_rawArguments[0]).fileName(); m_defaultArgument = new UCArgument(this); } /*! * \qmlproperty Argument Arguments::defaultArgument * * The default argument corresponds to the values passed on the command line * without any name. * * For example in: * * \code * ./application --volume=42 http://myaddress * \endcode * * \e{http://myaddress} is the first value of the default argument. * */ UCArgument* UCArguments::defaultArgument() const { return m_defaultArgument; } void UCArguments::setDefaultArgument(UCArgument* argument) { m_defaultArgument = argument; Q_EMIT(defaultArgumentChanged()); if (m_completed) { parseAndExposeArguments(); } } /*! * \qmlproperty Object Arguments::values * \readonly * * Object of which properties have the values of the command line arguments. * */ QQmlPropertyMap* UCArguments::values() const { return m_values; } /*! * \qmlproperty bool Arguments::error * \readonly * * Whether or not the command line arguments passed to the application correspond * to the expected arguments. * * Also set when calling \l quitWithError */ bool UCArguments::error() const { return m_error; } /*! * \qmlproperty string Arguments::errorMessage * \readonly * * Error message describing how the command line arguments passed to the application * failed to correspond to the expected arguments. * * Also set when calling \l quitWithError * */ QString UCArguments::errorMessage() const { return m_errorMessage; } QString UCArguments::usage() { QLatin1String indentation(" "); QString usage; QTextStream usageStream(&usage); UbuntuI18n* i18n = &UbuntuI18n::instance(); usageStream << i18n->tr("Usage: "); // display overall syntax, for example: program --argument=value DEFAULT_ARGUMENT usageStream << m_applicationBinary; Q_FOREACH (UCArgument* argument, m_arguments) { usageStream << ' '; QString syntax = argument->syntax(); if (!argument->required()) { syntax.prepend('[').append(']'); } usageStream << syntax; } if (m_defaultArgument != NULL) { usageStream << ' '; usageStream << m_defaultArgument->syntax(); } // display what each argument is used for usageStream << endl; usageStream << i18n->tr("Options:") << endl; Q_FOREACH (UCArgument* argument, m_arguments) { usageStream << indentation << argument->usage() << endl; } if (m_defaultArgument != NULL) { usageStream << endl << m_defaultArgument->help(); } return usage; } void UCArguments::setErrorMessage(const QString& errorMessage) { m_error = true; m_errorMessage = errorMessage; Q_EMIT errorChanged(); Q_EMIT errorMessageChanged(); } void UCArguments::quitApplication() { /* This function can be called multiple times before the application actually quit. See comment at the end about QCoreApplication::quit(). */ static bool quitting = false; if (quitting) { return; } /* Call QCoreApplication::quit() when the event loop starts running. "If the event loop is not running, [QCoreApplication::quit()] does nothing." Ref.: http://qt-project.org/doc/qt-5.0/qtcore/qcoreapplication.html#exit */ quitting = true; QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); } /*! * \qmlmethod void Arguments::printUsage() * * Outputs help to the console on how to pass arguments to the application. * */ void UCArguments::printUsage() { qWarning() << qPrintable(usage()); } /*! * \qmlmethod void Arguments::quitWithError(string errorMessage) * * Exits the application outputting \a errorMessage to the console. * */ void UCArguments::quitWithError(const QString& errorMessage) { setErrorMessage(errorMessage); // output to the console, first the errorMessage if any then the usage if (!errorMessage.isEmpty()) { qWarning() << qPrintable(errorMessage); } quitApplication(); } void UCArguments::classBegin() { } void UCArguments::componentComplete() { m_completed = true; parseAndExposeArguments(); // changing attributes' name, required and valueNames dynamically is not supported Q_FOREACH (UCArgument* argument, m_arguments) { QObject::connect(argument, &UCArgument::nameChanged, this, &UCArguments::warningArgumentPropertyChanged); QObject::connect(argument, &UCArgument::requiredChanged, this, &UCArguments::warningArgumentPropertyChanged); QObject::connect(argument, &UCArgument::valueNamesChanged, this, &UCArguments::warningArgumentPropertyChanged); } QObject::connect(m_defaultArgument, &UCArgument::nameChanged, this, &UCArguments::warningArgumentPropertyChanged); QObject::connect(m_defaultArgument, &UCArgument::requiredChanged, this, &UCArguments::warningArgumentPropertyChanged); QObject::connect(m_defaultArgument, &UCArgument::valueNamesChanged, this, &UCArguments::warningArgumentPropertyChanged); } void UCArguments::appendArguments(UCArgument* argument) { m_arguments.append(argument); if (m_completed) { parseAndExposeArguments(); } } UCArgument* UCArguments::atArguments(int index) { return m_arguments.at(index); } int UCArguments::countArguments() { return m_arguments.size(); } void UCArguments::clearArguments() { m_arguments.clear(); parseAndExposeArguments(); } // static callbacks calling the methods above void staticAppendArguments(QQmlListProperty* property, UCArgument* argument) { UCArguments* arguments = static_cast(property->data); arguments->appendArguments(argument); } UCArgument* staticAtArguments(QQmlListProperty* property, int index) { UCArguments* arguments = static_cast(property->data); return arguments->atArguments(index); } int staticCountArguments(QQmlListProperty* property) { UCArguments* arguments = static_cast(property->data); return arguments->countArguments(); } void staticClearArguments(QQmlListProperty* property) { UCArguments* arguments = static_cast(property->data); arguments->clearArguments(); } // end of static callbacks /*! * \qmlproperty list Arguments::arguments * \default * \readonly * * List of command line \l{Argument}{arguments} that are expected by the application. * * See detailed description above for an example on how to use it. * */ QQmlListProperty UCArguments::arguments() { return QQmlListProperty(this, this, &staticAppendArguments, &staticCountArguments, &staticAtArguments, &staticClearArguments); } void UCArguments::parseAndExposeArguments() { QHash expectedArguments; QHash argumentsValues; expectedArguments = buildExpectedArguments(m_arguments); argumentsValues = parseRawArguments(m_rawArguments, expectedArguments); if (usageRequested(argumentsValues.keys())) { quitWithError(); printUsage(); } QString error; if (!requiredArgumentsProvided(argumentsValues, error)) { quitWithError(error); printUsage(); } if (!requiredDefaultArgumentProvided(argumentsValues, error)) { quitWithError(error); printUsage(); } setValuesOnArguments(argumentsValues); exposeArgumentsAsProperties(argumentsValues); } void UCArguments::setValuesOnArguments(const QHash& argumentsValues) { // pass the values to the arguments Q_FOREACH (UCArgument* argument, m_arguments) { QString name = argument->name(); if (argumentsValues.contains(name)) { argument->setValues(argumentsValues.value(name)); } } // pass the values to the defaultArgument if (m_defaultArgument != NULL) { if (argumentsValues.contains("")) { int numberArguments = m_defaultArgument->valueNames().size(); m_defaultArgument->setValues(argumentsValues.value("").mid(0, numberArguments)); if (numberArguments > 0) { // FIXME: not very elegant way to inform that values have changed Q_EMIT(defaultArgumentChanged()); } } } } QHash UCArguments::buildExpectedArguments(const QList& declaredArguments) { QHash expectedArguments; Q_FOREACH (UCArgument* argument, declaredArguments) { expectedArguments.insert(argument->name(), argument->valueNames()); } return expectedArguments; } QHash UCArguments::parseRawArguments(const QStringList& rawArguments, const QHash& expectedArguments) { QHash argumentsValues; QString name; QStringList values; if (rawArguments.size() == 0) { return argumentsValues; } QStringList::const_iterator i = rawArguments.constBegin(); // ignore the first item in the rawArguments which is the name of the binary i++; for (; i != rawArguments.constEnd(); ++i) { QString rawArgument = (*i); if (rawArgument.startsWith('-')) { // it starts with a '-' therefore it is a named argument // remove all prepended '-' rawArgument = rawArgument.split('-', QString::SkipEmptyParts).join('-'); // string after the '=' sign is a value for the argument values = rawArgument.split("="); name = values.takeAt(0); if (expectedArguments.contains(name)) { values.append(collectArgumentValues(i, rawArguments.constEnd(), expectedArguments.value(name).size() - values.size())); } argumentsValues.insert(name, values); } else { // default/unnamed argument argumentsValues[""].append(rawArgument); } } return argumentsValues; } QStringList UCArguments::collectArgumentValues(QStringList::const_iterator& i, QStringList::const_iterator end, int nValues) { QStringList values; if (i == end) { return values; } for (; (i+1) != end; ++i) { QString rawArgument = *(i+1); if (rawArgument.startsWith('-')) { break; } else if (values.size() >= nValues) { break; } else { values.append(rawArgument); } } return values; } bool UCArguments::usageRequested(const QStringList& argumentNames) { return argumentNames.contains("help") || argumentNames.contains("h") || argumentNames.contains("usage"); } bool UCArguments::requiredArgumentsProvided(const QHash& argumentsValues, QString& error) { // check if all required named arguments were passed along with their values Q_FOREACH (UCArgument* argument, m_arguments) { if (argument->required()) { if (!argumentsValues.contains(argument->name())) { UbuntuI18n* i18n = &UbuntuI18n::instance(); error = i18n->tr("%1 is expecting an additional argument: %2"); error = error.arg(m_applicationBinary).arg(argument->syntax()); return false; } else if (argumentsValues.value(argument->name()).size() < argument->valueNames().size()) { UbuntuI18n* i18n = &UbuntuI18n::instance(); error = i18n->tr("%1 is expecting a value for argument: %2"); error = error.arg(m_applicationBinary).arg(argument->syntax()); return false; } } } return true; } bool UCArguments::requiredDefaultArgumentProvided(const QHash& argumentsValues, QString& error) { // check if the required default argument was passed if (m_defaultArgument != NULL && m_defaultArgument->required() && ((!argumentsValues.contains("") && m_defaultArgument->valueNames().size() > 0) || (argumentsValues.value("").size() < m_defaultArgument->valueNames().size()))) { UbuntuI18n* i18n = &UbuntuI18n::instance(); error = i18n->tr("%1 is expecting additional arguments: %2").arg(m_applicationBinary).arg(m_defaultArgument->syntax()); return false; } else { return true; } } void UCArguments::exposeArgumentsAsProperties(const QHash& argumentsValues) { Q_FOREACH (UCArgument* argument, m_arguments) { QString name = argument->name(); // if the argument has no value, convert to bool // if the argument has a single value, convert to string // if the argument has multiple values, convert to a list of strings QStringList values = argument->values(); QVariant value; switch (argument->valueNames().size()) { case 0: if (argumentsValues.contains(name)) { value.setValue(true); } else { // case of a boolean argument that was not passed on the command line value.setValue(false); } break; case 1: if (values.size() > 0) { value.setValue(values.at(0)); } break; default: value.setValue(values); break; } m_values->insert(name, value); Q_EMIT m_values->valueChanged(name, value); } } void UCArguments::warningArgumentPropertyChanged() { qWarning() << "Changing properties of arguments dynamically is not supported."; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/thumbnailgenerator.h0000644000015301777760000000214712321005637032404 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Jussi Pakkanen */ #ifndef THUMBNAIL_GENERATOR_H #define THUMBNAIL_GENERATOR_H #include #include class ThumbnailGenerator: public QQuickImageProvider { private: Thumbnailer tn; public: ThumbnailGenerator(); QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize); QImage getFallbackImage(const QString &id, QSize *size, const QSize &requestedSize); }; #endif ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucargument.h0000644000015301777760000000416612321005637030667 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UCARGUMENT_H #define UCARGUMENT_H #include #include #include class UCArgument : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString help READ help WRITE setHelp NOTIFY helpChanged) Q_PROPERTY(bool required READ required WRITE setRequired NOTIFY requiredChanged) Q_PROPERTY(QStringList valueNames READ valueNames WRITE setValueNames NOTIFY valueNamesChanged) public: explicit UCArgument(QObject *parent = 0); QString name() const; void setName(const QString &name); QString help() const; void setHelp(const QString &help); bool required() const; void setRequired(bool required); QStringList valueNames() const; void setValueNames(const QStringList &valueNames); // FIXME: maybe define UCArgument as a QQmlListProperty instead so that // operator[] is available from QML Q_INVOKABLE QVariant at(int i) const; protected: QString syntax() const; QString usage() const; QStringList values() const; void setValues(const QStringList &values); Q_SIGNALS: void nameChanged(); void helpChanged(); void requiredChanged(); void valueNamesChanged(); private: QString m_name; QString m_help; bool m_required; QStringList m_valueNames; QStringList m_values; friend class UCArguments; }; #endif // UCARGUMENT_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/thumbnailgenerator.cpp0000644000015301777760000000626212321005637032741 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authors: Jussi Pakkanen */ #include "thumbnailgenerator.h" #include #include #include #include const char *DEFAULT_VIDEO_ART = "/usr/share/unity/icons/video_missing.png"; const char *DEFAULT_ALBUM_ART = "/usr/share/unity/icons/album_missing.png"; ThumbnailGenerator::ThumbnailGenerator() : QQuickImageProvider(QQuickImageProvider::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading) { } QImage ThumbnailGenerator::requestImage(const QString &id, QSize *realSize, const QSize &requestedSize) { /* Allow appending a query string (e.g. ?something=timestamp) * to the id and then ignore it. * This is workaround to force reloading a thumbnail when it has * the same file name on disk but we know the content has changed. * It is necessary because in such a situation the QML image cache * will kick in and this ImageProvider will never get called. * The only "solution" is setting Image.cache = false, but in some * cases we don't want to do that for performance reasons, so this * is the only way around the issue for now. */ std::string src_path(QUrl(id).path().toUtf8().data()); std::string tgt_path; try { ThumbnailSize desiredSize; const int large_cutoff = 256; const int small_cutoff = 128; if(requestedSize.width() > large_cutoff || requestedSize.height() > large_cutoff) { desiredSize = TN_SIZE_ORIGINAL; } else if(requestedSize.width() > small_cutoff || requestedSize.height() > small_cutoff) { desiredSize = TN_SIZE_LARGE; } else { desiredSize = TN_SIZE_SMALL; } tgt_path = tn.get_thumbnail(src_path, desiredSize); if(!tgt_path.empty()) { QString tgt(tgt_path.c_str()); QImage image; image.load(tgt); *realSize = image.size(); return image; } } catch(std::runtime_error &e) { qDebug() << "Thumbnail generator failed: " << e.what(); } return getFallbackImage(id, realSize, requestedSize); } QImage ThumbnailGenerator::getFallbackImage(const QString &id, QSize *size, const QSize &requestedSize) { Q_UNUSED(requestedSize); QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(id); QImage result; if(mime.name().contains("audio")) { result.load(DEFAULT_ALBUM_ART); } else if(mime.name().contains("video")) { result.load(DEFAULT_VIDEO_ART); } *size = result.size(); return result; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/adapters/0000755000015301777760000000000012321006415030133 5ustar pbusernogroup00000000000000././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/adapters/alarmsadapter_or0000644000015301777760000004523612321005637033415 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ucalarm.h" #include "ucalarm_p.h" #include "alarmmanager_p.h" #include "alarmrequest_p.h" #include "alarmsadapter_p.h" #include #include #include #include #define ALARM_DATABASE "%1/alarms.database" /* * The main alarm manager engine used from Saucy onwards is EDS (Evolution Data * Server) based. Any previous release uses the generic "memory" manager engine * which does not store alarm data, does not schedule organizer events and does * not give visual or audible reminding. */ #define ALARM_MANAGER "eds" #define ALARM_MANAGER_FALLBACK "memory" #define ALARM_COLLECTION "Alarms" QTORGANIZER_USE_NAMESPACE /*----------------------------------------------------------------------------- * Adaptation layer for Alarms. */ AlarmManagerPrivate * createAlarmsAdapter(AlarmManager *alarms) { return new AlarmsAdapter(alarms); } AlarmsAdapter::AlarmsAdapter(AlarmManager *qq) : QObject(qq) , AlarmManagerPrivate(qq) , listDirty(false) , manager(0) , fetchRequest(0) { QOrganizerManager local; bool usingDefaultManager = local.availableManagers().contains(ALARM_MANAGER); manager = (usingDefaultManager) ? new QOrganizerManager(ALARM_MANAGER) : new QOrganizerManager(ALARM_MANAGER_FALLBACK); manager->setParent(q_ptr); if (!usingDefaultManager) { qWarning() << "WARNING: default alarm manager not installed, using" << manager->managerName() << "manager."; qWarning() << "This manager may not provide all the needed features."; } QList collections = manager->collections(); if (collections.count() > 0) { Q_FOREACH(const QOrganizerCollection &c, collections) { if (c.metaData(QOrganizerCollection::KeyName).toString() == ALARM_COLLECTION) { collection = c; break; } } } if (collection.id().isNull()) { // create alarm collection collection.setMetaData(QOrganizerCollection::KeyName, ALARM_COLLECTION); // EDS requires extra metadata to be set collection. setExtendedMetaData("collection-type", "Task List"); if (!manager->saveCollection(&collection)) { qWarning() << "WARNING: Creating dedicated collection for alarms was not possible, alarms will be saved into the default collection!"; collection = manager->defaultCollection(); } } loadAlarms(); // connect to manager to receive changes QObject::connect(manager, SIGNAL(dataChanged()), this, SLOT(fetchAlarms())); QObject::connect(manager, SIGNAL(itemsAdded(QList)), this, SLOT(fetchAlarms())); QObject::connect(manager, SIGNAL(itemsChanged(QList)), this, SLOT(fetchAlarms())); QObject::connect(manager, SIGNAL(itemsRemoved(QList)), this, SLOT(fetchAlarms())); } AlarmsAdapter::~AlarmsAdapter() { saveAlarms(); } // load fallback manager data void AlarmsAdapter::loadAlarms() { if (manager->managerName() != ALARM_MANAGER_FALLBACK) { return; } QFile file(QString(ALARM_DATABASE).arg(QStandardPaths::writableLocation(QStandardPaths::DataLocation))); if (!file.open(QFile::ReadOnly)) { return; } QDataStream in(&file); while (!in.atEnd()) { AlarmData alarm; int type, days; in >> alarm.message >> alarm.date >> alarm.sound >> type >> days >> alarm.enabled; alarm.type = static_cast(type); alarm.days = static_cast(days); QOrganizerTodo event; organizerEventFromAlarmData(alarm, event); manager->saveItem(&event); } file.close(); } // save fallback manager data only void AlarmsAdapter::saveAlarms() { if ((manager->managerName() != ALARM_MANAGER_FALLBACK) || !listDirty) { return; } QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); if (!dir.exists()) { dir.mkpath(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); } QFile file(QString(ALARM_DATABASE).arg(dir.path())); if (!file.open(QFile::WriteOnly | QFile::Truncate)) { return; } QDataStream out(&file); Q_FOREACH(const AlarmData &alarm, alarmList) { out << alarm.message << alarm.date << alarm.sound << alarm.type << alarm.days << alarm.enabled; } file.close(); listDirty = false; } void AlarmsAdapter::organizerEventFromAlarmData(const AlarmData &alarm, QOrganizerTodo &event) { event.setCollectionId(collection.id()); event.setAllDay(false); event.setStartDateTime(alarm.date); event.setDueDateTime(alarm.date); event.setDisplayLabel(alarm.message); if (alarm.enabled) { // set visual and audible reminder serving as alarm note QOrganizerItemVisualReminder visual; visual.setSecondsBeforeStart(0); visual.setMessage(alarm.message); event.saveDetail(&visual); QOrganizerItemAudibleReminder audible; audible.setSecondsBeforeStart(0); audible.setDataUrl(alarm.sound); event.saveDetail(&audible); } // save the sound as description as the audible reminder may be off event.setDescription(alarm.sound.toString()); // set repeating switch (alarm.type) { case UCAlarm::OneTime: { break; } case UCAlarm::Repeating: { QOrganizerRecurrenceRule rule; if (alarm.days == UCAlarm::Daily) { rule.setFrequency(QOrganizerRecurrenceRule::Daily); } else if (alarm.days) { rule.setFrequency(QOrganizerRecurrenceRule::Weekly); rule.setDaysOfWeek(daysToSet(alarm)); } event.setRecurrenceRule(rule); break; } default: break; } } void AlarmsAdapter::updateOrganizerEventFromAlarmData(const AlarmData &alarm, QOrganizerTodo &event) { // remove affected details if (!alarm.enabled || (alarm.changes & AlarmData::Enabled)) { // remove previously set reminders QOrganizerItemVisualReminder visual = event.detail(QOrganizerItemDetail::TypeVisualReminder); event.removeDetail(&visual); QOrganizerItemAudibleReminder audible = event.detail(QOrganizerItemDetail::TypeAudibleReminder); event.removeDetail(&audible); } if (((alarm.changes & AlarmData::Type) == AlarmData::Type) || ((alarm.changes & AlarmData::Days) == AlarmData::Days)) { QOrganizerItemRecurrence old = event.detail(QOrganizerItemDetail::TypeRecurrence); event.removeDetail(&old); } organizerEventFromAlarmData(alarm, event); } int AlarmsAdapter::alarmDataFromOrganizerEvent(const QOrganizerTodo &event, AlarmData &alarm) { if (event.isEmpty()) { return FetchedEventEmpty; } alarm.cookie = QVariant::fromValue(event.id()); alarm.message = event.displayLabel(); alarm.date = AlarmData::normalizeDate(event.dueDateTime()); alarm.sound = QUrl(event.description()); // check if the alarm is enabled or not QOrganizerItemVisualReminder visual = event.detail(QOrganizerItemDetail::TypeVisualReminder); QOrganizerItemAudibleReminder audible = event.detail(QOrganizerItemDetail::TypeAudibleReminder); alarm.enabled = !visual.isEmpty() && !audible.isEmpty(); // repeating QOrganizerRecurrenceRule rule = event.recurrenceRule(); switch (rule.frequency()) { case QOrganizerRecurrenceRule::Invalid: { alarm.type = UCAlarm::OneTime; alarm.days = UCAlarmPrivate::dayOfWeek(alarm.date); break; } case QOrganizerRecurrenceRule::Daily: { alarm.type = UCAlarm::Repeating; alarm.days = UCAlarm::Daily; break; } case QOrganizerRecurrenceRule::Weekly: { alarm.type = UCAlarm::Repeating; daysFromSet(alarm, rule.daysOfWeek()); break; } default: // fallback to OneTime, no error reported return UnhandledEventType; } return UCAlarm::NoError; } QSet AlarmsAdapter::daysToSet(const AlarmData &alarm) const { QSet result; for (Qt::DayOfWeek day = Qt::Monday; day <= Qt::Sunday; day = static_cast(static_cast(day) + 1)) { if (alarm.days & (1 << (static_cast(day) - 1))) result << day; } return result; } void AlarmsAdapter::daysFromSet(AlarmData &alarm, QSet set) { alarm.days = 0; QSetIterator i(set); while (i.hasNext()) { int day = static_cast(i.next()); alarm.days |= static_cast(1 << (day - 1)); } } /*----------------------------------------------------------------------------- * Abstract methods */ bool AlarmsAdapter::fetchAlarms() { if (fetchRequest) { // there is already a fetch request ongoing, exit return false; } // create self deleting request fetchRequest = new AlarmRequest(true, q_ptr); AlarmRequestAdapter *adapter = static_cast(AlarmRequestPrivate::get(fetchRequest)); return adapter->fetch(); } void AlarmsAdapter::completeFetchAlarms(const QList &alarms) { alarmList.clear(); QSet parentId; QOrganizerTodo event; Q_FOREACH(const QOrganizerItem &item, alarms) { // repeating alarms may be fetched as occurences, therefore check their parent event if (item.type() == QOrganizerItemType::TypeTodoOccurrence) { QOrganizerTodoOccurrence occurence = static_cast(item); QOrganizerItemId eventId = occurence.parentId(); if (parentId.contains(eventId)) { continue; } parentId << eventId; event = static_cast(manager->item(eventId)); } else if (item.type() == QOrganizerItemType::TypeTodo){ event = static_cast(item); } else { continue; } AlarmData alarm; if (alarmDataFromOrganizerEvent(event, alarm) == UCAlarm::NoError) { alarmList << alarm; } } saveAlarms(); Q_EMIT q_ptr->alarmsChanged(); completed = true; fetchRequest = 0; } /*----------------------------------------------------------------------------- * AlarmRequestAdapter implementation */ AlarmRequestPrivate * createAlarmRequest(AlarmRequest *request, bool autoDelete) { return new AlarmRequestAdapter(request, autoDelete); } AlarmRequestAdapter::AlarmRequestAdapter(AlarmRequest *parent, bool autoDelete) : AlarmRequestPrivate(parent, autoDelete) , m_request(0) { } /* * Save or update an alarm. Returns false on operation error. */ bool AlarmRequestAdapter::save(AlarmData &alarm) { QOrganizerTodo event; if (!alarm.cookie.isValid()) { // new event AlarmsAdapter::get()->organizerEventFromAlarmData(alarm, event); } else { // update existing event QOrganizerItemId itemId = alarm.cookie.value(); event = AlarmsAdapter::get()->manager->item(itemId); if (event.isEmpty()) { setStatus(AlarmRequest::Saving, AlarmRequest::Fail, UCAlarm::AdaptationError); return false; } AlarmsAdapter::get()->updateOrganizerEventFromAlarmData(alarm, event); } QOrganizerItemSaveRequest *operation = new QOrganizerItemSaveRequest(q_ptr); operation->setManager(AlarmsAdapter::get()->manager); operation->setItem(event); AlarmsAdapter::get()->listDirty = true; return start(operation); } /* * Removes an alarm from the collection. Returns false on failure. */ bool AlarmRequestAdapter::remove(AlarmData &alarm) { if (!alarm.cookie.isValid()) { setStatus(AlarmRequest::Canceling, AlarmRequest::Fail, UCAlarm::InvalidEvent); return false; } QOrganizerTodo event; AlarmsAdapter::get()->organizerEventFromAlarmData(alarm, event); event.setId(alarm.cookie.value()); QOrganizerItemRemoveRequest *operation = new QOrganizerItemRemoveRequest(q_ptr); operation->setManager(AlarmsAdapter::get()->manager); operation->setItem(event); AlarmsAdapter::get()->listDirty = true; return start(operation); } /* * Waits for event completion. msec zero means wait forever. */ bool AlarmRequestAdapter::wait(int msec) { return (m_request) ? m_request->waitForFinished(msec) : true; } /* * Initiates alarm fetching. */ bool AlarmRequestAdapter::fetch() { AlarmManager *manager = static_cast(q_ptr->parent()); AlarmsAdapter *owner = AlarmsAdapter::get(manager); QOrganizerItemFetchRequest *operation = new QOrganizerItemFetchRequest(q_ptr); operation->setManager(owner->manager); // FIXME: Since returning all events without a limit of date is not a good solution we need to find // a better solution for that. // The current solution filters only the next 7 days (one week). // This will be enough for now, since the current alarms occur weekly, but for the future // we want to allow create alarms with monthly or yearly recurrence QDate currentDate = QDate::currentDate(); QDateTime startDate(currentDate, QTime(0,0,0)); QDateTime endDate(currentDate.addDays(7), QTime(23,59,59)); operation->setStartDate(startDate); operation->setEndDate(endDate); // set sort order QOrganizerItemSortOrder sortOrder; sortOrder.setDirection(Qt::AscendingOrder); sortOrder.setDetail(QOrganizerItemDetail::TypeTodoTime, QOrganizerTodoTime::FieldDueDateTime); operation->setSorting(QList() << sortOrder); // set filter QOrganizerItemCollectionFilter filter; filter.setCollectionId(owner->collection.id()); operation->setFilter(filter); // start request return start(operation); } /* * Starts the asynchronous operation. */ bool AlarmRequestAdapter::start(QOrganizerAbstractRequest *operation) { m_request = operation; if (!m_request) { return false; } completed = false; // make sure we are in progress state setStatus(requestTypeToOperation(), AlarmRequest::InProgress); QObject::connect(m_request, SIGNAL(resultsAvailable()), q_ptr, SLOT(_q_updateProgress())); if (m_request->start()) { // check if the request got completed without having the slot called (some engines may do that) if (!completed && m_request->state() >= QOrganizerAbstractRequest::CanceledState) { _q_updateProgress(); } return true; } return false; } /* * Update operation progress. */ void AlarmRequestAdapter::_q_updateProgress() { completed = true; QOrganizerAbstractRequest::State state = m_request->state(); AlarmRequest::Operation opCode = requestTypeToOperation(); switch (state) { case QOrganizerAbstractRequest::InactiveState: { setStatus(opCode, AlarmRequest::Ready); break; } case QOrganizerAbstractRequest::ActiveState: { setStatus(opCode, AlarmRequest::InProgress); completed = false; break; } case QOrganizerAbstractRequest::CanceledState: { setStatus(opCode, AlarmRequest::Fail, AlarmsAdapter::OrganizerError + m_request->error()); break; } case QOrganizerAbstractRequest::FinishedState: { int code = m_request->error(); if (code != QOrganizerManager::NoError) { setStatus(opCode, AlarmRequest::Fail, AlarmsAdapter::OrganizerError + code); } else { switch (opCode) { case AlarmRequest::Saving: { completeUpdate(); break; } case AlarmRequest::Canceling: { completeRemove(); break; } case AlarmRequest::Fetching: { completeFetch(); break; } default: qWarning() << "Unhandled request:" << m_request->type(); setStatus(opCode, AlarmRequest::Fail, AlarmsAdapter::UnhandledRequest); break; } setStatus(opCode, AlarmRequest::Ready); } break; } default: { qWarning() << "Invalid status" << state; setStatus(opCode, AlarmRequest::Fail, UCAlarm::InvalidEvent); break; } } if (completed) { // cleanup request m_request->deleteLater(); m_request = 0; if (autoDelete) { q_ptr->deleteLater(); } } } AlarmRequest::Operation AlarmRequestAdapter::requestTypeToOperation() { switch (m_request->type()) { case QOrganizerAbstractRequest::ItemSaveRequest: { return AlarmRequest::Saving; } case QOrganizerAbstractRequest::ItemRemoveRequest: { return AlarmRequest::Canceling; } case QOrganizerAbstractRequest::ItemFetchRequest: { return AlarmRequest::Fetching; } default: return AlarmRequest::NoOperation; } } void AlarmRequestAdapter::completeUpdate() { UCAlarm *alarm = qobject_cast(q_ptr->parent()); if (!alarm) { return; } UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm); QOrganizerItemSaveRequest *save = qobject_cast(m_request); pAlarm->rawData.cookie = QVariant::fromValue(save->items()[0].id()); pAlarm->rawData.changes = AlarmData::NoChange; } void AlarmRequestAdapter::completeRemove() { UCAlarm *alarm = qobject_cast(q_ptr->parent()); if (!alarm) { return; } UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm); pAlarm->rawData.cookie = QVariant(); pAlarm->rawData.changes = AlarmData::NoChange; } void AlarmRequestAdapter::completeFetch() { AlarmManager *manager = static_cast(q_ptr->parent()); AlarmsAdapter *owner = AlarmsAdapter::get(manager); QOrganizerItemFetchRequest *fetch = static_cast(m_request); owner->completeFetchAlarms(fetch->items()); } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.hubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.0000644000015301777760000000534112321005637033303 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ALARMSADAPTER_P_H #define ALARMSADAPTER_P_H #include "alarmmanager_p_p.h" #include "alarmrequest_p_p.h" #include #include QTORGANIZER_USE_NAMESPACE /*----------------------------------------------------------------------------- * Adaptation layer for Alarms. */ class AlarmRequestAdapter : public AlarmRequestPrivate { public: AlarmRequestAdapter(AlarmRequest *parent, bool autoDelete); // adaptation methods bool save(AlarmData &alarm); bool remove(AlarmData &alarm); bool wait(int msec); bool fetch(); bool start(QOrganizerAbstractRequest *operation); void _q_updateProgress(); private: QOrganizerAbstractRequest *m_request; AlarmRequest::Operation requestTypeToOperation(); void completeUpdate(); void completeRemove(); void completeFetch(); }; class AlarmsAdapter : public QObject, public AlarmManagerPrivate { Q_OBJECT public: enum Error { FetchedEventEmpty = UCAlarm::AdaptationError + 1, // 101 UnhandledEventType, // 102 UnhandledRequest, // 103 OrganizerError // 104 onwards }; AlarmsAdapter(AlarmManager *qq); virtual ~AlarmsAdapter(); static AlarmsAdapter* get(AlarmManager *instance = 0) { return static_cast(AlarmManagerPrivate::get(instance)); } bool listDirty:1; QOrganizerManager *manager; QOrganizerCollection collection; void completeFetchAlarms(const QList &alarmList); void loadAlarms(); void saveAlarms(); void organizerEventFromAlarmData(const AlarmData &alarm, QOrganizerTodo &event); void updateOrganizerEventFromAlarmData(const AlarmData &alarm, QOrganizerTodo &event); int alarmDataFromOrganizerEvent(const QOrganizerTodo &event, AlarmData &alarm); QSet daysToSet(const AlarmData &alarm) const; void daysFromSet(AlarmData &alarm, QSet set); public Q_SLOTS: bool fetchAlarms(); protected: AlarmRequest *fetchRequest; }; #endif // ALARMSADAPTER_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/alarmmanager_p_p.h0000644000015301777760000000260112321005637031772 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ALARMMANAGER_P_H #define ALARMMANAGER_P_H #include "ucalarm.h" #include "alarmmanager_p.h" #include class AlarmManagerPrivate { Q_DECLARE_PUBLIC(AlarmManager) public: AlarmManagerPrivate(AlarmManager *qq); virtual ~AlarmManagerPrivate(); static AlarmManagerPrivate *get(AlarmManager *instance = 0) { if (!instance) { return AlarmManager::instance().d_func(); } else { return instance->d_func(); } } AlarmManager *q_ptr; QList alarmList; bool completed:1; virtual bool fetchAlarms() = 0; }; AlarmManagerPrivate * createAlarmsAdapter(AlarmManager *alarms); #endif // ALARMMANAGER_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/plugin/ucalarmmodel.cpp0000644000015301777760000001604012321005637031507 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ucalarmmodel.h" #include "ucalarm.h" #include "ucalarm_p.h" #include "alarmmanager_p.h" #include /*! * \qmltype AlarmModel * \instantiates UCAlarmModel * \inqmlmodule Ubuntu.Components 0.1 * \ingroup ubuntu-services * \brief AlarmModel holds the list of alarms defined. * * The AlarmModel is a simple container of \l Alarm definitions stored in the alarm * collection. The data provided by the model are read only, adding, modifying or * removing data is only possible through \l Alarm functions. Any modification on * the alarms or any new alarm added to the collection will refresh all the model * instances. This also means that the delegates visualizing the model elements will * also be re-created. * * Example usage: * \qml * import QtQuick 2.0 * import Ubuntu.Components 0.1 * import Ubuntu.Components.ListItems 0.1 * ListView { * model: AlarmModel {} * width: units.gu(80) * height: units.gu(100) * delegate: Subtitled { * text: message * subText: Qt.formatDateTime(date) * } * } * \endqml * * The model defines the same roles as the \l Alarm properties. Note that the use * of \a enabled role in delegates may be ambiguous. Therefore the model defines * the additional role called \a model, which represents the \l Alarm object from * the index the delegate is showing the data, so the \a enabled role can then be * accessed by simply dereferencing the model i.e. model.enabled. * * Example: * \qml * ListView { * model: AlarmModel{} * delegate: Standard { * text: message * control: Switch { * checked: model.enabled * } * } * } * \endqml * * The number of alarm events can be obtained from the \l count property. To get * a specific alarm event data from the model, use the \l get() function. * * As the \l get() function returns the alarm object from the given index. Combined * with the alarm functions the alarms can be updated in place. * * Example: * \qml * ListView { * model: AlarmModel{ * id: alarmModel * } * delegate: Standard { * text: message * control: Switch { * checked: model.enabled * onCheckedChanged: { * if (checked != model.enabled) { * var data = alarmModel.get(index); * data.enabled = checked; * data.save(); * } * } * } * } * } * \endqml * * In this kind of "in place" updates using the \a model role would give the same result: * \qml * ListView { * model: AlarmModel{ * id: alarmModel * } * delegate: Standard { * text: message * control: Switch { * checked: model.enabled * onCheckedChanged: { * if (checked != model.enabled) { * model.enabled = checked; * model.save(); * } * } * } * } * } * \endqml */ UCAlarmModel::UCAlarmModel(QObject *parent) : QAbstractListModel(parent) , m_ready(false) { m_roles = AlarmData::roles(); m_roles.insert(m_roles.count(), "model"); // keep in sync with alarms collection changes // make sure the connection is asynchronous, as changes made in in-place in // the delegates may cause the model data to be invalid (released) as some // backends may do the refresh/element removals synchronously connect(&AlarmManager::instance(), SIGNAL(alarmsChanged()), this, SLOT(refresh()), Qt::QueuedConnection); // fetch alarms refresh(); m_ready = true; } UCAlarmModel::~UCAlarmModel() { clear(); } void UCAlarmModel::clear() { if (m_alarms.count()) { Q_FOREACH(UCAlarm *alarm, m_alarms) { delete alarm; } m_alarms.clear(); } } int UCAlarmModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return count(); } QVariant UCAlarmModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } int idx = index.row(); if ((idx >= m_alarms.count()) || (idx < 0)) { return QVariant(); } const QString roleName = m_roles.value(role); if (roleName == "model") { const UCAlarm *alarm = m_alarms[idx]; return QVariant::fromValue(const_cast(alarm)); } else if (!roleName.isEmpty()){ return m_alarms[idx]->property(roleName.toLocal8Bit()); } return QVariant(); } QHash UCAlarmModel::roleNames() const { return m_roles; } /*! * \qmlmethod Alarm AlarmModel::get(int index) * Returns the copy of the alarm event at \a index in the model. This allows the * alarm data to be modified and updated either through normal component binding * or in Javascript functions. * * \code * Component.onCompleted: { * var alarm = alarmModel.get(0); * alarm.message += " updated"; * alarm.save(); * } * \endcode * * This Javascript code returns the alarm properties from the first index of the * model, updates its message and updates the alarm. Note that the alarm must be * saved in order to have the changes visible. The follwoing code will not update * the alarm in the model/collection: * * \code * Component.onCompleted: { * alarmModel.get(0).message += " updated"; * alarm.message += " updated"; * } * \endcode * * \b Warning: The returned object is not guarantied to remain valid, it should * not be used in property bindings. * * \sa Alarm */ UCAlarm* UCAlarmModel::get(int index) { if ((index >= 0) && (index < m_alarms.count())) { return m_alarms[index]; } return 0; } /*! * \qmlproperty int AlarmModel::count * The number of data entries in the model. */ int UCAlarmModel::count() const { return m_alarms.count(); } /*! * \internal * The slot prepares the views for the dataChanged() signal. */ void UCAlarmModel::refresh() { if (m_ready) { beginResetModel(); } clear(); QList alarms = AlarmManager::instance().alarms(); Q_FOREACH(const AlarmData &data, alarms) { UCAlarm *alarm = new UCAlarm; UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm); pAlarm->rawData = data; m_alarms << alarm; } Q_EMIT countChanged(); if (m_ready) { endResetModel(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/PageWrapper.qml0000644000015301777760000000526112321005637027773 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "PageWrapperUtils.js" as Utils /*! \internal \qmltype PageWrapper \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Internal class used by \l PageStack \b{This component is under heavy development.} */ PageTreeNode { id: pageWrapper anchors.fill: parent /*! \preliminary The reference to the page object. This can be the page itself (which is an Item), but also a url pointing to a QML file. */ property var reference /*! \preliminary The initialized page object, or null if the object needs to be created. */ property Item object: null /*! \preliminary This variable will be true if \l object holds an object that was created from the given reference, and thus can be destroyed when no the page is deactivated. */ property bool canDestroy: false /*! This value is updated when a PageWrapper is pushed to/popped from a PageStack. */ active: false /*! \internal */ onActiveChanged: { if (reference) { if (pageWrapper.active) Utils.activate(pageWrapper); else Utils.deactivate(pageWrapper); } } visible: active /*! \preliminary Properties are use to initialize a new object, or if reference is already an object, properties are copied to the object when activated. */ property var properties /*! \internal */ onReferenceChanged: { Utils.deactivate(pageWrapper); if (pageWrapper.object) pageWrapper.object = null; if (pageWrapper.active && reference) { Utils.activate(pageWrapper); } } /*! \internal */ Component.onDestruction: { Utils.deactivate(pageWrapper); if (pageWrapper.canDestroy) Utils.destroyObject(pageWrapper); } /*! \internal Destroy \l object. Only call this function if \l canDestroy */ function destroyObject() { Utils.destroyObject(pageWrapper); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/UbuntuShape.qml0000644000015301777760000000746112321005637030025 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 as Ubuntu /*! \qmltype UbuntuShape \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The UbuntuShape item provides a standard Ubuntu shaped rounded rectangle. The UbuntuShape is used where a rounded rectangle is needed either filled with a color or an image that it crops. When given with a \l color it is applied with an overlay blending as a vertical gradient going from \l color to \l gradientColor. Two corner \l radius are available, "small" (default) and "medium", that determine the size of the corners. Optionally, an Image can be passed that will be displayed inside the UbuntuShape and cropped to fit it. Examples: \qml import Ubuntu.Components 0.1 UbuntuShape { color: "lightblue" radius: "medium" } \endqml \qml import Ubuntu.Components 0.1 UbuntuShape { image: Image { source: "icon.png" } } \endqml */ Item { id: shapeProxy /*! \qmlproperty color UbuntuShape::color The top color of the gradient used to fill the shape. Setting only this one is enough to set the overall color the shape. */ property alias color: shape.color /*! \qmlproperty color UbuntuShape::gradientColor The bottom color of the gradient used for the overlay blending of the color that fills the shape. It is optional to set this one as setting \l color is enough to set the overall color of the shape. */ property alias gradientColor: shape.gradientColor /*! \qmlproperty string UbuntuShape::radius The size of the corners among: "small" (default) and "medium". */ property alias radius: shape.radius /*! \qmlproperty Image UbuntuShape::image The image used to fill the shape. */ property Item image /*! \deprecated \qmlproperty url UbuntuShape::borderSource The image used as a border. We plan to expose that feature through styling properties. */ property alias borderSource: shape.borderSource implicitWidth: shape.implicitWidth implicitHeight: shape.implicitHeight Ubuntu.Shape { id: shape anchors.fill: parent /* FIXME: only set the ShapeItem::image property when the Image's source is loaded (status == Image.Ready). Otherwise, Image::textureProvider()::texture() is NULL when ShapeItem::updatePaintNode() is called and ShapeItem::updatePaintNode() calls itself recursively forever. Ref.: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1197801 */ property bool isImageReady: shapeProxy.image && ((shapeProxy.image.status == Image.Ready) || QuickUtils.className(shapeProxy.image) == "QQuickShaderEffectSource") image: isImageReady ? shapeProxy.image : null /* FIXME: without this, rendering of the image inside the shape is sometimes garbled. */ stretched: isImageReady && (shapeProxy.image.fillMode == Image.PreserveAspectCrop) ? false : true } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Label.qml0000644000015301777760000000373612321005637026602 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Label \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Text with Ubuntu styling. Example: \qml Rectangle { color: UbuntuColors.coolGrey width: units.gu(30) height: units.gu(30) Label { anchors.centerIn: parent text: "Hello, world!" fontSize: "large" } } \endqml */ Text { id: label /*! The size of the text. One of the following strings (from smallest to largest): \list \li "xx-small" \li "x-small" \li "small" \li "medium" \li "large" \li "x-large" \endlist Default value is "medium". */ property string fontSize: "medium" font.pixelSize: FontUtils.sizeToPixels(fontSize) font.family: "Ubuntu" color: Theme.palette.selected.backgroundText /* FIXME: workaround for QTBUG 35095 where Text's alignment is incorrect when the width changes and LayoutMirroring is enabled. Ref.: https://bugreports.qt-project.org/browse/QTBUG-35095 */ /*! \internal */ onWidthChanged: if (LayoutMirroring.enabled) { // force a relayout lineHeight += 0.00001; lineHeight -= 0.00001; } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Button.qml0000644000015301777760000000667512321005637027043 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Button \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Standard Ubuntu button. \l {http://design.ubuntu.com/apps/building-blocks/buttons}{See also the Design Guidelines on Buttons}. Examples: \qml Column { Button { text: "Send" onClicked: print("clicked text-only Button") } Button { iconName: "compose" gradient: UbuntuColors.greyGradient onClicked: print("clicked icon-only Button") } Button { iconName: "compose" text: "Icon on left" iconPosition: "left" onClicked: print("clicked text and icon Button") } } \endqml An \l Action can be used to specify \b clicked, iconSource and text. Example: \qml Item { Action { id: action1 text: "Click me" onTriggered: print("action!") iconName: "compose" } Button { anchors.centerIn: parent action: action1 color: UbuntuColors.warmGrey } } \endqml */ AbstractButton { id: button /*! The background color of the button. \sa gradient */ property color color: __styleInstance.defaultColor /*! The gradient used to fill the background of the button. Standard Ubuntu gradients are defined in \l UbuntuColors. If both a gradient and a color are specified, the gradient will be used. \sa color */ property Gradient gradient: __styleInstance.defaultGradient /*! The source URL of the icon to display inside the button. Leave this value blank for a text-only button. If \l action is set, the default iconSource is that of the action. \qmlproperty url iconSource */ /*! The text to display in the button. If an icon was defined, the text will be shown next to the icon, otherwise it will be centered. Leave blank for an icon-only button. If \l action is set, the default text is that of the action. \qmlproperty string text */ /*! The position of the icon relative to the text. Options are "left" and "right". The default value is "left". If only text or only an icon is defined, this property is ignored and the text or icon is centered horizontally and vertically in the button. Currently this is a string value. We are waiting for support for enums: https://bugreports.qt-project.org/browse/QTBUG-14861 */ property string iconPosition: "left" style: Theme.createStyleComponent("ButtonStyle.qml", button) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/MainView.qml0000644000015301777760000004125112321005637027274 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Unity.Action 1.1 as UnityActions import Ubuntu.PerformanceMetrics 0.1 import QtQuick.Window 2.0 /*! \qmltype MainView \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief MainView is the root Item that should be used for all applications. It automatically adds a header and toolbar for its contents and can rotate its content based on the device orientation. The simplest way to use a MainView is to include a \l Page object inside the MainView: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Page { title: "Simple page" Button { anchors.centerIn: parent text: "Push me" width: units.gu(15) onClicked: print("Click!") } } } \endqml It is not required to set the anchors of the \l Page as it will automatically fill its parent. The MainView has a header that automatically shows the title of the \l Page. For the MainView to automatically rotate its content following the orientation of the device, set the \l automaticOrientation property to true. If the \l Page inside the MainView includes a Flickable with enough contents for scrolling, the header will automatically hide and show when the user scrolls up or down: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Page { title: "Page with Flickable" Flickable { anchors.fill: parent contentHeight: column.height Column { id: column Repeater { model: 100 Label { text: "line "+index } } } } } } \endqml The same header behavior is automatic when using a ListView instead of a Flickable in the above example. A toolbar can be added to the application by setting the tools property of the \l Page: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(48) height: units.gu(60) Page { title: "Page title" Rectangle { id: rectangle anchors.centerIn: parent width: units.gu(20) height: units.gu(20) color: UbuntuColors.coolGrey } tools: ToolbarItems { ToolbarButton { action: Action { text: "orange" onTriggered: rectangle.color = UbuntuColors.orange } } ToolbarButton { action: Action { text: "purple" onTriggered: rectangle.color = UbuntuColors.lightAubergine } } } } } \endqml The toolbar is hidden by default, but will be made visible when the user performs a bottom-edge-swipe gesture, and hidden when the user swipes it out, or when the active \l Page inside the MainView is changed. The examples above show how to include a single \l Page inside a MainView, but more advanced application structures are possible using \l PageStack and \l Tabs. See \l ToolbarItems for details on how to to control the behavior and contents of the toolbar. */ PageTreeNode { id: mainView /*! \preliminary The property holds the application's name, which must be the same as the desktop file's name. The name also sets the name of the QCoreApplication and defaults for data and cache folders that work on the desktop and under confinement. C++ code that writes files may use QStandardPaths::writableLocation with QStandardPaths::DataLocation or QStandardPaths::CacheLocation. */ property string applicationName: "" /*! \preliminary The property holds if the application should automatically resize the contents when the input method appears The default value is false. */ property bool anchorToKeyboard: false /*! \qmlproperty color headerColor Color of the header's background. \sa backgroundColor, footerColor */ property alias headerColor: background.headerColor /*! \qmlproperty color backgroundColor Color of the background. The background is usually a single color. However if \l headerColor or \l footerColor are set then a gradient of colors will be drawn. For example, in order for the MainView to draw a color gradient beneath the content: \qml import QtQuick 2.0 import Ubuntu.Components 0.1 MainView { width: units.gu(40) height: units.gu(60) headerColor: "#343C60" backgroundColor: "#6A69A2" footerColor: "#8896D5" } \endqml \sa footerColor, headerColor */ property alias backgroundColor: background.backgroundColor /*! \qmlproperty color footerColor Color of the footer's background. \sa backgroundColor, headerColor */ property alias footerColor: background.footerColor // FIXME: Make sure that the theming is only in the background, and the style // should not occlude contents of the MainView. When making changes here, make // sure that bug https://bugs.launchpad.net/manhattan/+bug/1124076 does not come back. StyledItem { id: background anchors.fill: parent style: Theme.createStyleComponent("MainViewStyle.qml", background) property color headerColor: backgroundColor property color backgroundColor: Theme.palette.normal.background property color footerColor: backgroundColor } /*! MainView is active by default. */ active: true /*! \preliminary Sets whether the application will be automatically rotating when the device is. The default value is false. \qmlproperty bool automaticOrientation */ property alias automaticOrientation: canvas.automaticOrientation /*! Setting this option will enable the old toolbar, and disable the new features that are being added to the new header. Unsetting it removes the toolbar and enables developers to have a sneak peek at the new features that are coming to the header, even before all the required functionality is implemented. This property will be deprecated after the new header implementation is done and all apps transitioned to using it. Default value: true. */ property bool useDeprecatedToolbar: true /*! \internal Use default property to ensure children added do not draw over the toolbar. */ default property alias contentsItem: contents.data OrientationHelper { id: canvas automaticOrientation: false // this will make sure that the keyboard does not obscure the contents anchors { bottomMargin: Qt.inputMethod.visible && anchorToKeyboard ? Qt.inputMethod.keyboardRectangle.height : 0 //this is an attempt to keep the keyboard animation in sync with the content resize //but this does not work very well because the keyboard animation has different steps Behavior on bottomMargin { NumberAnimation { easing.type: Easing.InOutQuad } } } // clip the contents so that it does not overlap the header Item { id: contentsClipper anchors { left: parent.left right: parent.right top: headerItem.bottom bottom: parent.bottom } // only clip when necessary // ListView headers may be positioned at the top, independent from // flickable.contentY, so do not clip depending on activePage.flickable.contentY. clip: headerItem.bottomY > 0 && activePage && activePage.flickable property Page activePage: isPage(mainView.activeLeafNode) ? mainView.activeLeafNode : null function isPage(item) { return item && item.hasOwnProperty("__isPageTreeNode") && item.__isPageTreeNode && item.hasOwnProperty("title") && item.hasOwnProperty("tools"); } Item { id: contents anchors { fill: parent // move the whole contents up if the toolbar is locked and opened otherwise the toolbar will obscure part of the contents bottomMargin: mainView.useDeprecatedToolbar && toolbarLoader.item.locked && toolbarLoader.item.opened ? toolbarLoader.item.height + toolbarLoader.item.triggerSize : 0 // compensate so that the actual y is always 0 topMargin: -parent.y } } MouseArea { id: contentsArea anchors.fill: contents // This mouse area will be on top of the page contents, but // under the toolbar and header. // It is used for detecting interaction with the page contents // which can close the toolbar and take a tab bar out of selection mode. onPressed: { mouse.accepted = false; if (mainView.useDeprecatedToolbar) { if (!toolbarLoader.item.locked) { toolbarLoader.item.close(); } } if (headerItem.tabBar && !headerItem.tabBar.alwaysSelectionMode) { headerItem.tabBar.selectionMode = false; } } propagateComposedEvents: true } } /*! Animate header and toolbar. */ property bool animate: true Component { id: toolbarComponent Toolbar { parent: canvas onPressedChanged: { if (!pressed) return; if (headerItem.tabBar !== null) { headerItem.tabBar.selectionMode = false; } } animate: canvas.animate } } Loader { id: toolbarLoader sourceComponent: mainView.useDeprecatedToolbar ? toolbarComponent : null } /*! The header of the MainView. Can be used to obtain the height of the header in \l Page to determine the area for the \l Page to fill. */ Header { // FIXME We need to set an object name to this header in order to differentiate it from the ListItem.Header on Autopilot tests. // This is a temporary workaround while we find a better solution for https://bugs.launchpad.net/autopilot/+bug/1210265 // --elopio - 2013-08-08 objectName: "MainView_Header" id: headerItem property real bottomY: headerItem.y + headerItem.height animate: canvas.animate property Item tabBar: null Binding { target: headerItem property: "tabBar" value: headerItem.contents when: headerItem.contents && headerItem.contents.hasOwnProperty("selectionMode") && headerItem.contents.hasOwnProperty("alwaysSelectionMode") && headerItem.contents.hasOwnProperty("selectedIndex") && headerItem.contents.hasOwnProperty("pressed") } Connections { // no connections are made when target is null target: headerItem.tabBar onPressedChanged: { if (mainView.useDeprecatedToolbar) { if (headerItem.tabBar.pressed) { if (!toolbarLoader.item.locked) toolbarLoader.item.close(); } } } } // 'window' is defined by QML between startup and showing on the screen. // There is no signal for when it becomes available and re-declaring it is not safe. property bool windowActive: typeof window != 'undefined' onWindowActiveChanged: { window.title = headerItem.title } Connections { target: headerItem onTitleChanged: { if (headerItem.windowActive) window.title = headerItem.title } } } Connections { target: Qt.application onActiveChanged: { if (Qt.application.active) { canvas.animate = false; headerItem.show(); if (headerItem.tabBar) { headerItem.tabBar.selectionMode = true; } if (mainView.useDeprecatedToolbar) { if (!toolbarLoader.item.locked) toolbarLoader.item.open(); } canvas.animate = true; } } } } /*! A global list of actions that will be available to the system (including HUD) as long as the application is running. For actions that are not always available to the system, but only when a certain \l Page is active, see the actions property of \l Page. \qmlproperty list actions */ property alias actions: unityActionManager.actions /*! The ActionManager that supervises the global and local ActionContexts. The \l actions property should be used preferably since it covers most use cases. The ActionManager is accessible to have a more refined control over the actions, e.g. if one wants to add/remove actions dynamically, create specific action contexts, etc. \qmlproperty UnityActions.ActionManager actionManager */ property alias actionManager: unityActionManager Object { id: internal UnityActions.ActionManager { id: unityActionManager onQuit: { // FIXME Wire this up to the application lifecycle management API instead of quit(). Qt.quit() } } } __propagated: QtObject { /*! \internal The header that will be propagated to the children in the page tree node. It will be used by the active \l Page to set the title. */ property Header header: headerItem /*! \internal The toolbar that will be propagated to the children in the page tree node. It will be used by the active \l Page to set the toolbar actions. */ property Toolbar toolbar: toolbarLoader.item /*! \internal The action manager that has the global context for the MainView's actions, and to which a local context can be added for each Page that has actions.actions. */ property var actionManager: unityActionManager } /*! \internal */ onApplicationNameChanged: { if (applicationName !== "") { i18n.domain = applicationName; UbuntuApplication.applicationName = applicationName } } PerformanceOverlay { id: performanceOverlay active: false } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/TextArea.qml0000644000015301777760000010404512321005637027273 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "mathUtils.js" as MathUtils /*! \qmltype TextArea \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The TextArea item displays a block of editable, scrollable, formatted text. The TextArea supports fix-size and auto-expanding modes. In fix-size mode the content is scrolled when exceeds the boundaries and can be scrolled both horizontally and vertically, depending on the contentWidth and contentHeight set. The following example will scroll the editing area both horizontally and vertically: \qml TextArea { width: units.gu(20) height: units.gu(12) contentWidth: units.gu(30) contentHeight: units.gu(60) } \endqml The auto-expand mode is realized using two properties: autoSize and maximumLineCount. Setting autoSize will set implicitHeight to one line, and the height will follow the line count, meaning when lines are added the area will expand and when removed the area will shrink. The maximumLineCount specifies how much the editor should be expanded. If this value is set to 0, the area will always expand vertically to fit the content. When autoSize is set, the contentHeight property value is ignored, and the expansion only happens vertically. \qml TextArea { width: units.gu(20) height: units.gu(12) contentWidth: units.gu(30) autoSize: true maximumLineCount: 0 } \endqml TextArea comes with 30 grid-units implicit width and one line height on auto-sizing mode and 4 lines on fixed-mode. The line size is calculated from the font size and the ovarlay and frame spacing specified in the style. Scrolling the editing area can happen when the size is fixed or in auto-sizing mode when the content size is bigger than the visible area. The scrolling is realized by swipe gestures, or by navigating the cursor. The item enters in selection mode when the user performs a long tap (or long mouse press) or a double tap/press on the text area. The mode is visualized by two selection cursors (pins) which can be used to select the desired text. The text can also be selected by moving the finger/mouse towards the desired area right after entering in selection mode. The way the text is selected is driven by the mouseSelectionMode value, which is either character or word. The editor leaves the selection mode by pressing/tapping again on it or by losing focus. \b{This component is under heavy development.} */ StyledItem { id: control implicitWidth: units.gu(30) implicitHeight: (autoSize) ? internal.minimumSize : internal.linesHeight(4) // new properties /*! The property presents whether the TextArea is highlighted or not. By default the TextArea gets highlighted when gets the focus, so can accept text input. This property allows to control the highlight separately from the focused behavior. */ property bool highlighted: focus /*! Text that appears when there is no focus and no content in the component (hint text). \qmlproperty string placeholderText */ property alias placeholderText: hint.text /*! This property contains the text that is displayed on the screen. May differ from the text property value when TextEdit.RichText format is selected. \qmlproperty string displayText */ readonly property alias displayText: internal.displayText /*! The property drives whether text selection should happen with the mouse or not. The default value is true. */ property bool selectByMouse: true /*! \deprecated This property specifies whether the text area expands following the entered text or not. The default value is false. The property is deprecated, use autoSize instead */ property bool autoExpand /*! \internal */ onAutoExpandChanged: console.debug("WARNING: autoExpand deprecated, use autoSize instead.") /*! This property specifies whether the text area sizes following the line count or not. The default value is false. */ property bool autoSize: false /*! The property holds the maximum amount of lines to expand when autoSize is enabled. The value of 0 does not put any upper limit and the control will expand forever. The default value is 5 lines. */ property int maximumLineCount: 5 // altered TextEdit properties /*! The property folds the width of the text editing content. This can be equal or bigger than the frame width minus the spacing between the frame and the input area defined in the current theme. The default value is the same as the visible input area's width. */ property real contentWidth: internal.inputAreaWidth /*! The property folds the height of the text editing content. This can be equal or bigger than the frame height minus the spacing between the frame and the input area defined in the current theme. The default value is the same as the visible input area's height. */ property real contentHeight: internal.inputAreaHeight /*! The property overrides the default popover of the TextArea. When set, the TextArea will open the given popover instead of the default one defined. The popover can either be a component or a URL to be loaded. */ property var popover // forwarded properties /*! Whether the TextArea should gain active focus on a mouse press. By default this is set to true. */ property bool activeFocusOnPress: true /*! This property specifies a base URL which is used to resolve relative URLs within the text. The default value is the url of the QML file instantiating the TextArea item. \qmlproperty url baseUrl */ property alias baseUrl: editor.baseUrl /*! Returns true if the TextArea is writable and the content of the clipboard is suitable for pasting into the TextArea. \qmlproperty bool canPaste */ property alias canPaste: editor.canPaste /*! Returns true if the TextArea is writable and there are undone operations that can be redone. \qmlproperty bool canRedo */ property alias canRedo: editor.canRedo /*! Returns true if the TextArea is writable and there are previous operations that can be undone. \qmlproperty bool canUndo */ property alias canUndo: editor.canUndo /*! The text color. \qmlproperty color color */ property alias color: editor.color /*! The delegate for the cursor in the TextArea. If you set a cursorDelegate for a TextArea, this delegate will be used for drawing the cursor instead of the standard cursor. An instance of the delegate will be created and managed by the text edit when a cursor is needed, and the x and y properties of delegate instance will be set so as to be one pixel before the top left of the current character. Note that the root item of the delegate component must be a QQuickItem or QQuickItem derived item. \qmlproperty Component cursorDelegate */ property alias cursorDelegate: editor.cursorDelegate /*! The position of the cursor in the TextArea. \qmlproperty int cursorPosition */ property alias cursorPosition: editor.cursorPosition /*! The rectangle where the standard text cursor is rendered within the text edit. Read-only. The position and height of a custom cursorDelegate are updated to follow the cursorRectangle automatically when it changes. The width of the delegate is unaffected by changes in the cursor rectangle. \qmlproperty rectangle cursorRectangle */ property alias cursorRectangle: editor.cursorRectangle /*! If true the text edit shows a cursor. This property is set and unset when the text edit gets active focus, but it can also be set directly (useful, for example, if a KeyProxy might forward keys to it). \qmlproperty bool cursorVisible */ property alias cursorVisible: editor.cursorVisible /*! Presents the effective horizontal alignment that can be different from the one specified at horizontalAlignment due to layout mirroring. \qmlproperty enumeration effectiveHorizontalAlignment */ property alias effectiveHorizontalAlignment: editor.effectiveHorizontalAlignment /*! The property holds the font used by the editing. \qmlproperty font font */ property alias font: editor.font /*! Sets the horizontal alignment of the text within the TextAre item's width and height. By default, the text alignment follows the natural alignment of the text, for example text that is read from left to right will be aligned to the left. Valid values for effectiveHorizontalAlignment are: \list \li TextEdit.AlignLeft (default) \li TextEdit.AlignRight \li TextEdit.AlignHCenter \li TextEdit.AlignJustify \endlist \qmlproperty enumeration horizontalAlignment */ property alias horizontalAlignment: editor.horizontalAlignment /*! This property holds whether the TextArea has partial text input from an input method. While it is composing an input method may rely on mouse or key events from the TextArea to edit or commit the partial text. This property can be used to determine when to disable events handlers that may interfere with the correct operation of an input method. \qmlproperty bool inputMethodComposing */ property alias inputMethodComposing: editor.inputMethodComposing /*! Provides hints to the input method about the expected content of the text edit and how it should operate. The value is a bit-wise combination of flags or Qt.ImhNone if no hints are set. Flags that alter behaviour are: \list \li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords. \li Qt.ImhSensitiveData - Typed text should not be stored by the active input method in any persistent storage like predictive user dictionary. \li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case when a sentence ends. \li Qt.ImhPreferNumbers - Numbers are preferred (but not required). \li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required). \li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required). \li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing. \li Qt.ImhDate - The text editor functions as a date field. \li Qt.ImhTime - The text editor functions as a time field. \endlist Flags that restrict input (exclusive flags) are: \list \li Qt.ImhDigitsOnly - Only digits are allowed. \li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign. \li Qt.ImhUppercaseOnly - Only upper case letter input is allowed. \li Qt.ImhLowercaseOnly - Only lower case letter input is allowed. \li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed. \li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed. \li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed. \endlist Masks: \list \li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used. \endlist \qmlproperty enumeration inputMethodHints */ property alias inputMethodHints: editor.inputMethodHints /*! Returns the total number of plain text characters in the TextArea item. As this number doesn't include any formatting markup it may not be the same as the length of the string returned by the text property. This property can be faster than querying the length the text property as it doesn't require any copying or conversion of the TextArea's internal string data. \qmlproperty int length */ property alias length: editor.length /*! Returns the total number of lines in the TextArea item. \qmlproperty int lineCount */ property alias lineCount: editor.lineCount /*! Specifies how text should be selected using a mouse. \list \li TextEdit.SelectCharacters - The selection is updated with individual characters. (Default) \li TextEdit.SelectWords - The selection is updated with whole words. \endlist This property only applies when selectByMouse is true. \qmlproperty enumeration mouseSelectionMode */ property alias mouseSelectionMode: editor.mouseSelectionMode /*! Whether the TextArea should keep the selection visible when it loses active focus to another item in the scene. By default this is set to true; \qmlproperty enumeration persistentSelection */ property alias persistentSelection: editor.persistentSelection /*! Whether the user can interact with the TextArea item. If this property is set to true the text cannot be edited by user interaction. By default this property is false. \qmlproperty bool readOnly */ property alias readOnly: editor.readOnly /*! Override the default rendering type for this component. Supported render types are: \list \li Text.QtRendering - the default \li Text.NativeRendering \endlist Select Text.NativeRendering if you prefer text to look native on the target platform and do not require advanced features such as transformation of the text. Using such features in combination with the NativeRendering render type will lend poor and sometimes pixelated results. \qmlproperty enumeration renderType */ property alias renderType: editor.renderType /*! This read-only property provides the text currently selected in the text edit. \qmlproperty string selectedText */ property alias selectedText: editor.selectedText /*! The selected text color, used in selections. \qmlproperty color selectedTextColor */ property alias selectedTextColor: editor.selectedTextColor /*! The text highlight color, used behind selections. \qmlproperty color selectionColor */ property alias selectionColor: editor.selectionColor /*! The cursor position after the last character in the current selection. This property is read-only. To change the selection, use select(start, end), selectAll(), or selectWord(). See also selectionStart, cursorPosition, and selectedText. \qmlproperty int selectionEnd */ property alias selectionEnd: editor.selectionEnd /*! The cursor position before the first character in the current selection. This property is read-only. To change the selection, use select(start, end), selectAll(), or selectWord(). See also selectionEnd, cursorPosition, and selectedText. \qmlproperty int selectionStart */ property alias selectionStart: editor.selectionStart /*! The text to display. If the text format is AutoText the text edit will automatically determine whether the text should be treated as rich text. This determination is made using Qt::mightBeRichText(). \qmlproperty string text */ property alias text: editor.text /*! The way the text property should be displayed. \list \li TextEdit.AutoText \li TextEdit.PlainText \li TextEdit.RichText \endlist The default is TextEdit.PlainText. If the text format is TextEdit.AutoText the text edit will automatically determine whether the text should be treated as rich text. This determination is made using Qt::mightBeRichText(). \qmlproperty enumeration textFormat */ property alias textFormat: editor.textFormat /*! Sets the vertical alignment of the text within the TextAres item's width and height. By default, the text alignment follows the natural alignment of the text. Valid values for verticalAlignment are: \list \li TextEdit.AlignTop (default) \li TextEdit.AlignBottom \li TextEdit.AlignVCenter \endlist \qmlproperty enumeration verticalAlignment */ property alias verticalAlignment: editor.verticalAlignment /*! Set this property to wrap the text to the TextEdit item's width. The text will only wrap if an explicit width has been set. \list \li TextEdit.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width. \li TextEdit.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width. \li TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word. \li TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. \endlist The default is TextEdit.Wrap \qmlproperty enumeration wrapMode */ property alias wrapMode:editor.wrapMode // signals /*! This handler is called when the user clicks on a link embedded in the text. The link must be in rich text or HTML format and the link string provides access to the particular link. */ signal linkActivated(string link) // functions /*! Copies the currently selected text to the system clipboard. */ function copy() { editor.copy(); } /*! Moves the currently selected text to the system clipboard. */ function cut() { editor.cut(); } /*! Removes active text selection. */ function deselect() { editor.deselect(); } /*! Inserts text into the TextArea at position. */ function insert(position, text) { editor.insert(position, text); } /*! Returns the text position closest to pixel position (x, y). Position 0 is before the first character, position 1 is after the first character but before the second, and so on until position text.length, which is after all characters. */ function positionAt(x, y) { return editor.positionAt(x, y); } /*! Returns true if the natural reading direction of the editor text found between positions start and end is right to left. */ function isRightToLeft(start, end) { return editor.isRightToLeft(start, end) } /*! Moves the cursor to position and updates the selection according to the optional mode parameter. (To only move the cursor, set the cursorPosition property.) When this method is called it additionally sets either the selectionStart or the selectionEnd (whichever was at the previous cursor position) to the specified position. This allows you to easily extend and contract the selected text range. The selection mode specifies whether the selection is updated on a per character or a per word basis. If not specified the selection mode will default to whatever is given in the mouseSelectionMode property. */ function moveCursorSelection(position, mode) { if (mode === undefined) editor.moveCursorSelection(position, mouseSelectionMode); else editor.moveCursorSelection(position, mode); } /*! \preliminary Places the clipboard or the data given as parameter into the text input. The selected text will be replaces with the data. */ function paste(data) { if ((data !== undefined) && (typeof data === "string") && !editor.readOnly) { var selTxt = editor.selectedText; var txt = editor.text; var pos = (selTxt !== "") ? txt.indexOf(selTxt) : editor.cursorPosition if (selTxt !== "") { editor.text = txt.substring(0, pos) + data + txt.substr(pos + selTxt.length); } else { editor.text = txt.substring(0, pos) + data + txt.substr(pos); } editor.cursorPosition = pos + data.length; } else editor.paste(); } /*! Returns the rectangle at the given position in the text. The x, y, and height properties correspond to the cursor that would describe that position. */ function positionToRectangle(position) { return editor.positionToRectangle(position); } /*! Redoes the last operation if redo is \l{canRedo}{available}. */ function redo() { editor.redo(); } /*! Causes the text from start to end to be selected. If either start or end is out of range, the selection is not changed. After calling this, selectionStart will become the lesser and selectionEnd will become the greater (regardless of the order passed to this method). See also selectionStart and selectionEnd. */ function select(start, end) { editor.select(start, end); } /*! Causes all text to be selected. */ function selectAll() { editor.selectAll(); } /*! Causes the word closest to the current cursor position to be selected. */ function selectWord() { editor.selectWord(); } /*! Returns the section of text that is between the start and end positions. The returned text will be formatted according the textFormat property. */ function getFormattedText(start, end) { return editor.getFormattedText(start, end); } /*! Returns the section of text that is between the start and end positions. The returned text does not include any rich text formatting. A getText(0, length) will result in the same value as displayText. */ function getText(start, end) { return editor.getText(start, end); } /*! Removes the section of text that is between the start and end positions from the TextArea. */ function remove(start, end) { return editor.remove(start, end); } /*! Undoes the last operation if undo is \l{canUndo}{available}. Deselects any current selection, and updates the selection start to the current cursor position. */ function undo() { editor.undo(); } /*! \internal Ensure focus propagation */ function forceActiveFocus() { internal.activateEditor(); } // logic /*!\internal - to remove warnings */ Component.onCompleted: { editor.linkActivated.connect(control.linkActivated); internal.prevShowCursor = control.cursorVisible; } // activation area on mouse click // the editor activates automatically when pressed in the editor control, // however that one can be slightly spaced to the main control area //internals opacity: enabled ? 1.0 : 0.3 /*!\internal */ onVisibleChanged: { if (!visible) control.focus = false; } /*!\internal */ onContentWidthChanged: internal.inputAreaWidth = control.contentWidth /*!\internal */ onContentHeightChanged: internal.inputAreaHeight = control.contentHeight /*!\internal */ onWidthChanged: internal.inputAreaWidth = control.width - 2 * internal.frameSpacing /*!\internal */ onHeightChanged: internal.inputAreaHeight = control.height - 2 * internal.frameSpacing LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true /*!\internal */ property alias __internal: internal QtObject { id: internal // public property locals enabling aliasing property string displayText: editor.getText(0, editor.length) property real lineSpacing: units.dp(3) property real frameSpacing: control.__styleInstance.frameSpacing property real lineSize: editor.font.pixelSize + lineSpacing property real minimumSize: units.gu(4) property real inputAreaWidth: control.width - 2 * frameSpacing property real inputAreaHeight: control.height - 2 * frameSpacing //selection properties property bool draggingMode: false property bool selectionMode: false property bool prevShowCursor signal popupTriggered(int pos) onDraggingModeChanged: { if (draggingMode) selectionMode = false; } onSelectionModeChanged: { if (selectionMode) draggingMode = false; else { toggleSelectionCursors(false); } } function toggleSelectionCursors(show) { if (!show) { leftCursorLoader.sourceComponent = undefined; rightCursorLoader.sourceComponent = undefined; editor.cursorVisible = prevShowCursor; } else { prevShowCursor = editor.cursorVisible; editor.cursorVisible = false; leftCursorLoader.sourceComponent = cursor; rightCursorLoader.sourceComponent = cursor; } } function activateEditor() { if (!editor.activeFocus) editor.forceActiveFocus(); else showInputPanel(); } function showInputPanel() { if (!Qt.inputMethod.visible) Qt.inputMethod.show(); } function hideInputPanel() { Qt.inputMethod.hide(); } function linesHeight(lines) { var lineHeight = editor.font.pixelSize * lines + lineSpacing * lines return lineHeight + 2 * frameSpacing; } function frameSize() { if (control.autoSize) { var max = (control.maximumLineCount <= 0) ? control.lineCount : Math.min(control.maximumLineCount, control.lineCount); control.height = linesHeight(MathUtils.clamp(control.lineCount, 1, max)); } } function enterSelectionMode(x, y) { if (undefined !== x && undefined !== y) { control.cursorPosition = control.positionAt(x, y); control.moveCursorSelection(control.cursorPosition + 1); } toggleSelectionCursors(true); } function positionCursor(x, y) { var cursorPos = control.positionAt(x, y); if (control.selectedText === "") control.cursorPosition = cursorPos; else if (control.selectionStart > cursorPos || control.selectionEnd < cursorPos) { control.cursorPosition = cursorPos; } } } // grab Enter/Return keys which may be stolen from parent components of TextArea // due to forwarded keys from TextEdit Keys.onPressed: { if ((event.key === Qt.Key_Enter) || (event.key === Qt.Key_Return)) { if (editor.textFormat === TextEdit.RichText) { // FIXME: use control.paste("
    ") instead when paste() gets sich text support editor.insert(editor.cursorPosition, "
    "); } else { control.paste("\n"); } event.accepted = true; } else { event.accepted = false; } } Keys.onReleased: event.accepted = (event.key === Qt.Key_Enter) || (event.key === Qt.Key_Return) // cursor is FIXME: move in a separate element and align with TextField Component { id: cursor TextCursor { id: cursorItem editorItem: control height: internal.lineSize popover: control.popover visible: editor.cursorVisible Component.onCompleted: internal.popupTriggered.connect(cursorItem.openPopover) } } // selection cursor loader Loader { id: leftCursorLoader onStatusChanged: { if (status == Loader.Ready && item) { item.positionProperty = "selectionStart"; item.parent = editor; } } } Loader { id: rightCursorLoader onStatusChanged: { if (status == Loader.Ready && item) { item.positionProperty = "selectionEnd"; item.parent = editor; } } } // holding default values Label { id: fontHolder } //hint Label { id: hint anchors { fill: parent margins: internal.frameSpacing } // hint is shown till user types something in the field visible: (editor.getText(0, editor.length) == "") && !editor.inputMethodComposing color: Theme.palette.normal.backgroundText fontSize: "medium" elide: Text.ElideRight wrapMode: Text.WordWrap } //scrollbars and flickable Scrollbar { id: rightScrollbar flickableItem: flicker } Scrollbar { id: bottomScrollbar flickableItem: flicker align: Qt.AlignBottom } Flickable { id: flicker anchors { fill: parent margins: internal.frameSpacing } clip: true contentWidth: editor.paintedWidth contentHeight: editor.paintedHeight interactive: !autoSize || (autoSize && maximumLineCount > 0) // do not allow rebounding boundsBehavior: Flickable.StopAtBounds pressDelay: 500 function ensureVisible(r) { if (moving || flicking) return; if (contentX >= r.x) contentX = r.x; else if (contentX+width <= r.x+r.width) contentX = r.x+r.width-width; if (contentY >= r.y) contentY = r.y; else if (contentY+height <= r.y+r.height) contentY = r.y+r.height-height; } // editor // Images are not shown when text contains tags // bug to watch: https://bugreports.qt-project.org/browse/QTBUG-27071 TextEdit { readOnly: false id: editor focus: true onCursorRectangleChanged: flicker.ensureVisible(cursorRectangle) width: internal.inputAreaWidth height: Math.max(internal.inputAreaHeight, editor.contentHeight) wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere mouseSelectionMode: TextEdit.SelectWords selectByMouse: false cursorDelegate: cursor color: control.__styleInstance.color selectedTextColor: Theme.palette.selected.foregroundText selectionColor: Theme.palette.selected.foreground font.pixelSize: FontUtils.sizeToPixels("medium") // forward keys to the root element so it can be captured outside of it Keys.forwardTo: [control] // autosize handling onLineCountChanged: internal.frameSize() // remove selection when typing starts or input method start entering text onInputMethodComposingChanged: { if (inputMethodComposing) internal.selectionMode = false; } Keys.onPressed: { if ((event.text !== "")) internal.selectionMode = false; } Keys.onReleased: { // selection positioners are updated after the keypress if (selectionStart == selectionEnd) internal.selectionMode = false; } // handling text selection MouseArea { id: handler enabled: control.enabled && control.activeFocusOnPress anchors.fill: parent propagateComposedEvents: true onPressed: { internal.activateEditor(); internal.draggingMode = true; } onPressAndHold: { // move mode gets false if there was a mouse move after the press; // this is needed as Flickable will send a pressAndHold in case of // press -> move-pressed ->stop-and-hold-pressed gesture is performed if (!internal.draggingMode) return; internal.draggingMode = false; // open popup internal.positionCursor(mouse.x, mouse.y); internal.popupTriggered(editor.cursorPosition); } onReleased: { internal.draggingMode = false; } onDoubleClicked: { internal.activateEditor(); if (control.selectByMouse) control.selectWord(); } onClicked: { internal.activateEditor(); internal.positionCursor(mouse.x, mouse.y); } } } } style: Theme.createStyleComponent("TextAreaStyle.qml", control) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ActivityIndicator.qml0000644000015301777760000000364012321005637031206 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ActivityIndicator \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The ActivityIndicator component visually indicates that a task of unknown duration is in progress, e.g. busy indication, connection in progress indication, etc. Note: for time consuming JavaScript operations use WorkerScript, otherwise no UI interaction will be possible and the ActicityIndicator animation will freeze. \b{This component is under heavy development.} Example: \qml Item { ActivityIndicator { id: activity } Button { id: toggleActive text: (activity.running) ? "Deactivate" : "Activate" onClicked: activity.running = !activity.running } } \endqml */ AnimatedItem { id: indicator /*! \preliminary Presents whether there is activity to be visualized or not. The default value is false. When activated (set to true), an animation is shown indicating an ongoing activity, which continues until deactivated (set to false). */ property bool running: false implicitWidth: units.gu(3) implicitHeight: units.gu(3) style: Theme.createStyleComponent("ActivityIndicatorStyle.qml", indicator) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/OptionSelector.qml0000644000015301777760000002365312321005637030534 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import "ListItems" as ListItem import Ubuntu.Components 0.1 as Toolkit /*! \qmltype OptionSelector \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu-components \brief Component displaying either a single selected value or expanded multiple choice with an optional image and subtext when not expanded, when expanding it opens a listing of all the possible values for selection with an additional option of always being expanded. If multiple choice is selected the list is expanded automatically. \b{This component is under heavy development.} Examples: \qml import Ubuntu.Components 0.1 Column { spacing: units.gu(3) OptionSelector { text: i18n.tr("Label") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } OptionSelector { text: i18n.tr("Label") expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } OptionSelector { objectName: "optionselector_multipleselection" text: i18n.tr("Multiple Selection") expanded: false multiSelection: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4")] } OptionSelector { text: i18n.tr("Label") model: customModel expanded: true colourImage: true delegate: selectorDelegate } Component { id: selectorDelegate OptionSelectorDelegate { text: name; subText: description; iconSource: image } } ListModel { id: customModel ListElement { name: "Name 1"; description: "Description 1"; image: "images.png" } ListElement { name: "Name 2"; description: "Description 2"; image: "images.png" } ListElement { name: "Name 3"; description: "Description 3"; image: "images.png" } ListElement { name: "Name 4"; description: "Description 4"; image: "images.png" } } OptionSelector { text: i18n.tr("Label") model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } OptionSelector { text: i18n.tr("Label") expanded: true model: [i18n.tr("Value 1"), i18n.tr("Value 2"), i18n.tr("Value 3"), i18n.tr("Value 4"), i18n.tr("Value 5"), i18n.tr("Value 6"), i18n.tr("Value 7"), i18n.tr("Value 8")] containerHeight: itemHeight * 4 } } \endqml */ ListItem.Empty { id: optionSelector /*! \preliminary The list of values that will be shown under the label text. This is a model. */ property var model /*! \preliminary Specifies whether the list is always expanded. */ property bool expanded: false /*! \preliminary If the multiple choice selection is enabled the list is always expanded. */ property bool multiSelection: false /*! \preliminary Colours image according to the fieldText colour of the theme, otherwise source colour is maintained. */ property bool colourImage: false /*! \preliminary ListView delegate. */ property Component delegate: Toolkit.OptionSelectorDelegate {} /*! \preliminary Custom height for list container which allows scrolling inside the selector. */ property real containerHeight: { /*The reason for this slightly unconventional method of setting the container height is due to the fact that if we set it to the selector height by default (which is bound to the colum height) then we wouldn't be able to scroll to the end of the bottom boundary. The text is also invisible if none is set so this is taken into account too.*/ var textHeight = text === "" ? 0 : label.height + column.spacing; if (parent && parent.height < list.contentHeight) { return parent.height - textHeight; } else { list.contentHeight; } } /*! \qmlproperty int selectedIndex The index of the currently selected element in our list. */ property alias selectedIndex: list.currentIndex /*! \qmlproperty bool currentlyExpanded Is our list currently expanded? */ property alias currentlyExpanded: listContainer.currentlyExpanded /*! \qmlproperty real itemHeight Height of an individual list item. */ readonly property alias itemHeight: list.itemHeight /*! Called when delegate is clicked. */ signal delegateClicked(int index) /*! Called when the selector has finished expanding or collapsing. */ signal expansionCompleted() /*! \internal Trigger the action, passing the current index. */ onDelegateClicked: { trigger(index) } __height: column.height showDivider: false Column { id: column spacing: units.gu(2) anchors { left: parent.left right: parent.right } Label { id : label text: optionSelector.text visible: optionSelector.text !== "" ? true : false } StyledItem { id: listContainer objectName: "listContainer" readonly property url chevron: __styleInstance.chevron readonly property url tick: __styleInstance.tick readonly property color themeColour: Theme.palette.selected.fieldText readonly property alias colourImage: optionSelector.colourImage property bool currentlyExpanded: expanded || multiSelection anchors { left: parent.left right: parent.right } state: optionSelector.expanded ? "expanded" : "collapsed" style: Theme.createStyleComponent("OptionSelectorStyle.qml", listContainer) states: [ State { name: "expanded" when: listContainer.currentlyExpanded PropertyChanges { target: listContainer height: list.contentHeight < containerHeight ? list.contentHeight : containerHeight } }, State { name: "collapsed" when: !listContainer.currentlyExpanded PropertyChanges { target: listContainer height: list.itemHeight } } ] transitions: [ Transition { SequentialAnimation { Toolkit.UbuntuNumberAnimation { properties: "height" duration: Toolkit.UbuntuAnimation.BriskDuration } ScriptAction { script: { if (listContainer.currentlyExpanded) { expansionCompleted(); } else { list.positionViewAtIndex(selectedIndex, ListView.Beginning); } } } } } ] ListView { id: list property int previousIndex: -1 readonly property alias expanded: optionSelector.expanded readonly property alias multiSelection: optionSelector.multiSelection readonly property alias container: listContainer property real itemHeight signal delegateClicked(int index) onDelegateClicked: optionSelector.delegateClicked(index); interactive: listContainer.height !== list.contentHeight && listContainer.currentlyExpanded ? true : false clip: true currentIndex: 0 model: optionSelector.model anchors.fill: parent delegate: optionSelector.delegate Behavior on contentY { Toolkit.UbuntuNumberAnimation { properties: "contentY" duration: Toolkit.UbuntuAnimation.BriskDuration } } } } } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/ProgressBar.qml0000644000015301777760000000364312321005637030011 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ProgressBar \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The ProgressBar component visually indicates the progress of a process of determinate or indeterminate duration. \b{This component is under heavy development.} Example: \qml Item { ProgressBar { id: indeterminateBar indeterminate: true } ProgressBar { id: determinateBar minimumValue: -3.0 maximumValue: 15 } } \endqml */ AnimatedItem { id: progressBar /*! \preliminary Specifies whether the progress interval is unknown. When set, altering other properties do not have any effect on the component's behavior. By default the property is set to false. */ property bool indeterminate: false /*! \preliminary Specifies the minimum value of the progress. */ property real minimumValue: 0.0 /*! \preliminary Specifies the maximum value of the progress. */ property real maximumValue: 1.0 /*! \preliminary Specifies the current value of the progress */ property real value: 0.5 style: Theme.createStyleComponent("ProgressBarStyle.qml", progressBar) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Scrollbar.qml0000644000015301777760000001162512321005637027502 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype ScrollBar \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The ScrollBar component provides scrolling functionality for scrollable views (i.e. Flickable, ListView). The ScrollBar can be set to any flickable and has built-in anchoring setup to the attached flickable's front, rear, top or bottom. the scrollbar can also be aligned using anchors, however the built-in align functionality makes sure to have the proper alignemt applied based on theme and layout direction (RTL or LTR). The content position is driven through the attached Flickable. Therefore every style implementation should drive the position through contentX/contentY properties, depending on whether the orientation is vertical or horizontal. Example: \qml Item { ListView { id: list width: units.gu(37) height: units.gu(37) model: 30 delegate: Rectangle { width: ListView.view.width height: units.gu(5) Text { anchors.fill: parent text: "Item " + modelData } } } Scrollbar { flickableItem: list align: Qt.AlignTrailing } } \endqml */ StyledItem { id: scrollbar /*! \preliminary This property holds the flickable item (Flickable, ListView or GridView) the Scrollbar is attached to. */ property Flickable flickableItem: null /*! \preliminary The property defines the alignment of the scrollbar to the flickableItem. The implementation handles the alignment as follows: \list \li Qt.AlignLeading anchors to the left on LTR and to the right on RTL layouts \li Qt.AlignTrailing anchors to the right on LTR and to the left on RTL layouts \li Qt.AlignTop anchors to the top \li Qt.AlignBottom anchors to the bottom \endlist The default value is \b Qt.AlignTrailing. */ property int align: Qt.AlignTrailing /*! \internal This property holds whether the scrollbar is active or passive. It is present for testing purposes. */ property bool __interactive: false implicitWidth: internals.vertical ? units.gu(4) : flickableItem.width implicitHeight: !internals.vertical ? units.gu(4) : flickableItem.height anchors { left: internals.leftAnchor(flickableItem) right: internals.rightAnchor(flickableItem) top: internals.topAnchor(flickableItem) bottom: internals.bottomAnchor(flickableItem) } /*! \internal */ onAlignChanged: if (!internals.checkAlign()) console.log("Wrong alignment set to Scrollbar: "+align) /*! \internal Internals: contains the common logic of the scrollbar like anchoring, alignemt check, scrollability check. */ property alias __private: internals QtObject { id: internals property bool vertical: (align === Qt.AlignLeading) || (align === Qt.AlignTrailing) property bool scrollable: flickableItem && flickableItem.interactive && checkAlign() function checkAlign() { return (align === Qt.AlignLeading) || (align === Qt.AlignTrailing) || (align === Qt.AlignTop) || (align === Qt.AlignBottom); } // LTR and RTL are provided by LayoutMirroring, so no need to check that function leftAnchor(object) { if (!internals.vertical || (align == Qt.AlignLeading)) return object.left; return undefined; } function rightAnchor(object) { if (!internals.vertical || (align == Qt.AlignTrailing)) return object.right; return undefined; } function topAnchor(object) { if (internals.vertical || (align == Qt.AlignTop)) return object.top; return undefined; } function bottomAnchor(object) { if (internals.vertical || (align == Qt.AlignBottom)) return object.bottom; return undefined; } } style: Theme.createStyleComponent("ScrollbarStyle.qml", scrollbar) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Icon.qml0000644000015301777760000000777712321005637026464 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 /*! \qmltype Icon \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief The Icon component displays an icon from the icon theme. The icon theme contains a set of standard icons referred to by their name. Using icons whenever possible enhances consistency accross applications. Each icon has a name and can have different visual representations depending on the size requested. Icons can also be colorized. Setting the \l color property will make all pixels with the \l keyColor (by default #808080) colored. Example: \qml Icon { width: 64 height: 64 name: "search" } \endqml Example of colorization: \qml Icon { width: 64 height: 64 name: "search" color: UbuntuColors.warmGrey } \endqml Icon themes are created following the \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}{Freedesktop Icon Theme Specification}. */ Item { id: icon /*! The name of the icon to display. \qmlproperty string name \note The complete list of icons available in Ubuntu is not published yet. For now please refer to the folders where the icon themes are installed: \list \li Ubuntu Touch: \l file:/usr/share/icons/ubuntu-mobile \li Ubuntu Desktop: \l file:/usr/share/icons/ubuntu-mono-dark \endlist These 2 separate icon themes will be merged soon. */ property string name /*! The color that all pixels that originally are of color \l keyColor should take. \qmlproperty color color */ property alias color: colorizedImage.keyColorOut /*! The color of the pixels that should be colorized. By default it is set to #808080. \qmlproperty color keyColor */ property alias keyColor: colorizedImage.keyColorIn Image { id: image /* Necessary so that icons are not loaded before a size is set. */ property bool ready: false Component.onCompleted: ready = true anchors.fill: parent source: ready && width > 0 && height > 0 && icon.name ? "image://theme/%1".arg(icon.name) : "" sourceSize { width: width height: height } cache: true visible: !colorizedImage.active } ShaderEffect { id: colorizedImage anchors.fill: parent visible: active && image.status == Image.Ready // Whether or not a color has been set. property bool active: keyColorOut != Qt.rgba(0.0, 0.0, 0.0, 0.0) property Image source: visible ? image : null property color keyColorOut: Qt.rgba(0.0, 0.0, 0.0, 0.0) property color keyColorIn: "#808080" property real threshold: 0.1 fragmentShader: " varying highp vec2 qt_TexCoord0; uniform sampler2D source; uniform highp vec4 keyColorOut; uniform highp vec4 keyColorIn; uniform lowp float threshold; uniform lowp float qt_Opacity; void main() { lowp vec4 sourceColor = texture2D(source, qt_TexCoord0); gl_FragColor = mix(vec4(keyColorOut.rgb, 1.0) * sourceColor.a, sourceColor, step(threshold, distance(sourceColor.rgb / sourceColor.a, keyColorIn.rgb))) * qt_Opacity; }" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/Switch.qml0000644000015301777760000000266612321005637027025 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ // FIXME(loicm) It would be nice to have a draggable thumb to toggle the switch, // that needs to be validated with designers though. import QtQuick 2.0 /*! \qmltype Switch \inqmlmodule Ubuntu.Components 0.1 \ingroup ubuntu \brief Switch is a component with two states, checked or unchecked. It can be used to set boolean options. The behavior is the same as \l CheckBox, the only difference is the graphical style. \b{This component is under heavy development.} \l {http://design.ubuntu.com/apps/building-blocks/toggles}{See also the Design Guidelines on Toggles}. Example: \qml Item { Switch { checked: true } } \endqml */ CheckBox { id: switchItem style: Theme.createStyleComponent("SwitchStyle.qml", switchItem) } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Components/deployment.pri0000644000015301777760000000364312321005637027741 0ustar pbusernogroup00000000000000uri = Ubuntu.Components installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) # Components QML_FILES = $$system(ls *.qml) JS_FILES = $$system(ls *.js) # Components/artwork ARTWORK_FILES = $$system(find artwork -type f) # Components/Listitems LISTITEMS_FILES = $$system(find ListItems -maxdepth 1 -type f) LISTITEMS_ARTWORK_FILES = $$system(find ListItems/artwork -type f) # Components/Popups POPUPS_FILES = $$system(find Popups -maxdepth 1 -type f) #Components/Pickers PICKER_FILES = $$system(find Pickers -maxdepth 1 -type f) # qmldir QMLDIR_FILE = qmldir # make found deployables visible in Qt Creator OTHER_FILES += $$QML_FILES $$JS_FILES $$ARTWORK_FILES $$LISTITEMS_FILES $$POPUPS_FILES $$QMLDIR_FILE $$LISTITEMS_ARTWORK_FILES # define deployment for found deployables qmldir_file.path = $$installPath qmldir_file.files = $$QMLDIR_FILE qml_files.path = $$installPath qml_files.files = $$QML_FILES js_files.path = $$installPath js_files.files = $$JS_FILES artwork_files.path = $$installPath/artwork artwork_files.files = $$ARTWORK_FILES listitems_files.path = $$installPath/ListItems listitems_files.files = $$LISTITEMS_FILES listitems_artwork_files.path = $$installPath/ListItems/artwork listitems_artwork_files.files = $$LISTITEMS_ARTWORK_FILES popups_files.path = $$installPath/Popups popups_files.files = $$POPUPS_FILES picker_files.path = $$installPath/Pickers picker_files.files = $$PICKER_FILES plugins_qmltypes.path = $$installPath plugins_qmltypes.files = plugins.qmltypes # Silence spam on stderr due to fonts # https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1256999 # https://bugreports.qt-project.org/browse/QTBUG-36243 plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Components 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes INSTALLS += qmldir_file qml_files js_files artwork_files listitems_files listitems_artwork_files popups_files picker_files plugins_qmltypes ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/0000755000015301777760000000000012321006415026475 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/PerformanceOverlay.qml0000644000015301777760000001060012321005637033015 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.PerformanceMetrics 0.1 as PerformanceMetrics /*! \qmltype PerformanceOverlay \inqmlmodule Ubuntu.PerformanceMetrics 0.1 \ingroup ubuntu-performance-metrics \brief Overlay displaying performance related metrics (rendering time, CPU usage, etc.) PerformanceOverlay displays various performance related indicators to help developers detect issues in their application. Examples: \qml PerformanceOverlay { active: true } \endqml */ Item { id: overlay anchors.fill: parent Component { id: overlayContent Item { MouseArea { anchors.fill: content drag.target: content onClicked: overlay.active = false } Item { id: content x: parent.width - width - units.gu(2) y: units.gu(10) width: units.gu(38) height: childrenRect.height PerformanceMetrics.RenderingTimes { id: renderingTimes period: 2000 samples: renderingTimeGraph.width timerType: PerformanceMetrics.RenderingTimes.Trivial } PerformanceMetrics.CpuUsage { id: cpuUsage period: 5000 samplingInterval: 200 } Column { anchors.left: parent.left anchors.right: parent.right spacing: units.gu(1) BarGraph { id: renderingTimeGraph anchors.left: parent.left anchors.right: parent.right model: renderingTimes.graphModel maximumValue: 20 threshold: 16 labels: [{"color": "darkorange", "value": 10, "label": "10 ms"}, {"color": "red", "value": 16, "label": "16 ms"}] labelFormat: "%1 ms" } BarGraph { id: cpuUsageGraph anchors.left: parent.left anchors.right: parent.right model: cpuUsage.graphModel maximumValue: 100 threshold: 75 labels: [{"color": "green", "value": 25, "label": "25%"}, {"color": "darkorange", "value": 50, "label": "50%"}, {"color": "red", "value": 75, "label": "75%"}] labelFormat: "%1 %" } } } } } /*! Whether or not the PerformanceOverlay is displayed. */ property bool active: true MouseArea { property var timeLastPress property int delayBetweenPresses: 500 property int pressCount: 0 property int pressCountToActivate: 4 anchors.fill: parent enabled: performanceOverlayEnabled onPressed: { mouse.accepted = false; var timePress = new Date().getTime(); if (timeLastPress && timePress - timeLastPress > delayBetweenPresses) { pressCount = 0; } pressCount += 1; if (pressCount >= pressCountToActivate) { overlay.active = true; pressCount = 0; } timeLastPress = timePress; } } Loader { id: loader anchors.fill: parent active: overlay.active asynchronous: true sourceComponent: overlayContent } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/PerformanceMetrics.pro0000644000015301777760000000007712321005637033020 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += plugin include(deployment.pri) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/BarGraph.qml0000644000015301777760000001021512321005637030702 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import Ubuntu.Components 0.1 import Ubuntu.PerformanceMetrics 0.1 as PerformanceMetrics Item { id: graph property var model property real maximumValue property alias labels: labelsRepeater.model property alias backgroundColor: background.color property color color: Qt.rgba(0.4, 0.73, 0.4, 1.0) property real threshold: 16.0 property color aboveThresholdColor: "#ff4e00" property string labelFormat: "%1" implicitWidth: units.gu(38) implicitHeight: units.gu(8) Rectangle { id: background anchors.fill: parent color: Qt.rgba(0.0, 0.0, 0.0, 0.8) } PerformanceMetrics.TextureFromImage { id: texture image: graph.model.image } ShaderEffect { anchors.fill: parent property var texture: texture property real shift: graph.model.shift / graph.model.samples property real maximumValue: graph.maximumValue property color color: graph.color property real threshold: graph.threshold property color aboveThresholdColor: graph.aboveThresholdColor vertexShader: " uniform mediump mat4 qt_Matrix; uniform mediump float shift; attribute mediump vec4 qt_Vertex; attribute mediump vec2 qt_MultiTexCoord0; varying mediump vec2 coord; void main() { coord = qt_MultiTexCoord0 + vec2(shift, 0.0); gl_Position = qt_Matrix * qt_Vertex; }" fragmentShader: " varying mediump vec2 coord; uniform sampler2D texture; uniform lowp float qt_Opacity; uniform lowp float maximumValue; uniform lowp vec4 color; uniform lowp float threshold; uniform lowp vec4 aboveThresholdColor; void main() { lowp vec4 tex = texture2D(texture, vec2(coord.x, coord.y)); lowp float value = tex.r * 255.0; lowp float isOn = 1.0 - step(value / maximumValue, 1.0 - coord.y); lowp float isAboveThreshold = step(threshold, value); gl_FragColor = mix(vec4(0.0), mix(color, aboveThresholdColor, isAboveThreshold), isOn) * qt_Opacity; }" } Repeater { id: labelsRepeater Item { anchors { left: parent.left right: parent.right bottom: parent.bottom bottomMargin: modelData.value / graph.maximumValue * parent.height } Label { id: label anchors { left: parent.left leftMargin: units.gu(0.5) verticalCenter: parent.verticalCenter } text: modelData.label color: modelData.color fontSize: "x-small" } Rectangle { anchors { left: label.right leftMargin: units.gu(0.5) right: parent.right } height: 1 color: modelData.color } } } Label { anchors { top: parent.top topMargin: units.gu(1) right: parent.right rightMargin: units.gu(1) } text: graph.labelFormat.arg(graph.model.currentValue) color: "white" } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/qmldir0000644000015301777760000000021712321005637027715 0ustar pbusernogroup00000000000000module Ubuntu.PerformanceMetrics plugin UbuntuPerformanceMetrics PerformanceOverlay 0.1 PerformanceOverlay.qml internal BarGraph BarGraph.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/0000755000015301777760000000000012321006415027773 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmcpuusage.h0000644000015301777760000000407212321005637032512 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UPMCPUUSAGE_H #define UPMCPUUSAGE_H #include #include #include #include #include #include "upmgraphmodel.h" class UPMCpuUsage : public QQuickItem { Q_OBJECT Q_PROPERTY(UPMGraphModel* graphModel READ graphModel NOTIFY graphModelChanged) Q_PROPERTY(int period READ period WRITE setPeriod NOTIFY periodChanged) Q_PROPERTY(int samplingInterval READ samplingInterval WRITE setSamplingInterval NOTIFY samplingIntervalChanged) public: explicit UPMCpuUsage(QQuickItem* parent = 0); // getters UPMGraphModel* graphModel() const; int period() const; int samplingInterval() const; // setters void setPeriod(int period); void setSamplingInterval(int samplingInterval); Q_SIGNALS: void graphModelChanged(); void periodChanged(); void samplingIntervalChanged(); protected: void itemChange(ItemChange change, const ItemChangeData & value); private Q_SLOTS: void connectToWindow(QQuickWindow* window); void onFrameRendered(); void appendCpuTime(); private: QQuickWindow* m_window; UPMGraphModel* m_graphModel; int m_period; int m_samplingInterval; QTimer m_timer; float m_timingFactor; struct tms m_previousTimes; clock_t m_previousClock; int m_timeAtLastFrame; }; #endif // UPMCPUUSAGE_H ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmrenderingtimes.hubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmrenderingtimes0000644000015301777760000000502212321005637033463 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UPMPERFORMANCE_METRICS_H #define UPMPERFORMANCE_METRICS_H #include #include #include #include "upmgraphmodel.h" #include "rendertimer.h" class UPMRenderingTimes : public QQuickItem { Q_OBJECT Q_PROPERTY(int period READ period WRITE setPeriod NOTIFY periodChanged) Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged) Q_PROPERTY(UPMGraphModel* graphModel READ graphModel NOTIFY graphModelChanged) Q_PROPERTY(RenderTimer::TimerType timerType READ timerType WRITE setTimerType NOTIFY timerTypeChanged) Q_ENUMS(RenderTimer::TimerType) public: explicit UPMRenderingTimes(QQuickItem* parent = 0); // getters int period() const; int samples() const; UPMGraphModel* graphModel() const; RenderTimer::TimerType timerType() const; // setters void setPeriod(int period); void setSamples(int samples); void setTimerType(RenderTimer::TimerType timerType); Q_SIGNALS: void periodChanged(); void samplesChanged(); void graphModelChanged(); void timerTypeChanged(); void frameRendered(qint64 renderTime); protected: void itemChange(ItemChange change, const ItemChangeData & value); private Q_SLOTS: void connectToWindow(QQuickWindow* window); void onSceneGraphInitialized(); void onSceneGraphInvalidated(); void onBeforeRendering(); void onAfterRendering(); void onFrameSwapped(); void onFrameRendered(qint64 renderTime); private: void appendRenderTime(qint64 renderTime); private: int m_period; UPMGraphModel* m_graphModel; RenderTimer::TimerType m_timerType; bool m_needsNewTimer; RenderTimer m_renderingTimer; QQuickWindow* m_window; bool m_oddFrame; qint64 m_oddFrameRenderTime; }; #endif // UPMPERFORMANCE_METRICS_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/rendertimer.cpp0000644000015301777760000002372012321005637033030 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include #include "rendertimer.h" #if !defined(GL_TIME_ELAPSED) #define GL_TIME_ELAPSED 0x88BF #endif RenderTimer::RenderTimer(QObject* parent) : QObject(parent), m_type(RenderTimer::Trivial) { } bool RenderTimer::isAvailable(TimerType type) { if (type == RenderTimer::Trivial) { return true; #if defined(QT_OPENGL_ES) } else if (type == RenderTimer::KHRFence) { QList eglExtensions = QByteArray( static_cast(eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS))).split(' '); QList glExtensions = QByteArray( reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); // Note the workaround for PowerVR that declares 'GL_OES_egl_sync'. return eglExtensions.contains("EGL_KHR_fence_sync") && (glExtensions.contains("GL_OES_EGL_sync") || glExtensions.contains("GL_OES_egl_sync")); } else if (type == RenderTimer::NVFence) { QList glExtensions = QByteArray( reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); return glExtensions.contains("GL_NV_fence"); #else } else if (type == RenderTimer::ARBTimerQuery) { // We could use the thin QOpenGLTimerQuery wrapper from Qt 5.1, but the lack of a method to check // the presence of glQueryCounter() would force us to inspect OpenGL version and extensions, which // is basically as annoying as doing the whole thing here. // TODO(loicm) Add an hasQuerycounter() method to QOpenGLTimerQuery. QOpenGLContext* context = QOpenGLContext::currentContext(); QSurfaceFormat format = context->format(); return qMakePair(format.majorVersion(), format.minorVersion()) >= qMakePair(3, 2) && context->hasExtension(QByteArrayLiteral("GL_ARB_timer_query")); } else if (type == RenderTimer::EXTTimerQuery) { QOpenGLContext* context = QOpenGLContext::currentContext(); return context->hasExtension(QByteArrayLiteral("GL_EXT_timer_query")); #endif } return false; } RenderTimer::TimerType RenderTimer::optimalTimerType() { QList types; #if defined(QT_OPENGL_ES) types << RenderTimer::KHRFence << RenderTimer::NVFence; #else types << RenderTimer::ARBTimerQuery << RenderTimer::EXTTimerQuery; #endif Q_FOREACH(TimerType type, types) { if (RenderTimer::isAvailable(type)) { return type; } } return RenderTimer::Trivial; } void RenderTimer::setup(TimerType type) { if (type == RenderTimer::Automatic) { type = RenderTimer::optimalTimerType(); } m_type = type; if (m_type == RenderTimer::Trivial) { #if defined(QT_OPENGL_ES) } else if (m_type == RenderTimer::KHRFence) { m_fenceSyncKHR.createSyncKHR = reinterpret_cast< EGLSyncKHR (QOPENGLF_APIENTRYP)(EGLDisplay, EGLenum, const EGLint*)>( eglGetProcAddress("eglCreateSyncKHR")); m_fenceSyncKHR.destroySyncKHR = reinterpret_cast< EGLBoolean (QOPENGLF_APIENTRYP)(EGLDisplay, EGLSyncKHR)>( eglGetProcAddress("eglDestroySyncKHR")); m_fenceSyncKHR.clientWaitSyncKHR = reinterpret_cast< EGLint (QOPENGLF_APIENTRYP)(EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR)>( eglGetProcAddress("eglClientWaitSyncKHR")); } else if (m_type == RenderTimer::NVFence) { m_fenceNV.genFencesNV = reinterpret_cast( eglGetProcAddress("glGenFencesNV")); m_fenceNV.deleteFencesNV = reinterpret_cast( eglGetProcAddress("glDeleteFencesNV")); m_fenceNV.setFenceNV = reinterpret_cast( eglGetProcAddress("glSetFenceNV")); m_fenceNV.finishFenceNV = reinterpret_cast( eglGetProcAddress("glFinishFenceNV")); m_fenceNV.genFencesNV(2, m_fence); #else } else if (m_type == RenderTimer::ARBTimerQuery) { QOpenGLContext* context = QOpenGLContext::currentContext(); m_timerQuery.genQueries = reinterpret_cast( context->getProcAddress("glGenQueries")); m_timerQuery.deleteQueries = reinterpret_cast( context->getProcAddress("glDeleteQueries")); m_timerQuery.getQueryObjectui64v = reinterpret_cast( context->getProcAddress("glGetQueryObjectui64v")); m_timerQuery.queryCounter = reinterpret_cast( context->getProcAddress("glQueryCounter")); m_timerQueryVersion = TimerQueryCore; m_timerQuery.genQueries(2, m_timer); } else if (m_type == RenderTimer::EXTTimerQuery) { QOpenGLContext* context = QOpenGLContext::currentContext(); m_timerQuery.genQueries = reinterpret_cast( context->getProcAddress("glGenQueries")); m_timerQuery.deleteQueries = reinterpret_cast( context->getProcAddress("glDeleteQueries")); m_timerQuery.beginQuery = reinterpret_cast( context->getProcAddress("glBeginQuery")); m_timerQuery.endQuery = reinterpret_cast( context->getProcAddress("glEndQuery")); m_timerQuery.getQueryObjectui64vExt = reinterpret_cast( context->getProcAddress("glGetQueryObjectui64vEXT")); m_timerQueryVersion = TimerQueryExt; m_timerQuery.genQueries(1, m_timer); #endif } } void RenderTimer::teardown() { teardown(m_type); } void RenderTimer::teardown(TimerType type) { if (type == RenderTimer::Trivial) { #if defined(QT_OPENGL_ES) } else if (type == RenderTimer::KHRFence) { if (m_beforeSync != EGL_NO_SYNC_KHR) { m_fenceSyncKHR.destroySyncKHR(eglGetCurrentDisplay(), m_beforeSync); } } else if (type == RenderTimer::NVFence) { m_fenceNV.deleteFencesNV(2, m_fence); #else } else if (type == RenderTimer::ARBTimerQuery) { m_timerQuery.deleteQueries(2, m_timer); } else if (type == RenderTimer::EXTTimerQuery) { m_timerQuery.deleteQueries(1, m_timer); #endif } } void RenderTimer::start() { if (m_type == RenderTimer::Trivial) { m_trivialTimer.start(); #if defined(QT_OPENGL_ES) } else if (m_type == RenderTimer::KHRFence) { m_beforeSync = m_fenceSyncKHR.createSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_FENCE_KHR, NULL); } else if (m_type == RenderTimer::NVFence) { m_fenceNV.setFenceNV(m_fence[0], GL_ALL_COMPLETED_NV); #else } else if (m_type == RenderTimer::ARBTimerQuery) { m_timerQuery.queryCounter(m_timer[0], GL_TIMESTAMP); } else if (m_type == RenderTimer::EXTTimerQuery) { m_timerQuery.beginQuery(GL_TIME_ELAPSED, m_timer[0]); #endif } } qint64 RenderTimer::stop() { if (m_type == RenderTimer::Trivial) { glFinish(); return m_trivialTimer.nsecsElapsed(); #if defined(QT_OPENGL_ES) } else if (m_type == RenderTimer::KHRFence) { QElapsedTimer timer; EGLDisplay dpy = eglGetCurrentDisplay(); EGLSyncKHR afterSync = m_fenceSyncKHR.createSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); EGLint beforeSyncValue = m_fenceSyncKHR.clientWaitSyncKHR(dpy, m_beforeSync, 0, EGL_FOREVER_KHR); qint64 beforeTime = timer.nsecsElapsed(); EGLint afterSyncValue = m_fenceSyncKHR.clientWaitSyncKHR(dpy, afterSync, 0, EGL_FOREVER_KHR); qint64 afterTime = timer.nsecsElapsed(); m_fenceSyncKHR.destroySyncKHR(dpy, afterSync); m_fenceSyncKHR.destroySyncKHR(dpy, m_beforeSync); m_beforeSync = EGL_NO_SYNC_KHR; if (beforeSyncValue == EGL_CONDITION_SATISFIED_KHR && afterSyncValue == EGL_CONDITION_SATISFIED_KHR) { return afterTime - beforeTime; } else { return -1; } } else if (m_type == RenderTimer::NVFence) { QElapsedTimer timer; m_fenceNV.setFenceNV(m_fence[1], GL_ALL_COMPLETED_NV); m_fenceNV.finishFenceNV(m_fence[0]); qint64 beforeTime = timer.nsecsElapsed(); m_fenceNV.finishFenceNV(m_fence[1]); qint64 afterTime = timer.nsecsElapsed(); return afterTime - beforeTime; #else } else if (m_type == RenderTimer::ARBTimerQuery) { GLuint64 time[2] = { 0, 0 }; m_timerQuery.queryCounter(m_timer[1], GL_TIMESTAMP); m_timerQuery.getQueryObjectui64v(m_timer[0], GL_QUERY_RESULT, &time[0]); m_timerQuery.getQueryObjectui64v(m_timer[1], GL_QUERY_RESULT, &time[1]); if (time[0] != 0 && time[1] != 0) { return time[1] - time[0]; } else { return -1; } } else if (m_type == RenderTimer::EXTTimerQuery) { GLuint64EXT time; m_timerQuery.endQuery(GL_TIME_ELAPSED); m_timerQuery.getQueryObjectui64vExt(m_timer[0], GL_QUERY_RESULT, &time); return static_cast(time); #endif } return 0; } ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmrenderingtimes.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmrenderingtimes0000644000015301777760000001300412321005637033462 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "upmrenderingtimes.h" #include UPMRenderingTimes::UPMRenderingTimes(QQuickItem* parent) : QQuickItem(parent), m_period(1000), m_graphModel(new UPMGraphModel(this)), m_timerType(RenderTimer::Automatic), m_needsNewTimer(true), m_window(NULL), m_oddFrame(false), m_oddFrameRenderTime(0) { /* Forward samplesChanged signal from graphModel */ QObject::connect(m_graphModel, &UPMGraphModel::samplesChanged, this, &UPMRenderingTimes::samplesChanged); /* Periodically append render time of the most costly frame rendered. The period is period / samples */ QObject::connect(this, &UPMRenderingTimes::frameRendered, this, &UPMRenderingTimes::onFrameRendered); } int UPMRenderingTimes::period() const { return m_period; } void UPMRenderingTimes::setPeriod(int period) { if (period != m_period) { m_period = period; Q_EMIT periodChanged(); } } int UPMRenderingTimes::samples() const { return m_graphModel->samples(); } void UPMRenderingTimes::setSamples(int samples) { m_graphModel->setSamples(samples); } UPMGraphModel* UPMRenderingTimes::graphModel() const { return m_graphModel; } RenderTimer::TimerType UPMRenderingTimes::timerType() const { return m_timerType; } void UPMRenderingTimes::setTimerType(RenderTimer::TimerType timerType) { if (timerType != m_timerType) { m_timerType = timerType; // setup/teardown of RenderTimers need to happen in the rendering thread m_needsNewTimer = true; Q_EMIT timerTypeChanged(); } } // FIXME: can be replaced with connecting to windowChanged() signal introduced in Qt5.2 void UPMRenderingTimes::itemChange(ItemChange change, const ItemChangeData & value) { if (change == QQuickItem::ItemSceneChange) { connectToWindow(value.window); } QQuickItem::itemChange(change, value); } void UPMRenderingTimes::connectToWindow(QQuickWindow* window) { if (window != m_window) { if (m_window != NULL) { QObject::disconnect(m_window, &QQuickWindow::sceneGraphInitialized, this, &UPMRenderingTimes::onSceneGraphInitialized); QObject::disconnect(m_window, &QQuickWindow::sceneGraphInvalidated, this, &UPMRenderingTimes::onSceneGraphInvalidated); QObject::disconnect(m_window, &QQuickWindow::beforeRendering, this, &UPMRenderingTimes::onBeforeRendering); QObject::disconnect(m_window, &QQuickWindow::afterRendering, this, &UPMRenderingTimes::onAfterRendering); QObject::disconnect(m_window, &QQuickWindow::frameSwapped, this, &UPMRenderingTimes::onFrameSwapped); } m_window = window; if (m_window != NULL) { QObject::connect(m_window, &QQuickWindow::sceneGraphInitialized, this, &UPMRenderingTimes::onSceneGraphInitialized, Qt::DirectConnection); QObject::connect(m_window, &QQuickWindow::sceneGraphInvalidated, this, &UPMRenderingTimes::onSceneGraphInvalidated, Qt::DirectConnection); QObject::connect(m_window, &QQuickWindow::beforeRendering, this, &UPMRenderingTimes::onBeforeRendering, Qt::DirectConnection); QObject::connect(m_window, &QQuickWindow::afterRendering, this, &UPMRenderingTimes::onAfterRendering, Qt::DirectConnection); QObject::connect(m_window, &QQuickWindow::frameSwapped, this, &UPMRenderingTimes::onFrameSwapped, Qt::DirectConnection); } } } void UPMRenderingTimes::onSceneGraphInitialized() { m_renderingTimer.setup(m_timerType); } void UPMRenderingTimes::onSceneGraphInvalidated() { m_renderingTimer.teardown(); } void UPMRenderingTimes::onBeforeRendering() { if (m_needsNewTimer) { m_renderingTimer.teardown(); m_renderingTimer.setup(m_timerType); m_needsNewTimer = false; } m_renderingTimer.start(); } void UPMRenderingTimes::onAfterRendering() { Q_EMIT frameRendered(m_renderingTimer.stop()); } void UPMRenderingTimes::onFrameSwapped() { } void UPMRenderingTimes::onFrameRendered(qint64 renderTime) { if (!m_oddFrame) { appendRenderTime(m_oddFrameRenderTime); appendRenderTime(renderTime); } else { m_oddFrameRenderTime = renderTime; } m_oddFrame = !m_oddFrame; } void UPMRenderingTimes::appendRenderTime(qint64 renderTime) { int renderTimeInMs = qCeil((qreal)renderTime / 1000000); int width = ((qreal)samples() / m_period) * renderTimeInMs; m_graphModel->appendValue(width, renderTimeInMs); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmgraphmodel.cpp0000644000015301777760000000445412321005637033357 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "upmgraphmodel.h" #include UPMGraphModel::UPMGraphModel(QObject *parent) : QObject(parent), m_shift(0), m_samples(100), m_currentValue(0) { m_image = QImage(m_samples, 1, QImage::Format_RGB32); m_image.fill(0); } void UPMGraphModel::appendValue(int width, int value) { /* FIXME: modifying m_image here implicitly triggers a deep copy of its data because UCTextureFromImage usually holds a reference to that image */ width = qMax(1, width); QRgb* line = (QRgb*)m_image.scanLine(0); if (width >= m_image.width()) { memset(&line[0], value, m_image.width() * 4); } else if (m_shift + width > m_image.width()) { int after = m_image.width() - m_shift; int before = width - after; memset(&line[m_shift], value, after * 4); memset(&line[0], value, before * 4); } else { memset(&line[m_shift], value, width * 4); } m_shift = (m_shift + width) % m_samples; m_currentValue = value; Q_EMIT imageChanged(); Q_EMIT shiftChanged(); Q_EMIT currentValueChanged(); } QImage UPMGraphModel::image() const { return m_image; } int UPMGraphModel::shift() const { return m_shift; } int UPMGraphModel::samples() const { return m_samples; } void UPMGraphModel::setSamples(int samples) { if (samples != m_samples) { m_samples = samples; m_image = QImage(m_samples, 1, QImage::Format_RGB32); m_image.fill(0); Q_EMIT samplesChanged(); Q_EMIT imageChanged(); } } int UPMGraphModel::currentValue() const { return m_currentValue; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/plugin.pro0000644000015301777760000000127512321005637032025 0ustar pbusernogroup00000000000000TEMPLATE = lib TARGET = ../UbuntuPerformanceMetrics QT += qml quick CONFIG += qt plugin no_keywords QMAKE_CXXFLAGS += -Werror TARGET = $$qtLibraryTarget($$TARGET) uri = Ubuntu.PerformanceMetrics # Input SOURCES += \ upmplugin.cpp \ upmgraphmodel.cpp \ upmtexturefromimage.cpp \ upmrenderingtimes.cpp \ upmcpuusage.cpp \ rendertimer.cpp HEADERS += \ upmplugin.h \ upmgraphmodel.h \ upmtexturefromimage.h \ upmrenderingtimes.h \ upmcpuusage.h \ rendertimer.h contains(QT_CONFIG, opengles2) { CONFIG += egl } # deployment rules for the plugin installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) target.path = $$installPath INSTALLS += target ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmtexturefromimage.cppubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmtexturefromima0000644000015301777760000000535712321005637033532 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include #include "upmtexturefromimage.h" UPMTextureFromImageTextureProvider::UPMTextureFromImageTextureProvider() : QSGTextureProvider(), m_texture(NULL) { } UPMTextureFromImageTextureProvider::~UPMTextureFromImageTextureProvider() { if (m_texture != NULL) { delete m_texture; } } QSGTexture* UPMTextureFromImageTextureProvider::texture() const { return m_texture; } void UPMTextureFromImageTextureProvider::setTexture(QSGTexture* texture) { if (m_texture != NULL) { delete m_texture; } m_texture = texture; // FIXME: hardcoded flag if (m_texture != NULL) { m_texture->setHorizontalWrapMode(QSGTexture::Repeat); } } UPMTextureFromImage::UPMTextureFromImage(QQuickItem* parent) : QQuickItem(parent), m_textureProvider(NULL), m_textureNeedsUpdate(true) { setFlag(QQuickItem::ItemHasContents); } UPMTextureFromImage::~UPMTextureFromImage() { if (m_textureProvider != NULL) { m_textureProvider->deleteLater(); } } bool UPMTextureFromImage::isTextureProvider() const { return true; } QSGTextureProvider* UPMTextureFromImage::textureProvider() const { if (m_textureProvider == NULL) { const_cast(this)->m_textureProvider = new UPMTextureFromImageTextureProvider; m_textureProvider->setTexture(window()->createTextureFromImage(m_image)); } return m_textureProvider; } QSGNode* UPMTextureFromImage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData) { Q_UNUSED(oldNode) Q_UNUSED(updatePaintNodeData) if (m_textureNeedsUpdate && m_textureProvider != NULL) { m_textureProvider->setTexture(window()->createTextureFromImage(m_image)); m_textureNeedsUpdate = false; } return NULL; } QImage UPMTextureFromImage::image() const { return m_image; } void UPMTextureFromImage::setImage(QImage image) { if (image != m_image) { m_image = image; Q_EMIT imageChanged(); m_textureNeedsUpdate = true; update(); } } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/rendertimer.h0000644000015301777760000000614712321005637032501 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef RENDERTIMER_H #define RENDERTIMER_H #include #include #include #include #if defined(QT_OPENGL_ES) #include #include #endif class RenderTimer : public QObject { Q_OBJECT Q_ENUMS(TimerType) public: enum TimerType { Automatic, Trivial, #if defined(QT_OPENGL_ES) KHRFence, NVFence, #else ARBTimerQuery, EXTTimerQuery #endif }; explicit RenderTimer(QObject* parent = 0); static bool isAvailable(TimerType type); static TimerType optimalTimerType(); void setup(TimerType type); void teardown(); void start(); qint64 stop(); protected: void teardown(TimerType type); private: TimerType m_type; QElapsedTimer m_trivialTimer; #if defined(QT_OPENGL_ES) struct { void (QOPENGLF_APIENTRYP genFencesNV)(GLsizei n, GLuint* fences); void (QOPENGLF_APIENTRYP deleteFencesNV)(GLsizei n, const GLuint* fences); void (QOPENGLF_APIENTRYP setFenceNV)(GLuint fence, GLenum condition); void (QOPENGLF_APIENTRYP finishFenceNV)(GLuint fence); } m_fenceNV; GLuint m_fence[2]; struct { EGLSyncKHR (QOPENGLF_APIENTRYP createSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list); EGLBoolean (QOPENGLF_APIENTRYP destroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync); EGLint (QOPENGLF_APIENTRYP clientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); } m_fenceSyncKHR; EGLSyncKHR m_beforeSync; #else struct { void (QOPENGLF_APIENTRYP genQueries)(GLsizei n, GLuint* ids); void (QOPENGLF_APIENTRYP deleteQueries)(GLsizei n, const GLuint* ids); void (QOPENGLF_APIENTRYP beginQuery)(GLenum target, GLuint id); void (QOPENGLF_APIENTRYP endQuery)(GLenum target); void (QOPENGLF_APIENTRYP getQueryObjectui64v)(GLuint id, GLenum pname, GLuint64* params); void (QOPENGLF_APIENTRYP getQueryObjectui64vExt)(GLuint id, GLenum pname, GLuint64EXT* params); void (QOPENGLF_APIENTRYP queryCounter)(GLuint id, GLenum target); } m_timerQuery; enum { TimerQueryUnavailable, TimerQueryCore, TimerQueryExt } m_timerQueryVersion; GLuint m_timer[2]; #endif }; #endif // RENDERTIMER_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmplugin.cpp0000644000015301777760000000321312321005637032523 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "upmplugin.h" #include "upmcpuusage.h" #include "upmtexturefromimage.h" #include "upmgraphmodel.h" #include #include #include #include "upmrenderingtimes.h" void UbuntuPerformanceMetricsPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("Ubuntu.PerformanceMetrics")); qmlRegisterType(uri, 0, 1, "RenderingTimes"); qmlRegisterType(uri, 0, 1, "CpuUsage"); qmlRegisterType(uri, 0, 1, "TextureFromImage"); qmlRegisterType(); } void UbuntuPerformanceMetricsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { QQmlExtensionPlugin::initializeEngine(engine, uri); QQmlContext* context = engine->rootContext(); QByteArray performanceOverlay = qgetenv("PERFORMANCE_OVERLAY"); context->setContextProperty("performanceOverlayEnabled", QVariant(!performanceOverlay.isEmpty())); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmgraphmodel.h0000644000015301777760000000316512321005637033022 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UPMGRAPHMODEL_H #define UPMGRAPHMODEL_H #include #include class UPMGraphModel : public QObject { Q_OBJECT Q_PROPERTY(QImage image READ image NOTIFY imageChanged) Q_PROPERTY(int shift READ shift NOTIFY shiftChanged) Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged) Q_PROPERTY(int currentValue READ currentValue NOTIFY currentValueChanged) public: explicit UPMGraphModel(QObject *parent = 0); void appendValue(int width, int value); // getters QImage image() const; int shift() const; int samples() const; int currentValue() const; // setters void setSamples(int samples); Q_SIGNALS: void imageChanged(); void shiftChanged(); void samplesChanged(); void currentValueChanged(); private: QImage m_image; int m_shift; int m_samples; int m_currentValue; }; #endif // UPMGRAPHMODEL_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmplugin.h0000644000015301777760000000220012321005637032163 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UBUNTU_PERFORMANCE_METRICS_PLUGIN_H #define UBUNTU_PERFORMANCE_METRICS_PLUGIN_H #include class UbuntuPerformanceMetricsPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri); void initializeEngine(QQmlEngine *engine, const char *uri); }; #endif // UBUNTU_PERFORMANCE_METRICS_PLUGIN_H ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmtexturefromimage.hubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmtexturefromima0000644000015301777760000000347412321005637033530 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #ifndef UPMTEXTUREFROMIMAGE_H #define UPMTEXTUREFROMIMAGE_H #include #include class UPMTextureFromImageTextureProvider : public QSGTextureProvider { Q_OBJECT public: explicit UPMTextureFromImageTextureProvider(); virtual ~UPMTextureFromImageTextureProvider(); QSGTexture* texture() const; void setTexture(QSGTexture* texture); private: QSGTexture* m_texture; }; class UPMTextureFromImage : public QQuickItem { Q_OBJECT Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged) public: explicit UPMTextureFromImage(QQuickItem* parent = 0); virtual ~UPMTextureFromImage(); bool isTextureProvider() const; QSGTextureProvider* textureProvider() const; QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData); // getter QImage image() const; // setters void setImage(QImage image); Q_SIGNALS: void imageChanged(); private: UPMTextureFromImageTextureProvider* m_textureProvider; QImage m_image; bool m_textureNeedsUpdate; }; #endif // UPMTEXTUREFROMIMAGE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/plugin/upmcpuusage.cpp0000644000015301777760000000741112321005637033045 0ustar pbusernogroup00000000000000/* * Copyright 2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Florian Boucault */ #include "upmcpuusage.h" #include UPMCpuUsage::UPMCpuUsage(QQuickItem *parent) : QQuickItem(parent), m_window(NULL), m_graphModel(new UPMGraphModel(this)), m_period(5000), m_samplingInterval(500), m_timeAtLastFrame(0) { m_timingFactor = 100.0f / sysconf(_SC_NPROCESSORS_ONLN); m_previousClock = times(&m_previousTimes); QObject::connect(&m_timer, &QTimer::timeout, this, &UPMCpuUsage::appendCpuTime); m_timer.setSingleShot(false); m_timer.setInterval(m_samplingInterval); m_timer.start(); } UPMGraphModel* UPMCpuUsage::graphModel() const { return m_graphModel; } int UPMCpuUsage::period() const { return m_period; } void UPMCpuUsage::setPeriod(int period) { if (period != m_period) { m_period = period; m_graphModel->setSamples(m_period / m_samplingInterval); Q_EMIT periodChanged(); } } int UPMCpuUsage::samplingInterval() const { return m_samplingInterval; } void UPMCpuUsage::setSamplingInterval(int samplingInterval) { if (samplingInterval != m_samplingInterval) { m_samplingInterval = samplingInterval; m_graphModel->setSamples(m_period / m_samplingInterval); m_timer.setInterval(m_samplingInterval); Q_EMIT samplingIntervalChanged(); } } // FIXME: can be replaced with connecting to windowChanged() signal introduced in Qt5.2 void UPMCpuUsage::itemChange(ItemChange change, const ItemChangeData & value) { if (change == QQuickItem::ItemSceneChange) { connectToWindow(value.window); } QQuickItem::itemChange(change, value); } void UPMCpuUsage::connectToWindow(QQuickWindow* window) { if (window != m_window) { if (m_window != NULL) { QObject::disconnect(m_window, &QQuickWindow::beforeSynchronizing, this, &UPMCpuUsage::onFrameRendered); } if (window != NULL) { QObject::connect(window, &QQuickWindow::beforeSynchronizing, this, &UPMCpuUsage::onFrameRendered); } m_window = window; } } void UPMCpuUsage::onFrameRendered() { /* A frame has been rendered: - if measuring CPU usage is diabled then restart it - otherwise store the time of the rendering */ if (!m_timer.isActive()) { m_timer.start(); } else { m_timeAtLastFrame = m_timer.remainingTime(); } } void UPMCpuUsage::appendCpuTime() { // if last frame was over 80% of the timer's interval ago, then stop measuring CPU usage if (m_timeAtLastFrame >= 0.8 * m_timer.interval()) { m_timer.stop(); return; } struct tms newTimes; clock_t newClock = times(&newTimes); float elapsed = (newTimes.tms_utime + newTimes.tms_stime - m_previousTimes.tms_utime - m_previousTimes.tms_stime) / (float)(newClock - m_previousClock); memcpy(&m_previousTimes, &newTimes, sizeof(tms)); m_previousClock = newClock; int width = ((qreal)m_graphModel->samples() / m_period) * m_samplingInterval; m_graphModel->appendValue(width, elapsed * m_timingFactor); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/PerformanceMetrics/deployment.pri0000644000015301777760000000135312321005637031400 0ustar pbusernogroup00000000000000uri = Ubuntu.PerformanceMetrics installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) # Components QML_FILES = $$system(ls *.qml) # qmldir QMLDIR_FILE = qmldir # make found deployables visible in Qt Creator OTHER_FILES += $$QMLDIR_FILE OTHER_FILES += $$QML_FILES $$QMLDIR_FILE # define deployment for found deployables qmldir_file.path = $$installPath qmldir_file.files = $$QMLDIR_FILE qml_files.path = $$installPath qml_files.files = $$QML_FILES plugins_qmltypes.path = $$installPath plugins_qmltypes.files = plugins.qmltypes plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.PerformanceMetrics 0.1 ../../ > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes INSTALLS += qmldir_file qml_files plugins_qmltypes ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/0000755000015301777760000000000012321006415024345 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/Layouts.pro0000644000015301777760000000007712321005637026540 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += plugin include(deployment.pri) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/qmldir0000644000015301777760000000005412321005637025564 0ustar pbusernogroup00000000000000module Ubuntu.Layouts plugin UbuntuLayouts ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/0000755000015301777760000000000012321006415025643 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ullayoutsattached.cpp0000644000015301777760000000466112321005637032122 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ullayouts.h" #include "ullayouts_p.h" #include #include ULLayoutsAttached::ULLayoutsAttached(QObject *parent) : QObject(parent) , m_valid(false) { // workaround to get notified about attachee completion to check // whether the attachee belongs to a Layouts component or not // connect to one of the attached components to receive completion QQmlComponentAttached *component = QQmlComponent::qmlAttachedProperties(parent); if (component) { QObject::connect(component, SIGNAL(completed()), this, SLOT(validateAttachedProperties())); } } /*! * \internal * Validates the attachee by checking whether its ascendant is a Layouts component or not. */ void ULLayoutsAttached::validateAttachedProperties() { QQuickItem *pl = qobject_cast(parent()); while (pl) { if (qobject_cast(pl)) { m_valid = !m_name.isEmpty(); return; } pl = pl->parentItem(); } ULLayoutsPrivate::error(parent(), "Item that is not a child of a Layouts component will not be laid out."); m_valid = false; } /*! * \qmlattachedproperty string Layouts::item * This attached property identifies a component to be laid out. It is the unique * identifier of the component within a layout block. The property can be attached * to components to be laid out and has no effect when applied on layout containers. * \sa ItemLayout */ QString ULLayoutsAttached::item() const { return m_name; } void ULLayoutsAttached::setItem(const QString &name) { if (name == m_name) { return; } m_name = name; Q_EMIT itemChanged(); } bool ULLayoutsAttached::isValid() { return m_valid; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ullayouts.h0000644000015301777760000000427212321005637030067 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ULLAYOUTS_H #define ULLAYOUTS_H #include #include "ulconditionallayout.h" class ULLayoutsAttached : public QObject { Q_OBJECT Q_PROPERTY(QString item READ item WRITE setItem NOTIFY itemChanged) public: explicit ULLayoutsAttached(QObject *parent = 0); //getter/setter QString item() const; void setItem(const QString &name); bool isValid(); Q_SIGNALS: void itemChanged(); private Q_SLOTS: void validateAttachedProperties(); private: QString m_name; bool m_valid; }; class ULLayoutsPrivate; class ULLayouts : public QQuickItem { Q_OBJECT Q_DISABLE_COPY(ULLayouts) Q_PROPERTY(QString currentLayout READ currentLayout NOTIFY currentLayoutChanged DESIGNABLE false) Q_PROPERTY(QQmlListProperty layouts READ layouts DESIGNABLE false) public: explicit ULLayouts(QQuickItem *parent = 0); ~ULLayouts(); static ULLayoutsAttached * qmlAttachedProperties(QObject *owner); QString currentLayout() const; QList layoutList(); Q_SIGNALS: void currentLayoutChanged(); protected: void componentComplete(); private: QQmlListProperty layouts(); friend class ULConditionalLayout; Q_DECLARE_PRIVATE(ULLayouts) QScopedPointer d_ptr; Q_PRIVATE_SLOT(d_func(), void _q_removeExcludedItem(QObject*)) }; QML_DECLARE_TYPE(ULLayouts) QML_DECLARE_TYPEINFO(ULLayouts, QML_HAS_ATTACHED_PROPERTIES) #endif // ULLAYOUTS_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/propertychanges_p.h0000644000015301777760000001206212321005637031556 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef LAYOUTACTION_P_H #define LAYOUTACTION_P_H #include #include #define foreach Q_FOREACH //workaround to fix private includes #include // for QmlBinding #undef foreach #include #include class PropertyAction { public: enum Type {Binding, Value}; PropertyAction(const PropertyAction &other); PropertyAction(); PropertyAction(QObject *item, const QString &name, Type type = Binding); PropertyAction(QObject *item, const QString &name, QQmlContext *context, const QVariant &value, Type type = Value); void setValue(const QVariant &value); void setTargetBinding(QQmlAbstractBinding *binding, bool deletable); void apply(); void reset(); void revert(bool reset = false); // members Type type; QQmlProperty property; QQmlAbstractBinding *fromBinding; QWeakPointer toBinding; QVariant fromValue; QVariant toValue; bool toValueSet:1; bool deleteFromBinding:1; bool deleteToBinding:1; }; class QQuickItem; class PropertyChange { public: enum Priority { High, Normal, Low, MaxPriority }; PropertyChange(Priority priority); PropertyChange(QQuickItem *target, const QString &property, const QVariant &value, Priority priority = Low); PropertyChange(QQuickItem *target, const QString &property, const QQmlScriptString &script, QQmlContext *scriptContext, Priority priority = Low); virtual ~PropertyChange() {} virtual void saveState(); virtual void apply(); virtual void revert(); inline Priority priority() { return actionPriority; } inline QQmlProperty property() const { return action.property; } inline PropertyAction &actionObject() { return action; } inline void resetWhenReverted(bool doReset) { resetOnRevert = doReset; } protected: Priority actionPriority; bool resetOnRevert; PropertyAction action; }; class PropertyBackup: public PropertyChange { public: PropertyBackup(QQuickItem *target, const QString &property); }; class ReparentChange : public PropertyChange { public: ReparentChange(QQuickItem *item, const QString &property, QQuickItem *source); protected: virtual void saveState(); QQmlProperty sourceProperty; }; class ParentChange : public PropertyChange { public: ParentChange(QQuickItem *item, QQuickItem *targetParent, bool topmostChild); void apply(); private: QQuickItem *newParent; bool topmostChild; }; class AnchorChange : public PropertyChange { public: AnchorChange(QQuickItem *item, const QString &anchor, QQuickItem *target, const QString &targetAnchor = QString()); void apply(); void revert(); private: bool active; }; class ItemStackBackup : public PropertyChange { public: ItemStackBackup(QQuickItem *item, QQuickItem *currentLayoutItem, QQuickItem *previousLayoutItem); void apply() {} void revert(); protected: virtual void saveState(); QQuickItem *target; QQuickItem *currentLayout; QQuickItem *previousLayout; QQuickItem *originalStackBefore; private: friend class ULLayouts; }; class QQuickAnchors; class AnchorBackup : public PropertyChange { public: AnchorBackup(QQuickItem *item); void apply(); void revert(); protected: virtual void saveState(); enum Anchor{ Left = 0, Right, Top, Bottom, HCenter, VCenter, Baseline, MaxAnchor }; enum Margins{ Margins = 0, LeftMargin, RightMargin, TopMargin, BottomMargin, HCenterOffset, VCenterOffset, BaselineOffset, MaxMargins }; inline QQuickAnchors::Anchor anchor(Anchor id) { return (QQuickAnchors::Anchor)(1 << (int)id); } QQuickAnchors *anchorsObject; QQuickAnchors::Anchors used; QList actions; }; class ULConditionalLayoutAttached; class ChangeList { public: ChangeList(){} ~ChangeList(); void apply(); void revert(); void clear(); ChangeList &addChange(PropertyChange *change); private: QList changes[PropertyChange::MaxPriority]; QList unifiedChanges(); }; #endif // LAYOUTACTION_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulitemlayout.cpp0000644000015301777760000000507112321005637031114 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ulitemlayout.h" /*! * \qmltype ItemLayout * \instantiates ULItemLayout * \inqmlmodule Ubuntu.Layouts 0.1 * \ingroup ubuntu-layouts * \brief ItemLayout defines a new size & position of a single Item, for the purposes * of specifying layouts. This is to be used within a ConditionalLayout definition. * * Use ItemLayout to define the size and position of a single item within a layout. * The item name to be positioned should be specified in item property, * which should correspond to the string specified in \b Layouts.item attached to * an Item in the default layout. The Item with Layouts.item attached is reparented * into ItemLayout and it is anchor filled to it. * * Example: * \qml * import QtQuick 2.0 * import Ubuntu.Layouts 0.1 * * Layouts { * id: layouts * width: units.gu(50) * height: units.gu(50) * layouts: [ * ConditionalLayout { * when: layouts.width > units.gu(40) * Row { * width: parent.width * ItemLayout { * item: "input" * width: units.gu(30) * height: units.gu(20) * } * TextArea { * text: "extra component" * } * } * } * ] * // default layout * TextInput { * anchors.fill: parent * text: "input" * Layouts.item: "input" * } * } * \endqml */ ULItemLayout::ULItemLayout(QQuickItem *parent) : QQuickItem(parent) { } ULItemLayout::~ULItemLayout() { } /*! * \qmlproperty string ItemLayout::item * The property holds the item name to be positioned in the fragment. */ QString ULItemLayout::item() const { return m_itemName; } void ULItemLayout::setItem(const QString &value) { if (value == m_itemName) { return; } m_itemName = value; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/propertychanges.cpp0000644000015301777760000003401212321005637031571 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "propertychanges_p.h" #include "ullayouts_p.h" #include "ullayouts.h" #include #include #include #include /****************************************************************************** * PropertyAction * Saves property state, applies target values or bindings and restores property * saved values. Distinguishes Binding and Value types, which is relevant when * the property is restored to its defaults. */ PropertyAction::PropertyAction() : type(Value) , fromBinding(0) , toValueSet(false) , deleteFromBinding(false) , deleteToBinding(false) { } PropertyAction::PropertyAction(const PropertyAction &other) : type(other.type) , property(other.property) , fromBinding(other.fromBinding) , toBinding(other.toBinding) , fromValue(other.fromValue) , toValue(other.toValue) , toValueSet(other.toValueSet) , deleteFromBinding(other.deleteFromBinding) , deleteToBinding(other.deleteToBinding) { } PropertyAction::PropertyAction(QObject *item, const QString &name, Type type) : type(type) , property(item, name, qmlContext(item)) , fromBinding(QQmlPropertyPrivate::binding(property)) , fromValue(property.read()) , toValueSet(false) , deleteFromBinding(false) , deleteToBinding(false) { } PropertyAction::PropertyAction(QObject *item, const QString &name, QQmlContext *context, const QVariant &value, Type type) : type(type) , property(item, name, context) , fromBinding(QQmlPropertyPrivate::binding(property)) , fromValue(property.read()) , toValue(value) , toValueSet(value.isValid()) , deleteFromBinding(false) , deleteToBinding(false) { } /* * Set target value. */ void PropertyAction::setValue(const QVariant &value) { toValue = value; toValueSet = true; } /* * Set target binding and whether it can be deleted upon reset. */ void PropertyAction::setTargetBinding(QQmlAbstractBinding *binding, bool deletable) { toBinding = QQmlAbstractBinding::getPointer(binding); deleteToBinding = deletable; } /* * Apply property action by setting the target binding (toBinding) or by setting the * target value if the value is set. */ void PropertyAction::apply() { if (!toBinding.isNull()) { QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(property, toBinding.data()); if (binding != fromBinding || (binding == fromBinding && deleteFromBinding)) { binding->destroy(); if (binding == fromBinding) { fromBinding = 0; } } } else if (toValueSet) { if (!property.object()->setProperty(property.name().toLocal8Bit(), toValue)) { qmlInfo(property.object()) << "Layouts: updating property \"" << property.name() << "\" failed."; } } } /* * Resets the hosted property and removes its bindings. */ void PropertyAction::reset() { property.reset(); if (fromBinding) { QQmlPropertyPrivate::setBinding(property, 0); if (deleteFromBinding) { fromBinding->destroy(); fromBinding = 0; deleteFromBinding = false; } } } /* * Reverts the property to its defaults. Restores original bindings and in case * of Value types restores their original values. */ void PropertyAction::revert(bool reset) { if (reset) { property.reset(); } if (fromBinding) { QQmlAbstractBinding *revertedBinding = QQmlPropertyPrivate::setBinding(property, fromBinding); if (revertedBinding && ((revertedBinding != toBinding.data()) || (revertedBinding == toBinding.data() && deleteToBinding))) { revertedBinding->destroy(); } } else if (!toBinding.isNull() && QQmlPropertyPrivate::binding(property) == toBinding.data()) { QQmlPropertyPrivate::setBinding(property, 0); if (deleteToBinding) { toBinding.data()->destroy(); toBinding.clear(); deleteToBinding = false; } } else if (property.isValid() && fromValue.isValid() && (type == Value)) { property.write(fromValue); } } /****************************************************************************** * PropertyChange * Default low priority change. */ PropertyChange::PropertyChange(Priority priority) : actionPriority(priority) , resetOnRevert(true) { } PropertyChange::PropertyChange(QQuickItem *target, const QString &property, const QVariant &value, Priority priority) : actionPriority(priority) , resetOnRevert(true) , action(target, property, PropertyAction::Value) { if (value.isValid()) { action.setValue(value); } } PropertyChange::PropertyChange(QQuickItem *target, const QString &property, const QQmlScriptString &script, QQmlContext *scriptContext, Priority priority) : actionPriority(priority) , resetOnRevert(true) , action(target, property, PropertyAction::Value) { if (!script.isEmpty()) { bool ok = false; qreal value = script.numberLiteral(&ok); if (ok) { action.setValue(value); } else { QQmlBinding *binding = new QQmlBinding(script, target, scriptContext); binding->setTarget(action.property); action.toBinding = QQmlAbstractBinding::getPointer(binding); action.deleteToBinding = true; } } } void PropertyChange::saveState() { } void PropertyChange::apply() { action.apply(); } void PropertyChange::revert() { action.revert(resetOnRevert); } /****************************************************************************** * PropertyBackup */ PropertyBackup::PropertyBackup(QQuickItem *target, const QString &property) : PropertyChange(target, property, QVariant(), High) { } /****************************************************************************** * ReparentChange */ ReparentChange::ReparentChange(QQuickItem *target, const QString &property, QQuickItem *source) : PropertyChange(target, property, QVariant(), Normal) , sourceProperty(source, property, qmlContext(source)) { action.type = PropertyAction::Binding; } void ReparentChange::saveState() { action.toValue = sourceProperty.read(); PropertyChange::saveState(); if (sourceProperty.isValid()) { action.setTargetBinding(QQmlPropertyPrivate::binding(sourceProperty), false); } } /****************************************************************************** * ParentChange * Normal priority change, a PropertyChange reparenting an item to the target. */ ParentChange::ParentChange(QQuickItem *item, QQuickItem *targetParent, bool topmostChild) : PropertyChange(item, "parent", qVariantFromValue(targetParent), Normal) , newParent(targetParent) , topmostChild(topmostChild) { } void ParentChange::apply() { // get child items before reparenting QList items = newParent->childItems(); PropertyChange::apply(); if (topmostChild && (items.count() > 0)) { // move the hosted item as topmost child QQuickItem *item = static_cast(action.property.object()); item->stackBefore(items[0]); } } /****************************************************************************** * AnchorChange * Low priority change for anchoring */ AnchorChange::AnchorChange(QQuickItem *item, const QString &anchor, QQuickItem *target, const QString &targetAnchor) : PropertyChange(item, "anchors." + anchor, QVariant()) , active(false) { QQuickAnchors *anchors = item->property("anchors").value(); // check the special cases, like fill, centerIn if (anchor != "fill" || (anchor == "fill" && !anchors->fill())) { active = true; if (targetAnchor.isEmpty()) { action.setValue(qVariantFromValue(target)); } else { action.setValue(target->property(QString("anchors." + targetAnchor).toLocal8Bit())); } } } void AnchorChange::apply() { if (!active) return; PropertyChange::apply(); } void AnchorChange::revert() { if (!active) return; PropertyChange::revert(); } /****************************************************************************** * ItemStackBackup * High priority change backing up the item's stack position. */ ItemStackBackup::ItemStackBackup(QQuickItem *item, QQuickItem *currentLayoutItem, QQuickItem *previousLayoutItem) : PropertyChange(High) , target(item) , currentLayout(currentLayoutItem) , previousLayout(previousLayoutItem) , originalStackBefore(0) { } void ItemStackBackup::saveState() { QQuickItem *rewindParent = target->parentItem(); // save original stack position, but detect layout objects! QList children = rewindParent->childItems(); for (int ii = 0; ii < children.count() - 1; ++ii) { if (children.at(ii) == target) { originalStackBefore = children.at(ii + 1); if (originalStackBefore == currentLayout || originalStackBefore == previousLayout) { originalStackBefore = 0; } break; } } } void ItemStackBackup::revert() { if (originalStackBefore) { target->stackBefore(originalStackBefore); } } /****************************************************************************** * AnchorBackup * High priority change backing up item anchors and margins. */ AnchorBackup::AnchorBackup(QQuickItem *item) : PropertyChange(item, "anchors", QVariant(), High) , anchorsObject(action.fromValue.value()) , used(anchorsObject->usedAnchors()) { if ((used & QQuickAnchors::LeftAnchor) == QQuickAnchors::LeftAnchor) { actions << PropertyAction(item, "anchors.left") << PropertyAction(item, "anchors.leftMargin", PropertyAction::Value); } if ((used & QQuickAnchors::RightAnchor) == QQuickAnchors::RightAnchor) { actions << PropertyAction(item, "anchors.right") << PropertyAction(item, "anchors.rightMargin", PropertyAction::Value); } if ((used & QQuickAnchors::TopAnchor) == QQuickAnchors::TopAnchor) { actions << PropertyAction(item, "anchors.top") << PropertyAction(item, "anchors.topMargin", PropertyAction::Value); } if ((used & QQuickAnchors::BottomAnchor) == QQuickAnchors::BottomAnchor) { actions << PropertyAction(item, "anchors.bottom") << PropertyAction(item, "anchors.bottomMargin", PropertyAction::Value); } if ((used & QQuickAnchors::HCenterAnchor) == QQuickAnchors::HCenterAnchor) { actions << PropertyAction(item, "anchors.horizontalCenter") << PropertyAction(item, "anchors.horizontalCenterOffset", PropertyAction::Value); } if ((used & QQuickAnchors::VCenterAnchor) == QQuickAnchors::VCenterAnchor) { actions << PropertyAction(item, "anchors.verticalCenter") << PropertyAction(item, "anchors.verticalCenterOffset", PropertyAction::Value); } if ((used & QQuickAnchors::BaselineAnchor) == QQuickAnchors::BaselineAnchor) { actions << PropertyAction(item, "anchors.baseline") << PropertyAction(item, "anchors.baselineOffset", PropertyAction::Value); } if (anchorsObject->fill()) { actions << PropertyAction(item, "anchors.fill") << PropertyAction(item, "anchors.margins", PropertyAction::Value); } if (anchorsObject->centerIn()) { actions << PropertyAction(item, "anchors.centerIn") << PropertyAction(item, "anchors.alignWhenCentered", PropertyAction::Value); } } void AnchorBackup::saveState() { // no need to call superclass' saveState() as we don't touch the anchor property // only its properties } void AnchorBackup::apply() { // reset all anchors if (!used) { return; } for (int i = 0; i < actions.count(); i++) { actions[i].reset(); } } void AnchorBackup::revert() { // revert all anchors if (!used) { return; } for (int i = 0; i < actions.count(); i++) { actions[i].revert(true); } } /****************************************************************************** * ChangeList */ ChangeList::~ChangeList() { clear(); } void ChangeList::apply() { QList list = unifiedChanges(); for (int i = 0; i < list.count(); i++) { list[i]->apply(); } } void ChangeList::revert() { // reverse order of apply() QList list = unifiedChanges(); for (int i = list.count() - 1; i >= 0; i--) { list[i]->revert(); } } void ChangeList::clear() { for (int priority = PropertyChange::High; priority < PropertyChange::MaxPriority; priority++) { for (int change = 0; change < changes[priority].count(); change++) { delete changes[priority][change]; } changes[priority].clear(); } } ChangeList &ChangeList::addChange(PropertyChange *change) { if (change && (change->priority() < PropertyChange::MaxPriority)) { change->saveState(); changes[change->priority()] << change; } return *this; } QList ChangeList::unifiedChanges() { QList list; for (int priority = PropertyChange::High; priority < PropertyChange::MaxPriority; priority++) { list << changes[priority]; } return list; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulitemlayout.h0000644000015301777760000000215512321005637030561 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ULITEMLAYOUT_H #define ULITEMLAYOUT_H #include class ULItemLayout : public QQuickItem { Q_OBJECT Q_DISABLE_COPY(ULItemLayout) Q_PROPERTY(QString item READ item WRITE setItem) public: explicit ULItemLayout(QQuickItem *parent = 0); ~ULItemLayout(); QString item() const; void setItem(const QString &value); private: QString m_itemName; }; #endif // ULITEMLAYOUT_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulplugin.cpp0000644000015301777760000000211012321005637030205 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ulplugin.h" #include "ullayouts.h" #include "ulconditionallayout.h" #include "ulitemlayout.h" #include void PluginPlugin::registerTypes(const char *uri) { // @uri Ubuntu.Layouts qmlRegisterType(uri, 0, 1, "Layouts"); qmlRegisterType(uri, 0, 1, "ConditionalLayout"); qmlRegisterType(uri, 0, 1, "ItemLayout"); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulconditionallayout.h0000644000015301777760000000327412321005637032131 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ULCONDITIONALLAYOUT_H #define ULCONDITIONALLAYOUT_H #include #include #include class QQmlBinding; class ULConditionalLayoutPrivate; class ULConditionalLayout : public QObject { Q_OBJECT Q_DISABLE_COPY(ULConditionalLayout) Q_PROPERTY(QString name READ layoutName WRITE setLayoutName) Q_PROPERTY(QQmlBinding* when READ when WRITE setWhen) Q_PROPERTY(QQmlComponent *layout READ layout WRITE setLayout) Q_CLASSINFO("DefaultProperty", "layout") public: explicit ULConditionalLayout(QObject *parent = 0); ~ULConditionalLayout(); // getter/setter QString layoutName() const; void setLayoutName(const QString &name); QQmlBinding *when() const; void setWhen(QQmlBinding *when); QQmlComponent *layout() const; void setLayout(QQmlComponent *component); private: Q_DECLARE_PRIVATE(ULConditionalLayout) QScopedPointer d_ptr; }; #endif // ULCONDITIONALLAYOUT_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ullayouts.cpp0000644000015301777760000005011512321005637030417 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #include "ullayouts.h" #include "ullayouts_p.h" #include "ulitemlayout.h" #include "ulconditionallayout.h" #include "propertychanges_p.h" #include ULLayoutsPrivate::ULLayoutsPrivate(ULLayouts *qq) : QQmlIncubator(Asynchronous) , q_ptr(qq) , currentLayoutItem(0) , previousLayoutItem(0) , currentLayoutIndex(-1) , ready(false) { } /****************************************************************************** * QQmlListProperty functions */ void ULLayoutsPrivate::append_layout(QQmlListProperty *list, ULConditionalLayout *layout) { ULLayouts *_this = static_cast(list->object); if (layout) { layout->setParent(_this); _this->d_ptr->layouts.append(layout); } } int ULLayoutsPrivate::count_layouts(QQmlListProperty *list) { ULLayouts *_this = static_cast(list->object); return _this->d_ptr->layouts.count(); } ULConditionalLayout *ULLayoutsPrivate::at_layout(QQmlListProperty *list, int index) { ULLayouts *_this = static_cast(list->object); return _this->d_ptr->layouts.at(index); } void ULLayoutsPrivate::clear_layouts(QQmlListProperty *list) { ULLayouts *_this = static_cast(list->object); _this->d_ptr->layouts.clear(); } /****************************************************************************** * ULLayoutsPrivate also acts as QQmlIncubator for the dynamically created layouts. * QQmlIncubator stuff */ void ULLayoutsPrivate::setInitialState(QObject *object) { Q_Q(ULLayouts); // object context's parent is the creation context; link it to the object so we // delete them together qmlContext(object)->parentContext()->setParent(object); // set parent object->setParent(q); QQuickItem *item = static_cast(object); // set disabled and invisible, and set its parent as last action item->setVisible(false); item->setEnabled(false); } /* * Called upon QQmlComponent::create() to notify the status of the component * creation. */ void ULLayoutsPrivate::statusChanged(Status status) { Q_Q(ULLayouts); if (status == Ready) { // complete layouting previousLayoutItem = currentLayoutItem; // reset the layout currentLayoutItem = qobject_cast(object()); Q_ASSERT(currentLayoutItem); // hide all non-laid out items first hideExcludedItems(); //reparent components to be laid out reparentItems(); // set parent item, then enable and show layout changes.addChange(new ParentChange(currentLayoutItem, q, false)); itemActivate(currentLayoutItem, true); // apply changes changes.apply(); // clear previous layout delete previousLayoutItem; previousLayoutItem = 0; Q_EMIT q->currentLayoutChanged(); } else if (status == Error) { Q_Q(ULLayouts); error(q, errors()); } } void ULLayoutsPrivate::hideExcludedItems() { for (int i = 0; i < excludedFromLayout.count(); i++) { itemActivate(excludedFromLayout[i], false); } } /* * Re-parent items to the new layout. */ void ULLayoutsPrivate::reparentItems() { // create copy of items list, to keep track of which ones we change LaidOutItemsMap unusedItems = itemsToLayout; // iterate through the Layout definition to find containers - those Items with // ConditionalLayout.items set QList items = currentLayoutItem->findChildren(); // add the root item as that also can be the container items.prepend(currentLayoutItem); Q_FOREACH(QQuickItem *container, items) { // check whether we have ItemLayout declared ULItemLayout *itemLayout = qobject_cast(container); if (itemLayout) { reparentToItemLayout(unusedItems, itemLayout); } } // hide the rest of the unused ones LaidOutItemsMapIterator i(unusedItems); while (i.hasNext()) { i.next(); itemActivate(i.value(), false); } } /* * Re-parent to ItemLayout. */ void ULLayoutsPrivate::reparentToItemLayout(LaidOutItemsMap &map, ULItemLayout *fragment) { QString itemName = fragment->item(); if (itemName.isEmpty()) { warning(fragment, "item not specified for ItemLayout"); return; } QQuickItem *item = map.value(itemName); if (!item) { warning(fragment, "item \"" + itemName + "\" not specified or has been specified for layout by " " more than one active ItemLayout"); return; } // the component fills the parent changes.addChange(new ParentChange(item, fragment, true)); changes.addChange(new ItemStackBackup(item, currentLayoutItem, previousLayoutItem)); changes.addChange(new AnchorChange(item, "fill", fragment)); changes.addChange(new PropertyChange(item, "anchors.margins", 0)); changes.addChange(new PropertyChange(item, "anchors.leftMargin", 0)); changes.addChange(new PropertyChange(item, "anchors.topMargin", 0)); changes.addChange(new PropertyChange(item, "anchors.rightMargin", 0)); changes.addChange(new PropertyChange(item, "anchors.bottomMargin", 0)); // backup size changes.addChange(new PropertyBackup(item, "width")); changes.addChange(new PropertyBackup(item, "height")); // break and backup anchors changes.addChange(new AnchorBackup(item)); // remove from unused ones map.remove(itemName); } void ULLayoutsPrivate::itemActivate(QQuickItem *item, bool activate) { changes.addChange(new PropertyChange(item, "visible", activate)) .addChange(new PropertyChange(item, "enabled", activate)); } // remove the deleted item from the excluded ones void ULLayoutsPrivate::_q_removeExcludedItem(QObject *excludedItem) { excludedFromLayout.removeAll(static_cast(excludedItem)); } /* * Validates the declared conditional layouts by checking whether they have name * property set and whether the value set is unique, and whether the conditional * layout has container defined. */ void ULLayoutsPrivate::validateConditionalLayouts() { Q_Q(ULLayouts); QStringList names; for (int i = 0; i < layouts.count(); i++) { ULConditionalLayout *layout = layouts[i]; if (!layout) { error(q, "Error in layout definitions!"); continue; } if (layout->layoutName().isEmpty()) { warning(layout, "No name specified for layout. ConditionalLayout cannot be activated without name."); continue; } if (names.contains(layout->layoutName())) { warning(layout, "layout name \"" + layout->layoutName() + "\" not unique. Layout may not behave as expected."); } if (!layout->layout()) { error(layout, "no container specified for layout \"" + layout->layoutName() + "\". ConditionalLayout cannot be activated without a container."); continue; } } } /* * Collect items to be laid out. */ void ULLayoutsPrivate::getLaidOutItems() { Q_Q(ULLayouts); QList items = q->findChildren(); for (int i = 0; i < items.count(); i++) { QQuickItem *item = items[i]; ULLayoutsAttached *marker = qobject_cast( qmlAttachedPropertiesObject(item, false)); if (marker && !marker->item().isEmpty()) { itemsToLayout.insert(marker->item(), item); } else { // the item is not marked to be laid out but one of its parents // can be, therefore check // check if the item's parent is included in the layout QQuickItem *pl = item->parentItem(); marker = 0; if (!pl && item->parent()) { // this may be an item instance assigned to a property // like "property var anItem: Item {}" // in which case we must get the parent object of it, not the parent item pl = qobject_cast(item->parent()); } while (pl) { marker = qobject_cast( qmlAttachedPropertiesObject(pl, false)); if (marker && !marker->item().isEmpty()) { break; } pl = pl->parentItem(); } if (!marker || (marker && marker->item().isEmpty())) { // remember theese so we hide them once we switch away from default layout excludedFromLayout << item; // and make sure we remove the item from excluded ones in case the item is destroyed QObject::connect(item, SIGNAL(destroyed(QObject*)), q, SLOT(_q_removeExcludedItem(QObject*))); } } } } /* * Apply layout change. The new layout creation will be completed in statusChange(). */ void ULLayoutsPrivate::reLayout() { if (!ready || (currentLayoutIndex < 0)) { return; } if (!layouts[currentLayoutIndex]->layout()) { return; } // redo changes changes.revert(); changes.clear(); // clear the incubator before using it clear(); QQmlComponent *component = layouts[currentLayoutIndex]->layout(); // create using incubation as it may be created asynchronously, // case when the attached properties are not yet enumerated Q_Q(ULLayouts); QQmlContext *context = new QQmlContext(qmlContext(q), q); component->create(*this, context); } /* * Updates the current layout. */ void ULLayoutsPrivate::updateLayout() { if (!ready) { return; } // go through conditions and re-parent for the first valid one for (int i = 0; i < layouts.count(); i++) { ULConditionalLayout *layout = layouts[i]; if (!layout->layout()) { warning(layout, "Cannot activate layout \"" + layout->layoutName() + "\" with no container specified. Falling back to default layout."); break; } if (!layout->layoutName().isEmpty() && layout->when() && layout->when()->evaluate().toBool()) { if (currentLayoutIndex == i) { return; } currentLayoutIndex = i; // update layout reLayout(); return; } } // check if we need to switch back to default layout if (currentLayoutIndex >= 0) { // revert and clear changes changes.revert(); changes.clear(); delete currentLayoutItem; currentLayoutItem = 0; currentLayoutIndex = -1; Q_Q(ULLayouts); Q_EMIT q->currentLayoutChanged(); } } void ULLayoutsPrivate::error(QObject *item, const QString &message) { qmlInfo(item) << "ERROR: " << message; QQmlEngine *engine = qmlEngine(item); if (engine) { engine->quit(); } } void ULLayoutsPrivate::error(QObject *item, const QList &errors) { qmlInfo(item, errors); QQmlEngine *engine = qmlEngine(item); if (engine) { engine->quit(); } } void ULLayoutsPrivate::warning(QObject *item, const QString &message) { qmlInfo(item) << "WARNING: " << message; } /*! * \qmltype Layouts * \instantiates ULLayouts * \inqmlmodule Ubuntu.Layouts 0.1 * \ingroup ubuntu-layouts * \brief The Layouts component allows one to specify multiple different layouts for a * fixed set of Items, and applies the desired layout to those Items. * * Layouts is a layout block component incorporating layout definitions and * components to lay out. The layouts are defined in the \l layouts property, which * is a list of ConditionalLayout components, each declaring the sizes and positions * of the components specified to be laid out. * * \qml * Layouts { * id: layouts * layouts: [ * ConditionalLayout { * name: "flow" * when: layouts.width > units.gu(60) && layouts.width <= units.gu(100) * Flow { * anchors.fill: parent * //[...] * } * }, * ConditionalLayout { * name: "column" * when: layouts.width > units.gu(100) * Flickable { * anchors.fill: parent * contentHeight: column.childrenRect.height * Column { * id: column * //[...] * } * } * } * ] * } * \endqml * * The components to be laid out must be declared as children of the Layouts component, * each set an attached property "Layouts.item" to be a unique string. * * \qml * Layouts { * id: layouts * layouts: [ * ConditionalLayout { * name: "flow" * when: layouts.width > units.gu(60) && layouts.width <= units.gu(100) * Flow { * anchors.fill: parent * //[...] * } * }, * ConditionalLayout { * name: "column" * when: layouts.width > units.gu(100) * Flickable { * anchors.fill: parent * contentHeight: column.childrenRect.height * Column { * id: column * //[...] * } * } * } * ] * * Row { * anchors.fill: parent * Button { * text: "Press me" * Layouts.item: "item1" * } * Button { * text: "Cancel" * Layouts.item: "item2" * } * } * } * \endqml * * The layout of the children of Layouts is considered the default layout, i.e. * currentLayout is an empty string. So in the above example, the buttons arranged * in a row is the default layout. * * The layouts defined by ConditionalLayout components are created and activated * when at least one of the layout's condition is evaluated to true. In which * case components marked for layout are re-parented to the components defined * to lay out those defined in the ConditionalLayout. In case multiple conditions * are evaluated to true, the first one in the list will be activated. The deactivated * layout is destroyed, exception being the default layout, which is kept in memory for * the entire lifetime of the Layouts component. * * Upon activation, the created component fills in the entire layout block. * * \qml * Layouts { * id: layouts * layouts: [ * ConditionalLayout { * name: "flow" * when: layouts.width > units.gu(60) && layouts.width <= units.gu(100) * Flow { * anchors.fill: parent * ItemLayout { * item: "item1" * } * ItemLayout { * item: "item2" * } * } * }, * ConditionalLayout { * name: "column" * when: layouts.width > units.gu(100) * Flickable { * anchors.fill: parent * contentHeight: column.childrenRect.height * Column { * id: column * ItemLayout { * item: "item1" * } * ItemLayout { * item: "item2" * } * } * } * } * ] * * Row { * anchors.fill: parent * Button { * text: "Press me" * Layouts.item: "item1" * } * Button { * text: "Cancel" * Layouts.item: "item2" * } * } * } * \endqml * * Conditional layouts must be named in order to be activatable. These names (strings) * should be unique within a Layouts item and can be used to identify changes in * between layouts in scripts, so additional layout specific customization on laid * out items can be done. The current layout is presented by the currentLayout * property. * * Extending the previous example by changing the button color to green when the * current layout is "column", the code would look as follows: * \qml * Layouts { * id: layouts * layouts: [ * ConditionalLayout { * name: "flow" * when: layouts.width > units.gu(60) && layouts.width <= units.gu(100) * Flow { * anchors.fill: parent * ItemLayout { * item: "item1" * } * ItemLayout { * item: "item2" * } * } * }, * ConditionalLayout { * name: "column" * when: layouts.width > units.gu(100) * Flickable { * anchors.fill: parent * contentHeight: column.childrenRect.height * Column { * id: column * ItemLayout { * item: "item1" * } * ItemLayout { * item: "item2" * } * } * } * } * ] * * Row { * anchors.fill: parent * Button { * text: "Press me" * Layouts.item: "item1" * color: (layouts.currentLayout === "column") ? "green" : "gray" * } * Button { * text: "Cancel" * Layouts.item: "item2" * color: (layouts.currentLayout === "column") ? "green" : "gray" * } * } * } * \endqml */ ULLayouts::ULLayouts(QQuickItem *parent): QQuickItem(parent), d_ptr(new ULLayoutsPrivate(this)) { } ULLayouts::~ULLayouts() { } ULLayoutsAttached * ULLayouts::qmlAttachedProperties(QObject *owner) { return new ULLayoutsAttached(owner); } void ULLayouts::componentComplete() { QQuickItem::componentComplete(); Q_D(ULLayouts); d->ready = true; d->validateConditionalLayouts(); d->getLaidOutItems(); d->updateLayout(); } /*! * \qmlproperty string Layouts::currentLayout * The property holds the active layout name. The default layout is identified * by an empty string. This property can be used for additional customization * of the components which are not supported by the layouting. */ QString ULLayouts::currentLayout() const { Q_D(const ULLayouts); return d->currentLayoutIndex >= 0 ? d->layouts[d->currentLayoutIndex]->layoutName() : QString(); } /*! * \internal * Provides a list of layouts for internal use. */ QList ULLayouts::layoutList() { Q_D(ULLayouts); return d->layouts; } /*! * \qmlproperty list Layouts::layouts * The property holds the list of different ConditionalLayout elements. */ QQmlListProperty ULLayouts::layouts() { Q_D(ULLayouts); return QQmlListProperty(this, &(d->layouts), &ULLayoutsPrivate::append_layout, &ULLayoutsPrivate::count_layouts, &ULLayoutsPrivate::at_layout, &ULLayoutsPrivate::clear_layouts); } #include "moc_ullayouts.cpp" ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/plugin.pro0000644000015301777760000000142312321005637027670 0ustar pbusernogroup00000000000000TEMPLATE = lib TARGET = ../UbuntuLayouts QT += qml quick CONFIG += qt plugin no_keywords QMAKE_CXXFLAGS += -Werror QT += quick-private QT += qml-private core-private equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { QT += v8-private } TARGET = $$qtLibraryTarget($$TARGET) uri = Ubuntu.Layouts # Input SOURCES += \ ullayouts.cpp \ ulconditionallayout.cpp \ ulplugin.cpp \ ulitemlayout.cpp \ ullayoutsattached.cpp \ propertychanges.cpp HEADERS += \ ullayouts.h \ ullayouts_p.h \ ulconditionallayout.h \ ulconditionallayout_p.h \ ulplugin.h \ ulitemlayout.h \ propertychanges_p.h # deployment rules for the plugin installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) target.path = $$installPath INSTALLS += target ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulplugin.h0000644000015301777760000000175212321005637027665 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef PLUGIN_PLUGIN_H #define PLUGIN_PLUGIN_H #include class PluginPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri); }; #endif // PLUGIN_PLUGIN_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ullayouts_p.h0000644000015301777760000000465512321005637030413 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ULLAYOUTS_P_H #define ULLAYOUTS_P_H #include "ullayouts.h" #include #include "propertychanges_p.h" typedef QHash LaidOutItemsMap; typedef QHashIterator LaidOutItemsMapIterator; class ULItemLayout; class ULLayoutsPrivate : QQmlIncubator { Q_DECLARE_PUBLIC(ULLayouts) public: ULLayoutsPrivate(ULLayouts *qq); void _q_removeExcludedItem(QObject *excludedItem); void validateConditionalLayouts(); void getLaidOutItems(); void updateLayout(); static void error(QObject *item, const QString &message); static void error(QObject *item, const QList &errors); static void warning(QObject *item, const QString &message); protected: // QQmlIncubator stuff void setInitialState(QObject *object); void statusChanged(Status status); private: ULLayouts *q_ptr; QList layouts; ChangeList changes; LaidOutItemsMap itemsToLayout; QList excludedFromLayout; QQuickItem* currentLayoutItem; QQuickItem* previousLayoutItem; int currentLayoutIndex; bool ready:1; // callbacks for the "layouts" QQmlListProperty of ULLayouts static void append_layout(QQmlListProperty*, ULConditionalLayout*); static int count_layouts(QQmlListProperty*); static ULConditionalLayout *at_layout(QQmlListProperty*, int); static void clear_layouts(QQmlListProperty*); void reLayout(); void hideExcludedItems(); void reparentItems(); void reparentToItemLayout(LaidOutItemsMap &map, ULItemLayout *fragment); void itemActivate(QQuickItem *item, bool activate); }; #endif // ULLAYOUTS_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulconditionallayout_p.h0000644000015301777760000000215212321005637032442 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #ifndef ULCONDITIONALLAYOUT_P_H #define ULCONDITIONALLAYOUT_P_H #include "ulconditionallayout.h" class ULLayouts; class ULConditionalLayoutPrivate { Q_DECLARE_PUBLIC(ULConditionalLayout) public: ULConditionalLayoutPrivate(ULConditionalLayout *qq); ULConditionalLayout *q_ptr; QQmlBinding *when; QQmlComponent *component; QString name; ULLayouts *layouts(); }; #endif // ULCONDITIONALLAYOUT_P_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/plugin/ulconditionallayout.cpp0000644000015301777760000001252012321005637032456 0ustar pbusernogroup00000000000000/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Zsombor Egri */ #define foreach Q_FOREACH #include #undef foreach #include "ulconditionallayout.h" #include "ulconditionallayout_p.h" #include "ullayouts.h" #include "ullayouts_p.h" ULConditionalLayoutPrivate::ULConditionalLayoutPrivate(ULConditionalLayout *qq) : q_ptr(qq), when(0), component(0) { } ULLayouts *ULConditionalLayoutPrivate::layouts() { Q_Q(ULConditionalLayout); return qobject_cast(q->parent()); } /*! * \qmltype ConditionalLayout * \instantiates ULConditionalLayout * \inqmlmodule Ubuntu.Layouts 0.1 * \ingroup ubuntu-layouts * \brief ConditionalLayout defines the layout of a given form factor. * * ConditionalLayout is a non-visual element defining the actual layout to be applied * when a given condition evaluates to true. The condition can be any valid boolean * JavaScript expression. * * As Layouts can be nested, it is recommended to choose properties of the Layouts item, * often width and height, when defining the condition. Other elements like Screen * orientation can also be used to define the layout activation condition. * * There must be only a single component defined in the ConditionalLayout which will be * instantiated upon activation. * * Each conditional layout must be named with a string, which identifies the layout * when activated. * * \qml * Layouts { * id: layouts * width: units.gu(40) * height: units.gu(40) * layouts: [ * ConditionalLayout { * name: "flow" * when: layouts.width > units.gu(60) * Flow { * anchors.fill: parent * spacing: units.dp(3) * flow: Flow.LeftToRight * ItemLayout { * item: "item1" * width: units.gu(30) * height: units.gu(20) * } * ItemLayout { * item: "item2" * width: units.gu(30) * height: units.gu(20) * } * ItemLayout { * item: "item3" * width: units.gu(30) * height: units.gu(20) * } * } * } * ] * * Column { * spacing: units.dp(2) * Button { * text: "Button #1" * Layouts.item: "item1" * } * Button { * text: "Button #2" * Layouts.item: "item2" * } * Button { * text: "Button #3" * Layouts.item: "item3" * } * } * } * \endqml * * All Items to be managed by the Layouts engine must identify themselves by setting * the Layouts.item attached property to a unique name (string). These unique names * are then used by the ItemLayout component, so can apply the new layout to the * correct Item. * * \sa {ItemLayout} */ ULConditionalLayout::ULConditionalLayout(QObject *parent) : QObject(parent), d_ptr(new ULConditionalLayoutPrivate(this)) { } ULConditionalLayout::~ULConditionalLayout() { } /*! * \qmlproperty string ConditionalLayout::name * This property defines the name of the layout. Within the definition of Layouts, * these names should be unique for each layout. * \sa Layouts */ QString ULConditionalLayout::layoutName() const { Q_D(const ULConditionalLayout); return d->name; } void ULConditionalLayout::setLayoutName(const QString &name) { Q_D(ULConditionalLayout); if (name == d->name) { return; } d->name = name; } /*! * \qmlproperty bool ConditionalLayout::when * This property defines the condition that when evaluating to true, chooses this * ConditionalLayout to become the active layout. * When two ConditionalLayouts \b when condition is evaluated to true, the first * one declared in the layouts list is chosen. */ QQmlBinding *ULConditionalLayout::when() const { Q_D(const ULConditionalLayout); return d->when; } void ULConditionalLayout::setWhen(QQmlBinding *when) { Q_D(ULConditionalLayout); d->when = when; // re-layout ULLayouts *layouts = qobject_cast(parent()); if (layouts) { layouts->d_ptr->updateLayout(); } } /*! * \qmlproperty Component ConditionalLayout::layout * \default * Default property holding the definition component of the layout. The component * will be instantiated once the condition evaluates to true. */ QQmlComponent *ULConditionalLayout::layout() const { Q_D(const ULConditionalLayout); return d->component; } void ULConditionalLayout::setLayout(QQmlComponent *component) { Q_D(ULConditionalLayout); d->component = component; } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Layouts/deployment.pri0000644000015301777760000000133512321005637027250 0ustar pbusernogroup00000000000000uri = Ubuntu.Layouts installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) # qmldir QMLDIR_FILE = qmldir # make found deployables visible in Qt Creator OTHER_FILES += $$QMLDIR_FILE # define deployment for found deployables qmldir_file.path = $$installPath qmldir_file.files = $$QMLDIR_FILE plugins_qmltypes.path = $$installPath plugins_qmltypes.files = plugins.qmltypes # Silence spam on stderr due to fonts # https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1256999 # https://bugreports.qt-project.org/browse/QTBUG-36243 plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Layouts 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes INSTALLS += qmldir_file plugins_qmltypes ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/0000755000015301777760000000000012321006415023624 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/Test.pro0000644000015301777760000000014012321005637025265 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += plugin OTHER_FILES += $$system(ls *.qml) include(deployment.pri) ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/qmldir0000644000015301777760000000004612321005637025044 0ustar pbusernogroup00000000000000UbuntuTestCase 0.1 UbuntuTestCase.qml ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/plugin/0000755000015301777760000000000012321006415025122 5ustar pbusernogroup00000000000000ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/plugin/uctestcase.cpp0000644000015301777760000000303112321005637027773 0ustar pbusernogroup00000000000000/* * Copyright 2013-2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #include "uctestcase.h" #include #include #include #include #include #include /*! * \ingroup ubuntu * \brief UbuntuTestCase is the C++ pendant to the QML UbuntuTestCase. */ UbuntuTestCase::UbuntuTestCase(const QString& file, QWindow* parent) : QQuickView(parent) { QString modules("../../../modules"); Q_ASSERT(QDir(modules).exists()); QString modulePath(QDir(modules).absolutePath()); engine()->addImportPath(modulePath); m_spy = new QSignalSpy(engine(), SIGNAL(warnings(QList))); m_spy->setParent(this); Q_ASSERT(!file.isEmpty()); setSource(QUrl::fromLocalFile(file)); Q_ASSERT(status() == QQuickView::Ready); Q_ASSERT(rootObject()); show(); QTest::qWaitForWindowExposed(this); } ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/plugin/uctestcase.h0000644000015301777760000000271612321005637027451 0ustar pbusernogroup00000000000000/* * Copyright 2013-2014 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Christian Dywan */ #ifndef UBUNTU_TEST_UBUNTUTESTCASE_H #define UBUNTU_TEST_UBUNTUTESTCASE_H #include #include #include class UbuntuTestCase : public QQuickView { Q_OBJECT public: UbuntuTestCase(const QString& file, QWindow* parent = 0); // getter template inline T findItem(const QString& objectName) const { T item = rootObject()->findChild(objectName); if (item) return item; if (rootObject()->findChild(objectName)) qFatal("Item '%s' found with unexpected type", qPrintable(objectName)); qFatal("No item '%s' found", qPrintable(objectName)); } private: QSignalSpy* m_spy; }; #endif // UBUNTU_TEST_UBUNTUTESTCASE_H ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/plugin/plugin.pro0000644000015301777760000000076312321005637027155 0ustar pbusernogroup00000000000000TEMPLATE = lib TARGET = ../UbuntuTest QT += core-private qml qml-private quick quick-private equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { QT += v8-private } CONFIG += qt plugin no_keywords QMAKE_CXXFLAGS += -Werror TARGET = $$qtLibraryTarget($$TARGET) uri = Ubuntu.Test HEADERS += \ uctestcase.h \ SOURCES += \ uctestcase.cpp \ # deployment rules for the plugin installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) target.path = $$installPath INSTALLS += target ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/Ubuntu/Test/UbuntuTestCase.qml0000644000015301777760000000577312321005637027276 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtTest 1.0 import Ubuntu.Components 0.1 /*! \qmlabstract UbuntuTestCase \inqmlmodule Ubuntu.Test 0.1 \ingroup ubuntu \brief The UbuntuTestCase class expands the default TestCase class. \b{This component is under heavy development.} This class extends the default QML TestCase class which is available in QtTest 1.0. */ TestCase { TestUtil { id:util } /*! Find a child from the item based on the objectName. */ function findChild(obj,objectName) { var childs = new Array(0); childs.push(obj) while (childs.length > 0) { if (childs[0].objectName == objectName) { return childs[0] } for (var i in childs[0].children) { childs.push(childs[0].children[i]) } childs.splice(0, 1); } return null; } function findInvisibleChild(obj,objectName) { var childs = new Array(0); childs.push(obj) while (childs.length > 0) { if (childs[0].objectName == objectName) { return childs[0] } for (var i in childs[0].data) { childs.push(childs[0].data[i]) } childs.splice(0, 1); } return null; } /*! Move Mouse from x,y to distance of dx, dy divided to steps with a stepdelay (ms). */ function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay) { mouseMove(item,x,y); var step_dx = dx/steps; var step_dy = dy/steps; var ix = 0; var iy = 0; for (var step=0; step/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes INSTALLS += qmldir_file plugins_qmltypes ubuntu-ui-toolkit-0.1.46+14.04.20140408.1/modules/ubuntu-ui-toolkit.pro0000644000015301777760000000017012321005637025570 0ustar pbusernogroup00000000000000TEMPLATE = subdirs SUBDIRS += Ubuntu/Components \ Ubuntu/Layouts \ Ubuntu/PerformanceMetrics \ Ubuntu/Test