aboutsummaryrefslogtreecommitdiffstats
path: root/meta-agl-profile-core
diff options
context:
space:
mode:
Diffstat (limited to 'meta-agl-profile-core')
-rw-r--r--meta-agl-profile-core/classes/cloc.bbclass29
-rw-r--r--meta-agl-profile-core/conf/include/agl-devel.inc15
-rw-r--r--meta-agl-profile-core/conf/include/agl-gplv2.inc8
-rw-r--r--meta-agl-profile-core/conf/include/base-agl.inc19
-rw-r--r--meta-agl-profile-core/conf/layer.conf10
-rw-r--r--meta-agl-profile-core/files/group90
-rw-r--r--meta-agl-profile-core/files/passwd60
-rw-r--r--meta-agl-profile-core/recipes-core/dbus/.appends.core0
l---------meta-agl-profile-core/recipes-core/dbus/dbus-cynara_%.bbappend1
-rw-r--r--meta-agl-profile-core/recipes-core/dbus/dbus/dbus.service10
-rw-r--r--meta-agl-profile-core/recipes-core/dbus/dbus/dbus.socket9
-rw-r--r--meta-agl-profile-core/recipes-core/dbus/dbus/dbus_env.conf5
-rw-r--r--meta-agl-profile-core/recipes-core/dbus/dbus_%.bbappend28
-rw-r--r--meta-agl-profile-core/recipes-core/glibc/.appends.core0
-rw-r--r--meta-agl-profile-core/recipes-core/glibc/glibc/arm/local-arm-futex.diff22
-rw-r--r--meta-agl-profile-core/recipes-core/glibc/glibc_2.2%.bbappend3
-rw-r--r--meta-agl-profile-core/recipes-core/images/agl-image-boot.bb9
-rw-r--r--meta-agl-profile-core/recipes-core/images/agl-image-boot.inc10
-rw-r--r--meta-agl-profile-core/recipes-core/images/agl-image-minimal-qa.bb12
-rw-r--r--meta-agl-profile-core/recipes-core/images/agl-image-minimal.bb9
-rw-r--r--meta-agl-profile-core/recipes-core/images/agl-image-minimal.inc10
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-automotive.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-connectivity.bb15
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-graphics.bb10
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-kernel.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-multimedia.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-navi-lbs.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-os-commonlibs.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-security.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-speech-services.bb13
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-boot.bb18
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-minimal.bb27
-rw-r--r--meta-agl-profile-core/recipes-core/packagegroups/packagegroup-core-boot-agl.bb50
-rw-r--r--meta-agl-profile-core/recipes-core/psplash/.appends.core0
-rwxr-xr-xmeta-agl-profile-core/recipes-core/psplash/files/psplash-anim11
-rw-r--r--meta-agl-profile-core/recipes-core/psplash/files/psplash-colors.h34
-rw-r--r--meta-agl-profile-core/recipes-core/psplash/files/psplash-poky-img.h5411
-rw-r--r--meta-agl-profile-core/recipes-core/psplash/files/psplash-quit.service11
-rw-r--r--meta-agl-profile-core/recipes-core/psplash/files/psplash-start.service12
-rw-r--r--meta-agl-profile-core/recipes-core/psplash/psplash_git.bbappend27
-rw-r--r--meta-agl-profile-core/recipes-core/systemd/.appends.core0
-rw-r--r--meta-agl-profile-core/recipes-core/systemd/systemd/0001-Switch-Smack-label-earlier.patch52
-rw-r--r--meta-agl-profile-core/recipes-core/systemd/systemd/e2fsck.conf3
-rw-r--r--meta-agl-profile-core/recipes-core/systemd/systemd/wired.network5
-rw-r--r--meta-agl-profile-core/recipes-core/systemd/systemd_%.bbappend26
-rw-r--r--meta-agl-profile-core/recipes-core/systemd/systemd_234.bbappend6
-rw-r--r--meta-agl-profile-core/recipes-devtools/gdb/gdb_%.bbappend1
-rw-r--r--meta-agl-profile-core/recipes-devtools/low-level-can-generator/low-level-can-generator_git.bb16
-rw-r--r--meta-agl-profile-core/recipes-devtools/packagegroups/nativesdk-packagegroup-sdk-host.bbappend1
-rw-r--r--meta-agl-profile-core/recipes-devtools/packagegroups/packagegroup-agl-devel.bb24
-rwxr-xr-xmeta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts48
-rw-r--r--meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts.service17
-rw-r--r--meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts_1.0.bb46
-rw-r--r--meta-agl-profile-core/recipes-devtools/run-postinsts/run-postinsts_%.bbappend5
-rw-r--r--meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-crosssdk.bb19
-rw-r--r--meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-qa.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.bb17
-rw-r--r--meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.inc3
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-image-ivi.bb31
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-automotive.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb19
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-graphics.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-kernel.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb17
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-navi-lbs.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-os-commonlibs.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-security.bb14
-rw-r--r--meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-speech-services.bb14
-rw-r--r--meta-agl-profile-core/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend2
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/.appends.meta-efl0
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch33
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/dbus-lightmediascanner.conf7
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch11
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/lightmediascanner.service11
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/plugin-ogg-fix-chucksize-issue.patch53
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend33
-rw-r--r--meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb63
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/agl-audio-plugin_0.1.bb28
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0001-install-files-for-a-module-development.patch78
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0002-volume-ramp-additions-to-the-low-level-infra.patch566
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0003-volume-ramp-adding-volume-ramping-to-sink-input.patch189
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0004-sink-input-Code-cleanup-regarding-volume-ramping.patch62
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0005-sink-input-volume-Add-support-for-volume-ramp-factor.patch299
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0006-sink-input-Remove-pa_sink_input_set_volume_ramp.patch63
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/enable-ofono-hfp-backend.patch11
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0008-install-files-for-a-module-development.patch53
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0010-volume-ramp-additions-to-the-low-level-infra.patch503
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0011-volume-ramp-adding-volume-ramping-to-sink-input.patch159
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0012-volume-ramp-add-volume-ramping-to-sink.patch159
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0013-add-internal-corking-state-for-sink-input.patch72
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0020-core-util-Add-pa_join.patch37
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0021-dynarray-Add-pa_dynarray_get_raw_array.patch21
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0022-device-port-Add-pa_device_port.active.patch198
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0030-volume-api-Add-libvolume-api.patch6118
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0031-Add-module-main-volume-policy.patch1418
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0039-main-volume-policy-adapt-to-pa6rev.patch11
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend28
-rw-r--r--meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_10.0.bbappend15
-rw-r--r--meta-agl-profile-core/recipes-navigation/geoclue/files/org.freedesktop.GeoClue2.Client.conf8
-rw-r--r--meta-agl-profile-core/recipes-navigation/geoclue/geoclue_%.bbappend9
-rw-r--r--meta-agl-profile-core/recipes-navigation/gpsd/gpsd_%.bbappend14
-rw-r--r--meta-agl-profile-core/recipes-support/libsoup/libsoup-2.4_%.bbappend1
-rw-r--r--meta-agl-profile-core/recipes-test/aiostress/aiostress_0.22.bb24
-rw-r--r--meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0001-Makefile.patch53
-rw-r--r--meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0002-auto.patch95
-rw-r--r--meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0003-printcleanup.patch11
-rw-r--r--meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0004-bs_main.c.patch15
-rw-r--r--meta-agl-profile-core/recipes-test/blobsallad/blobsallad_2006-11-14-23-57.bb36
-rw-r--r--meta-agl-profile-core/recipes-test/dung/dung_3.4.25-m2.bb18
-rw-r--r--meta-agl-profile-core/recipes-test/ebizzy/ebizzy_0.3.bb20
-rw-r--r--meta-agl-profile-core/recipes-test/ffsb/ffsb_6.0-rc2.bb14
-rw-r--r--meta-agl-profile-core/recipes-test/fontconfig/fontconfig_%.bbappend17
-rw-r--r--meta-agl-profile-core/recipes-test/freetype/files/0001-Makefile-dont-build-gfx-demos.patch32
-rw-r--r--meta-agl-profile-core/recipes-test/freetype/files/0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch30
-rw-r--r--meta-agl-profile-core/recipes-test/freetype/freetype_2.8.bbappend32
-rw-r--r--meta-agl-profile-core/recipes-test/fsfuzzer/files/0001-fix_missing_header_sys_stat.patch11
-rw-r--r--meta-agl-profile-core/recipes-test/fsfuzzer/fsfuzzer_0.7.bb18
-rw-r--r--meta-agl-profile-core/recipes-test/glmark2/glmark2_%.bbappend2
-rw-r--r--meta-agl-profile-core/recipes-test/himeno/himeno_2.0.bb27
-rw-r--r--meta-agl-profile-core/recipes-test/interbench/files/interbench.c.patch68
-rw-r--r--meta-agl-profile-core/recipes-test/interbench/interbench_0.31.bb31
-rw-r--r--meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0001-fix-out-of-tree-config.patch52
-rw-r--r--meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0002-fix-bool-size-m4.patch16
-rw-r--r--meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/iperf-2.0.5_ManPage.patch8
-rw-r--r--meta-agl-profile-core/recipes-test/iperf/iperf_2.0.9.bb20
-rw-r--r--meta-agl-profile-core/recipes-test/ipv6connect/ipv6connect.bb24
-rw-r--r--meta-agl-profile-core/recipes-test/linpack/linpack.bb23
-rw-r--r--meta-agl-profile-core/recipes-test/linus-stress/linus-stress.bb23
-rw-r--r--meta-agl-profile-core/recipes-test/packagegroups/packagegroup-agl-test.bb57
-rw-r--r--meta-agl-profile-core/recipes-test/trinity/trinity_git.bb42
130 files changed, 17696 insertions, 0 deletions
diff --git a/meta-agl-profile-core/classes/cloc.bbclass b/meta-agl-profile-core/classes/cloc.bbclass
new file mode 100644
index 000000000..53713bfc3
--- /dev/null
+++ b/meta-agl-profile-core/classes/cloc.bbclass
@@ -0,0 +1,29 @@
+# (C) 2017 Jan-Simon Möller <dl9pf@gmx.de>
+#
+# License: GPLv2
+#
+# summary with
+# cloc --sum-reports `find . -name "*clocreport" | grep -v "\-native" ` --out summary.report
+
+CLOC_DIRECTORY ??= "${DEPLOY_DIR}/cloc/"
+CLOCSTATEDIR = "${WORKDIR}/cloc-destdir/"
+
+python do_cloc() {
+
+ import subprocess
+
+ source_dir = d.getVar('S', True)
+ pn = d.getVar('PN', True)
+
+ destdir = d.expand('${CLOCSTATEDIR}')
+ bb.utils.mkdirhier(destdir)
+
+ cloc_cmd = 'cloc %s -q --out=%s/%s.clocreport' % (source_dir, destdir, pn )
+ subprocess.call(cloc_cmd, shell=True)
+
+}
+
+
+addtask cloc before do_configure after do_unpack
+
+EXPORT_FUNCTIONS do_cloc
diff --git a/meta-agl-profile-core/conf/include/agl-devel.inc b/meta-agl-profile-core/conf/include/agl-devel.inc
new file mode 100644
index 000000000..705b1739a
--- /dev/null
+++ b/meta-agl-profile-core/conf/include/agl-devel.inc
@@ -0,0 +1,15 @@
+IMAGE_FEATURES =+ "debug-tweaks eclipse-debug tools-debug tools-profile"
+
+#IMAGE_INSTALL_append = " \
+# packagegroup-agl-core-devel \
+#"
+
+IMAGE_INSTALL_append = "${@bb.utils.contains('IMAGE_FSTYPES', 'wic.vmdk', ' open-vm-tools vboxguestdrivers', '', d)}"
+
+# disable install of debug files in SDK
+# initial value: SDKIMAGE_FEATURES="dev-pkgs dbg-pkgs staticdev-pkgs"
+SDKIMAGE_FEATURES="dev-pkgs"
+
+# allows insertion of code or items specific to developement
+OVERRIDES .= ":agl-devel"
+DISTRO_FEATURES_append = " agl-devel"
diff --git a/meta-agl-profile-core/conf/include/agl-gplv2.inc b/meta-agl-profile-core/conf/include/agl-gplv2.inc
new file mode 100644
index 000000000..fc9a4072b
--- /dev/null
+++ b/meta-agl-profile-core/conf/include/agl-gplv2.inc
@@ -0,0 +1,8 @@
+# GPLv3 Compliance
+PREFERRED_VERSION_bash = "3.2.%"
+PREFERRED_VERSION_gawk = "3.1.%"
+PREFERRED_VERSION_gdbm = "1.8.%"
+PREFERRED_VERSION_gnupg = "1.4.7"
+PREFERRED_VERSION_gnutls = "3.3.%"
+PREFERRED_VERSION_mc = "4.7.5.%"
+PREFERRED_VERSION_readline = "5.2"
diff --git a/meta-agl-profile-core/conf/include/base-agl.inc b/meta-agl-profile-core/conf/include/base-agl.inc
new file mode 100644
index 000000000..a332c08a4
--- /dev/null
+++ b/meta-agl-profile-core/conf/include/base-agl.inc
@@ -0,0 +1,19 @@
+# AGL includes all kernel modules here for ease-of-use during development.
+# Comment this out to be able to select the kernel modules yourself.
+IMAGE_INSTALL_append = " kernel-modules"
+
+# Likewise as we included all kernel modules by default in the filesystem,
+# we do not need a separate tarball stored.
+# Comment this out to receive the separate modules tarball again.
+MODULE_TARBALL_DEPLOY ?= "0"
+
+# Comment out below if want to use QtWebkit
+PACKAGECONFIG_remove_pn-qtquick1 = "webkit"
+
+
+ASSUME_PROVIDED_remove = "tar-native"
+
+# Use static IDs to enable full-filesystem updates
+USERADDEXTENSION = "useradd-staticids"
+USERADD_ERROR_DYNAMIC = "error"
+
diff --git a/meta-agl-profile-core/conf/layer.conf b/meta-agl-profile-core/conf/layer.conf
new file mode 100644
index 000000000..83c5555bc
--- /dev/null
+++ b/meta-agl-profile-core/conf/layer.conf
@@ -0,0 +1,10 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH =. "${LAYERDIR}:"
+
+# We have recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "aglprofilecore"
+BBFILE_PATTERN_aglprofilecore = "^${LAYERDIR}/"
+BBFILE_PRIORITY_aglprofilecore = "80"
diff --git a/meta-agl-profile-core/files/group b/meta-agl-profile-core/files/group
new file mode 100644
index 000000000..f8a3843bd
--- /dev/null
+++ b/meta-agl-profile-core/files/group
@@ -0,0 +1,90 @@
+root::0:
+daemon::1:
+bin::2:
+sys::3:
+adm::4:
+tty::5:
+disk::6:
+lp::7:
+mail::8:
+news::9:
+uucp::10:
+man::12:
+proxy::13:
+kmem::15:
+input::19:
+dialout::20:
+fax::21:
+voice::22:
+cdrom::24:
+floppy::25:
+tape::26:
+sudo::27:
+audio::29:
+dip::30:
+www-data::33:
+backup::34:
+operator::37:
+list::38:
+irc::39:
+src::40:
+gnats::41:
+shadow::42:
+utmp::43:
+video::44:
+sasl::45:
+plugdev::46:
+staff::50:
+games::60:
+shutdown::70:
+users::100:
+nogroup::65534:
+cynara::999:
+dhcp::998:
+avahi::997:
+tracing::1000:
+sshd::996:
+systemd-bus-proxy::995:
+netdev::993:
+messagebus::994:
+afm::992:
+weston-launch::986:
+lock::990:
+systemd-journal::989:
+systemd-timesync::988:
+pulse::991:
+bind::987:
+trinity::985:
+mpd::984:
+mysql::983:
+polkitd::982:
+datetime::981:
+network::980:
+zabbix::979:
+nm-openvpn::978:
+xuser::1002:
+builder::977:
+rpc::976:
+crontab::975:
+lpadmin::974:
+_apt::972:
+rpcuser::970:
+avahi-autoipd::969:
+ntp::968:
+dovecot::967:
+dovenull::966:
+quagga::965:
+quaggavty::964:
+rwhod::963:
+ftp::962:
+squid::960:
+postfix::959:
+vmail::958:
+opensaf::957:
+lldpd::956:
+postdrop::954:
+display::200:
+agl-driver::1001:
+agl-passenger::1002:
+systemd-network::1005:
+systemd-resolve::1006:
diff --git a/meta-agl-profile-core/files/passwd b/meta-agl-profile-core/files/passwd
new file mode 100644
index 000000000..754cb819a
--- /dev/null
+++ b/meta-agl-profile-core/files/passwd
@@ -0,0 +1,60 @@
+root::0:0:::
+daemon::1:1:::
+bin::2:2:::
+sys::3:3:::
+sync::4:65534:::
+games::5:60:::
+man::6:12:::
+lp::7:7:::
+mail::8:8:::
+news::9:9:::
+uucp::10:10:::
+proxy::13:13:::
+www-data::33:33:::
+backup::34:34:::
+list::38:38:::
+irc::39:39:::
+gnats::41:41:::
+nobody::65534:65534:::
+cynara::999:999:::
+dhcp::998:998:::
+avahi::997:997:::
+sshd::996:996:::
+systemd-bus-proxy::995:995:::
+agl-driver::1001:1001:::
+agl-passenger::1002:1002:::
+messagebus::994:994:::
+afm::992:992:::
+systemd-timesync::988:988:::
+pulse::991:991:::
+bind::987:987:::
+trinity::985:985:::
+mpd::984:984:::
+mysql::983:983:::
+polkitd::982:982:::
+zabbix::979:979:::
+nm-openvpn::978:978:::
+xuser::1002:1002:::
+builder::977:977:::
+rpc::976:976:::
+distcc::973:65534:::
+_apt::972:972:::
+ppp::971:65534:::
+rpcuser::970:970:::
+avahi-autoipd::969:969:::
+ntp::968:968:::
+dovecot::967:967:::
+dovenull::966:966:::
+quagga::965:965:::
+rwhod::963:963:::
+ftp::962:962:::
+radvd::961:65534:::
+squid::960:960:::
+postfix::959:959:::
+vmail::958:958:::
+opensaf::957:957:::
+lldpd::956:956:::
+cyrus::955:8:::
+display::200:200:::
+systemd-network::1005:1005:::
+systemd-resolve::1006:1006:::
diff --git a/meta-agl-profile-core/recipes-core/dbus/.appends.core b/meta-agl-profile-core/recipes-core/dbus/.appends.core
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/dbus/.appends.core
diff --git a/meta-agl-profile-core/recipes-core/dbus/dbus-cynara_%.bbappend b/meta-agl-profile-core/recipes-core/dbus/dbus-cynara_%.bbappend
new file mode 120000
index 000000000..fcdfb1783
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/dbus/dbus-cynara_%.bbappend
@@ -0,0 +1 @@
+dbus_%.bbappend \ No newline at end of file
diff --git a/meta-agl-profile-core/recipes-core/dbus/dbus/dbus.service b/meta-agl-profile-core/recipes-core/dbus/dbus/dbus.service
new file mode 100644
index 000000000..dee6ad741
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/dbus/dbus/dbus.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=D-Bus User Message Bus
+Documentation=man:dbus-daemon(1)
+Requires=dbus.socket
+
+[Service]
+ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation
+ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
+Restart=always
+RestartSec=1
diff --git a/meta-agl-profile-core/recipes-core/dbus/dbus/dbus.socket b/meta-agl-profile-core/recipes-core/dbus/dbus/dbus.socket
new file mode 100644
index 000000000..af76b2f12
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/dbus/dbus/dbus.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=D-Bus User Message Bus Socket
+Before=sockets.target
+
+[Socket]
+ListenStream=%t/bus
+
+[Install]
+WantedBy=default.target
diff --git a/meta-agl-profile-core/recipes-core/dbus/dbus/dbus_env.conf b/meta-agl-profile-core/recipes-core/dbus/dbus/dbus_env.conf
new file mode 100644
index 000000000..f8f02669b
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/dbus/dbus/dbus_env.conf
@@ -0,0 +1,5 @@
+[Unit]
+Wants=dbus.service
+
+[Service]
+Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/bus
diff --git a/meta-agl-profile-core/recipes-core/dbus/dbus_%.bbappend b/meta-agl-profile-core/recipes-core/dbus/dbus_%.bbappend
new file mode 100644
index 000000000..e63ea0f28
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/dbus/dbus_%.bbappend
@@ -0,0 +1,28 @@
+FILESEXTRAPATHS_append := ":${THISDIR}/dbus"
+
+SRC_URI_append = "file://dbus.service \
+ file://dbus.socket \
+ file://dbus_env.conf \
+ "
+
+inherit systemd
+
+do_install_append() {
+ if [ "${PN}" != "nativesdk-dbus" ]; then
+ if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
+ install -m 644 -p -D ${WORKDIR}/dbus.service ${D}${systemd_user_unitdir}/dbus.service
+ install -m 644 -p -D ${WORKDIR}/dbus.socket ${D}${systemd_user_unitdir}/dbus.socket
+ install -m 644 -p -D ${WORKDIR}/dbus_env.conf ${D}${systemd_system_unitdir}/user@.service.d/dbus_env.conf
+
+ # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb)
+ # because it does not support systemd's user mode.
+ mkdir -p ${D}/etc/systemd/user/default.target.wants/
+ ln -sf ${systemd_user_unitdir}/dbus.socket ${D}/etc/systemd/user/default.target.wants/dbus.socket
+ fi
+ fi
+}
+
+FILES_${PN} += " \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/dbus.*', '', d)} \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_system_unitdir}/user@.service.d/dbus_env.conf', '', d)} \
+ "
diff --git a/meta-agl-profile-core/recipes-core/glibc/.appends.core b/meta-agl-profile-core/recipes-core/glibc/.appends.core
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/glibc/.appends.core
diff --git a/meta-agl-profile-core/recipes-core/glibc/glibc/arm/local-arm-futex.diff b/meta-agl-profile-core/recipes-core/glibc/glibc/arm/local-arm-futex.diff
new file mode 100644
index 000000000..27d1144d0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/glibc/glibc/arm/local-arm-futex.diff
@@ -0,0 +1,22 @@
+Description: Lie about futex_atomic_cmpxchg_inatomic kernel support.
+ In past versions of glibc, we incorrectly assumed all ARM kernels
+ in all configurations supported futex_atomic_cmpxchg_inatomic. This
+ was clearly a lie, however it was a lie that we relied on, because
+ the fallback implementation appears to not play nicely with certain
+ applications like pulseaudio. Restore the lie for kernels > 2.6.32
+ and plug our ears and scream "LA LA LA" about how wrong this is.
+Author: Adam Conrad <adconrad@ubuntu.com>
+Bug-Ubuntu: https://launchpad.net/bugs/1436162
+Bug-Debian: https://bugs.debian.org/788799
+Last-Update: 2015-03-25
+
+--- a/sysdeps/unix/sysv/linux/arm/kernel-features.h
++++ b/sysdeps/unix/sysv/linux/arm/kernel-features.h
+@@ -22,7 +22,7 @@
+ /* The ARM kernel before 3.14.3 may or may not support
+ futex_atomic_cmpxchg_inatomic, depending on kernel
+ configuration. */
+-#if __LINUX_KERNEL_VERSION < 0x030E03
++#if __LINUX_KERNEL_VERSION < 0x020620
+ # undef __ASSUME_SET_ROBUST_LIST
+ #endif
diff --git a/meta-agl-profile-core/recipes-core/glibc/glibc_2.2%.bbappend b/meta-agl-profile-core/recipes-core/glibc/glibc_2.2%.bbappend
new file mode 100644
index 000000000..0868a2c7d
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/glibc/glibc_2.2%.bbappend
@@ -0,0 +1,3 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI_append_arm = " file://arm/local-arm-futex.diff "
diff --git a/meta-agl-profile-core/recipes-core/images/agl-image-boot.bb b/meta-agl-profile-core/recipes-core/images/agl-image-boot.bb
new file mode 100644
index 000000000..84cdbcf31
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/images/agl-image-boot.bb
@@ -0,0 +1,9 @@
+SUMMARY = "An AGL small image just capable of allowing a device to boot."
+
+require agl-image-boot.inc
+
+LICENSE = "MIT"
+
+IMAGE_INSTALL_append = "\
+ packagegroup-agl-image-boot \
+ "
diff --git a/meta-agl-profile-core/recipes-core/images/agl-image-boot.inc b/meta-agl-profile-core/recipes-core/images/agl-image-boot.inc
new file mode 100644
index 000000000..825393978
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/images/agl-image-boot.inc
@@ -0,0 +1,10 @@
+IMAGE_LINGUAS = " "
+
+inherit core-image
+
+IMAGE_INSTALL = "${CORE_IMAGE_EXTRA_INSTALL}"
+
+IMAGE_ROOTFS_SIZE ?= "8192"
+
+# Allow extra IMAGE_FSTYPES to be added by boards configs
+IMAGE_FSTYPES += "${AGL_EXTRA_IMAGE_FSTYPES}"
diff --git a/meta-agl-profile-core/recipes-core/images/agl-image-minimal-qa.bb b/meta-agl-profile-core/recipes-core/images/agl-image-minimal-qa.bb
new file mode 100644
index 000000000..b162f2904
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/images/agl-image-minimal-qa.bb
@@ -0,0 +1,12 @@
+SUMMARY = "An AGL small image just capable of allowing a device to boot and run tests."
+
+DESCRIPTION = "A minimal set of AGL Distribution. This image also has additional \
+packages (e.g. commandline tools) for Quality Assurance(QA)."
+
+require agl-image-minimal.bb
+
+LICENSE = "MIT"
+
+IMAGE_INSTALL_append = " \
+ packagegroup-ivi-common-test \
+ "
diff --git a/meta-agl-profile-core/recipes-core/images/agl-image-minimal.bb b/meta-agl-profile-core/recipes-core/images/agl-image-minimal.bb
new file mode 100644
index 000000000..1fd213d0f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/images/agl-image-minimal.bb
@@ -0,0 +1,9 @@
+SUMMARY = "An AGL small image just capable of allowing a device to boot."
+
+require agl-image-minimal.inc
+
+LICENSE = "MIT"
+
+IMAGE_INSTALL_append = "\
+ packagegroup-agl-image-minimal \
+ "
diff --git a/meta-agl-profile-core/recipes-core/images/agl-image-minimal.inc b/meta-agl-profile-core/recipes-core/images/agl-image-minimal.inc
new file mode 100644
index 000000000..825393978
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/images/agl-image-minimal.inc
@@ -0,0 +1,10 @@
+IMAGE_LINGUAS = " "
+
+inherit core-image
+
+IMAGE_INSTALL = "${CORE_IMAGE_EXTRA_INSTALL}"
+
+IMAGE_ROOTFS_SIZE ?= "8192"
+
+# Allow extra IMAGE_FSTYPES to be added by boards configs
+IMAGE_FSTYPES += "${AGL_EXTRA_IMAGE_FSTYPES}"
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-automotive.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-automotive.bb
new file mode 100644
index 000000000..d9f2279e1
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-automotive.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Automotive Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-automotive \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-connectivity.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-connectivity.bb
new file mode 100644
index 000000000..e909d5e5f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-connectivity.bb
@@ -0,0 +1,15 @@
+DESCRIPTION = "The minimal set of packages for Connectivity Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-connectivity \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ dhcp-server \
+ ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','connman','connman connman-client connman-tests connman-tools connman-ncurses','',d)} \
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-graphics.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-graphics.bb
new file mode 100644
index 000000000..1cc6f457b
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-graphics.bb
@@ -0,0 +1,10 @@
+DESCRIPTION = "The minimal set of packages for Graphics Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-graphics \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-kernel.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-kernel.bb
new file mode 100644
index 000000000..3d5556fd5
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-kernel.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Kernel Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-kernel \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-multimedia.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-multimedia.bb
new file mode 100644
index 000000000..01ca4cb85
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-multimedia.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Multimedia Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-multimedia \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-navi-lbs.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-navi-lbs.bb
new file mode 100644
index 000000000..2b04d5387
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-navi-lbs.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Navigation and Location Based Services Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-navi-lbs \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-os-commonlibs.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-os-commonlibs.bb
new file mode 100644
index 000000000..c44166e12
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-os-commonlibs.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Operating System and Common libraries Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-os-commonlibs \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-security.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-security.bb
new file mode 100644
index 000000000..eb5a68f0a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-security.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Security Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-security \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-speech-services.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-speech-services.bb
new file mode 100644
index 000000000..a494e5889
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-core-speech-services.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "The minimal set of packages for Speech Services Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-core-speech-services \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-boot.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-boot.bb
new file mode 100644
index 000000000..29f859c49
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-boot.bb
@@ -0,0 +1,18 @@
+DESCRIPTION = "The minimal set of packages required by AGL"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-image-boot \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ packagegroup-core-boot-agl \
+ "
+
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-minimal.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-minimal.bb
new file mode 100644
index 000000000..630c11d43
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-agl-image-minimal.bb
@@ -0,0 +1,27 @@
+DESCRIPTION = "The minimal set of packages required by AGL"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-image-minimal \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ packagegroup-core-boot-agl \
+ "
+
+
+RDEPENDS_${PN} += "\
+ packagegroup-agl-core-automotive \
+ packagegroup-agl-core-connectivity \
+ packagegroup-agl-core-graphics \
+ packagegroup-agl-core-multimedia \
+ packagegroup-agl-core-navi-lbs \
+ packagegroup-agl-core-os-commonlibs \
+ packagegroup-agl-core-speech-services \
+ packagegroup-agl-core-security \
+ packagegroup-agl-core-kernel \
+ "
diff --git a/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-core-boot-agl.bb b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-core-boot-agl.bb
new file mode 100644
index 000000000..c9d679879
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/packagegroups/packagegroup-core-boot-agl.bb
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2007 OpenedHand Ltd.
+#
+# derived from oe-core: meta/recipes-core/packagegroups/packagegroup-core-boot.bb
+
+SUMMARY = "Minimal boot requirements"
+DESCRIPTION = "The minimal set of packages required to boot the system"
+LICENSE = "MIT"
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+inherit packagegroup
+
+#
+# Set by the machine configuration with packages essential for device bootup
+#
+MACHINE_ESSENTIAL_EXTRA_RDEPENDS ?= ""
+MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS ?= ""
+
+# Distro can override the following VIRTUAL-RUNTIME providers:
+VIRTUAL-RUNTIME_dev_manager ?= "udev"
+VIRTUAL-RUNTIME_login_manager ?= "busybox"
+VIRTUAL-RUNTIME_init_manager ?= "sysvinit"
+VIRTUAL-RUNTIME_initscripts ?= "initscripts"
+VIRTUAL-RUNTIME_keymaps ?= "keymaps"
+
+SYSVINIT_SCRIPTS = "${@bb.utils.contains('MACHINE_FEATURES', 'rtc', 'busybox-hwclock', '', d)} \
+ modutils-initscripts \
+ init-ifupdown \
+ ${VIRTUAL-RUNTIME_initscripts} \
+ "
+
+RDEPENDS_${PN} = "\
+ base-files \
+ base-passwd \
+ busybox \
+ run-agl-postinsts \
+ ${@bb.utils.contains("DISTRO_FEATURES", "sysvinit", "${SYSVINIT_SCRIPTS}", "", d)} \
+ ${@bb.utils.contains("MACHINE_FEATURES", "keyboard", "${VIRTUAL-RUNTIME_keymaps}", "", d)} \
+ netbase \
+ ${VIRTUAL-RUNTIME_login_manager} \
+ ${VIRTUAL-RUNTIME_init_manager} \
+ ${VIRTUAL-RUNTIME_dev_manager} \
+ ${VIRTUAL-RUNTIME_update-alternatives} \
+ ${MACHINE_ESSENTIAL_EXTRA_RDEPENDS}"
+
+RRECOMMENDS_${PN} = "\
+ tzdata \
+ ${MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS}"
+
diff --git a/meta-agl-profile-core/recipes-core/psplash/.appends.core b/meta-agl-profile-core/recipes-core/psplash/.appends.core
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/.appends.core
diff --git a/meta-agl-profile-core/recipes-core/psplash/files/psplash-anim b/meta-agl-profile-core/recipes-core/psplash/files/psplash-anim
new file mode 100755
index 000000000..ac9bf674a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/files/psplash-anim
@@ -0,0 +1,11 @@
+#/bin/bash
+
+psplash-default "$@" &
+sleep .2
+while :; do
+ for x in 0 1 2 3 4 5 6 7 8 9 10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 10 9 8 7 6 5 4 3 2 1; do
+ psplash-write "PROGRESS ${x}0" || exit 0
+ psplash-write "MSG $(journalctl -n1 -ocat)" || exit 0
+ sleep .1
+ done
+done
diff --git a/meta-agl-profile-core/recipes-core/psplash/files/psplash-colors.h b/meta-agl-profile-core/recipes-core/psplash/files/psplash-colors.h
new file mode 100644
index 000000000..447490397
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/files/psplash-colors.h
@@ -0,0 +1,34 @@
+/*
+ * pslash - a lightweight framebuffer splashscreen for embedded devices.
+ *
+ * Copyright (c) 2012 sleep(5) ltd
+ * Author: Tomas Frydrych <tomas@sleepfive.com>
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that 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.
+ *
+ */
+
+#ifndef _HAVE_PSPLASH_COLORS_H
+#define _HAVE_PSPLASH_COLORS_H
+
+/* This is the overall background color */
+#define PSPLASH_BACKGROUND_COLOR 0xff,0xff,0xff
+
+/* This is the color of any text output */
+#define PSPLASH_TEXT_COLOR 0x00,0x00,0x00
+
+/* This is the color of the progress bar indicator */
+#define PSPLASH_BAR_COLOR 0x00,0x00,0x00
+
+/* This is the color of the progress bar background */
+#define PSPLASH_BAR_BACKGROUND_COLOR 0xff,0xff,0xff
+
+#endif
diff --git a/meta-agl-profile-core/recipes-core/psplash/files/psplash-poky-img.h b/meta-agl-profile-core/recipes-core/psplash/files/psplash-poky-img.h
new file mode 100644
index 000000000..c0e8b0818
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/files/psplash-poky-img.h
@@ -0,0 +1,5411 @@
+/* GdkPixbuf RGB C-Source image dump 1-byte-run-length-encoded */
+
+#define POKY_IMG_ROWSTRIDE (1800)
+#define POKY_IMG_WIDTH (600)
+#define POKY_IMG_HEIGHT (400)
+#define POKY_IMG_BYTES_PER_PIXEL (3) /* 3:RGB, 4:RGBA */
+#define POKY_IMG_RLE_PIXEL_DATA ((uint8*) \
+ "\377\377\377\377\377\377\377\377\203\377\377\377\1\376\376\376\221\377" \
+ "\377\377\1\376\376\376\215\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\376\376\376\233\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\202\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\376\376\376\206\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\204\377\377\377\1\376\376\376\203\377\377\377\5\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\202\376\376\376\207\377\377" \
+ "\377\1\376\376\376\205\377\377\377\1\376\376\376\211\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\235\377\377\377\1\376\376\376\203\377" \
+ "\377\377\1\376\376\376\213\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\216\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\365\377\377\377\1\376" \
+ "\376\376\203\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376" \
+ "\203\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\205\377" \
+ "\377\377\1\376\376\376\203\377\377\377\12\376\376\376\377\377\377\346" \
+ "\346\346\315\315\315\316\316\316\265\265\265\235\235\235\234\234\234" \
+ "\233\233\233\204\204\204\203kkm\202lln\2EEG;;=\215::<\204kkm\3kkkxxx" \
+ "\235\235\235\202\234\234\234\1\265\265\265\202\316\316\316\1\332\332" \
+ "\332\207\377\377\377\202\376\376\376\2\377\377\377\376\376\376\211\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\203\377\377\377\5\376" \
+ "\376\376\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\366\377\377\377\1\376\376\376\205" \
+ "\377\377\377\1\376\376\376\214\377\377\377\11\376\376\376\332\332\332" \
+ "\316\316\320\247\247\251\236\236\240\204\204\206kkm__a<<>\202::<\11;" \
+ ";=99;;;=99;::<;;=::<;;=99;\203::<\1<<>\213::<\13;;=::<;;=::<;;=::<;;" \
+ "=::<;;=::<;;=\207::<\3SSUllnxxz\202\234\234\236\202\316\316\316\2\377" \
+ "\377\377\376\376\376\214\377\377\377\1\376\376\376\203\377\377\377\1" \
+ "\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\376\377" \
+ "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\203\377\377\377" \
+ "\7\332\332\334\302\302\304\234\234\236\203\203\205llnEEG;;=\202::<\6" \
+ ";;=::<;;=::<;;=99;\204::<\1""99;\202;;=\1""99;\205::<\1;;=\213::<\11" \
+ ";;=::<;;=::<;;=::<;;=::<;;=\202::<\1""99;\206::<\1;;=\203::<\13;;=99" \
+ ";;;=::<;;=::<kkmxxz\234\234\236\300\300\302\316\316\316\203\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\204\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\374\377\377\377\7\346\346\350\301\301\303\235\235\237ww" \
+ "y``b99;;;=\202::<\1;;=\204::<\203;;=\3::<99;;;=\207::<\202;;=\204::<" \
+ "\203;;=\215::<\1;;=\207::<\11;;=::<;;=99;::<;;=::<99;::<\202;;=\5::<" \
+ ";;=::<;;=99;\202::<\2;;=::<\202;;=\6::<SSUkkm\235\235\237\264\264\266" \
+ "\332\332\334\210\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\377\377\377\377\377\377\377\377\377\377\377\377\362\377\377\377" \
+ "\1\376\376\376\202\377\377\377\11\346\346\350\265\265\267\221\221\223" \
+ "kkm::<;;=::<99;;;=\203::<\1;;=\202::<\3""99;::<;;=\202::<\4;;=99;::<" \
+ ";;=\204::<\1;;=\202::<\202;;=\1::<\202;;=\202::<\1;;=\203::<\1;;=\211" \
+ "::<\2;;=99;\202::<\2;;=99;\206::<\1;;=\202::<\2""99;;;=\210::<\1;;=\202" \
+ "::<\1;;=\203::<\1;;=\203::<\1;;=\202::<\4kkm\222\222\224\265\265\267" \
+ "\332\332\334\204\377\377\377\1\376\376\376\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\362\377\377\377\12\363\363\363\316\316\316\235\235" \
+ "\235jjjFFH;;=::<;;=::<;;=\202::<\1;;=\204::<\1""99;\202::<\2;;=::<\202" \
+ ";;=\204::<\7;;=::<;;=::<;;=::<;;=\203::<\1;;=\202::<\1;;=\217::<\2""9" \
+ "9;;;=\203::<\1;;=\202::<\4""99;;;=::<;;=\203::<\2;;=99;\202::<\1;;=\207" \
+ "::<\1;;=\213::<\1;;=\204::<\7kkk\221\221\221\301\301\301\363\363\363" \
+ "\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\321\377\377\377\1\376\376\376\202\377\377\377\1\376" \
+ "\376\376\221\377\377\377\1\376\376\376\204\377\377\377\4\363\363\365" \
+ "\301\301\303\222\222\224__a\220::<\3;;=::<;;=\204::<\203;;=\203::<\2" \
+ ";;=::<\202;;=\4::<;;=::<;;=\204::<\1;;=\202::<\4;;=::<99;;;=\211::<\1" \
+ "99;\205::<\202;;=\210::<\5;;=::<;;=::<;;=\203::<\1;;=\212::<\4;;=99;" \
+ ";;=99;\211::<\4SSU\204\204\206\266\266\270\345\345\345\221\377\377\377" \
+ "\1\376\376\376\204\377\377\377\202\376\376\376\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\266\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\207\377\377\377\1\376\376" \
+ "\376\210\377\377\377\10\363\363\363\301\301\301\221\221\221``b99;;;=" \
+ "::<;;=\213::<\3;;=::<;;=\203::<\1;;=\204::<\2;;=99;\202::<\1""99;\202" \
+ ";;=\204::<\1;;=\210::<\202;;=\202::<\2;;=99;\215::<\1;;=\204::<\1;;=" \
+ "\205::<\5;;=99;;;=::<;;=\202::<\202;;=\4""99;;;=::<;;=\203::<\1;;=\204" \
+ "::<\3;;=99;;;=\210::<\11;;=::<;;=99;;;=SSS\205\205\205\266\266\266\363" \
+ "\363\363\202\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376" \
+ "\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\266\377\377\377\1\376\376\376" \
+ "\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\207\377" \
+ "\377\377\5\376\376\376\333\333\335\250\250\252kkm;;=\203::<\202;;=\212" \
+ "::<\10;;=::<;;=::<;;=::<;;=::<\202;;=\206::<\10;;=::<;;=::<;;=::<;;=" \
+ "::<\202;;=\2::<;;=\203::<\3;;=::<;;=\202::<\1;;=\202::<\1;;=\211::<\1" \
+ "99;\202;;=\203::<\1;;=\205::<\1;;=\204::<\1;;=\206::<\203;;=\202::<\1" \
+ ";;=\206::<\1;;=\213::<\1;;=\204::<\1;;=\202::<\3__a\221\221\223\316\316" \
+ "\316\204\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\207" \
+ "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\267\377\377\377\202\376\376\376\210\377\377\377\1\376\376\376\207" \
+ "\377\377\377\3\301\301\301\204\204\206SSU\203::<\3;;=::<;;=\202::<\2" \
+ "99;;;=\215::<\1;;=\204::<\2;;=99;\202::<\202;;=\202::<\7""99;::<;;=:" \
+ ":<;;=99;;;=\202::<\2""99;;;=\202::<\1;;=\207::<\1;;=\211::<\2""99;;;" \
+ "=\202::<\3;;=::<;;=\202::<\2""99;;;=\206::<\4;;=::<;;=::<\202;;=\206" \
+ "::<\3;;=::<;;=\202::<\5;;=::<;;=99;;;=\220::<\2;;=::<\202;;=\5""99;G" \
+ "GIxxx\265\265\265\363\363\363\207\377\377\377\1\376\376\376\205\377\377" \
+ "\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\274" \
+ "\377\377\377\1\376\376\376\204\377\377\377\202\376\376\376\4\364\364" \
+ "\364\265\265\265xxz;;=\20299;\202::<\1""99;\204::<\3;;=::<;;=\213::<" \
+ "\1;;=\203::<\3;;=::<;;=\207::<\2;;=::<\202;;=\4""99;;;=::<;;=\202::<" \
+ "\5__allnkkm\221\221\223\235\235\237\202\234\234\236\6\317\317\317\315" \
+ "\315\315\317\317\317\315\315\315\316\316\316\346\346\346\213\377\377" \
+ "\377\3\376\376\376\377\377\377\346\346\346\204\316\316\316\5\316\316" \
+ "\320\251\251\253\234\234\236\233\233\235\235\235\237\203kkm\202::<\1" \
+ ";;=\202::<\6;;=::<;;=99;::<;;=\205::<\2;;=::<\203;;=\202::<\1;;=\212" \
+ "::<\1;;=\202::<\1;;=\202::<\1;;=\204::<\1;;=\202::<\3lln\250\250\252" \
+ "\346\346\350\206\377\377\377\1\376\376\376\204\377\377\377\1\376\376" \
+ "\376\377\377\377\377\377\377\377\377\377\377\377\377\271\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\4\362\362" \
+ "\362\266\266\270xxz::<\202;;=\202::<\10;;=::<99;;;=::<;;=::<;;=\203:" \
+ ":<\1;;=\213::<\3;;=::<;;=\205::<\1;;=\202::<\1<<>\202::<\7llnkkm\233" \
+ "\233\235\235\235\237\302\302\304\316\316\320\347\347\351\241\377\377" \
+ "\377\202\376\376\376\203\377\377\377\17\376\376\376\377\377\377\376\376" \
+ "\376\377\377\377\376\376\376\363\363\363\316\316\316\315\315\315\234" \
+ "\234\234\235\235\235xxxllnFFH::<;;=\205::<\5;;=99;;;=::<;;=\212::<\202" \
+ ";;=\212::<\5;;=99;;;=::<99;\202::<\5__a\250\250\252\346\346\346\377\377" \
+ "\377\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\271\377\377\377\202\376\376\376\2\377\377\377" \
+ "\376\376\376\203\377\377\377\3\363\363\363\266\266\266wwy\202;;=\210" \
+ "::<\1<<>\203::<\2<<>99;\215::<\1;;=\205::<\11;;=::<;;;___xxx\235\235" \
+ "\235\266\266\266\315\315\315\364\364\364\207\377\377\377\1\376\376\376" \
+ "\213\377\377\377\1\376\376\376\231\377\377\377\5\376\376\376\377\377" \
+ "\377\376\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376\376" \
+ "\204\377\377\377\1\376\376\376\202\377\377\377\5\316\316\316\302\302" \
+ "\302\233\233\233yyykkk\202::<\6;;=::<;;=::<99;;;=\211::<\1;;=\202::<" \
+ "\1;;=\206::<\1""99;\202;;=\202::<\203;;=\1""99;\202::<\3__a\251\251\253" \
+ "\346\346\346\204\377\377\377\3\376\376\376\377\377\377\376\376\376\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\266\377\377\377\1\376\376" \
+ "\376\202\377\377\377\2\302\302\302xxx\203::<\3;;=::<;;=\232::<\1;;=\202" \
+ "::<\6RRTkkm\235\235\237\301\301\303\332\332\334\376\376\376\222\377\377" \
+ "\377\1\376\376\376\260\377\377\377\3\376\376\376\377\377\377\376\376" \
+ "\376\202\377\377\377\5\345\345\347\316\316\320\235\235\237xxzSSU\215" \
+ "::<\202;;=\202::<\203;;=\2::<;;=\203::<\1;;=\204::<\10;;=::<;;=::<;;" \
+ "=kkm\266\266\266\363\363\363\202\377\377\377\1\376\376\376\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\245\377\377\377\1\376\376\376\214" \
+ "\377\377\377\1\376\376\376\202\377\377\377\5\376\376\376\377\377\377" \
+ "\332\332\332\205\205\207GGI\202::<\1;;=\211::<\202;;=\205::<\2;;=::<" \
+ "\202;;=\203::<\14;;=99;::<;;=99;;;=FFFxxx\234\234\234\315\315\315\364" \
+ "\364\364\376\376\376\323\377\377\377\4\317\317\317\250\250\250xxxSSS" \
+ "\202::<\1;;=\206::<\2;;=::<\203;;=\202::<\2;;=99;\204::<\7;;=::<;;=:" \
+ ":<;;=::<;;=\204::<\3\204\204\206\301\301\301\376\376\376\220\377\377" \
+ "\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\225" \
+ "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\206\377\377" \
+ "\377\1\376\376\376\202\377\377\377\4\363\363\363\251\251\251___;;=\202" \
+ "::<\1;;=\202::<\202;;=\204::<\1;;=\202::<\7;;=::<;;=::<;;=::<;;=\203" \
+ "::<\3""99;::<;;=\202::<\5;;=__a\221\221\223\265\265\267\346\346\346\323" \
+ "\377\377\377\1\376\376\376\211\377\377\377\5\363\363\363\301\301\303" \
+ "\235\235\237lln::<\202;;=\203::<\1;;=\204::<\1;;=\202::<\2""99;;;=\205" \
+ "::<\2;;=99;\203::<\1""99;\204::<\3TTT\233\233\233\346\346\346\207\377" \
+ "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\250\377\377\377\3\316\316\316\204\204\204;;=\203::<\1;;=\203::<\1;;" \
+ "=\202::<\1;;=\205::<\3;;=::<;;=\202::<\4""99;;;=::<;;=\202::<\202;;=" \
+ "\4___\221\221\221\301\301\303\363\363\365\203\377\377\377\1\376\376\376" \
+ "\203\377\377\377\202\376\376\376\321\377\377\377\1\376\376\376\210\377" \
+ "\377\377\1\376\376\376\202\377\377\377\4\316\316\316\235\235\235kkk;" \
+ ";=\202::<\202;;=\203::<\5;;=::<;;=99;;;=\204::<\202;;=\7::<;;=99;::<" \
+ ";;=::<;;=\202::<\202;;=\2xxz\302\302\304\213\377\377\377\1\376\376\376" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\224\377\377\377\1\376" \
+ "\376\376\212\377\377\377\3\363\363\363\266\266\266TTV\203::<\3;;=::<" \
+ ";;=\202::<\203;;=\202::<\202;;=\205::<\1;;=\202::<\1;;=\204::<\4SSU\221" \
+ "\221\223\301\301\301\363\363\363\206\377\377\377\1\376\376\376\203\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\315\377\377\377" \
+ "\202\376\376\376\202\377\377\377\1\376\376\376\210\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\202\377\377\377\3\316\316\316" \
+ "\221\221\223__a\203::<\1;;=\203::<\3;;=::<;;=\203::<\5;;=99;;;=::<;;" \
+ "=\204::<\1""99;\205::<\3SSU\234\234\236\346\346\346\207\377\377\377\3" \
+ "\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\233\377\377\377\4\376\376\376\347\347\347\221\221\221" \
+ "FFH\207::<\4""99;;;=::<;;=\20299;\202;;=\202::<\1;;=\203::<\2;;=::<\202" \
+ ";;=\202::<\3xxz\250\250\252\346\346\350\215\377\377\377\203\376\376\376" \
+ "\316\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\211\377" \
+ "\377\377\1\376\376\376\211\377\377\377\4\363\363\363\265\265\267\205" \
+ "\205\207FFH\210::<\3;;=::<;;=\204::<\1;;=\207::<\2;;=::<\202;;=\2\203" \
+ "\203\205\317\317\321\206\377\377\377\1\376\376\376\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\233\377\377\377\3\316\316\316yy{99;\206" \
+ "::<\2;;=99;\202;;=\205::<\5""99;::<;;=::<;;=\202::<\6;;=::<;;=SSU\204" \
+ "\204\204\301\301\301\226\377\377\377\1\376\376\376\317\377\377\377\1" \
+ "\376\376\376\203\377\377\377\1\376\376\376\204\377\377\377\1\376\376" \
+ "\376\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\202" \
+ "\377\377\377\3\316\316\316\221\221\221SSU\203::<\3;;=::<99;\204::<\1" \
+ ";;=\203::<\2""99;;;=\202::<\1;;=\204::<\5""99;<<>::<kkk\264\264\264\203" \
+ "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\232\377\377\377\2\266\266\270__a\202::<\5;;=::<;;=::<99;\202;;=" \
+ "\10::<;;=::<;;=::<;;=99;;;=\202::<\11;;=::<99;;;=::<;;=SSU\221\221\223" \
+ "\331\331\331\211\377\377\377\1\376\376\376\204\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\324\377\377\377\1\376\376\376\202" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\212\377\377\377\1" \
+ "\376\376\376\214\377\377\377\14\332\332\332\251\251\251``b::<;;=::<;" \
+ ";=99;::<;;=::<;;=\202::<\3;;=99;;;=\203::<\1;;=\202::<\10;;=99;;;=::" \
+ "<;;=SSU\250\250\252\363\363\363\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\231\377\377\377\2\265\265\265SSU\216::<\4;;=::<99;;;=\205::" \
+ "<\10;;=SSU\222\222\224\332\332\334\377\377\377\376\376\376\377\377\377" \
+ "\376\376\376\205\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\327\377\377\377\1\376\376\376\202" \
+ "\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376\207\377\377" \
+ "\377\1\376\376\376\216\377\377\377\4\347\347\351\250\250\252``b::<\202" \
+ ";;=\202::<\1;;=\203::<\1;;=\203::<\1;;=\202::<\3;;=::<;;=\202::<\6""9" \
+ "9;;;=::<FFF\233\233\233\363\363\363\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\206\377\377\377\3\376\376\376\377\377\377\376\376\376\213" \
+ "\377\377\377\4\363\363\365\234\234\236FFH;;=\206::<\2""99;;;=\204::<" \
+ "\202;;=\2::<;;=\206::<\4FFH\204\204\206\333\333\333\376\376\376\264\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\327\377\377\377\4\346" \
+ "\346\346\221\221\221SSS:::\202::<\1;;=\204::<\3;;=::<;;=\214::<\3GGI" \
+ "\221\221\223\347\347\347\211\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\376\376\376\377\377\377\377\377\377\377\377\371\377\377\377\1\376" \
+ "\376\376\207\377\377\377\5\363\363\363\234\234\234FFH::<;;=\204::<\1" \
+ ";;=\202::<\1;;=\203::<\1;;=\204::<\1;;=\203::<\5;;=xxz\300\300\302\377" \
+ "\377\377\376\376\376\267\377\377\377\1\376\376\376\202\377\377\377\1" \
+ "\376\376\376\215\377\377\377\1\376\376\376\303\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\204\377\377\377\4\332\332\332\203\203\205" \
+ "GGI99;\207::<\202;;=\203::<\6;;=::<;;=::<;;=99;\202;;=\202::<\3\204\204" \
+ "\204\346\346\346\376\376\376\205\377\377\377\1\376\376\376\377\377\377" \
+ "\377\377\377\377\377\373\377\377\377\1\376\376\376\203\377\377\377\1" \
+ "\376\376\376\204\377\377\377\3\362\362\362\234\234\236GGI\203::<\15;" \
+ ";=::<;;=::<;;=::<;;=99;;;=::<;;=::<99;\202;;=\7::<;;=99;::<```\250\250" \
+ "\250\363\363\363\202\377\377\377\1\375\375\375\272\377\377\377\1\376" \
+ "\376\376\214\377\377\377\1\376\376\376\306\377\377\377\1\375\375\375" \
+ "\210\377\377\377\6\265\265\265lln::<;;=::<;;=\202::<\5;;=99;;;=::<99" \
+ ";\205::<\1;;=\206::<\4\204\204\206\345\345\345\377\377\377\376\376\376" \
+ "\207\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\372\377" \
+ "\377\377\1\376\376\376\202\377\377\377\3\364\364\364\233\233\235GGI\202" \
+ "::<\203;;=\2""99;;;=\202::<\3""99;::<;;=\202::<\13;;=99;::<;;=::<;;=" \
+ "::<FFH\204\204\204\333\333\333\376\376\376\204\377\377\377\1\376\376" \
+ "\376\204\377\377\377\1\376\376\376\304\377\377\377\1\376\376\376\317" \
+ "\377\377\377\4\346\346\346\221\221\223GGI99;\204::<\1""99;\202;;=\2:" \
+ ":<;;=\204::<\1;;=\204::<\202;;=\3::<\221\221\223\364\364\364\203\377" \
+ "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377" \
+ "\377\377\377\377\371\377\377\377\1\376\376\376\202\377\377\377\6\265" \
+ "\265\267SSU::<99;::<;;=\203::<\1;;=\202::<\1;;=\204::<\3;;=::<;;=\202" \
+ "::<\6;;=SSS\264\264\264\363\363\363\377\377\377\376\376\376\204\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\267\377\377\377\1\376\376" \
+ "\376\221\377\377\377\1\376\376\376\307\377\377\377\1\376\376\376\207" \
+ "\377\377\377\4\376\376\376\377\377\377\266\266\266kkm\202::<\1;;=\202" \
+ "::<\6;;=::<99;;;=99;;;=\205::<\3;;=::<99;\202::<\4GGI\234\234\234\363" \
+ "\363\363\376\376\376\377\377\377\377\377\377\377\377\375\377\377\377" \
+ "\4\376\376\376\377\377\377\265\265\265SSU\202::<\1;;=\204::<\1;;=\203" \
+ "::<\3;;=99;;;=\205::<\202;;=\2yyy\316\316\316\203\377\377\377\1\376\376" \
+ "\376\206\377\377\377\3\376\376\376\377\377\377\376\376\376\263\377\377" \
+ "\377\1\376\376\376\205\377\377\377\2\315\315\315;;;\211::<\3;;;:::\315" \
+ "\315\315\202\377\377\377\1\376\376\376\312\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\205\377\377\377\5\346\346\346\204\204\204FF" \
+ "H::<;;=\202::<\4;;=::<;;=::<\203;;=\203::<\2<<>99;\202::<\4""99;;;=F" \
+ "FF\234\234\234\377\377\377\377\377\377\377\377\375\377\377\377\11\316" \
+ "\316\320kkm::<;;=::<;;=99;::<;;=\203::<\202;;=\2::<99;\205::<\13;;=F" \
+ "FH\221\221\221\346\346\346\376\376\376\377\377\377\376\376\376\377\377" \
+ "\377\376\376\376\377\377\377\376\376\376\204\377\377\377\1\376\376\376" \
+ "\273\377\377\377\2\376\376\376\317\317\317\212::<\6;;=;;;\316\316\316" \
+ "\376\376\376\377\377\377\376\376\376\304\377\377\377\1\376\376\376\206" \
+ "\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\204\377\377\377\4\363\363\363\235\235\235RRT;;=\202::<\202;;=\7" \
+ "::<;;=99;::<;;=::<;;=\203::<\1;;=\202::<\6;;=::<SSU\264\264\264\377\377" \
+ "\377\376\376\376\377\377\377\377\377\377\377\377\367\377\377\377\3\346" \
+ "\346\346xxz;;=\205::<\1;;=\203::<\3;;=::<;;=\207::<\3SSU\247\247\251" \
+ "\363\363\363\217\377\377\377\1\376\376\376\272\377\377\377\1\316\316" \
+ "\316\213::<\2;;=\316\316\316\306\377\377\377\3\376\376\376\377\377\377" \
+ "\376\376\376\221\377\377\377\4\265\265\267SSU;;=99;\202::<\2""99;;;=" \
+ "\206::<\1;;=\204::<\1;;=\202::<\3jjj\317\317\317\376\376\376\377\377" \
+ "\377\377\377\377\377\377\343\377\377\377\1\376\376\376\211\377\377\377" \
+ "\1\376\376\376\206\377\377\377\2\363\363\363\233\233\233\210::<\1;;=" \
+ "\203::<\1;;=\203::<\1;;=\203::<\2SSS\265\265\265\315\377\377\377\1\316" \
+ "\316\316\214::<\1\316\316\316\334\377\377\377\3\316\316\316kkk::<\202" \
+ ";;=\206::<\1;;=\202::<\1;;=\202::<\7""99;;;=::<;;=::<\204\204\206\346" \
+ "\346\350\377\377\377\377\377\377\377\377\347\377\377\377\1\376\376\376" \
+ "\212\377\377\377\3\265\265\265SSS::<\202;;=\205::<\1;;=\202::<\202;;" \
+ "=\202::<\1;;=\203::<\2lln\265\265\267\203\377\377\377\1\376\376\376\313" \
+ "\377\377\377\1\316\316\316\214::<\1\316\316\316\336\377\377\377\6\316" \
+ "\316\316kkm::<;;=::<;;=\202::<\3;;=::<;;=\204::<\10;;=99;;;=::<99;;;" \
+ "=FFH\234\234\234\210\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\377\377\377\377\377\327\377\377\377\2\376\376\376\377\377" \
+ "\377\202\376\376\376\205\377\377\377\1\376\376\376\203\377\377\377\5" \
+ "\332\332\332kkk;;=::<;;=\205::<\4;;=::<;;=::<\202;;=\2::<;;=\203::<\2" \
+ "kkm\317\317\317\204\377\377\377\1\376\376\376\314\377\377\377\1\316\316" \
+ "\316\214::<\1\316\316\316\336\377\377\377\14\376\376\376\377\377\377" \
+ "\316\316\316\204\204\206;;=::<;;=::<;;=99;::<;;=\205::<\11;;=99;;;=9" \
+ "9;::<;;;RRR\317\317\317\376\376\376\204\377\377\377\1\376\376\376\377" \
+ "\377\377\377\377\377\377\377\332\377\377\377\202\376\376\376\211\377" \
+ "\377\377\2\363\363\363\221\221\223\203::<\1;;=\207::<\1;;=\202::<\202" \
+ ";;=\10::<99;::<lln\316\316\316\376\376\376\377\377\377\376\376\376\206" \
+ "\377\377\377\1\376\376\376\311\377\377\377\1\316\316\316\214::<\1\316" \
+ "\316\316\335\377\377\377\7\376\376\376\377\377\377\376\376\376\377\377" \
+ "\377\376\376\376\347\347\347kkm\202::<\2""88:;;=\203::<\1;;=\204::<\3" \
+ ";;=99;;;=\202::<\4;;=::<xxx\346\346\346\206\377\377\377\1\376\376\376" \
+ "\377\377\377\377\377\377\377\377\331\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\203\377\377\377\4\376\376\376\377\377\377\300\300\302" \
+ "SSU\207::<\1;;=\202::<\1;;=\205::<\4""99;;;=SSU\316\316\316\204\377\377" \
+ "\377\1\376\376\376\205\377\377\377\1\376\376\376\202\377\377\377\1\376" \
+ "\376\376\307\377\377\377\1\316\316\316\214::<\1\316\316\316\334\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\204\377\377\377\3\317" \
+ "\317\317kkm;;=\205::<\3;;=::<99;\203::<\1;;=\204::<\3;;=FFH\250\250\250" \
+ "\205\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377" \
+ "\377\377\377\377\326\377\377\377\1\376\376\376\204\377\377\377\4\376" \
+ "\376\376\377\377\377\347\347\351xxz\202::<\1;;=\204::<\1;;=\203::<\1" \
+ ";;=\204::<\4""99;;;=SSU\266\266\266\205\377\377\377\1\376\376\376\202" \
+ "\377\377\377\1\376\376\376\205\377\377\377\1\375\375\375\310\377\377" \
+ "\377\1\316\316\316\214::<\1\316\316\316\344\377\377\377\7\376\376\376" \
+ "\377\377\377\316\316\316kkm;;=::<99;\202::<\203;;=\2::<;;=\204::<\1;" \
+ ";=\202::<\3;;=__a\332\332\334\377\377\377\377\377\377\377\377\335\377" \
+ "\377\377\1\376\376\376\204\377\377\377\4\250\250\252FFH::<;;=\202::<" \
+ "\3;;=::<;;=\202::<\3""99;::<;;=\202::<\1;;=\202::<\4HHJ\250\250\250\377" \
+ "\377\377\376\376\376\206\377\377\377\202\376\376\376\205\377\377\377" \
+ "\1\376\376\376\311\377\377\377\1\316\316\316\214::<\1\316\316\316\345" \
+ "\377\377\377\1\376\376\376\202\377\377\377\2\301\301\301SSU\202::<\1" \
+ ";;=\202::<\2""99;;;=\212::<\3;;=\233\233\233\363\363\363\377\377\377" \
+ "\377\377\377\377\377\331\377\377\377\1\376\376\376\204\377\377\377\2" \
+ "\346\346\346kkk\211::<\3;;=99;;;=\206::<\2\235\235\237\363\363\363\205" \
+ "\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\321\377\377" \
+ "\377\1\316\316\316\214::<\1\316\316\316\352\377\377\377\2\250\250\252" \
+ "GGI\206::<\5;;=::<;;=::<;;=\202::<\202;;=\4::<:::SSS\316\316\316\203" \
+ "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\330\377\377" \
+ "\377\2\251\251\251FFH\203::<\1""99;\207::<\1;;=\204::<\3;;=xxx\346\346" \
+ "\346\334\377\377\377\1\316\316\316\214::<\1\316\316\316\350\377\377\377" \
+ "\13\376\376\376\377\377\377\376\376\376\363\363\363\234\234\23699;;;" \
+ "=::<;;=99;;;=\202::<\2""99;;;=\206::<\202;;=\2\221\221\223\363\363\363" \
+ "\204\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377" \
+ "\1\376\376\376\377\377\377\377\377\377\377\377\316\377\377\377\2\346" \
+ "\346\346kkk\202;;=\206::<\1;;=\203::<\3;;=::<;;=\202::<\2``b\316\316" \
+ "\320\336\377\377\377\1\316\316\316\214::<\1\316\316\316\353\377\377\377" \
+ "\4\376\376\376\377\377\377\350\350\352kkm\206::<\2;;=99;\203::<\1;;=" \
+ "\203::<\6;;=::<TTV\331\331\331\377\377\377\376\376\376\207\377\377\377" \
+ "\1\376\376\376\377\377\377\377\377\377\377\377\306\377\377\377\1\376" \
+ "\376\376\203\377\377\377\5\376\376\376\377\377\377\266\266\266EEG;;=" \
+ "\203::<\1;;=\203::<\1;;=\204::<\202;;=\3::<GGI\250\250\252\205\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\327\377\377\377\1\316" \
+ "\316\316\214::<\1\316\316\316\351\377\377\377\1\376\376\376\203\377\377" \
+ "\377\5\376\376\376\377\377\377\316\316\316TTV;;=\203::<\3;;=::<;;=\204" \
+ "::<\202;;=\5::<;;=99;;;=\234\234\236\207\377\377\377\1\376\376\376\377" \
+ "\377\377\377\377\377\377\377\303\377\377\377\3\376\376\376\377\377\377" \
+ "\376\376\376\203\377\377\377\6\376\376\376\377\377\377\364\364\364ww" \
+ "y::<;;=\202::<\202;;=\202::<\5;;=::<99;::<;;=\202::<\4;;=::<\204\204" \
+ "\206\363\363\363\202\377\377\377\1\376\376\376\202\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\331\377\377\377\1\316\316\316\214::" \
+ "<\1\316\316\316\353\377\377\377\1\376\376\376\204\377\377\377\11\376" \
+ "\376\376\234\234\234GGI::<;;=::<;;=::<;;=\207::<\1;;=\202::<\2__a\332" \
+ "\332\332\377\377\377\377\377\377\377\377\320\377\377\377\4\316\316\316" \
+ "FFH::<;;=\202::<\1;;=\207::<\2;;=99;\202;;=\3__a\316\316\320\376\376" \
+ "\376\342\377\377\377\1\316\316\316\214::<\1\316\316\316\361\377\377\377" \
+ "\5\376\376\376\347\347\347lln::<;;=\210::<\1""99;\202::<\7;;=::<99;G" \
+ "GI\247\247\247\377\377\377\376\376\376\202\377\377\377\1\376\376\376" \
+ "\377\377\377\377\377\377\377\377\305\377\377\377\1\376\376\376\203\377" \
+ "\377\377\3\221\221\221:::;;=\203::<\1;;=\202::<\1;;=\203::<\1;;=\202" \
+ "::<\4;;=FFH\234\234\234\376\376\376\202\377\377\377\1\375\375\375\202" \
+ "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\332\377\377" \
+ "\377\1\316\316\316\214::<\1\316\316\316\364\377\377\377\3\301\301\303" \
+ "FFH;;=\206::<\1;;=\205::<\5;;=99;;;=yy{\363\363\363\377\377\377\377\377" \
+ "\377\377\377\312\377\377\377\3\346\346\346^^`;;=\207::<\1;;=\203::<\1" \
+ ";;=\203::<\2jjl\346\346\350\202\377\377\377\1\376\376\376\213\377\377" \
+ "\377\1\375\375\375\327\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\360\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377" \
+ "\2\363\363\363\220\220\220\202;;=\203::<\2;;=99;\206::<\1;;=\202::<\2" \
+ "SSU\316\316\320\202\377\377\377\1\376\376\376\377\377\377\377\377\377" \
+ "\377\377\303\377\377\377\4\376\376\376\377\377\377\302\302\302FFH\217" \
+ "::<\2GGI\250\250\252\205\377\377\377\1\376\376\376\211\377\377\377\3" \
+ "\376\376\376\377\377\377\376\376\376\326\377\377\377\1\316\316\316\214" \
+ "::<\1\316\316\316\356\377\377\377\1\376\376\376\210\377\377\377\3\316" \
+ "\316\316SSU;;=\203::<\202;;=\207::<\1;;=\202::<\1\235\235\237\377\377" \
+ "\377\377\377\377\377\377\306\377\377\377\1\221\221\221\202::<\2;;=99" \
+ ";\203::<\3;;=::<;;=\203::<\1;;=\202::<\2kkm\346\346\346\351\377\377\377" \
+ "\1\316\316\316\214::<\1\316\316\316\370\377\377\377\2\362\362\362\221" \
+ "\221\221\204::<\3;;=::<;;=\206::<\1;;=\202::<\2xxz\362\362\364\377\377" \
+ "\377\377\377\377\377\377\301\377\377\377\3\376\376\376\363\363\363__" \
+ "_\204::<\3;;=::<;;=\202::<\2;;=99;\202;;=\4::<99;GGI\250\250\252\353" \
+ "\377\377\377\1\316\316\316\214::<\1\316\316\316\366\377\377\377\1\376" \
+ "\376\376\203\377\377\377\2\317\317\317SSS\211::<\202;;=\6""99;;;=99;" \
+ "::<SSU\332\332\332\202\377\377\377\1\376\376\376\377\377\377\377\377" \
+ "\377\377\377\267\377\377\377\11\376\376\376\377\377\377\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377\317\317\321FFH;;=\202::<\3;;=::<99;" \
+ "\203::<\203;;=\202::<\4;;=lll\346\346\346\376\376\376\353\377\377\377" \
+ "\1\316\316\316\214::<\1\316\316\316\367\377\377\377\1\376\376\376\202" \
+ "\377\377\377\5\376\376\376\363\363\363\221\221\223;;=99;\202;;=\3::<" \
+ "99;;;=\202::<\202;;=\6::<;;=::<;;=::<\265\265\265\202\377\377\377\1\376" \
+ "\376\376\377\377\377\377\377\377\377\377\273\377\377\377\1\250\250\252" \
+ "\202::<\2""99;;;=\203::<\1;;=\202::<\1;;=\204::<\3;;=\250\250\250\376" \
+ "\376\376\205\377\377\377\1\376\376\376\347\377\377\377\1\316\316\316" \
+ "\214::<\1\316\316\316\373\377\377\377\5\376\376\376\377\377\377\300\300" \
+ "\300FFH;;=\202::<\1;;=\202::<\3;;=::<;;=\202::<\2;;=::<\202;;=\4\205" \
+ "\205\207\376\376\376\377\377\377\376\376\376\377\377\377\377\377\377" \
+ "\377\377\267\377\377\377\3\376\376\376\364\364\364\205\205\207\202::" \
+ "<\202;;=\15""99;;;=::<;;=::<;;=::<99;;;=99;;;=__a\331\331\331\357\377" \
+ "\377\377\1\316\316\316\214::<\1\316\316\316\366\377\377\377\1\376\376" \
+ "\376\203\377\377\377\1\376\376\376\203\377\377\377\2\363\363\363kkm\215" \
+ "::<\4;;=99;__a\363\363\363\202\377\377\377\1\376\376\376\377\377\377" \
+ "\377\377\377\377\377\265\377\377\377\4\347\347\351__a::<;;=\203::<\1" \
+ ";;=\202::<\1;;=\203::<\1;;=\202::<\2\221\221\223\363\363\363\360\377" \
+ "\377\377\1\316\316\316\214::<\1\316\316\316\364\377\377\377\1\376\376" \
+ "\376\203\377\377\377\1\376\376\376\207\377\377\377\2\251\251\253;;=\203" \
+ "::<\1;;=\203::<\1;;=\203::<\203;;=\3FFH\332\332\332\376\376\376\377\377" \
+ "\377\377\377\377\377\377\265\377\377\377\4\331\331\331FFH::<;;=\203:" \
+ ":<\1;;=\202::<\1;;=\205::<\2FFH\302\302\302\205\377\377\377\7\376\376" \
+ "\376\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377\376" \
+ "\376\376\346\377\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377" \
+ "\377\202\377\377\377\2\332\332\332SSU\203::<\1;;=\203::<\12""99;;;=:" \
+ ":<99;::<;;=99;;;=\266\266\266\376\376\376\377\377\377\377\377\377\377" \
+ "\377\263\377\377\377\1\265\265\265\202::<\1;;=\205::<\202;;=\202::<\1" \
+ ";;=\202::<\2__a\346\346\350\203\377\377\377\1\376\376\376\357\377\377" \
+ "\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\203\377\377\377" \
+ "\2\363\363\363\204\204\204\202::<\1;;=\203::<\1;;=\205::<\1;;=\202::" \
+ "<\1\221\221\221\377\377\377\377\377\377\377\377\262\377\377\377\4\235" \
+ "\235\237;;=::<;;=\203::<\1;;=\206::<\3;;=::<\222\222\222\202\377\377" \
+ "\377\1\376\376\376\362\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\377\377\377\377\205\377\377\377\3\265\265\265:::;;=\206::<\5;;=::<;" \
+ ";=::<;;=\202::<\2\204\204\206\363\363\363\212\377\377\377\1\376\376\376" \
+ "\377\377\377\377\377\377\377\377\236\377\377\377\1\376\376\376\202\377" \
+ "\377\377\4\376\376\376\377\377\377\376\376\377\204\204\206\206::<\12" \
+ ";;=::<;;=::<;;=::<;;=::<FFH\301\301\301\366\377\377\377\1\316\316\316" \
+ "\214::<\1\316\316\316\377\377\377\377\206\377\377\377\4\333\333\333S" \
+ "SU::<;;=\205::<\4;;=::<;;=::<\202;;=\3::<__a\364\364\364\202\377\377" \
+ "\377\1\376\376\376\205\377\377\377\1\376\376\376\202\377\377\377\1\376" \
+ "\376\376\377\377\377\377\377\377\377\377\236\377\377\377\4\376\376\376" \
+ "\377\377\377\363\363\365__a\203::<\10""99;;;=::<;;=99;;;=99;;;=\203:" \
+ ":<\2__a\332\332\332\203\377\377\377\1\376\376\376\363\377\377\377\1\316" \
+ "\316\316\214::<\1\316\316\316\377\377\377\377\207\377\377\377\7\363\363" \
+ "\363kkm;;=::<;;=::<;;=\204::<\202;;=\10""99;;;=::<SSU\332\332\332\376" \
+ "\376\376\377\377\377\376\376\376\205\377\377\377\1\376\376\376\377\377" \
+ "\377\377\377\377\377\377\236\377\377\377\1\376\376\376\202\377\377\377" \
+ "\2\346\346\350__a\202::<\4;;=::<;;=99;\204::<\1;;=\203::<\3xxz\362\362" \
+ "\362\377\377\377\202\376\376\376\365\377\377\377\1\316\316\316\214::" \
+ "<\1\316\316\316\377\377\377\377\210\377\377\377\5\376\376\376\234\234" \
+ "\234;;=::<;;=\202::<\14;;=::<;;=99;;;=::<;;=::<;;=FFH\332\332\332\376" \
+ "\376\376\203\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377\377\377\377\377\377\235\377\377" \
+ "\377\4\332\332\332FFH::<;;=\205::<\1;;=\205::<\2;;=\234\234\234\372\377" \
+ "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\212\377\377" \
+ "\377\2\300\300\300FFH\203::<\1""99;\202::<\2;;=99;\203::<\4;;=::<FFH" \
+ "\266\266\266\205\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\377\377\377\377\377\377\377\377\235\377\377\377\3\332\332\332FF" \
+ "H;;=\205::<\1;;=\202::<\1""99;\203::<\6FFH\301\301\301\377\377\377\376" \
+ "\376\376\377\377\377\376\376\376\207\377\377\377\1\376\376\376\357\377" \
+ "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\211\377\377" \
+ "\377\4\376\376\376\377\377\377\331\331\331SSU\204::<\6""99;::<;;=::<" \
+ ";;=::<\202;;=\202::<\1\266\266\270\203\377\377\377\1\376\376\376\377" \
+ "\377\377\377\377\377\377\377\240\377\377\377\2\265\265\265EEG\202::<" \
+ "\6;;=::<;;=::<;;=99;\203::<\4;;=::<SSU\332\332\332\203\377\377\377\1" \
+ "\376\376\376\207\377\377\377\1\376\376\376\360\377\377\377\1\316\316" \
+ "\316\214::<\1\316\316\316\377\377\377\377\212\377\377\377\15\376\376" \
+ "\376\377\377\377\363\363\363__a::<;;=99;;;=::<99;;;=::<;;=\202::<\4;" \
+ ";=99;;;=\250\250\252\204\377\377\377\1\376\376\376\377\377\377\377\377" \
+ "\377\377\377\235\377\377\377\5\265\265\265::<;;=::<;;=\202::<\202;;=" \
+ "\2::<;;=\204::<\2__a\364\364\364\206\377\377\377\1\376\376\376\366\377" \
+ "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\211\377\377" \
+ "\377\1\376\376\376\204\377\377\377\2\204\204\20699;\204::<\1;;=\204:" \
+ ":<\5""99;;;=99;::<\204\204\204\377\377\377\377\377\377\377\377\232\377" \
+ "\377\377\1\376\376\376\205\377\377\377\2\265\265\267;;=\211::<\1;;=\203" \
+ "::<\1\205\205\205\377\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\377\377\377\377\215\377\377\377\12\376\376\376\377\377\377\250\250\250" \
+ "::<;;=::<99;;;=::<;;=\202::<\3;;=::<99;\202::<\1\205\205\207\212\377" \
+ "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\223\377\377\377" \
+ "\1\265\265\267\203::<\202;;=\1""99;\204::<\5;;=::<;;=::<\235\235\237" \
+ "\377\377\377\377\2\377\377\377\316\316\316\214::<\1\316\316\316\377\377" \
+ "\377\377\216\377\377\377\3\376\376\376\377\377\377\265\265\267\202::" \
+ "<\3;;=::<;;=\205::<\1;;=\203::<\1\204\204\204\210\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\220" \
+ "\377\377\377\6\234\234\236::<;;=::<;;=99;\204::<\1;;=\204::<\1\265\265" \
+ "\265\377\377\377\377\202\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\377\377\377\377\215\377\377\377\1\376\376\376\203\377\377\377\2\334" \
+ "\334\334FFH\207::<\202;;=\203::<\3;;=\204\204\206\376\376\376\207\377" \
+ "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\216\377\377\377" \
+ "\11\376\376\376\377\377\377\376\376\376\204\204\206::<99;;;=::<;;=\204" \
+ "::<\6;;=99;;;=::<FFH\301\301\301\377\377\377\377\203\377\377\377\1\316" \
+ "\316\316\214::<\1\316\316\316\377\377\377\377\215\377\377\377\1\376\376" \
+ "\376\202\377\377\377\202\376\376\376\3\332\332\332FFH::<\202;;=\203:" \
+ ":<\3;;=99;;;=\204::<\2\205\205\207\376\376\376\203\377\377\377\1\376" \
+ "\376\376\203\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377" \
+ "\377\377\377\377\377\377\212\377\377\377\7\376\376\376\377\377\377\376" \
+ "\376\376\204\204\20499;::<;;=\202::<\1""99;\205::<\4;;=::<GGI\332\332" \
+ "\334\377\377\377\377\204\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\377\377\377\377\217\377\377\377\6\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\362\362\362__a\203::<\202;;=\11""99;;;=::<99;;;=::<;;=:" \
+ ":<\204\204\204\205\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\377\377\377\377\377\377\377\377\215\377\377\377\1\204\204\204\202" \
+ "::<\1;;=\207::<\1<<>\202::<\2FFH\331\331\333\377\377\377\377\205\377" \
+ "\377\377\1\316\316\316\214::<\1\316\316\316\377\377\377\377\216\377\377" \
+ "\377\1\376\376\376\203\377\377\377\4\376\376\376\377\377\377\363\363" \
+ "\363__a\204::<\2;;=99;\206::<\2;;=\204\204\204\203\377\377\377\1\376" \
+ "\376\376\377\377\377\377\377\377\377\377\220\377\377\377\1\204\204\204" \
+ "\205::<\1;;=\203::<\1;;=\203::<\4__a\363\363\363\377\377\377\376\376" \
+ "\376\377\377\377\377\204\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\377\377\377\377\224\377\377\377\4\376\376\376\363\363\363xxx::<\202" \
+ ";;=\202::<\1;;=\203::<\1;;=\203::<\1\205\205\207\204\377\377\377\1\376" \
+ "\376\376\377\377\377\377\377\377\377\377\215\377\377\377\1\250\250\250" \
+ "\205::<\1;;=\203::<\12;;=99;;;=::<__a\363\363\365\377\377\377\376\376" \
+ "\376\377\377\377\376\376\376\377\377\377\377\203\377\377\377\1\316\316" \
+ "\316\214::<\1\316\316\316\377\377\377\377\227\377\377\377\5\204\204\204" \
+ "::<;;=::<;;=\204::<\1""99;\204::<\1\204\204\204\377\377\377\377\377\377" \
+ "\377\377\213\377\377\377\1\376\376\376\202\377\377\377\4\376\376\376" \
+ "\377\377\377\265\265\267;;=\212::<\4;;=::<__a\363\363\363\217\377\377" \
+ "\377\1\376\376\376\367\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\376\377\377\377\202\377\377\375\3\377\376\377\377\377\377\376\377\375" \
+ "\224\377\377\377\3\204\204\206::<;;=\211::<\7""99;::<\203\203\205\377" \
+ "\377\377\376\376\376\377\377\377\376\376\376\205\377\377\377\1\376\376" \
+ "\376\202\377\377\377\202\376\376\376\377\377\377\377\377\377\377\377" \
+ "\2\264\264\266;;=\202::<\202;;=\1""99;\207::<\2__a\363\363\365\217\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\366\377\377\377\1\316" \
+ "\316\316\214::<\1\316\316\316\375\377\377\377\5\377\377\375\377\376\377" \
+ "\377\375\377\377\377\375\377\377\377\202\377\376\377\221\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\204\204\206\203::<\1;;=\202::<\2;;=" \
+ "::<\202;;=\202::<\3;;=\204\204\204\376\376\376\211\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\377\377\377\377\375\377\377\377\7\376" \
+ "\376\376\264\264\266;;=99;::<;;=99;\204::<\1;;=\203::<\2aac\363\363\363" \
+ "\221\377\377\377\1\376\376\376\367\377\377\377\1\316\316\316\214::<\1" \
+ "\316\316\316\375\377\377\377\202\376\376\376\203\377\377\377\202\376" \
+ "\377\377\222\377\377\377\10\376\376\376\377\377\377\376\376\376\204\204" \
+ "\206::<;;=::<;;=\203::<\202;;=\202::<\6""99;;;=\205\205\207\376\376\376" \
+ "\377\377\377\376\376\376\203\377\377\377\202\376\376\376\202\377\377" \
+ "\377\1\376\376\376\377\377\377\377\375\377\377\377\3\376\376\376\302" \
+ "\302\304;;=\203::<\1;;=\204::<\6;;=99;;;=::<aac\362\362\362\223\377\377" \
+ "\377\1\376\376\376\366\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\374\377\377\377\6\375\377\376\377\377\375\377\376\377\376\377\377\376" \
+ "\376\376\377\377\375\202\377\376\377\225\377\377\377\2\376\376\376\204" \
+ "\204\206\206::<\1""99;\203::<\1;;=\202::<\1\251\251\253\204\377\377\377" \
+ "\1\376\376\376\377\377\377\377\377\377\377\377\203\377\377\377\4\332" \
+ "\332\332FFH::<;;=\202::<\1""99;\205::<\4;;=::<__a\363\363\365\202\377" \
+ "\377\377\1\376\376\376\377\377\377\377\211\377\377\377\1\316\316\316" \
+ "\214::<\1\316\316\316\374\377\377\377\5\376\377\377\376\376\376\377\376" \
+ "\377\377\377\375\376\377\375\202\376\377\377\1\377\377\375\221\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\203\377\377\377\2\204\204" \
+ "\206;;=\205::<\1;;=\203::<\7;;=::<;;=\265\265\265\376\376\376\377\377" \
+ "\377\376\376\376\202\377\377\377\5\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377\377\373\377\377\377\6\331\331\331" \
+ "GGI::<;;=::<;;=\205::<\1<<>\202::<\2__a\363\363\365\202\377\377\377\1" \
+ "\376\376\376\213\377\377\377\1\376\376\376\375\377\377\377\1\316\316" \
+ "\316\214::<\1\316\316\316\374\377\377\377\7\377\376\377\376\377\377\376" \
+ "\376\374\377\376\377\377\377\375\376\377\377\377\377\375\226\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\203\203\203\214::<\2;;=\265\265" \
+ "\265\206\377\377\377\1\376\376\376\377\377\377\377\374\377\377\377\4" \
+ "\364\364\364GGI99;;;=\206::<\1;;=\203::<\2__a\363\363\363\205\377\377" \
+ "\377\1\376\376\376\212\377\377\377\1\363\363\363\203\377\377\377\1\376" \
+ "\376\376\370\377\377\377\1\316\316\316\214::<\1\316\316\316\374\377\377" \
+ "\377\10\377\377\375\377\376\377\377\377\377\377\377\375\377\376\377\370" \
+ "\373\362\370\373\364\377\376\377\220\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\204\204\204\203::<\1;;=\210::<\2FFH\332\332\334\204\377\377\377\1" \
+ "\376\376\376\377\377\377\377\374\377\377\377\3\363\363\363___;;=\202" \
+ "::<\1;;=\204::<\6;;=99;;;=::<__a\363\363\365\220\377\377\377\3\265\265" \
+ "\265FFF\333\333\333\373\377\377\377\1\316\316\316\214::<\1\316\316\316" \
+ "\376\377\377\377\6\374\377\377\377\377\375\371\374\365\242\320c\240\322" \
+ "c\371\372\362\221\377\377\377\1\376\376\376\210\377\377\377\2\203\203" \
+ "\203;;=\202::<\1;;=\203::<\1;;=\203::<\3;;=FFH\333\333\333\202\377\377" \
+ "\377\1\376\376\376\377\377\377\377\371\377\377\377\1\376\376\376\203" \
+ "\377\377\377\2kkm::<\202;;=\1""99;\205::<\202;;=\3::<__a\363\363\363" \
+ "\220\377\377\377\5\265\265\267::<;;=FFH\332\332\332\206\377\377\377\3" \
+ "\376\376\376\377\377\377\376\376\376\361\377\377\377\1\316\316\316\213" \
+ "::<\2;;=\316\316\316\365\377\377\377\22\376\376\377\377\377\375\377\377" \
+ "\377\377\377\375\377\377\377\377\376\377\377\377\375\377\377\377\376" \
+ "\376\377\377\377\377\371\374\365\242\320c\215\307\77\215\305@\242\322" \
+ "e\372\373\365\376\377\375\377\376\377\230\377\377\377\3\205\205\207:" \
+ ":<;;=\206::<\1;;=\202::<\4;;=SSU\363\363\365\376\376\376\377\377\377" \
+ "\377\374\377\377\377\13\376\376\376\204\204\204::<;;=99;::<;;=::<;;=" \
+ "::<;;=\203::<\3__a\364\364\366\376\376\376\217\377\377\377\1\265\265" \
+ "\267\203::<\3;;=FFF\332\332\332\206\377\377\377\1\376\376\376\361\377" \
+ "\377\377\2\376\376\376\317\317\317\212::<\6;;=;;;\316\316\316\376\376" \
+ "\376\377\377\377\376\376\376\361\377\377\377\6\376\376\377\377\376\377" \
+ "\375\376\377\376\377\377\377\377\375\375\377\376\202\377\377\377\17\376" \
+ "\376\376\377\377\377\371\372\364\240\322a\215\305@\212\307>\215\307\77" \
+ "\215\305>\242\320c\370\372\365\377\377\377\377\376\377\376\377\375\377" \
+ "\377\375\377\376\377\225\377\377\377\5kkm::<;;=99;;;=\210::<\4__a\364" \
+ "\364\364\376\376\376\377\377\377\202\376\376\376\377\377\377\377\363" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\4" \
+ "\250\250\252::<;;=99;\202;;=\205::<\202;;=\3FFH\345\345\345\376\376\376" \
+ "\217\377\377\377\4\264\264\266;;=::<;;=\203::<\2GGI\332\332\332\203\377" \
+ "\377\377\1\376\376\376\356\377\377\377\1\376\376\376\205\377\377\377" \
+ "\2\315\315\315;;;\211::<\3;;;:::\315\315\315\202\377\377\377\1\376\376" \
+ "\376\361\377\377\377\23\377\377\375\375\376\377\376\377\377\376\377\375" \
+ "\377\374\377\377\377\375\375\377\376\377\377\377\377\377\375\371\372" \
+ "\364\242\321g\215\306A\212\307>\215\306A\212\306@\214\305@\212\306B\241" \
+ "\322_\367\372\361\204\377\377\377\1\377\377\375\220\377\377\377\1\376" \
+ "\376\376\203\377\377\377\3\363\363\363__a99;\202::<\6;;=::<99;;;=99;" \
+ ";;=\203::<\1\205\205\207\204\377\377\377\1\376\376\376\377\377\377\377" \
+ "\362\377\377\377\1\376\376\376\202\377\377\377\22\376\376\376\265\265" \
+ "\267::<99;;;=::<;;=99;;;=::<;;=::<;;=::<FFH\331\331\331\377\377\377\376" \
+ "\376\376\216\377\377\377\1\265\265\267\203::<\1;;=\202::<\4;;=::<GGI" \
+ "\332\332\332\210\377\377\377\1\376\376\376\353\377\377\377\1\376\376" \
+ "\376\221\377\377\377\1\376\376\376\363\377\377\377\17\376\377\377\376" \
+ "\377\375\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377" \
+ "\367\374\365\240\320b\215\307=\213\305=\215\306A\215\305>\214\305@\214" \
+ "\306>\202\214\305@\4\241\321a\371\374\365\376\376\377\377\377\375\202" \
+ "\376\377\377\221\377\377\377\1\376\376\376\203\377\377\377\3\362\362" \
+ "\362``b99;\205::<\1;;=\203::<\6;;=99;\235\235\237\376\376\376\377\377" \
+ "\377\376\376\376\377\377\377\377\366\377\377\377\2\332\332\332FFH\202" \
+ ";;=\4""99;;;=::<;;=\205::<\2FFH\332\332\334\202\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\213\377\377\377\4\266\266\26699;::<;;=\202" \
+ "::<\1;;=\202::<\4;;=::<FFF\332\332\332\203\377\377\377\1\376\376\376" \
+ "\202\377\377\377\1\376\376\376\375\377\377\377\1\376\376\376\363\377" \
+ "\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202\377" \
+ "\377\377\21\370\373\364\241\321c\216\306\77\212\306@\214\306>\215\305" \
+ "@\212\306@\213\310=\214\306<\216\306\77\214\304=\214\306>\241\321c\372" \
+ "\375\362\376\376\376\377\376\377\376\376\374\220\377\377\377\2\376\376" \
+ "\376\377\377\377\203\376\376\376\4\377\377\377\364\364\364FFH;;=\202" \
+ "::<\1;;=\202::<\1;;=\203::<\3;;=::<\265\265\265\377\377\377\377\367\377" \
+ "\377\377\4\362\362\362SSU::<;;=\205::<\1""99;\202;;=\3::<;;=\265\265" \
+ "\267\216\377\377\377\3\376\376\376\377\377\377\265\265\265\202::<\5;" \
+ ";=99;;;=::<;;=\204::<\4;;=FFH\332\332\332\376\376\376\205\377\377\377" \
+ "\1\376\376\376\355\377\377\377\1\376\376\376\214\377\377\377\1\376\376" \
+ "\376\366\377\377\377\1\375\377\376\202\377\377\375\24\377\377\377\376" \
+ "\376\376\373\373\363\243\322b\213\307A\214\306>\215\305@\214\305@\212" \
+ "\307>\214\306>\215\305>\213\307A\214\305@\216\310@\214\306>\215\305>" \
+ "\242\320c\366\373\364\375\377\376\377\376\377\221\377\377\377\1\376\376" \
+ "\376\204\377\377\377\3\376\376\376\333\333\333EEG\202;;=\2::<;;=\207" \
+ "::<\3GGI\332\332\332\376\376\376\377\377\377\377\365\377\377\377\1__" \
+ "a\205::<\10;;=::<;;=::<;;=::<;;=\265\265\265\202\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\213\377\377\377\1\266\266\266\203::<\5""9" \
+ "9;<<>::<;;=::<\202;;=\203::<\4;;=FFH\333\333\333\376\376\376\202\377" \
+ "\377\377\1\376\376\376\355\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\215\377\377\377\1\376\376\376\363\377\377\377\3\377\376" \
+ "\377\377\377\377\375\377\376\202\377\377\377\2\373\373\363\241\321d\202" \
+ "\214\306>\17\216\306=\215\305@\215\307\77\214\306>\217\304>\214\306>" \
+ "\214\305B\215\307\77\211\305A\215\306A\216\306\77\214\305@\242\322e\370" \
+ "\373\364\377\377\375\230\377\377\377\1\333\333\335\203::<\202;;=\206" \
+ "::<\3;;=FFH\363\363\363\377\377\377\377\364\377\377\377\1\204\204\206" \
+ "\203::<\1;;=\207::<\2;;=\204\204\206\220\377\377\377\1\346\346\346\204" \
+ "::<\1;;=\203::<\1;;=\202::<\202;;=\203::<\2FFH\332\332\332\357\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\204\377\377" \
+ "\377\1\377\377\375\202\377\377\377\17\377\376\377\370\373\364\243\322" \
+ "b\214\306>\213\310\77\212\307>\214\306>\215\306C\212\307>\214\306<\213" \
+ "\310\77\214\305@\214\306<\214\306>\216\306\77\203\214\306>\3\214\306" \
+ "<\265\334\211\376\376\376\222\377\377\377\1\376\376\376\205\377\377\377" \
+ "\4\376\376\377\265\265\267::<;;=\212::<\1___\377\377\377\377\363\377" \
+ "\377\377\1\265\265\267\204::<\1;;=\206::<\2;;=\203\203\203\222\377\377" \
+ "\377\2\265\265\265;;=\203::<\1;;=\205::<\1;;=\204::<\3;;=FFH\332\332" \
+ "\332\206\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\377\345\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375" \
+ "\377\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370" \
+ "\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4" \
+ "\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306" \
+ ">\215\307\77\214\305@\244\317c\367\375\361\233\377\377\377\3\234\234" \
+ "\236::<99;\211::<\2;;=\204\204\206\377\377\377\377\360\377\377\377\13" \
+ "\376\376\376\332\332\33299;::<99;;;=::<99;;;=::<;;=\202::<\3;;=^^`\364" \
+ "\364\364\223\377\377\377\12\265\265\267;;=::<;;=99;;;=::<;;=::<;;=\202" \
+ "::<\1;;=\203::<\3;;=FFF\332\332\332\206\377\377\377\1\376\376\376\377" \
+ "\377\377\377\345\377\377\377\6\376\376\377\377\376\377\375\376\377\376" \
+ "\377\377\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373" \
+ "\366\241\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212" \
+ "\306@\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306" \
+ ">\215\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\233" \
+ "\377\377\377\1\204\204\206\203::<\13;;=::<;;=::<;;=::<;;=::<;;=\266\266" \
+ "\266\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377\352\377" \
+ "\377\377\2\363\363\363TTV\202::<\3;;=99;;;=\204::<\4;;=99;FFH\363\363" \
+ "\363\224\377\377\377\7\376\376\376\265\265\265;;=::<;;=::<;;=\203::<" \
+ "\1;;=\203::<\1;;=\203::<\2GGI\332\332\332\203\377\377\377\1\376\376\376" \
+ "\377\377\377\377\347\377\377\377\7\377\377\375\375\376\377\376\377\377" \
+ "\376\377\375\377\374\377\377\377\375\375\377\376\202\377\377\377\5\372" \
+ "\373\366\240\320b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305" \
+ "@\212\306@\214\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@" \
+ "\214\306>\215\307\77\215\305@\242\320c\370\373\362\377\377\373\377\376" \
+ "\377\377\377\375\232\377\377\377\3\376\376\376\377\377\377^^`\202;;=" \
+ "\205::<\1""99;\202;;=\5::<;;=\332\332\332\377\377\377\376\376\376\377" \
+ "\377\377\377\347\377\377\377\1\376\376\376\204\377\377\377\1lln\204:" \
+ ":<\202;;=\203::<\6;;=99;GGI\332\332\332\377\377\377\376\376\376\225\377" \
+ "\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::<\3""99;;;=::<\202;;" \
+ "=\202::<\4;;=::<GGI\332\332\332\210\377\377\377\1\376\376\376\377\377" \
+ "\377\377\342\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377" \
+ "\376\377\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307" \
+ "\77\215\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216" \
+ "\306\77\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306" \
+ ">\242\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377" \
+ "\234\377\377\377\2\364\364\364RRT\202::<\4""99;;;=::<;;=\205::<\3SSU" \
+ "\362\362\362\377\377\377\202\376\376\376\377\377\377\377\351\377\377" \
+ "\377\1\234\234\236\204::<\1;;=\203::<\1;;=\203::<\1\265\265\267\231\377" \
+ "\377\377\2\265\265\267;;=\203::<\2""99;;;=\202::<\1;;=\202::<\1;;=\202" \
+ "::<\4;;=::<FFF\332\332\332\203\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\376\376\376\377\377\377\377\342\377\377\377\202\377\377\375\3" \
+ "\377\374\377\375\377\376\376\377\377\202\377\377\377\25\370\373\364\243" \
+ "\322b\217\304@\212\306@\214\305@\215\305>\212\307>\212\306@\214\305B" \
+ "\214\305@\214\305B\214\306>\212\307>\212\310\77\214\306>\217\304@\214" \
+ "\306>\214\305@\242\322b\370\373\362\377\377\377\202\377\376\377\1\377" \
+ "\377\375\235\377\377\377\3\376\376\376\332\332\334GGI\202;;=\6::<;;=" \
+ "99;;;=::<;;=\203::<\1yyy\202\376\376\376\202\377\377\377\1\376\376\376" \
+ "\377\377\377\377\345\377\377\377\4\376\376\376\317\317\317::<;;=\202" \
+ "::<\3;;=99;;;=\204::<\6;;=\221\221\223\377\377\377\376\376\376\377\377" \
+ "\377\376\376\376\226\377\377\377\3\376\376\376\265\265\267;;=\202::<" \
+ "\2;;=99;\205::<\1;;=\204::<\4;;=FFH\332\332\332\376\376\376\205\377\377" \
+ "\377\1\376\376\376\377\377\377\377\342\377\377\377\1\375\377\376\202" \
+ "\377\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307" \
+ "B\212\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214" \
+ "\306<\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307" \
+ ">\244\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377" \
+ "\377\377\375\377\376\377\236\377\377\377\4\265\265\267::<;;=99;\202;" \
+ ";=\205::<\202;;=\1\250\250\250\202\377\377\377\1\376\376\376\377\377" \
+ "\377\377\343\377\377\377\1\376\376\376\202\377\377\377\3\363\363\363" \
+ "FFH;;=\202::<\5;;=::<;;=::<99;\202;;=\2::<kkm\205\377\377\377\1\376\376" \
+ "\376\227\377\377\377\1\265\265\265\204::<\6;;=::<;;=::<;;=::<\202;;=" \
+ "\203::<\4;;=FFH\333\333\333\376\376\376\202\377\377\377\1\376\376\376" \
+ "\377\377\377\377\343\377\377\377\3\377\376\377\377\377\377\375\377\376" \
+ "\202\377\377\377\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214" \
+ "\305@\213\310=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214" \
+ "\306>\215\305>\217\304@\215\307\77\215\307=\242\320c\367\375\361\376" \
+ "\376\377\377\376\377\376\376\376\202\377\377\375\2\374\377\377\377\376" \
+ "\377\234\377\377\377\1\376\376\376\202\377\377\377\10\221\221\221::<" \
+ ";;=99;::<;;=::<;;=\205::<\2\333\333\333\376\376\376\377\377\377\377\347" \
+ "\377\377\377\1kkk\202::<\1;;=\205::<\1;;=\202::<\2RRT\363\363\365\236" \
+ "\377\377\377\1\265\265\267\203::<\2""99;;;=\203::<\1;;=\202::<\202;;" \
+ "=\203::<\2FFH\332\332\332\377\377\377\377\346\377\377\377\1\377\377\375" \
+ "\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306>\213\310" \
+ "\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215\307=\214" \
+ "\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<\244\317c" \
+ "\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377\377\377" \
+ "\377\202\377\376\377\241\377\377\377\2kkm::<\202;;=\1""99;\204::<\203" \
+ ";;=\2SSU\364\364\364\377\377\377\377\336\377\377\377\3\376\376\376\377" \
+ "\377\377\376\376\376\204\377\377\377\2\376\376\376\250\250\252\202::" \
+ "<\1;;=\210::<\2FFH\333\333\333\202\377\377\377\1\376\376\376\235\377" \
+ "\377\377\2\265\265\265;;=\203::<\1;;=\205::<\1;;=\204::<\3;;=FFH\332" \
+ "\332\332\206\377\377\377\3\376\376\376\377\377\377\376\376\376\243\377" \
+ "\377\377\4\376\377\377\377\377\375\377\376\377\376\376\377\202\377\377" \
+ "\377\2\376\377\375\376\377\377\230\377\377\377\10\376\377\377\377\376" \
+ "\377\376\377\377\376\377\375\376\376\376\376\377\377\377\377\377\377" \
+ "\376\377\231\377\377\377\7\377\376\377\376\376\374\376\377\377\377\377" \
+ "\375\374\377\377\376\377\377\377\376\377\231\377\377\377\17\375\377\374" \
+ "\377\377\375\377\377\377\377\376\377\376\377\377\377\376\377\377\377" \
+ "\377\376\377\377\376\376\374\377\377\377\377\377\373\377\377\377\376" \
+ "\377\377\377\377\377\377\377\375\220\377\377\377\4\377\377\373\377\377" \
+ "\377\377\377\375\377\377\377\202\376\377\377\2\377\377\375\377\377\373" \
+ "\251\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375\377" \
+ "\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370\373" \
+ "\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4\214" \
+ "\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215" \
+ "\307\77\214\305@\244\317c\367\375\361\251\377\377\377\6\363\363\363T" \
+ "TT::<;;=::<;;=\206::<\2;;=www\204\377\377\377\1\376\376\376\377\377\377" \
+ "\377\340\377\377\377\2\332\332\332;;=\203::<\3;;=99;;;=\203::<\3;;=:" \
+ ":<\265\265\267\204\377\377\377\1\376\376\376\235\377\377\377\12\265\265" \
+ "\267;;=::<;;=99;;;=::<;;=::<;;=\202::<\1;;=\203::<\3;;=FFF\332\332\332" \
+ "\206\377\377\377\1\376\376\376\244\377\377\377\202\377\377\375\1\377" \
+ "\377\377\202\376\377\375\3\376\376\377\377\377\377\377\376\377\230\377" \
+ "\377\377\3\376\377\375\377\377\377\377\377\373\202\377\376\377\2\377" \
+ "\377\377\376\376\376\231\377\377\377\10\376\377\373\376\375\377\377\377" \
+ "\375\377\376\377\377\375\377\377\377\373\377\376\377\377\377\375\230" \
+ "\377\377\377\12\377\376\377\377\377\377\377\375\376\376\377\377\376\377" \
+ "\372\376\377\377\377\377\377\376\377\375\377\376\377\377\377\375\203" \
+ "\377\377\377\202\376\377\375\1\375\376\377\227\377\377\377\1\377\374" \
+ "\377\250\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377" \
+ "\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241" \
+ "\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@" \
+ "\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215" \
+ "\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\251\377" \
+ "\377\377\2\331\331\331;;=\206::<\1;;=\203::<\2;;=\265\265\265\204\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377" \
+ "\322\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\202\377\377\377\2\363\363\363SSU\203::<\2;;=::<\202" \
+ ";;=\2""99;;;=\202::<\1\204\204\204\206\377\377\377\1\376\376\376\234" \
+ "\377\377\377\7\376\376\376\265\265\265;;=::<;;=::<;;=\203::<\1;;=\203" \
+ "::<\1;;=\203::<\2GGI\332\332\332\203\377\377\377\1\376\376\376\247\377" \
+ "\377\377\1\377\377\375\202\377\376\377\1\377\375\377\202\377\377\377" \
+ "\1\377\376\377\232\377\377\377\6\377\377\375\377\377\377\375\377\376" \
+ "\376\377\375\377\377\375\377\375\377\230\377\377\377\202\377\377\375" \
+ "\2\377\377\377\376\376\376\202\377\377\377\2\376\377\377\374\377\377" \
+ "\230\377\377\377\1\377\377\375\202\377\376\377\1\375\376\377\203\377" \
+ "\377\377\1\377\377\375\202\377\377\377\6\376\376\377\377\377\375\377" \
+ "\377\377\377\375\377\377\376\377\377\377\375\220\377\377\377\1\376\377" \
+ "\377\202\377\377\377\3\376\377\375\376\376\376\377\376\377\252\377\377" \
+ "\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374\377\377" \
+ "\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215\307\77" \
+ "\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D\216\306" \
+ "\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77\215\305" \
+ "@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\252\377\377" \
+ "\377\2\250\250\25099;\204::<\12;;=99;::<;;=99;::<FFH\346\346\346\377" \
+ "\377\377\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377\330" \
+ "\377\377\377\1\376\376\376\204\377\377\377\3\221\221\221::<;;=\202::" \
+ "<\5;;=::<;;=::<;;=\202::<\4___\363\363\363\377\377\377\376\376\376\202" \
+ "\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\234\377\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::<\3""99;" \
+ ";;=::<\202;;=\202::<\4;;=::<GGI\332\332\332\210\377\377\377\1\376\376" \
+ "\376\241\377\377\377\7\376\377\377\376\376\377\377\377\377\377\377\375" \
+ "\376\377\375\375\377\376\376\377\377\230\377\377\377\3\376\376\377\376" \
+ "\377\377\376\376\377\203\377\377\377\1\376\376\374\231\377\377\377\1" \
+ "\377\376\377\202\377\377\377\202\376\377\377\1\376\376\376\232\377\377" \
+ "\377\11\376\377\377\376\376\376\377\377\377\376\377\377\377\377\377\377" \
+ "\377\375\376\377\377\376\376\377\376\377\377\202\377\377\377\5\377\377" \
+ "\375\377\377\377\377\376\377\377\377\377\376\377\377\220\377\377\377" \
+ "\10\376\376\377\377\376\377\377\377\377\376\376\376\377\376\377\377\377" \
+ "\375\377\376\377\377\377\375\251\377\377\377\37\376\377\377\376\377\375" \
+ "\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373" \
+ "\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306" \
+ ">\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212" \
+ "\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377" \
+ "\376\376\376\376\377\377\253\377\377\377\1yyy\205::<\3;;=::<99;\202;" \
+ ";=\3::<__a\376\376\376\377\377\377\377\335\377\377\377\1\376\376\376" \
+ "\202\377\377\377\5\301\301\301::<;;=99;;;=\207::<\2GGI\332\332\332\203" \
+ "\377\377\377\1\376\376\376\243\377\377\377\2\265\265\267;;=\203::<\2" \
+ "99;;;=\202::<\1;;=\202::<\1;;=\202::<\4;;=::<FFF\332\332\332\203\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\242\377\377\377" \
+ "\1\377\377\375\204\377\377\377\1\376\377\377\231\377\377\377\202\377" \
+ "\376\377\202\377\377\377\4\377\377\375\377\377\377\376\377\377\375\377" \
+ "\376\230\377\377\377\203\377\377\375\202\377\377\377\2\376\376\376\376" \
+ "\377\377\231\377\377\377\1\376\376\376\202\376\377\377\13\377\376\374" \
+ "\377\376\377\376\376\374\376\377\377\377\377\377\376\377\377\377\377" \
+ "\377\377\377\375\376\376\376\377\377\377\377\376\377\222\377\377\377" \
+ "\202\377\377\375\5\377\377\377\376\377\377\377\377\377\377\377\375\376" \
+ "\377\377\251\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376" \
+ "\377\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214" \
+ "\305@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>" \
+ "\212\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370" \
+ "\373\362\377\377\377\202\377\376\377\1\377\377\375\254\377\377\377\4" \
+ "\363\363\363SSU;;=99;\202;;=\1""99;\204::<\3;;=::<\235\235\237\377\377" \
+ "\377\377\334\377\377\377\1\376\376\376\202\377\377\377\2\363\363\363" \
+ "GGI\202::<\7;;=::<99;::<;;=::<;;=\202::<\2\266\266\266\376\376\376\204" \
+ "\377\377\377\202\376\376\376\202\377\377\377\1\376\376\376\236\377\377" \
+ "\377\3\376\376\376\265\265\267;;=\202::<\2;;=99;\205::<\1;;=\204::<\4" \
+ ";;=FFH\332\332\332\376\376\376\205\377\377\377\1\376\376\376\240\377" \
+ "\377\377\10\376\377\375\377\375\377\377\377\375\376\377\375\377\377\377" \
+ "\377\376\377\377\377\377\376\376\374\230\377\377\377\10\374\377\377\377" \
+ "\376\374\377\377\377\376\376\374\377\376\377\376\377\377\377\377\377" \
+ "\377\376\377\230\377\377\377\3\377\377\375\377\377\377\376\377\375\203" \
+ "\377\377\377\1\377\376\377\231\377\377\377\6\377\375\377\376\376\374" \
+ "\377\377\377\377\376\377\376\377\375\377\376\377\202\377\377\377\2\377" \
+ "\376\377\377\377\377\202\376\377\377\2\376\376\377\376\377\377\222\377" \
+ "\377\377\2\377\377\375\377\375\377\202\376\377\377\4\376\376\376\376" \
+ "\377\377\375\377\374\377\375\377\251\377\377\377\1\375\377\376\202\377" \
+ "\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212" \
+ "\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<" \
+ "\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244" \
+ "\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377" \
+ "\377\375\377\376\377\252\377\377\377\5\376\376\376\377\377\377\333\333" \
+ "\33399;;;=\202::<\5;;=99;;;=99;;;=\203::<\1\332\332\334\377\377\377\377" \
+ "\330\377\377\377\1\376\376\376\205\377\377\377\1xxx\202::<\1;;=\202:" \
+ ":<\1;;=\204::<\4:::xxx\376\376\376\377\377\377\202\376\376\376\205\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\237\377\377\377\1\265" \
+ "\265\265\204::<\6;;=::<;;=::<;;=::<\202;;=\203::<\4;;=FFH\333\333\333" \
+ "\376\376\376\202\377\377\377\1\376\376\376\242\377\377\377\7\376\376" \
+ "\376\377\376\377\326\352\267\247\324o\247\324m\252\324r\247\324o\231" \
+ "\252\324p\10\323\353\271\377\376\377\377\377\377\376\377\377\350\365" \
+ "\333\253\323p\250\324r\251\324k\230\252\324p\10\250\325n\252\324p\277" \
+ "\337\223\376\377\377\377\377\377\375\377\376\376\377\377\276\336\222" \
+ "\230\252\324p\7\250\325p\250\324r\247\324o\253\324n\251\323m\346\364" \
+ "\332\377\376\377\202\377\377\377\7\323\352\266\253\323p\251\323m\253" \
+ "\323r\251\323o\247\324m\252\324r\220\252\324p\10\252\324n\253\324n\247" \
+ "\324k\252\324p\254\325o\247\324m\252\324p\324\353\267\250\377\377\377" \
+ "\3\377\376\377\377\377\377\375\377\376\202\377\377\377\11\373\373\363" \
+ "\241\321d\214\306>\213\310=\214\306>\214\305@\213\310=\212\306@\217\304" \
+ ">\202\215\307=\14\214\306>\215\305>\214\306>\215\305>\217\304@\215\307" \
+ "\77\215\307=\242\320c\367\375\361\376\376\377\377\376\377\376\376\376" \
+ "\202\377\377\375\2\374\377\377\377\376\377\254\377\377\377\2\376\376" \
+ "\376\251\251\251\202::<\5;;=::<;;=99;;;=\204::<\1``b\377\377\377\377" \
+ "\334\377\377\377\3\376\376\376\301\301\301:::\205::<\1""99;\202::<\4" \
+ ";;=::<SSS\362\362\362\207\377\377\377\1\376\376\376\202\377\377\377\202" \
+ "\376\376\376\240\377\377\377\1\265\265\267\203::<\2""99;;;=\203::<\1" \
+ ";;=\202::<\202;;=\203::<\2FFH\332\332\332\245\377\377\377\10\376\377" \
+ "\377\377\377\377\305\342\237\215\306A\215\307\77\215\305@\213\310=\214" \
+ "\305@\230\214\306>\10\304\341\237\377\374\377\377\376\377\377\377\377" \
+ "\341\362\322\215\305>\212\307>\215\305>\230\214\306>\4\215\305<\214\305" \
+ "@\252\324r\376\377\377\202\377\377\377\2\377\377\375\250\324r\230\214" \
+ "\306>\20\215\307\77\214\306>\214\306<\214\305B\212\307>\337\363\320\377" \
+ "\376\377\376\377\377\376\376\374\305\342\240\214\305@\213\310=\215\305" \
+ "@\214\306>\212\307<\214\305@\220\214\306>\10\214\305@\215\306C\212\307" \
+ "<\214\306>\215\305>\212\306@\215\305>\304\343\237\250\377\377\377\1\377" \
+ "\377\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306" \
+ ">\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215" \
+ "\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<" \
+ "\244\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377" \
+ "\377\377\377\202\377\376\377\257\377\377\377\1kkm\202::<\2;;=::<\202" \
+ ";;=\3::<;;=::<\202;;=\1\233\233\233\377\377\377\377\330\377\377\377\1" \
+ "\376\376\376\202\377\377\377\3\364\364\366FFH;;=\205::<\3;;=::<;;=\202" \
+ "::<\1\316\316\316\256\377\377\377\2\265\265\265;;=\203::<\1;;=\205::" \
+ "<\1;;=\204::<\3;;=FFH\332\332\332\206\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\235\377\377\377\1\304\343\240\235\214\306>\1\305\342" \
+ "\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377" \
+ "\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377" \
+ "\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306" \
+ ">\1\214\305@\205\214\306>\1\305\342\237\241\377\377\377\10\376\376\377" \
+ "\377\377\375\377\377\377\377\377\375\377\377\377\377\376\377\377\377" \
+ "\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211\307B\213" \
+ "\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214\306<\215" \
+ "\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305@\244\317" \
+ "c\367\375\361\267\377\377\377\2\363\363\363FFF\204::<\1;;=\203::<\4:" \
+ "9>::<;;=\332\332\332\377\377\377\377\332\377\377\377\1yy{\202::<\2""9" \
+ "9;;;=\202::<\6;;=99;::<;;=::<\234\234\236\260\377\377\377\12\265\265" \
+ "\267;;=::<;;=99;;;=::<;;=::<;;=\202::<\1;;=\203::<\3;;=FFF\332\332\332" \
+ "\206\377\377\377\1\376\376\376\236\377\377\377\1\304\343\240\235\214" \
+ "\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214\306>\1\250" \
+ "\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316" \
+ "\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305" \
+ "@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\240\377\377\377" \
+ "\6\376\376\377\377\376\377\375\376\377\376\377\377\377\377\375\375\377" \
+ "\376\203\377\377\377\27\377\377\375\372\373\366\241\321a\217\304@\212" \
+ "\307<\214\306>\215\305>\215\305@\213\310=\212\306@\214\306>\214\305B" \
+ "\215\307\77\215\305>\215\306A\212\307>\214\306>\215\307\77\214\306>\242" \
+ "\322b\370\373\362\376\376\377\377\375\376\267\377\377\377\1\301\301\301" \
+ "\205::<\3;;=::<;;=\202::<\2""99;```\377\377\377\377\331\377\377\377\1" \
+ "\301\301\301\202::<\1;;=\203::<\1;;=\202::<\3<<>::<__a\261\377\377\377" \
+ "\7\376\376\376\265\265\265;;=::<;;=::<;;=\203::<\1;;=\203::<\1;;=\203" \
+ "::<\2GGI\332\332\332\203\377\377\377\1\376\376\376\240\377\377\377\1" \
+ "\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \
+ "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \
+ "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \
+ "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \
+ "\240\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377" \
+ "\374\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320" \
+ "b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214" \
+ "\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307" \
+ "\77\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375" \
+ "\270\377\377\377\3\204\204\204::<;;=\206::<\4;;=::<;;=\234\234\236\377" \
+ "\377\377\377\325\377\377\377\4\376\376\376\377\377\377\363\363\363SS" \
+ "U\211::<\4""99;::<\332\332\334\376\376\376\202\377\377\377\1\376\376" \
+ "\376\257\377\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::<\3""99;" \
+ ";;=::<\202;;=\202::<\4;;=::<GGI\332\332\332\210\377\377\377\1\376\376" \
+ "\376\232\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377" \
+ "\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252" \
+ "\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342" \
+ "\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305" \
+ "@\205\214\306>\1\305\342\237\241\377\377\377\37\376\377\377\376\377\375" \
+ "\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373" \
+ "\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306" \
+ ">\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212" \
+ "\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377" \
+ "\376\376\376\376\377\377\270\377\377\377\3\363\363\363TTT;;=\202::<\1" \
+ ";;=\203::<\5""99;;;=::<;;=\332\332\332\377\377\377\377\323\377\377\377" \
+ "\1\376\376\376\202\377\377\377\4\221\221\221;;=99;;;=\202::<\1;;=\202" \
+ "::<\1;;=\202::<\1\233\233\233\202\377\377\377\1\376\376\376\262\377\377" \
+ "\377\2\265\265\267;;=\203::<\2""99;;;=\202::<\1;;=\202::<\1;;=\202::" \
+ "<\4;;=::<FFF\332\332\332\203\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\233\377\377\377\1\304\343\240\235\214\306>\1\305\342\237" \
+ "\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377" \
+ "\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305" \
+ "\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214" \
+ "\305@\205\214\306>\1\305\342\237\240\377\377\377\202\377\377\375\3\377" \
+ "\374\377\375\377\376\376\377\377\202\377\377\377\25\370\373\364\243\322" \
+ "b\217\304@\212\306@\214\305@\215\305>\212\307>\212\306@\214\305B\214" \
+ "\305@\214\305B\214\306>\212\307>\212\310\77\214\306>\217\304@\214\306" \
+ ">\214\305@\242\322b\370\373\362\377\377\377\202\377\376\377\1\377\377" \
+ "\375\272\377\377\377\7\316\316\316::<;;=::<99;::<;;=\205::<\1kkm\377" \
+ "\377\377\377\325\377\377\377\1\315\315\315\206::<\6""99;::<99;;;=::<" \
+ "```\206\377\377\377\1\376\376\376\257\377\377\377\3\376\376\376\265\265" \
+ "\267;;=\202::<\2;;=99;\205::<\1;;=\204::<\4;;=FFH\332\332\332\376\376" \
+ "\376\205\377\377\377\1\376\376\376\232\377\377\377\1\304\343\240\235" \
+ "\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214\306>\1" \
+ "\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362" \
+ "\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214" \
+ "\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\241\377\377" \
+ "\377\1\375\377\376\202\377\377\375\34\377\377\377\376\376\376\373\373" \
+ "\363\243\322b\211\307B\212\307<\215\305>\214\306>\212\307>\214\305@\217" \
+ "\304>\212\307<\214\306<\214\306>\215\307\77\213\307A\214\306>\215\305" \
+ "@\215\307\77\212\307>\244\317c\370\373\362\377\377\373\376\377\377\377" \
+ "\376\377\375\376\377\377\377\375\377\376\377\272\377\377\377\2\222\222" \
+ "\22299;\205::<\1;;=\203::<\2;;=\250\250\250\377\377\377\377\324\377\377" \
+ "\377\4```;;=99;;;=\204::<\5;;=::<;;=::<\331\331\331\207\377\377\377\1" \
+ "\376\376\376\260\377\377\377\1\265\265\265\204::<\6;;=::<;;=::<;;=::" \
+ "<\202;;=\203::<\4;;=FFH\333\333\333\376\376\376\202\377\377\377\1\376" \
+ "\376\376\234\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203" \
+ "\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1" \
+ "\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305" \
+ "\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214" \
+ "\305@\205\214\306>\1\305\342\237\240\377\377\377\3\377\376\377\377\377" \
+ "\377\375\377\376\202\377\377\377\11\373\373\363\241\321d\214\306>\213" \
+ "\310=\214\306>\214\305@\213\310=\212\306@\217\304>\202\215\307=\14\214" \
+ "\306>\215\305>\214\306>\215\305>\217\304@\215\307\77\215\307=\242\320" \
+ "c\367\375\361\376\376\377\377\376\377\376\376\376\202\377\377\375\2\374" \
+ "\377\377\377\376\377\262\377\377\377\2\376\376\376\377\377\377\202\376" \
+ "\376\376\204\377\377\377\5\363\363\363SSU99;::<;;=\207::<\2GGG\363\363" \
+ "\363\377\377\377\377\322\377\377\377\4\234\234\234:::::<;;=\202::<\1" \
+ ";;=\203::<\202;;=\1\234\234\236\207\377\377\377\1\376\376\376\262\377" \
+ "\377\377\1\265\265\267\203::<\2""99;;;=\203::<\1;;=\202::<\202;;=\203" \
+ "::<\2FFH\332\332\332\237\377\377\377\1\304\343\240\235\214\306>\1\305" \
+ "\342\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377" \
+ "\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377" \
+ "\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214" \
+ "\306>\1\214\305@\205\214\306>\1\305\342\237\240\377\377\377\1\377\377" \
+ "\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306>\213" \
+ "\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215\307" \
+ "=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<\244" \
+ "\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377\377" \
+ "\377\377\202\377\376\377\273\377\377\377\2\376\376\376\316\316\316\206" \
+ "::<\202;;=\4::<;;=::<xxx\377\377\377\377\321\377\377\377\2\346\346\350" \
+ "FFH\203::<\1;;=\206::<\1__a\202\377\377\377\1\377\377\375\271\377\377" \
+ "\377\2\265\265\265;;=\203::<\1;;=\205::<\1;;=\203::<\4;;=::<GGI\331\331" \
+ "\331\236\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377" \
+ "\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252" \
+ "\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342" \
+ "\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305" \
+ "@\205\214\306>\1\305\342\237\231\377\377\377\10\376\376\377\377\377\375" \
+ "\377\377\377\377\377\375\377\377\377\377\376\377\377\377\375\376\377" \
+ "\377\202\377\377\377\6\370\373\362\243\322b\211\307B\213\310=\214\305" \
+ "@\214\306<\202\215\305@\4\214\306<\214\305@\214\306<\215\307\77\202\214" \
+ "\306>\6\212\307>\214\306>\215\307\77\214\305@\244\317c\367\375\361\305" \
+ "\377\377\377\2xxz;;=\203::<\3;;=::<;;=\203::<\2;;=\315\315\315\377\377" \
+ "\377\377\313\377\377\377\203\376\376\376\202\377\377\377\3xxz;;=::<\202" \
+ ";;=\1""99;\202;;=\202::<\4;;=::<\333\333\335\376\376\376\274\377\377" \
+ "\377\12\265\265\267;;=::<;;=99;;;=::<;;=::<;;=\202::<\1;;=\202::<\4;" \
+ ";=99;GGI\332\332\332\235\377\377\377\1\304\343\240\235\214\306>\1\305" \
+ "\342\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377" \
+ "\377\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377" \
+ "\377\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214" \
+ "\306>\1\214\305@\205\214\306>\1\305\342\237\230\377\377\377\6\376\376" \
+ "\377\377\376\377\375\376\377\376\377\377\377\377\375\375\377\376\203" \
+ "\377\377\377\27\377\377\375\372\373\366\241\321a\217\304@\212\307<\214" \
+ "\306>\215\305>\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77" \
+ "\215\305>\215\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370" \
+ "\373\362\376\376\377\377\375\376\304\377\377\377\2\364\364\364FFH\203" \
+ "::<\2""99;;;=\203::<\4<<>99;TTT\376\376\376\377\377\377\377\310\377\377" \
+ "\377\1\376\376\376\205\377\377\377\3\316\316\316::<99;\206::<\1;;=\202" \
+ "::<\1\221\221\221\203\377\377\377\1\376\376\376\272\377\377\377\7\376" \
+ "\376\376\265\265\265;;=::<;;=::<;;=\203::<\1;;=\203::<\6;;=::<;;=::<" \
+ "FFH\332\332\332\234\377\377\377\1\304\343\240\235\214\306>\1\305\342" \
+ "\237\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377" \
+ "\377\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377" \
+ "\3\305\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306" \
+ ">\1\214\305@\205\214\306>\1\305\342\237\230\377\377\377\7\377\377\375" \
+ "\375\376\377\376\377\377\376\377\375\377\374\377\377\377\375\375\377" \
+ "\376\202\377\377\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305" \
+ ">\202\214\305@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215" \
+ "\307\77\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373" \
+ "\362\377\377\373\377\376\377\377\377\375\304\377\377\377\3\376\376\376" \
+ "\265\265\267;;=\204::<\1""99;\203::<\3;;=::<\234\234\234\203\377\377" \
+ "\377\1\376\376\376\377\377\377\377\306\377\377\377\7\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377__a::<;;=\203::<\7;;=::<;;=::<;;=SSU" \
+ "\363\363\363\300\377\377\377\2\264\264\264;;=\202::<\2""99;;;=\202::" \
+ "<\3""99;;;=::<\202;;=\204::<\2FFH\332\332\332\233\377\377\377\1\304\343" \
+ "\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214" \
+ "\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77" \
+ "\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214" \
+ "\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\231" \
+ "\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376\377\377" \
+ "\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77\215\307" \
+ "=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306\77\215" \
+ "\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321" \
+ "a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\301\377" \
+ "\377\377\1\376\376\376\204\377\377\377\2kkm99;\203::<\202;;=\1""99;\203" \
+ "::<\2FFH\363\363\363\377\377\377\377\310\377\377\377\1\376\376\376\203" \
+ "\377\377\377\3\250\250\252::<;;=\203::<\1;;=\202::<\5;;=::<;;=\301\301" \
+ "\301\376\376\376\301\377\377\377\2\265\265\267;;=\203::<\2""99;;;=\202" \
+ "::<\1;;=\202::<\2;;=::<\202;;=\3::<GGI\332\332\332\232\377\377\377\1" \
+ "\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \
+ "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \
+ "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \
+ "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \
+ "\230\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377" \
+ "\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215" \
+ "\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>" \
+ "\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362" \
+ "\377\377\377\202\377\376\377\1\377\377\375\301\377\377\377\1\376\376" \
+ "\376\204\377\377\377\2\376\376\376\346\346\350\203::<\4;;=99;::<;;=\204" \
+ "::<\3\203\203\203\377\377\377\376\376\376\377\377\377\377\311\377\377" \
+ "\377\2\364\364\364FFH\202::<\5;;=::<;;=::<;;=\202::<\2;;=kkm\202\377" \
+ "\377\377\1\376\376\376\300\377\377\377\3\376\376\376\265\265\267;;=\202" \
+ "::<\2;;=99;\204::<\3;;=99;;;=\202::<\3;;=::<\265\265\265\232\377\377" \
+ "\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362" \
+ "\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>" \
+ "\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215" \
+ "\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1" \
+ "\305\342\237\231\377\377\377\1\375\377\376\202\377\377\375\34\377\377" \
+ "\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214" \
+ "\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77" \
+ "\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \
+ "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \
+ "\377\301\377\377\377\202\376\376\376\2\377\377\377\376\376\376\202\377" \
+ "\377\377\1\234\234\236\203::<\1;;=\206::<\2;;=\331\331\331\377\377\377" \
+ "\377\306\377\377\377\1\376\376\376\203\377\377\377\4\233\233\233;;=:" \
+ ":<;;=\202::<\3;;=99;;;=\203::<\1\346\346\350\305\377\377\377\1\265\265" \
+ "\265\204::<\3;;=::<;;=\203::<\5;;=99;;;=::<\265\265\267\233\377\377\377" \
+ "\1\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \
+ "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \
+ "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \
+ "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \
+ "\230\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \
+ "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \
+ "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \
+ ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \
+ "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\301\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\6\364" \
+ "\364\364SSU::<;;=::<;;=\205::<\4""99;kkk\377\377\377\376\376\376\377" \
+ "\377\377\377\307\377\377\377\2\346\346\346;;;\204::<\3;;=99;;;=\203:" \
+ ":<\1\234\234\236\205\377\377\377\1\376\376\376\301\377\377\377\1\265" \
+ "\265\267\203::<\2""99;;;=\202::<\1;;;\204::<\1\265\265\267\234\377\377" \
+ "\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362" \
+ "\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>" \
+ "\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215" \
+ "\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1" \
+ "\305\342\237\230\377\377\377\1\377\377\375\202\377\377\377\32\377\376" \
+ "\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215\305" \
+ "@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A\212" \
+ "\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377" \
+ "\375\376\377\377\375\376\377\377\377\377\377\202\377\376\377\306\377" \
+ "\377\377\1\376\376\376\202\377\377\377\2\301\301\303::<\202;;=\11::<" \
+ ";;=::<;;=::<99;;;=::<\301\301\301\377\377\377\377\306\377\377\377\12" \
+ "\376\376\376\377\377\377\204\204\204;;=::<:9>;;=::<99;;;=\203::<\5SS" \
+ "U\363\363\363\376\376\376\377\377\377\376\376\376\305\377\377\377\5\265" \
+ "\265\26599;;;=::<;;=\206::<\1\266\266\270\235\377\377\377\1\304\343\240" \
+ "\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235\214\306" \
+ ">\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307\77\342" \
+ "\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214\306" \
+ ">\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\221\377" \
+ "\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375\377\377\377" \
+ "\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243" \
+ "\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214" \
+ "\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77" \
+ "\214\305@\244\317c\367\375\361\322\377\377\377\1kkk\203::<\4;;=99;::" \
+ "<;;=\203::<\1SSU\210\377\377\377\1\376\376\376\377\377\377\377\276\377" \
+ "\377\377\1\316\316\316\202::<\1;;=\202::<\202;;=\202::<\4;;=::<\265\265" \
+ "\267\376\376\376\307\377\377\377\3\376\376\376\377\377\377\265\265\267" \
+ "\207::<\3""99;\266\266\270\376\376\377\202\377\377\377\1\376\376\376" \
+ "\232\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \
+ "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \
+ "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \
+ "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \
+ "\214\306>\1\305\342\237\220\377\377\377\6\376\376\377\377\376\377\375" \
+ "\376\377\376\377\377\377\377\375\375\377\376\203\377\377\377\27\377\377" \
+ "\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215\305>\215\305" \
+ "@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305>\215\306A\212" \
+ "\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362\376\376\377\377" \
+ "\375\376\321\377\377\377\1\346\346\346\204::<\1;;=\202::<\5;;=99;;;=" \
+ "::<\266\266\266\205\377\377\377\202\376\376\376\2\377\377\377\376\376" \
+ "\376\377\377\377\377\273\377\377\377\5\376\376\376\377\377\377kkm::<" \
+ ";;=\202::<\1;;=\203::<\3;;=::<kkm\203\377\377\377\1\376\376\376\306\377" \
+ "\377\377\4\376\376\376\377\377\377\265\265\265::<\202;;=\202::<\2""9" \
+ "9;\266\266\270\237\377\377\377\1\304\343\240\235\214\306>\1\305\342\237" \
+ "\203\377\377\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377" \
+ "\1\252\324p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305" \
+ "\342\237\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214" \
+ "\305@\205\214\306>\1\305\342\237\220\377\377\377\7\377\377\375\375\376" \
+ "\377\376\377\377\376\377\375\377\374\377\377\377\375\375\377\376\202" \
+ "\377\377\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305>\202" \
+ "\214\305@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307\77" \
+ "\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362" \
+ "\377\377\373\377\376\377\377\377\375\322\377\377\377\1\221\221\223\202" \
+ "::<\12;;=99;::<;;=::<;;=99;;;=EEG\364\364\364\203\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\377\377\377\377\275\377\377\377\2" \
+ "\316\316\320;;=\205::<\2""99;;;=\203::<\3\316\316\316\377\377\377\376" \
+ "\376\376\313\377\377\377\3\265\265\265;;=99;\202::<\1\266\266\270\203" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\232\377\377\377\1" \
+ "\304\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316" \
+ "\235\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215" \
+ "\307\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202" \
+ "\214\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237" \
+ "\221\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376\377" \
+ "\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77\215" \
+ "\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306\77" \
+ "\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242" \
+ "\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\322" \
+ "\377\377\377\2\363\363\363FFH\203::<\202;;=\203::<\3;;=::<\235\235\235" \
+ "\204\377\377\377\1\376\376\376\377\377\377\377\277\377\377\377\1__a\202" \
+ "::<\1;;=\203::<\5;;=::<;;=::<\204\204\206\312\377\377\377\1\376\376\376" \
+ "\202\377\377\377\7\376\376\376\377\377\377\265\265\267;;=99;\266\266" \
+ "\270\376\376\377\203\377\377\377\202\376\376\376\233\377\377\377\1\304" \
+ "\343\240\235\214\306>\1\305\342\237\203\377\377\377\1\342\362\316\235" \
+ "\214\306>\1\250\325p\204\377\377\377\1\252\324p\234\214\306>\2\215\307" \
+ "\77\342\362\316\203\377\377\377\3\305\342\237\214\305@\215\305>\202\214" \
+ "\306>\1\214\305@\222\214\306>\1\214\305@\205\214\306>\1\305\342\237\220" \
+ "\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202" \
+ "\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305" \
+ ">\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212" \
+ "\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377" \
+ "\377\377\202\377\376\377\1\377\377\375\324\377\377\377\4\234\234\234" \
+ ";;=::<<<>\204::<\1;;=\202::<\2FFH\363\363\363\204\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\377\377\377\377\272\377\377\377\1" \
+ "\265\265\265\202::<\5;;=99;::<;;=::<\202;;=\3""99;;;=\346\346\346\320" \
+ "\377\377\377\2\264\264\266\265\265\267\203\377\377\377\202\376\376\376" \
+ "\235\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \
+ "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \
+ "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \
+ "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \
+ "\214\306>\1\305\342\237\221\377\377\377\1\375\377\376\202\377\377\375" \
+ "\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215" \
+ "\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>" \
+ "\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370" \
+ "\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375" \
+ "\377\376\377\320\377\377\377\1\376\376\376\203\377\377\377\2SSU;;=\203" \
+ "::<\1;;=\203::<\3""99;::<\234\234\236\203\377\377\377\1\376\376\376\377" \
+ "\377\377\377\276\377\377\377\5RRT99;;;=99;;;=\203::<\4""99;;;=::<\234" \
+ "\234\236\314\377\377\377\1\376\376\376\212\377\377\377\1\376\376\376" \
+ "\235\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \
+ "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \
+ "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \
+ "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \
+ "\214\306>\1\305\342\237\220\377\377\377\3\377\376\377\377\377\377\375" \
+ "\377\376\202\377\377\377\11\373\373\363\241\321d\214\306>\213\310=\214" \
+ "\306>\214\305@\213\310=\212\306@\217\304>\202\215\307=\14\214\306>\215" \
+ "\305>\214\306>\215\305>\217\304@\215\307\77\215\307=\242\320c\367\375" \
+ "\361\376\376\377\377\376\377\376\376\376\202\377\377\375\2\374\377\377" \
+ "\377\376\377\324\377\377\377\3\265\265\265;;=99;\202;;=\1""99;\202;;" \
+ "=\5::<;;=::<GGI\363\363\363\206\377\377\377\1\376\376\376\377\377\377" \
+ "\377\271\377\377\377\2\266\266\270;;=\202::<\1;;=\202::<\6;;=::<;;=:" \
+ ":<FFH\363\363\363\324\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\236\377\377\377\1\304\343\240\235\214\306>\1\305\342\237\203\377\377" \
+ "\377\1\342\362\316\235\214\306>\1\250\325p\204\377\377\377\1\252\324" \
+ "p\234\214\306>\2\215\307\77\342\362\316\203\377\377\377\3\305\342\237" \
+ "\214\305@\215\305>\202\214\306>\1\214\305@\222\214\306>\1\214\305@\205" \
+ "\214\306>\1\305\342\237\220\377\377\377\1\377\377\375\202\377\377\377" \
+ "\32\377\376\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215" \
+ "\305>\215\305@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>" \
+ "\215\306A\212\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377" \
+ "\377\377\377\375\376\377\377\375\376\377\377\377\377\377\202\377\376" \
+ "\377\326\377\377\377\1__a\203::<\1;;=\203::<\1;;=\202::<\1\234\234\234" \
+ "\377\377\377\377\274\377\377\377\1\376\376\376\203\377\377\377\3SSU;" \
+ ";=99;\210::<\1\234\234\234\365\377\377\377\7\376\377\375\304\341\236" \
+ "\215\306A\214\305B\215\307=\212\307>\212\306@\230\214\305@\1\304\341" \
+ "\236\203\377\377\377\4\341\362\320\214\306>\213\310\77\215\305@\231\214" \
+ "\305@\2\215\307\77\252\322q\202\377\376\377\202\377\377\377\1\250\325" \
+ "n\230\214\305@\3\215\305>\215\306A\215\307\77\202\214\306<\10\342\360" \
+ "\317\376\377\377\377\377\375\376\377\377\305\342\240\215\305@\212\306" \
+ "@\215\305>\202\214\305@\1\215\307=\220\214\305@\10\214\306>\212\306@" \
+ "\216\306A\212\307>\215\305>\215\305@\214\305@\304\343\237\211\377\377" \
+ "\377\10\376\376\377\377\377\375\377\377\377\377\377\375\377\377\377\377" \
+ "\376\377\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322" \
+ "b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305" \
+ "@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214" \
+ "\305@\244\317c\367\375\361\335\377\377\377\2\376\376\376\316\316\316" \
+ "\211::<\3;;=GGI\363\363\365\203\377\377\377\1\376\376\376\377\377\377" \
+ "\377\266\377\377\377\10\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\265\265\265;;=::<;;=\207::<\2GGI\363\363\363\364\377\377\377\7\377\376" \
+ "\377\377\377\375\304\341\236\215\305>\215\307\77\214\306>\214\305@\231" \
+ "\214\306>\7\304\343\237\377\377\377\375\376\377\377\377\375\341\360\321" \
+ "\215\306A\214\305@\233\214\306>\6\252\324n\376\376\376\377\377\377\376" \
+ "\377\377\377\376\377\252\324p\230\214\306>\7\215\306A\212\307>\214\306" \
+ ">\212\307>\214\306>\343\361\320\376\377\377\202\377\377\377\7\305\342" \
+ "\237\215\305>\213\310\77\214\306>\214\305@\212\306@\215\307\77\222\214" \
+ "\306>\6\215\305>\212\307>\214\306>\215\307=\215\305@\305\342\237\210" \
+ "\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377\377\377" \
+ "\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241\321a" \
+ "\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@\214\306" \
+ ">\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215\307\77" \
+ "\214\306>\242\322b\370\373\362\376\376\377\377\375\376\336\377\377\377" \
+ "\1kkm\202::<\1;;=\205::<\202;;=\3\233\233\235\377\377\377\376\376\376" \
+ "\377\377\377\377\274\377\377\377\3SSU99;;;=\20299;\1;;=\203::<\3;;=:" \
+ ":<\234\234\236\366\377\377\377\7\376\377\375\305\342\240\213\304\77\213" \
+ "\310\77\214\305@\215\306A\216\306=\230\214\306>\10\305\342\240\377\377" \
+ "\375\376\377\377\377\376\377\341\360\317\214\306<\214\305@\212\306@\231" \
+ "\214\306>\7\215\305@\252\324p\377\377\377\377\377\375\376\377\377\377" \
+ "\376\374\252\324p\230\214\306>\7\212\307>\215\307\77\216\306A\212\307" \
+ ">\213\304\77\343\361\320\377\377\375\202\377\377\377\3\307\342\237\214" \
+ "\304\77\213\310\77\203\214\306>\1\215\307\77\220\214\306>\4\214\305@" \
+ "\214\306<\215\304B\213\310\77\202\212\307>\2\215\305@\305\342\240\210" \
+ "\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374" \
+ "\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215" \
+ "\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D" \
+ "\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77" \
+ "\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\331" \
+ "\377\377\377\1\376\376\376\203\377\377\377\4\376\376\376\317\317\321" \
+ "::<;;=\203::<\3;;=::<;;=\202::<\4FFH\363\363\363\377\377\377\376\376" \
+ "\376\377\377\377\377\264\377\377\377\1\376\376\376\205\377\377\377\1" \
+ "\265\265\267\202;;=\3::<99;;;=\202::<\202;;=\2::<SSU\366\377\377\377" \
+ "\7\377\376\377\375\377\374\304\341\237\216\306\77\212\307<\213\310\77" \
+ "\212\307>\231\214\306>\2\305\342\240\377\377\377\202\377\376\377\3\341" \
+ "\362\316\216\306\77\214\306<\231\214\306>\3\215\305@\212\307>\252\324" \
+ "p\203\377\377\377\2\377\376\377\247\324o\230\214\306>\20\215\306A\214" \
+ "\305B\215\307\77\211\305\77\214\304;\342\362\315\377\377\377\377\376" \
+ "\377\376\376\376\305\342\237\215\306A\210\307;\215\306A\216\306A\214" \
+ "\306>\212\306@\220\214\306>\202\214\305@\6\216\305C\213\305=\214\305" \
+ "B\215\307\77\216\306\77\303\344\237\211\377\377\377\37\376\377\377\376" \
+ "\377\375\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377" \
+ "\370\373\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<" \
+ "\214\306>\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215" \
+ "\305>\212\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376" \
+ "\377\377\376\376\376\376\377\377\331\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\203\377\377\377\1kkm\202::<\6;;=::<;;=::<;;=::<\202" \
+ ";;=\1\233\233\235\377\377\377\377\267\377\377\377\1\376\376\376\204\377" \
+ "\377\377\2kkm;;=\202::<\2;;=::<\202;;=\203::<\5\265\265\267\377\377\377" \
+ "\376\376\376\377\377\377\376\376\376\362\377\377\377\2\376\377\377\377" \
+ "\376\377\202\377\377\377\202\377\376\377\2\377\377\377\377\377\375\231" \
+ "\377\377\377\4\377\376\377\376\377\377\375\377\376\377\377\377\202\376" \
+ "\377\377\231\377\377\377\10\374\377\375\377\376\377\377\377\375\376\376" \
+ "\376\377\377\377\376\377\377\376\376\374\377\376\377\230\377\377\377" \
+ "\1\377\376\377\203\377\377\375\4\376\377\377\377\375\377\377\377\377" \
+ "\376\377\377\202\377\377\377\3\376\376\376\377\376\377\377\377\375\202" \
+ "\376\377\377\1\377\377\375\220\377\377\377\10\377\377\375\377\377\377" \
+ "\376\376\376\377\377\377\377\377\375\377\377\377\376\377\377\377\375" \
+ "\377\210\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377" \
+ "\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305" \
+ "@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212" \
+ "\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373" \
+ "\362\377\377\377\202\377\376\377\1\377\377\375\340\377\377\377\1\316" \
+ "\316\316\203::<\3;;=99;;;=\204::<\2FFH\363\363\363\202\377\377\377\1" \
+ "\376\376\376\377\377\377\377\264\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\316\316\320\206::<\1;;=\203::<\2SSU\376\376\376\366\377\377\377" \
+ "\1\377\377\375\202\377\376\377\202\377\377\377\3\377\377\375\377\377" \
+ "\377\376\377\377\230\377\377\377\202\376\377\377\6\377\377\375\377\377" \
+ "\377\376\377\375\377\377\377\376\377\375\377\377\375\231\377\377\377" \
+ "\2\376\377\377\377\377\375\202\377\377\377\1\376\376\376\232\377\377" \
+ "\377\5\377\376\377\377\377\377\376\377\375\377\377\377\377\377\375\204" \
+ "\377\377\377\202\376\377\377\1\376\376\376\202\377\377\377\202\376\377" \
+ "\377\220\377\377\377\1\377\377\375\202\377\377\377\4\376\376\374\377" \
+ "\376\377\377\377\377\376\377\375\212\377\377\377\1\375\377\376\202\377" \
+ "\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212" \
+ "\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<" \
+ "\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244" \
+ "\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377" \
+ "\377\375\377\376\377\334\377\377\377\1\376\376\376\202\377\377\377\10" \
+ "\376\376\376kkm::<;;=99;;;=::<;;=\202::<\202;;=\1\234\234\236\203\377" \
+ "\377\377\1\376\376\376\377\377\377\377\262\377\377\377\5\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377lln\210::<\3""99;;;=\265\265\265" \
+ "\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\370\377" \
+ "\377\377\1\376\377\377\230\377\377\377\7\377\376\377\377\377\375\377" \
+ "\376\377\376\376\377\377\377\375\377\377\377\377\377\375\233\377\377" \
+ "\377\1\377\376\377\203\377\377\377\1\376\377\375\231\377\377\377\5\377" \
+ "\377\375\377\377\377\377\377\375\377\377\377\377\377\375\202\377\377" \
+ "\377\1\377\377\375\203\377\377\377\2\376\376\376\377\376\377\226\377" \
+ "\377\377\5\377\377\375\377\377\377\376\377\377\377\377\375\376\377\377" \
+ "\210\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \
+ "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \
+ "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \
+ ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \
+ "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\333\377\377" \
+ "\377\1\376\376\376\202\377\377\377\3\376\376\376\377\377\377\316\316" \
+ "\320\203::<\1;;=\202::<\1;;=\203::<\2FFH\377\377\377\202\376\376\376" \
+ "\377\377\377\377\262\377\377\377\5\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\332\332\332\206::<\1;;=\202::<\5;;=FFH\363\363\363\377\377" \
+ "\377\376\376\376\203\377\377\377\1\376\376\376\365\377\377\377\1\377" \
+ "\377\375\202\377\377\377\1\377\377\375\230\377\377\377\2\376\377\377" \
+ "\377\377\375\204\377\377\377\2\377\376\377\376\377\375\230\377\377\377" \
+ "\4\377\377\375\377\377\377\377\377\373\376\377\377\203\377\377\377\1" \
+ "\377\376\377\230\377\377\377\13\376\377\377\377\377\375\377\377\377\376" \
+ "\377\377\377\375\376\377\377\377\377\377\375\376\377\377\377\376\377" \
+ "\377\377\377\376\376\376\202\377\377\377\1\377\377\375\226\377\377\377" \
+ "\202\376\377\377\2\377\377\375\377\376\377\210\377\377\377\1\377\377" \
+ "\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306>\213" \
+ "\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215\307" \
+ "=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<\244" \
+ "\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377\377" \
+ "\377\377\202\377\376\377\333\377\377\377\1\376\376\376\204\377\377\377" \
+ "\11\376\376\376\377\377\377kkm::<;;=99;;;=::<;;=\202::<\3;;=::<\264\264" \
+ "\264\377\377\377\377\265\377\377\377\1\376\376\376\202\377\377\377\1" \
+ "\204\204\204\203::<\1;;=\206::<\1\235\235\237\377\377\377\377\377\377" \
+ "\377\377\203\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377" \
+ "\375\377\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377" \
+ "\6\370\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305" \
+ "@\4\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214" \
+ "\306>\215\307\77\214\305@\244\317c\367\375\361\352\377\377\377\1\316" \
+ "\316\316\203::<\1;;=\203::<\202;;=\2::<RRT\377\377\377\377\267\377\377" \
+ "\377\3\346\346\346::<;;=\203::<\202;;=\5""99;::<;;=FFH\363\363\365\377" \
+ "\377\377\377\377\377\377\377\202\377\377\377\6\376\376\377\377\376\377" \
+ "\375\376\377\376\377\377\377\377\375\375\377\376\203\377\377\377\27\377" \
+ "\377\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215\305>\215" \
+ "\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305>\215\306" \
+ "A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362\376\376" \
+ "\377\377\375\376\352\377\377\377\2kkm;;=\207::<\3;;=::<\301\301\301\377" \
+ "\377\377\377\266\377\377\377\2\221\221\221;;=\202::<\202;;=\202::<\1" \
+ ";;=\202::<\1\235\235\237\377\377\377\377\377\377\377\377\203\377\377" \
+ "\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374\377\377" \
+ "\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215\307\77" \
+ "\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D\216\306" \
+ "\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77\215\305" \
+ "@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\350\377\377" \
+ "\377\4\376\376\376\377\377\377\265\265\26799;\203::<\3;;=::<;;=\203:" \
+ ":<\2kkk\376\376\376\377\377\377\377\264\377\377\377\2\362\362\362FFH" \
+ "\202::<\1;;=\203::<\5;;=::<;;=::<\363\363\363\377\377\377\377\377\377" \
+ "\377\377\204\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377" \
+ "\376\377\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307" \
+ "\77\215\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216" \
+ "\306\77\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306" \
+ ">\242\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377" \
+ "\352\377\377\377\2\376\376\376TTV\204::<\7;;=99;::<;;=99;::<\332\332" \
+ "\332\377\377\377\377\263\377\377\377\3\376\376\376\266\266\266;;=\203" \
+ "::<\202;;=\204::<\1\205\205\207\377\377\377\377\377\377\377\377\204\377" \
+ "\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202\377" \
+ "\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305>" \
+ "\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212\310" \
+ "\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377\377" \
+ "\377\202\377\376\377\1\377\377\375\354\377\377\377\2\265\265\267::<\202" \
+ ";;=\205::<\4;;=::<\204\204\204\376\376\376\377\377\377\377\263\377\377" \
+ "\377\1SSU\202::<\1;;=\206::<\2;;=\346\346\346\377\377\377\377\377\377" \
+ "\377\377\205\377\377\377\1\375\377\376\202\377\377\375\34\377\377\377" \
+ "\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214\306" \
+ ">\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77\213" \
+ "\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362\377" \
+ "\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376\377" \
+ "\354\377\377\377\4FFH;;=99;;;=\203::<\5;;=99;;;=99;\364\364\364\377\377" \
+ "\377\377\262\377\377\377\1\316\316\316\202;;=\1""99;\203::<\1;;=\203" \
+ "::<\1xxz\377\377\377\377\377\377\377\377\205\377\377\377\3\377\376\377" \
+ "\377\377\377\375\377\376\202\377\377\377\11\373\373\363\241\321d\214" \
+ "\306>\213\310=\214\306>\214\305@\213\310=\212\306@\217\304>\202\215\307" \
+ "=\14\214\306>\215\305>\214\306>\215\305>\217\304@\215\307\77\215\307" \
+ "=\242\320c\367\375\361\376\376\377\377\376\377\376\376\376\202\377\377" \
+ "\375\2\374\377\377\377\376\377\354\377\377\377\1\235\235\237\204::<\1" \
+ "<<>\202::<\4;;=::<;;=\247\247\251\377\377\377\377\262\377\377\377\4\204" \
+ "\204\204;;=::<;;=\206::<\2;;=\316\316\316\377\377\377\377\377\377\377" \
+ "\377\205\377\377\377\1\377\377\375\202\377\377\377\32\377\376\377\370" \
+ "\373\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215\305@\214" \
+ "\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A\212\306@" \
+ "\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377\375" \
+ "\376\377\377\375\376\377\377\377\377\377\202\377\376\377\355\377\377" \
+ "\377\1\363\363\363\212::<\1TTV\377\377\377\377\261\377\377\377\5\347" \
+ "\347\351::<;;=::<;;=\204::<\3;;=::<TTT\377\377\377\377\376\377\377\377" \
+ "\10\376\376\377\377\377\375\377\377\377\377\377\375\377\377\377\377\376" \
+ "\377\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211" \
+ "\307B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214" \
+ "\306<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305" \
+ "@\244\317c\367\375\361\361\377\377\377\1\376\376\376\204\377\377\377" \
+ "\1\204\204\204\202;;=\203::<\1;;=\202::<\202;;=\1\302\302\302\203\377" \
+ "\377\377\1\376\376\376\377\377\377\377\244\377\377\377\1\376\376\376" \
+ "\203\377\377\377\1\376\376\376\203\377\377\377\1\234\234\236\202::<\1" \
+ ";;=\204::<\6;;=::<;;=\264\264\264\377\377\377\376\376\376\377\377\377" \
+ "\377\373\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377" \
+ "\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241" \
+ "\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@" \
+ "\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215" \
+ "\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\365\377" \
+ "\377\377\1\332\332\332\202::<\1;;=\202::<\6""99;::<;;=99;;;=xxx\205\377" \
+ "\377\377\1\376\376\376\377\377\377\377\243\377\377\377\1\376\376\376" \
+ "\206\377\377\377\4SSU;;=::<;;=\202::<\1;;=\203::<\3GGI\362\362\362\376" \
+ "\376\376\377\377\377\377\374\377\377\377\7\377\377\375\375\376\377\376" \
+ "\377\377\376\377\375\377\374\377\377\377\375\375\377\376\202\377\377" \
+ "\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305>\202\214\305" \
+ "@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307\77\214\306" \
+ ">\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362\377\377" \
+ "\373\377\376\377\377\377\375\364\377\377\377\3\376\376\376\377\377\377" \
+ "__a\203::<\202;;=\6::<99;;;=::<;;=\345\345\345\203\377\377\377\1\376" \
+ "\376\376\377\377\377\377\245\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\202\377\377\377\2\316\316\316::<\202;;=\205::<\202;;=\1\203" \
+ "\203\205\204\377\377\377\1\376\376\376\377\377\377\377\372\377\377\377" \
+ "\37\376\377\377\376\377\375\377\375\376\375\377\376\377\377\375\377\377" \
+ "\377\377\376\377\370\373\362\241\321a\215\307\77\215\307=\214\305@\214" \
+ "\306>\212\307<\214\306>\214\306<\214\306>\216\306\77\215\305<\212\307" \
+ ">\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321a\373\374\364" \
+ "\377\377\377\376\377\377\376\376\376\376\377\377\362\377\377\377\202" \
+ "\376\376\376\3\377\377\377\376\376\376\265\265\267\202::<\1;;=\207::" \
+ "<\3\251\251\253\377\377\377\376\376\376\203\377\377\377\1\376\376\376" \
+ "\377\377\377\377\247\377\377\377\2\376\376\376\204\204\206\207::<\1;" \
+ ";=\202::<\3\346\346\346\377\377\377\376\376\376\377\377\377\377\374\377" \
+ "\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202\377" \
+ "\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305>" \
+ "\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212\310" \
+ "\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377\377" \
+ "\377\202\377\376\377\1\377\377\375\364\377\377\377\17\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377FFH;;=99;::<;;=::<;;=99;;;=::<SSU\377" \
+ "\377\377\377\251\377\377\377\1\376\376\376\203\377\377\377\3\363\363" \
+ "\365::<;;=\202::<\11;;=::<;;=::<;;=::<kkm\377\377\377\376\376\376\377" \
+ "\377\377\377\376\377\377\377\1\375\377\376\202\377\377\375\34\377\377" \
+ "\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214" \
+ "\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77" \
+ "\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \
+ "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \
+ "\377\361\377\377\377\202\376\376\376\2\377\377\377\376\376\376\202\377" \
+ "\377\377\1\221\221\221\205::<\202;;=\5::<;;=99;\316\316\320\376\376\376" \
+ "\377\377\377\377\250\377\377\377\1\376\376\376\202\377\377\377\4\266" \
+ "\266\270::<99;;;=\203::<\1;;=\203::<\1\265\265\265\377\377\377\377\377" \
+ "\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377\11" \
+ "\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310=\212" \
+ "\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305>\217" \
+ "\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376\377" \
+ "\376\376\376\202\377\377\375\2\374\377\377\377\376\377\360\377\377\377" \
+ "\1\376\376\376\202\377\377\377\202\376\376\376\202\377\377\377\6\346" \
+ "\346\346;;=99;::<99;;;=\204::<\2;;=\204\204\206\202\377\377\377\1\376" \
+ "\376\376\377\377\377\377\251\377\377\377\1__a\203::<\3;;=::<;;=\203:" \
+ ":<\4FFF\363\363\363\377\377\377\376\376\376\377\377\377\377\375\377\377" \
+ "\377\1\377\377\375\202\377\377\377\32\377\376\377\370\373\364\243\322" \
+ "b\214\306>\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212" \
+ "\307<\215\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>" \
+ "\212\307<\244\317c\370\373\364\377\377\377\377\375\376\377\377\375\376" \
+ "\377\377\377\377\377\202\377\376\377\371\377\377\377\4^^`;;=::<;;=\202" \
+ "::<\5;;=::<;;=::<FFH\377\377\377\377\253\377\377\377\3\346\346\346::" \
+ "<;;=\210::<\1\204\204\204\202\377\377\377\202\376\376\376\377\377\377" \
+ "\377\365\377\377\377\10\376\376\377\377\377\375\377\377\377\377\377\375" \
+ "\377\377\377\377\376\377\377\377\375\376\377\377\202\377\377\377\6\370" \
+ "\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202\215\305@\4" \
+ "\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214\306" \
+ ">\215\307\77\214\305@\244\317c\367\375\361\377\377\377\377\202\377\377" \
+ "\377\3\265\265\267::<;;=\204::<\1;;=\202::<\2;;=\265\265\265\202\377" \
+ "\377\377\1\376\376\376\377\377\377\377\246\377\377\377\2\376\376\376" \
+ "\234\234\234\202;;=\203::<\1;;=\202::<\3""99;::<\332\332\332\377\377" \
+ "\377\377\370\377\377\377\6\376\376\377\377\376\377\375\376\377\376\377" \
+ "\377\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373\366" \
+ "\241\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306" \
+ "@\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215" \
+ "\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\377\377" \
+ "\377\377\5\377\377\377\363\363\365;;=::<;;=\202::<\3;;=::<;;=\202::<" \
+ "\3xxz\377\377\377\376\376\376\377\377\377\377\246\377\377\377\3\376\376" \
+ "\376\377\377\377SSS\202::<\1;;=\202::<\1;;=\202::<\6;;=SSU\377\377\377" \
+ "\376\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376\376\377" \
+ "\377\377\377\362\377\377\377\7\377\377\375\375\376\377\376\377\377\376" \
+ "\377\375\377\374\377\377\377\375\375\377\376\202\377\377\377\5\372\373" \
+ "\366\240\320b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212" \
+ "\306@\214\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306" \
+ ">\215\307\77\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377" \
+ "\377\375\377\377\377\377\11\377\377\377\376\376\376\204\204\206;;=::" \
+ "<99;;;=::<;;=\204::<\3\362\362\362\377\377\377\376\376\376\377\377\377" \
+ "\377\246\377\377\377\1\333\333\333\203::<\202;;=\202::<\5<<>99;::<\250" \
+ "\250\252\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377\365" \
+ "\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376\377\377" \
+ "\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77\215\307" \
+ "=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306\77\215" \
+ "\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321" \
+ "a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\377\377" \
+ "\377\377\202\377\377\377\1\301\301\301\202::<\1;;=\203::<\1;;=\203::" \
+ "<\1\266\266\270\377\377\377\377\250\377\377\377\2\220\220\220;;=\204" \
+ "::<\6;;=::<99;;;=::<\346\346\346\205\377\377\377\1\376\376\376\377\377" \
+ "\377\377\363\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376" \
+ "\377\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214" \
+ "\305@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>" \
+ "\212\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370" \
+ "\373\362\377\377\377\202\377\376\377\1\377\377\375\377\377\377\377\204" \
+ "\377\377\377\2TTV99;\202::<\1;;=\202::<\6;;=::<;;=__a\377\377\377\376" \
+ "\376\376\377\377\377\377\244\377\377\377\3\376\376\376\377\377\377TT" \
+ "V\207::<\3;;=99;```\377\377\377\377\373\377\377\377\1\375\377\376\202" \
+ "\377\377\375\34\377\377\377\376\376\376\373\373\363\243\322b\211\307" \
+ "B\212\307<\215\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214" \
+ "\306<\214\306>\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307" \
+ ">\244\317c\370\373\362\377\377\373\376\377\377\377\376\377\375\376\377" \
+ "\377\377\375\377\376\377\377\377\377\377\203\377\377\377\3\221\221\221" \
+ "::<;;=\202::<\202;;=\203::<\2;;=\345\345\347\377\377\377\377\246\377" \
+ "\377\377\4\332\332\332;;=::<;;=\203::<\1;;=\203::<\1\265\265\265\203" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\364" \
+ "\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377\11" \
+ "\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310=\212" \
+ "\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305>\217" \
+ "\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376\377" \
+ "\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377\377" \
+ "\202\377\377\377\5\376\376\376\332\332\332;;=::<;;=\202::<\6;;=::<;;" \
+ "=99;::<\250\250\252\377\377\377\377\244\377\377\377\6\376\376\376\377" \
+ "\377\377\221\221\223::<;;=99;\202::<\3;;=::<;;=\202::<\1\363\363\363" \
+ "\377\377\377\377\372\377\377\377\1\377\377\375\202\377\377\377\32\377" \
+ "\376\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215" \
+ "\305@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A" \
+ "\212\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377" \
+ "\377\375\376\377\377\375\376\377\377\377\377\377\202\377\376\377\377" \
+ "\377\377\377\204\377\377\377\2\376\376\376SSU\204::<\204;;=\2::<__a\377" \
+ "\377\377\377\243\377\377\377\6\376\376\376\377\377\377\376\376\376TT" \
+ "V99;;;=\204::<\4;;=99;<<>xxz\377\377\377\377\364\377\377\377\10\376\376" \
+ "\377\377\377\375\377\377\377\377\377\375\377\377\377\377\376\377\377" \
+ "\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211\307B" \
+ "\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214\306" \
+ "<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305@\244" \
+ "\317c\367\375\361\377\377\377\377\213\377\377\377\5\376\376\376\377\377" \
+ "\377\221\221\223::<;;=\204::<\5;;=::<;;=::<\363\363\363\204\377\377\377" \
+ "\1\376\376\376\202\377\377\377\202\376\376\376\377\377\377\377\233\377" \
+ "\377\377\5\332\332\332::<;;=99;<<>\202::<\1;;=\203::<\1\265\265\267\377" \
+ "\377\377\377\363\377\377\377\6\376\376\377\377\376\377\375\376\377\376" \
+ "\377\377\377\377\375\375\377\376\203\377\377\377\27\377\377\375\372\373" \
+ "\366\241\321a\217\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212" \
+ "\306@\214\306>\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306" \
+ ">\215\307\77\214\306>\242\322b\370\373\362\376\376\377\377\375\376\377" \
+ "\377\377\377\213\377\377\377\2\375\375\375\333\333\333\202::<\1;;=\202" \
+ "::<\1;;=\202::<\3""99;::<\265\265\265\206\377\377\377\3\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377\377\233\377\377\377\2\235\235\23599" \
+ ";\202;;=\1""99;\202;;=\202::<\3;;=::<\363\363\365\377\377\377\377\363" \
+ "\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374" \
+ "\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215" \
+ "\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D" \
+ "\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77" \
+ "\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\377" \
+ "\377\377\377\214\377\377\377\2\376\376\376SSU\207::<\3;;=::<xxx\203\377" \
+ "\377\377\202\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377" \
+ "\234\377\377\377\1^^`\211::<\3xxz\377\377\377\376\376\376\377\377\377" \
+ "\377\363\377\377\377\37\376\377\377\376\377\375\377\375\376\375\377\376" \
+ "\377\377\375\377\377\377\377\376\377\370\373\362\241\321a\215\307\77" \
+ "\215\307=\214\305@\214\306>\212\307<\214\306>\214\306<\214\306>\216\306" \
+ "\77\215\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>" \
+ "\242\321a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377" \
+ "\377\377\377\377\212\377\377\377\4\376\376\376\377\377\377\376\376\376" \
+ "\222\222\222\205::<\1;;=\20299;\202::<\3\363\363\363\377\377\377\376" \
+ "\376\376\377\377\377\377\240\377\377\377\1\346\346\346\202::<\1;;=\204" \
+ "::<\1;;=\202::<\1\250\250\252\202\377\377\377\1\376\376\376\377\377\377" \
+ "\377\361\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377" \
+ "\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305" \
+ "@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212" \
+ "\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373" \
+ "\362\377\377\377\202\377\376\377\1\377\377\375\377\377\377\377\212\377" \
+ "\377\377\1\376\376\376\203\377\377\377\2\332\332\332<<>\203::<\3;;=:" \
+ ":<<<>\203::<\2\301\301\303\376\376\376\202\377\377\377\5\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377\377\231" \
+ "\377\377\377\4\376\376\376\251\251\253::<;;=\204::<\5;;=::<99;::<\346" \
+ "\346\346\377\377\377\377\365\377\377\377\1\375\377\376\202\377\377\375" \
+ "\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215" \
+ "\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>" \
+ "\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370" \
+ "\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375" \
+ "\377\376\377\377\377\377\377\212\377\377\377\1\376\376\376\203\377\377" \
+ "\377\1SSS\207::<\3;;=::<\205\205\207\205\377\377\377\1\376\376\376\377" \
+ "\377\377\377\234\377\377\377\3wwy::<;;=\206::<\2;;=__a\377\377\377\377" \
+ "\365\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \
+ "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \
+ "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \
+ ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \
+ "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377" \
+ "\377\211\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\204" \
+ "\204\204::<\202;;=\1::<\202;;=\203::<\1SSU\204\377\377\377\1\376\376" \
+ "\376\377\377\377\377\235\377\377\377\1;;=\203::<\1;;=\202::<\1;;=\202" \
+ "::<\1\234\234\234\202\377\377\377\1\376\376\376\377\377\377\377\362\377" \
+ "\377\377\1\377\377\375\202\377\377\377\32\377\376\377\370\373\364\243" \
+ "\322b\214\306>\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305" \
+ "B\212\307<\215\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214" \
+ "\306>\212\307<\244\317c\370\373\364\377\377\377\377\375\376\377\377\375" \
+ "\376\377\377\377\377\377\202\377\376\377\377\377\377\377\212\377\377" \
+ "\377\1\376\376\376\204\377\377\377\6\301\301\301;;=::<;;=::<;;=\205:" \
+ ":<\1\333\333\333\202\377\377\377\1\376\376\376\377\377\377\377\231\377" \
+ "\377\377\1\376\376\376\203\377\377\377\1\301\301\303\204::<\1;;=\202" \
+ "::<\1:9>\202::<\1\332\332\332\377\377\377\377\356\377\377\377\10\376" \
+ "\376\377\377\377\375\377\377\377\377\377\375\377\377\377\377\376\377" \
+ "\377\377\375\376\377\377\202\377\377\377\6\370\373\362\243\322b\211\307" \
+ "B\213\310=\214\305@\214\306<\202\215\305@\4\214\306<\214\305@\214\306" \
+ "<\215\307\77\202\214\306>\6\212\307>\214\306>\215\307\77\214\305@\244" \
+ "\317c\367\375\361\377\377\377\377\230\377\377\377\2""99;;;=\210::<\1" \
+ "\250\250\250\377\377\377\377\240\377\377\377\3\221\221\223::<;;=\207" \
+ "::<\2SSU\376\376\376\377\377\377\377\355\377\377\377\6\376\376\377\377" \
+ "\376\377\375\376\377\376\377\377\377\377\375\375\377\376\203\377\377" \
+ "\377\27\377\377\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215" \
+ "\305>\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305" \
+ ">\215\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362" \
+ "\376\376\377\377\375\376\377\377\377\377\227\377\377\377\1yy{\211::<" \
+ "\6lll\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376\377" \
+ "\377\377\377\224\377\377\377\202\376\376\376\7\377\377\377\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377__a;;=\202::<\4<<>;;=::<;;=\202:" \
+ ":<\1\204\204\206\203\377\377\377\1\376\376\376\377\377\377\377\352\377" \
+ "\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377\374\377" \
+ "\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320b\215\307" \
+ "\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214\305D\216" \
+ "\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307\77\215" \
+ "\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375\377\377" \
+ "\377\377\221\377\377\377\3\376\376\376\377\377\377\376\376\376\203\377" \
+ "\377\377\1\265\265\267\212::<\1\363\363\363\377\377\377\377\227\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1\345" \
+ "\345\345\202::<\202;;=\1""99;\203::<\4;;=::<\301\301\301\376\376\376" \
+ "\203\377\377\377\1\376\376\376\377\377\377\377\352\377\377\377\37\376" \
+ "\377\377\376\377\375\377\375\376\375\377\376\377\377\375\377\377\377" \
+ "\377\376\377\370\373\362\241\321a\215\307\77\215\307=\214\305@\214\306" \
+ ">\212\307<\214\306>\214\306<\214\306>\216\306\77\215\305<\212\307>\213" \
+ "\307A\215\305>\212\307>\215\307\77\214\306>\242\321a\373\374\364\377" \
+ "\377\377\376\377\377\376\376\376\376\377\377\377\377\377\377\222\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\1\347" \
+ "\347\347\212::<\1\302\302\304\205\377\377\377\1\376\376\376\377\377\377" \
+ "\377\222\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202" \
+ "\377\377\377\5\265\265\265::<;;=99;;;=\203::<\1;;=\202::<\1\363\363\363" \
+ "\377\377\377\377\356\377\377\377\202\377\377\375\3\377\374\377\375\377" \
+ "\376\376\377\377\202\377\377\377\25\370\373\364\243\322b\217\304@\212" \
+ "\306@\214\305@\215\305>\212\307>\212\306@\214\305B\214\305@\214\305B" \
+ "\214\306>\212\307>\212\310\77\214\306>\217\304@\214\306>\214\305@\242" \
+ "\322b\370\373\362\377\377\377\202\377\376\377\1\377\377\375\377\377\377" \
+ "\377\230\377\377\377\2\376\376\376TTT\211::<\3\221\221\223\377\377\377" \
+ "\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377\231\377\377" \
+ "\377\2\204\204\204::<\202;;=\202::<\1;;=\203::<\2``b\376\376\376\377" \
+ "\377\377\377\357\377\377\377\1\375\377\376\202\377\377\375\34\377\377" \
+ "\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215\305>\214" \
+ "\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>\215\307\77" \
+ "\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \
+ "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \
+ "\377\377\377\377\377\225\377\377\377\1\376\376\376\202\377\377\377\1" \
+ "\221\221\221\210::<\2;;=__a\202\377\377\377\1\376\376\376\377\377\377" \
+ "\377\227\377\377\377\1\376\376\376\203\377\377\377\1SSU\202::<\1;;=\204" \
+ "::<\202;;=\1\234\234\234\204\377\377\377\1\376\376\376\377\377\377\377" \
+ "\352\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \
+ "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \
+ "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \
+ ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \
+ "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377" \
+ "\377\222\377\377\377\1\376\376\376\205\377\377\377\1\301\301\301\210" \
+ "::<\4""99;;;=\364\364\366\376\376\376\377\377\377\377\233\377\377\377" \
+ "\1\346\346\346\207::<\4;;=99;::<\316\316\316\203\377\377\377\1\376\376" \
+ "\376\377\377\377\377\353\377\377\377\1\377\377\375\202\377\377\377\32" \
+ "\377\376\377\370\373\364\243\322b\214\306>\213\310\77\214\305@\215\305" \
+ ">\215\305@\214\306>\214\305B\212\307<\215\307=\214\305B\214\306>\215" \
+ "\306A\212\306@\212\307>\214\306>\212\307<\244\317c\370\373\364\377\377" \
+ "\377\377\375\376\377\377\375\376\377\377\377\377\377\202\377\376\377" \
+ "\377\377\377\377\224\377\377\377\1\376\376\376\204\377\377\377\1\363" \
+ "\363\363\210::<\3;;=::<\302\302\304\377\377\377\377\231\377\377\377\1" \
+ "\376\376\376\202\377\377\377\1\266\266\270\203::<\203;;=\203::<\1:::" \
+ "\377\377\377\377\351\377\377\377\10\376\376\377\377\377\375\377\377\377" \
+ "\377\377\375\377\377\377\377\376\377\377\377\375\376\377\377\202\377" \
+ "\377\377\6\370\373\362\243\322b\211\307B\213\310=\214\305@\214\306<\202" \
+ "\215\305@\4\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212" \
+ "\307>\214\306>\215\307\77\214\305@\244\317c\367\375\361\377\377\377\377" \
+ "\242\377\377\377\3__a::<;;=\207::<\1\221\221\221\377\377\377\377\234" \
+ "\377\377\377\1\204\204\206\204::<\202;;=\203::<\1lll\203\377\377\377" \
+ "\1\375\375\375\377\377\377\377\344\377\377\377\6\376\376\377\377\376" \
+ "\377\375\376\377\376\377\377\377\377\375\375\377\376\203\377\377\377" \
+ "\27\377\377\375\372\373\366\241\321a\217\304@\212\307<\214\306>\215\305" \
+ ">\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305>\215" \
+ "\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362\376" \
+ "\376\377\377\375\376\377\377\377\377\241\377\377\377\2\221\221\223;;" \
+ "=\202::<\202;;=\203::<\2;;=^^^\204\377\377\377\1\376\376\376\377\377" \
+ "\377\377\224\377\377\377\1\376\376\376\202\377\377\377\1``b\202::<\1" \
+ ";;=\206::<\1\234\234\234\205\377\377\377\1\376\376\376\377\377\377\377" \
+ "\342\377\377\377\7\377\377\375\375\376\377\376\377\377\376\377\375\377" \
+ "\374\377\377\377\375\375\377\376\202\377\377\377\5\372\373\366\240\320" \
+ "b\215\307\77\212\306@\215\305>\202\214\305@\20\215\305@\212\306@\214" \
+ "\305D\216\306\77\214\306>\215\307\77\214\306>\212\306@\214\306>\215\307" \
+ "\77\215\305@\242\320c\370\373\362\377\377\373\377\376\377\377\377\375" \
+ "\377\377\377\377\241\377\377\377\6\301\301\303::<;;=::<99;;;=\203::<" \
+ "\6;;=:::\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\377\224\377\377\377\1\376\376\376\202\377\377\377\2\363\363\363;;=\211" \
+ "::<\1\316\316\316\203\377\377\377\1\376\376\376\202\377\377\377\1\376" \
+ "\376\376\377\377\377\377\342\377\377\377\37\376\377\377\376\377\375\377" \
+ "\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373\362" \
+ "\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306>\214" \
+ "\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212\307" \
+ ">\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377\376" \
+ "\376\376\376\377\377\377\377\377\377\241\377\377\377\1\363\363\365\202" \
+ "::<\1;;=\202::<\2""99;;;=\202::<\2;;=\316\316\316\377\377\377\377\231" \
+ "\377\377\377\10\376\376\376\316\316\316::<;;=::<;;=99;;;=\204::<\202" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\344" \
+ "\377\377\377\202\377\377\375\3\377\374\377\375\377\376\376\377\377\202" \
+ "\377\377\377\25\370\373\364\243\322b\217\304@\212\306@\214\305@\215\305" \
+ ">\212\307>\212\306@\214\305B\214\305@\214\305B\214\306>\212\307>\212" \
+ "\310\77\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377" \
+ "\377\377\202\377\376\377\1\377\377\375\377\377\377\377\243\377\377\377" \
+ "\1``b\203::<\203;;=\6::<<<>::<\234\234\234\377\377\377\376\376\376\377" \
+ "\377\377\377\230\377\377\377\1\234\234\236\204::<\12;;=99;::<;;=::<k" \
+ "km\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377\377\346" \
+ "\377\377\377\1\375\377\376\202\377\377\375\34\377\377\377\376\376\376" \
+ "\373\373\363\243\322b\211\307B\212\307<\215\305>\214\306>\212\307>\214" \
+ "\305@\217\304>\212\307<\214\306<\214\306>\215\307\77\213\307A\214\306" \
+ ">\215\305@\215\307\77\212\307>\244\317c\370\373\362\377\377\373\376\377" \
+ "\377\377\376\377\375\376\377\377\377\375\377\376\377\377\377\377\377" \
+ "\242\377\377\377\2\222\222\222::<\202;;=\7""99;::<;;=::<99;;;=lln\202" \
+ "\377\377\377\1\376\376\376\377\377\377\377\225\377\377\377\3\376\376" \
+ "\376\377\377\377jjl\204;;=\2""99;;;=\202::<\2;;=\221\221\223\202\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\377\377\377\377" \
+ "\343\377\377\377\3\377\376\377\377\377\377\375\377\376\202\377\377\377" \
+ "\11\373\373\363\241\321d\214\306>\213\310=\214\306>\214\305@\213\310" \
+ "=\212\306@\217\304>\202\215\307=\14\214\306>\215\305>\214\306>\215\305" \
+ ">\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377\376" \
+ "\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\377\377\377" \
+ "\377\242\377\377\377\2\264\264\264;;=\206::<\6;;=::<FFH\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377\377\227\377\377\377\1GGI\204::<\6;;" \
+ "=::<;;=::<;;=\302\302\304\206\377\377\377\1\376\376\376\377\377\377\377" \
+ "\342\377\377\377\1\377\377\375\202\377\377\377\32\377\376\377\370\373" \
+ "\364\243\322b\214\306>\213\310\77\214\305@\215\305>\215\305@\214\306" \
+ ">\214\305B\212\307<\215\307=\214\305B\214\306>\215\306A\212\306@\212" \
+ "\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377\375\376" \
+ "\377\377\375\376\377\377\377\377\377\202\377\376\377\377\377\377\377" \
+ "\243\377\377\377\2\346\346\346;;=\211::<\1\346\346\350\377\377\377\377" \
+ "\230\377\377\377\3\346\346\350::<;;=\202::<\1;;=\205::<\1\346\346\346" \
+ "\302\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376" \
+ "\376\376\377\377\377\377\233\377\377\377\10\376\376\377\377\377\375\377" \
+ "\377\377\377\377\375\377\377\377\377\376\377\377\377\375\376\377\377" \
+ "\202\377\377\377\6\370\373\362\243\322b\211\307B\213\310=\214\305@\214" \
+ "\306<\202\215\305@\4\214\306<\214\305@\214\306<\215\307\77\202\214\306" \
+ ">\6\212\307>\214\306>\215\307\77\214\305@\244\317c\367\375\361\345\377" \
+ "\377\377\1\376\376\376\305\377\377\377\3FFF::<;;=\202::<\3;;=::<;;=\202" \
+ "::<\1\301\301\303\377\377\377\377\230\377\377\377\4\301\301\30399;::" \
+ "<;;=\204::<\3;;=::<GGI\215\377\377\377\1\376\376\376\266\377\377\377" \
+ "\1\376\376\376\203\377\377\377\1\376\376\376\377\377\377\377\231\377" \
+ "\377\377\6\376\376\377\377\376\377\375\376\377\376\377\377\377\377\375" \
+ "\375\377\376\203\377\377\377\27\377\377\375\372\373\366\241\321a\217" \
+ "\304@\212\307<\214\306>\215\305>\215\305@\213\310=\212\306@\214\306>" \
+ "\214\305B\215\307\77\215\305>\215\306A\212\307>\214\306>\215\307\77\214" \
+ "\306>\242\322b\370\373\362\376\376\377\377\375\376\341\377\377\377\5" \
+ "\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376\265\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\212\377\377\377\3\376" \
+ "\376\376\377\377\377lll\206::<\202;;=\2::<\234\234\236\377\377\377\377" \
+ "\224\377\377\377\1\376\376\376\203\377\377\377\2\233\233\235;;=\203:" \
+ ":<\2""99;;;=\202::<\2;;=xxz\213\377\377\377\1\376\376\376\265\377\377" \
+ "\377\1\376\376\376\377\377\377\377\240\377\377\377\7\377\377\375\375" \
+ "\376\377\376\377\377\376\377\375\377\374\377\377\377\375\375\377\376" \
+ "\202\377\377\377\5\372\373\366\240\320b\215\307\77\212\306@\215\305>" \
+ "\202\214\305@\20\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307" \
+ "\77\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362" \
+ "\377\377\373\377\376\377\377\377\375\377\377\377\377\233\377\377\377" \
+ "\3\376\376\376\377\377\377\376\376\376\213\377\377\377\6\376\376\376" \
+ "\377\377\377\233\233\233;;=::<;;=\206::<\1lln\377\377\377\377\226\377" \
+ "\377\377\3\376\376\376\377\377\377kkm\210::<\2;;=\234\234\236\214\377" \
+ "\377\377\1\315\315\315\202\234\234\234\262\234\234\236\2\234\234\234" \
+ "\265\265\265\377\377\377\377\240\377\377\377\37\376\377\377\376\377\375" \
+ "\377\375\376\375\377\376\377\377\375\377\377\377\377\376\377\370\373" \
+ "\362\241\321a\215\307\77\215\307=\214\305@\214\306>\212\307<\214\306" \
+ ">\214\306<\214\306>\216\306\77\215\305<\212\307>\213\307A\215\305>\212" \
+ "\307>\215\307\77\214\306>\242\321a\373\374\364\377\377\377\376\377\377" \
+ "\376\376\376\376\377\377\344\377\377\377\4\376\376\376\347\347\347\234" \
+ "\234\234\235\235\235\260\234\234\236\204\234\234\234\216\377\377\377" \
+ "\1\301\301\301\202::<\1;;=\203::<\202;;=\2::<EEG\377\377\377\377\230" \
+ "\377\377\377\1FFH\204::<\202;;=\4::<;;=99;\302\302\304\212\377\377\377" \
+ "\5\376\376\376\377\377\377\234\234\234::<;;=\263::<\1jjj\205\377\377" \
+ "\377\1\376\376\376\377\377\377\377\231\377\377\377\202\377\377\375\3" \
+ "\377\374\377\375\377\376\376\377\377\202\377\377\377\25\370\373\364\243" \
+ "\322b\217\304@\212\306@\214\305@\215\305>\212\307>\212\306@\214\305B" \
+ "\214\305@\214\305B\214\306>\212\307>\212\310\77\214\306>\217\304@\214" \
+ "\306>\214\305@\242\322b\370\373\362\377\377\377\202\377\376\377\1\377" \
+ "\377\375\346\377\377\377\2\316\316\316:::\263::<\4;;=:::\377\377\377" \
+ "\376\376\376\214\377\377\377\3\346\346\346::<;;=\205::<\4;;=::<;;=\346" \
+ "\346\346\377\377\377\377\226\377\377\377\2\362\362\362;;=\204::<\3""9" \
+ "9;::<;;=\202::<\1\346\346\350\214\377\377\377\2\234\234\234;;=\264::" \
+ "<\1kkm\377\377\377\377\240\377\377\377\1\375\377\376\202\377\377\375" \
+ "\34\377\377\377\376\376\376\373\373\363\243\322b\211\307B\212\307<\215" \
+ "\305>\214\306>\212\307>\214\305@\217\304>\212\307<\214\306<\214\306>" \
+ "\215\307\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370" \
+ "\373\362\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375" \
+ "\377\376\377\345\377\377\377\2\316\316\31699;\265::<\216\377\377\377" \
+ "\2\376\376\376FFH\203::<\1;;=\203::<\3;;=99;\316\316\316\377\377\377" \
+ "\377\226\377\377\377\1\317\317\317\206::<\202;;=\4""99;FFH\377\377\377" \
+ "\376\376\376\213\377\377\377\1\234\234\236\202::<\1;;=\261::<\2;;=kk" \
+ "m\205\377\377\377\1\376\376\376\377\377\377\377\231\377\377\377\3\377" \
+ "\376\377\377\377\377\375\377\376\202\377\377\377\11\373\373\363\241\321" \
+ "d\214\306>\213\310=\214\306>\214\305@\213\310=\212\306@\217\304>\202" \
+ "\215\307=\14\214\306>\215\305>\214\306>\215\305>\217\304@\215\307\77" \
+ "\215\307=\242\320c\367\375\361\376\376\377\377\376\377\376\376\376\202" \
+ "\377\377\375\2\374\377\377\377\376\377\345\377\377\377\1\316\316\316" \
+ "\264::<\202;;=\215\377\377\377\4\376\376\376\377\377\377lln99;\210::" \
+ "<\2\234\234\234\376\376\376\377\377\377\377\225\377\377\377\5\234\234" \
+ "\234::<;;=99;::<\202;;=\5::<;;=::<kkm\376\376\377\214\377\377\377\1\234" \
+ "\234\236\203::<\1:9>\261::<\1kkm\377\377\377\377\237\377\377\377\1\377" \
+ "\377\375\202\377\377\377\32\377\376\377\370\373\364\243\322b\214\306" \
+ ">\213\310\77\214\305@\215\305>\215\305@\214\306>\214\305B\212\307<\215" \
+ "\307=\214\305B\214\306>\215\306A\212\306@\212\307>\214\306>\212\307<" \
+ "\244\317c\370\373\364\377\377\377\377\375\376\377\377\375\376\377\377" \
+ "\377\377\377\202\377\376\377\346\377\377\377\1\316\316\316\266::<\217" \
+ "\377\377\377\2\234\234\236;;=\206::<\3""99;;;=www\377\377\377\377\226" \
+ "\377\377\377\3\204\204\206::<;;=\207::<\3\222\222\222\377\377\377\376" \
+ "\376\376\213\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\210" \
+ "\377\377\377\7\376\376\376\377\377\377\377\377\375\376\377\375\376\377" \
+ "\377\377\377\377\377\376\377\203\377\377\377\1\376\376\376\203\377\377" \
+ "\377\1\376\377\377\203\377\377\377\16\377\377\375\377\377\377\377\376" \
+ "\377\377\377\377\377\377\373\376\377\377\377\377\377\377\377\373\371" \
+ "\372\364\242\322d\214\306<\215\307\77\214\305@\214\306<\202\215\305@" \
+ "\4\214\306<\214\305@\214\306<\215\307\77\202\214\306>\6\212\307>\214" \
+ "\306>\215\307\77\214\305@\244\317c\367\375\361\356\377\377\377\1\316" \
+ "\316\316\266::<\214\377\377\377\1\376\376\376\202\377\377\377\1\266\266" \
+ "\266\202::<\1;;=\203::<\1;;=\202::<\3__a\377\377\377\376\376\376\377" \
+ "\377\377\377\224\377\377\377\2kkm;;=\202::<\202;;=\202::<\3;;=::<\265" \
+ "\265\265\215\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\214" \
+ "\377\377\377\2\376\377\377\376\377\375\202\377\377\375\203\377\377\377" \
+ "\204\377\377\375\205\377\377\377\1\376\376\377\202\377\377\377\6\377" \
+ "\377\375\377\377\377\371\372\362\242\320c\214\305@\215\305@\202\214\306" \
+ ">\20\215\305@\213\310=\212\306@\214\306>\214\305B\215\307\77\215\305" \
+ ">\215\306A\212\307>\214\306>\215\307\77\214\306>\242\322b\370\373\362" \
+ "\376\376\377\377\375\376\355\377\377\377\1\316\316\316\266::<\215\377" \
+ "\377\377\4\376\376\376\377\377\377\315\315\315;;=\203::<\1;;=\203::<" \
+ "\2;;=99;\377\377\377\377\226\377\377\377\203::<\1;;=\202::<\1;;=\203" \
+ "::<\2\317\317\317\376\376\376\214\377\377\377\1\234\234\236\265::<\1" \
+ "kkm\377\377\377\377\211\377\377\377\3\376\376\376\377\376\377\377\377" \
+ "\377\203\377\376\377\204\377\377\377\1\376\376\376\202\377\377\377\1" \
+ "\377\376\377\203\377\377\377\1\376\376\376\203\377\377\377\31\376\376" \
+ "\377\377\376\377\371\372\365\241\322e\212\307<\216\306\77\212\311<\216" \
+ "\303\77\212\307>\215\305@\212\306@\214\305D\216\306\77\214\306>\215\307" \
+ "\77\214\306>\212\306@\214\306>\215\307\77\215\305@\242\320c\370\373\362" \
+ "\377\377\373\377\376\377\377\377\375\355\377\377\377\1\316\316\316\266" \
+ "::<\220\377\377\377\202::<\4;;=::<;;=::<\202;;=\3""99;;;=\346\346\346" \
+ "\377\377\377\377\224\377\377\377\2\362\362\362;;=\202::<\7""99;::<;;" \
+ "=88:;;=::<;;=\216\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377" \
+ "\212\377\377\377\202\376\377\377\202\377\377\377\1\377\376\377\206\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\376\376\376\202\377\377\377\6\370\373\364\242\322b\214\306>\214\305" \
+ "@\215\305>\214\305@\202\215\306A\20\214\306<\214\306>\216\306\77\215" \
+ "\305<\212\307>\213\307A\215\305>\212\307>\215\307\77\214\306>\242\321" \
+ "a\373\374\364\377\377\377\376\377\377\376\376\376\376\377\377\355\377" \
+ "\377\377\1\316\316\316\266::<\216\377\377\377\6\376\376\376\377\377\377" \
+ "SSU;;=99;;;=\206::<\1\316\316\316\377\377\377\377\224\377\377\377\2\316" \
+ "\316\31699;\205::<\1;;=\202::<\1FFH\216\377\377\377\1\234\234\236\265" \
+ "::<\1kkm\377\377\377\377\207\377\377\377\202\377\376\377\2\377\377\377" \
+ "\377\377\375\203\377\377\377\1\376\377\375\202\377\377\375\203\377\377" \
+ "\377\202\377\377\375\2\377\377\377\377\377\375\205\377\377\377\26\377" \
+ "\377\375\371\372\362\243\322b\211\305A\215\305>\215\307\77\214\305@\214" \
+ "\306>\215\305@\212\307>\214\305@\214\305B\214\306>\212\307>\212\310\77" \
+ "\214\306>\217\304@\214\306>\214\305@\242\322b\370\373\362\377\377\377" \
+ "\202\377\376\377\1\377\377\375\356\377\377\377\1\316\316\316\266::<\220" \
+ "\377\377\377\3kkm::<;;=\202::<\6;;=::<;;=::<;;=\233\233\233\377\377\377" \
+ "\377\223\377\377\377\2\376\376\376\265\265\265\205::<\1;;=\202::<\2""9" \
+ "9;lln\216\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\207\377" \
+ "\377\377\3\376\377\375\375\377\376\377\377\377\202\377\376\377\3\377" \
+ "\376\374\377\377\377\376\377\377\202\377\377\377\1\377\377\375\204\377" \
+ "\377\377\2\375\377\376\377\377\375\202\377\377\377\1\377\377\375\202" \
+ "\377\377\377\32\376\376\374\365\367\354\223\312K\215\305>\214\306<\211" \
+ "\305\77\214\306>\212\307>\215\307\77\214\306>\214\306<\214\306>\215\307" \
+ "\77\213\307A\214\306>\215\305@\215\307\77\212\307>\244\317c\370\373\362" \
+ "\377\377\373\376\377\377\377\376\377\375\376\377\377\377\375\377\376" \
+ "\377\355\377\377\377\1\316\316\316\266::<\217\377\377\377\5\376\376\376" \
+ "\234\234\236;;=::<;;=\202::<\2""99;::<\202;;=\1\221\221\221\377\377\377" \
+ "\377\224\377\377\377\1\235\235\235\211::<\2\221\221\223\376\376\376\215" \
+ "\377\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\207\377\377\377" \
+ "\1\377\376\377\202\377\377\375\202\377\377\377\202\377\377\375\1\377" \
+ "\377\377\202\376\377\377\1\377\377\377\202\377\377\375\5\376\376\377" \
+ "\377\377\377\377\377\373\377\377\377\376\376\376\203\377\377\377\27\376" \
+ "\376\376\377\377\375\376\377\372\347\365\333\225\311K\217\304>\214\305" \
+ "B\215\307\77\212\306B\214\306>\215\306A\214\306>\215\305>\214\306>\215" \
+ "\305>\217\304@\215\307\77\215\307=\242\320c\367\375\361\376\376\377\377" \
+ "\376\377\376\376\376\202\377\377\375\2\374\377\377\377\376\377\355\377" \
+ "\377\377\1\316\316\316\266::<\214\377\377\377\1\376\376\376\203\377\377" \
+ "\377\3\250\250\252::<;;=\203::<\202;;=\202::<\1kkk\377\377\377\377\224" \
+ "\377\377\377\4www;;=::<;;=\202::<\202;;=\202::<\1\234\234\236\216\377" \
+ "\377\377\1\234\234\236\265::<\1kkm\377\377\377\377\207\377\377\377\15" \
+ "\367\374\365\343\361\316\316\346\254\305\342\240\304\343\240\303\342" \
+ "\236\305\342\237\312\346\251\345\356\317\365\373\357\376\377\377\376" \
+ "\376\377\377\377\375\214\377\377\377\24\350\365\333\223\312K\216\306" \
+ "\77\212\307>\215\304B\214\306>\215\307=\214\306>\215\306A\212\306@\212" \
+ "\307>\214\306>\212\307<\244\317c\370\373\364\377\377\377\377\375\376" \
+ "\377\377\375\376\377\377\377\377\377\202\377\376\377\356\377\377\377" \
+ "\1\316\316\316\266::<\217\377\377\377\2\376\376\376\316\316\320\207:" \
+ ":<\3;;=::<SSS\377\377\377\377\223\377\377\377\2\376\376\376kkm\202::" \
+ "<\1;;=\206::<\1\316\316\316\377\377\377\377\276\377\377\377\4\377\377" \
+ "\375\376\377\377\377\377\377\377\376\377\202\377\377\377\10\377\377\375" \
+ "\377\376\377\376\377\375\376\376\376\377\377\377\350\365\333\277\337" \
+ "\224\232\315V\210\214\306>\10\212\306@\212\307>\232\315W\277\337\224" \
+ "\352\364\333\377\377\377\377\376\377\377\377\375\202\376\377\377\202" \
+ "\377\377\377\2\377\376\377\377\377\375\202\377\377\377\17\377\377\375" \
+ "\377\376\377\347\365\333\226\312L\215\306A\213\310=\212\306@\217\304" \
+ ">\216\307<\214\305@\215\305<\214\305@\215\307=\244\317c\366\373\364\377" \
+ "\377\377\377\276\377\377\377\6\346\346\346;;=99;;;=::<;;=\205::<\377" \
+ "\377\377\377\224\377\377\377\1::<\202;;=\2::<;;=\203::<\4;;=::<\316\316" \
+ "\316\376\376\376\377\377\377\377\274\377\377\377\14\377\375\377\377\377" \
+ "\377\376\376\374\377\377\375\377\376\377\377\377\375\376\377\377\377" \
+ "\377\377\376\377\377\377\376\377\324\353\265\231\316Z\202\214\306<\1" \
+ "\215\305>\210\214\306>\202\215\305>\16\214\306>\213\307A\211\306;\233" \
+ "\314V\324\353\265\377\377\377\377\376\377\377\377\375\375\377\376\376" \
+ "\377\377\377\377\377\377\376\377\376\377\377\377\377\373\202\377\377" \
+ "\377\6\376\376\377\350\365\333\222\312K\215\306A\217\304>\212\306@\202" \
+ "\214\305@\6\213\310\77\212\307>\242\322d\370\373\364\377\377\377\377" \
+ "\377\375\377\377\377\377\276\377\377\377\203::<\3;;=::<99;\202;;=\202" \
+ "::<\1\346\346\350\377\377\377\377\222\377\377\377\2\376\376\376;;=\202" \
+ "::<\202;;=\205::<\377\377\377\377\275\377\377\377\4\377\377\375\377\377" \
+ "\377\377\377\373\377\376\374\202\376\377\377\12\377\377\375\377\377\377" \
+ "\376\377\375\342\360\317\232\315V\214\306<\220\306=\215\306A\215\306" \
+ "C\215\306A\210\214\306>\202\215\307\77\7\215\306A\214\306>\214\305@\213" \
+ "\307A\214\305@\230\315W\341\361\315\203\377\377\377\2\376\376\374\374" \
+ "\377\375\202\377\377\377\2\377\377\375\377\376\377\202\377\377\377\13" \
+ "\352\364\331\221\311J\215\306A\213\310=\216\306\77\214\305@\214\306<" \
+ "\242\322e\370\373\364\376\376\377\377\377\375\377\377\377\377\277\377" \
+ "\377\377\1``b\202::<\2;;=99;\202;;=\4::<;;=::<\316\316\320\377\377\377" \
+ "\377\222\377\377\377\4\316\316\316;;=::<99;\202::<\2;;=::<\202;;=\3:" \
+ ":<\376\376\376\377\377\377\202\376\376\376\377\377\377\377\271\377\377" \
+ "\377\17\376\377\377\376\376\374\377\376\374\376\377\377\377\377\377\377" \
+ "\377\375\376\377\377\370\373\364\277\336\222\215\305<\214\305@\215\307" \
+ "\77\212\307>\215\307\77\213\307A\211\214\306>\16\216\306A\214\305B\213" \
+ "\307A\214\306>\215\305<\213\305=\215\306A\214\306<\215\305>\300\337\223" \
+ "\370\373\362\376\376\377\377\377\375\376\377\377\204\377\377\377\16\377" \
+ "\376\377\376\376\377\376\377\377\352\364\331\222\312K\215\306A\214\306" \
+ "<\214\305@\243\321d\371\373\360\376\376\377\376\377\377\377\377\377\376" \
+ "\377\377\377\377\377\377\273\377\377\377\4\376\376\376\377\377\377\376" \
+ "\376\376lln\203::<\1;;=\20299;\1;;=\202::<\1\266\266\270\377\377\377" \
+ "\377\222\377\377\377\5\316\316\316::<;;=::<;;=\205::<\3kkm\377\377\377" \
+ "\376\376\376\377\377\377\377\274\377\377\377\14\377\377\375\376\377\377" \
+ "\377\377\377\377\377\375\376\376\376\367\374\365\244\317c\214\305@\215" \
+ "\307=\211\306=\213\307A\215\306A\202\212\306@\1\213\310<\210\214\306" \
+ ">\202\212\307>\3\212\307<\214\306>\216\306\77\202\214\306>\12\215\305" \
+ "<\215\307\77\212\306@\242\322b\371\374\365\377\377\375\376\376\374\376" \
+ "\377\377\377\376\377\376\377\377\202\377\377\377\13\376\377\375\376\376" \
+ "\377\377\377\377\350\365\333\225\311K\214\305B\242\320c\371\374\361\377" \
+ "\377\377\376\377\377\377\376\377\377\377\377\377\300\377\377\377\7\221" \
+ "\221\223::<99;::<;;=::<;;=\203::<\1\234\234\236\377\377\377\377\222\377" \
+ "\377\377\2\250\250\25099;\206::<\3;;=::<jjl\377\377\377\377\275\377\377" \
+ "\377\202\377\376\377\16\376\377\377\377\377\375\376\376\376\352\364\333" \
+ "\223\312K\220\306=\215\306A\214\305B\213\310=\215\306C\215\305>\216\306" \
+ "\77\215\305>\215\305@\210\214\306>\37\215\305@\215\307\77\212\306@\215" \
+ "\307\77\214\304\77\215\306A\212\307;\212\306@\214\306>\216\307B\214\306" \
+ ">\222\312K\354\364\334\377\376\377\377\377\377\377\377\373\376\377\377" \
+ "\377\375\376\376\377\375\377\377\377\377\376\377\377\377\377\376\376" \
+ "\377\347\365\333\260\327z\371\374\363\375\377\376\376\377\377\377\376" \
+ "\377\377\377\377\377\377\375\377\377\377\377\276\377\377\377\3\376\376" \
+ "\376\234\234\23699;\203;;=\205::<\1\221\221\223\377\377\377\377\222\377" \
+ "\377\377\2\234\234\234;;=\204::<\202;;=\3::<;;=\235\235\237\377\377\377" \
+ "\377\276\377\377\377\202\377\377\375\15\376\377\377\367\374\365\223\312" \
+ "K\214\306>\213\310\77\215\305@\214\306<\215\307=\214\305@\213\307A\211" \
+ "\305\77\215\307\77\215\305>\210\214\306>\20\215\306A\213\305=\215\307" \
+ "=\214\305@\215\306A\214\306>\213\304A\220\305\77\216\306\77\212\306@" \
+ "\215\305@\213\307A\221\311L\367\375\363\376\377\377\377\377\377\202\377" \
+ "\377\373\1\377\375\376\202\377\377\377\4\377\376\377\376\377\377\377" \
+ "\376\377\376\377\377\203\377\377\377\3\377\376\377\376\376\377\374\377" \
+ "\375\377\377\377\377\277\377\377\377\2\265\265\267<<>\20299;\7::<;;=" \
+ "::<99;;;=::<lln\377\377\377\377\222\377\377\377\3\221\221\221::<;;=\205" \
+ "::<\3;;=::<\234\234\236\377\377\377\377\276\377\377\377\17\376\377\377" \
+ "\377\377\377\366\373\364\244\317c\220\306=\213\310\77\212\306@\211\307" \
+ "@\216\306\77\215\305@\215\307\77\213\310\77\215\307\77\215\305>\214\305" \
+ "@\210\214\306>\22\216\306A\215\307\77\213\305=\216\306\77\214\306>\212" \
+ "\307>\213\310\77\214\305@\215\306C\214\306<\215\307=\215\305>\213\310" \
+ "=\242\320d\372\372\362\376\377\375\377\375\377\377\377\375\202\376\377" \
+ "\377\5\377\377\377\377\377\375\377\377\377\377\377\375\377\377\377\202" \
+ "\377\376\377\5\376\377\375\376\377\377\377\377\377\377\375\376\377\377" \
+ "\375\377\377\377\377\274\377\377\377\5\376\376\376\377\377\377\316\316" \
+ "\320::<;;=\202::<\1;;=\202::<\3""99;::<kkm\377\377\377\377\222\377\377" \
+ "\377\2kkm::<\203;;=\205::<\1\264\264\264\377\377\377\377\275\377\377" \
+ "\377\10\377\376\377\376\377\377\377\377\377\300\336\224\212\307>\214" \
+ "\306<\214\306>\211\307>\231\214\306>\1\216\306\77\203\214\306>\2\214" \
+ "\305@\266\334\207\202\377\377\377\7\377\376\377\377\377\377\377\376\377" \
+ "\377\377\375\377\377\377\377\377\375\376\377\377\377\377\377\377\303" \
+ "\377\377\377\1\376\376\376\202\377\377\377\1\316\316\316\206::<\6;;=" \
+ "::<;;=FFH\377\377\377\376\376\376\205\377\377\377\1\376\376\376\377\377" \
+ "\377\377\212\377\377\377\1lln\202::<\3;;=99;;;=\204::<\3\317\317\317" \
+ "\377\377\377\376\376\376\377\377\377\377\273\377\377\377\10\377\375\377" \
+ "\374\377\375\343\361\320\214\306>\215\306A\214\304=\212\307>\215\305" \
+ ">\230\214\306>\20\214\306<\213\304\77\212\307>\212\306B\214\306<\212" \
+ "\307>\220\304>\337\363\316\377\376\377\377\377\377\376\377\377\377\377" \
+ "\377\376\376\377\377\377\377\376\376\376\376\377\377\377\377\377\377" \
+ "\302\377\377\377\1\376\376\376\202\377\377\377\2\376\376\376\377\377" \
+ "\377\204::<\1;;=\202::<\3;;=99;;;=\203\377\377\377\1\376\376\376\202" \
+ "\377\377\377\1\376\376\376\377\377\377\377\213\377\377\377\2SSU;;=\202" \
+ "::<\2;;=99;\204::<\1\315\315\315\203\377\377\377\1\376\376\376\377\377" \
+ "\377\377\271\377\377\377\10\376\376\376\377\377\377\233\316W\214\305" \
+ "@\212\306@\216\306=\214\305@\215\305@\230\214\306>\17\214\306<\215\306" \
+ "C\211\306=\213\307A\214\304\77\212\306@\214\305B\234\313W\376\377\375" \
+ "\377\377\377\376\377\375\377\377\375\376\377\377\376\376\377\376\377" \
+ "\375\377\377\377\377\302\377\377\377\1\376\376\376\202\377\377\377\4" \
+ "\376\376\376\377\377\377\376\376\376;;=\206::<\202;;=\3::<\377\377\377" \
+ "\376\376\376\203\377\377\377\3\376\376\376\377\377\377\376\376\376\377" \
+ "\377\377\377\212\377\377\377\3::<99;;;=\202::<\10;;=::<;;=99;;;=\363" \
+ "\363\363\377\377\377\376\376\376\377\377\377\377\274\377\377\377\7\323" \
+ "\354\265\214\305@\215\307\77\215\306A\216\305C\213\304\77\212\307<\230" \
+ "\214\306>\20\215\307\77\215\304B\214\305@\214\306>\215\305>\215\307=" \
+ "\212\307<\215\307\77\323\351\270\377\376\377\377\377\377\376\376\376" \
+ "\376\377\375\376\376\376\376\377\377\377\376\374\377\377\377\377\302" \
+ "\377\377\377\202\376\376\376\202\377\377\377\2\376\376\376FFH\210::<" \
+ "\2;;=\316\316\316\202\377\377\377\1\376\376\376\377\377\377\377\215\377" \
+ "\377\377\1\376\376\376\202;;=\4""99;;;=::<;;=\202::<\2;;=::<\377\377" \
+ "\377\377\277\377\377\377\7\231\316X\220\304>\214\305@\215\307\77\214" \
+ "\306<\214\311>\214\305@\231\214\306>\11\215\304B\214\306>\215\306A\214" \
+ "\306<\215\306A\214\305B\215\307\77\234\315X\375\377\374\204\377\377\377" \
+ "\2\376\377\377\377\376\377\377\377\377\377\304\377\377\377\202\376\376" \
+ "\376\4\377\377\377jjl::<99;\202;;=\205::<\7\316\316\316\377\377\377\376" \
+ "\376\376\377\377\377\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\377\212\377\377\377\6\363\363\363::<99;;;=::<;;=\202::<\1;;=\202::<" \
+ "\377\377\377\377\276\377\377\377\2\342\361\320\214\306<\202\215\305>" \
+ "\4\212\307>\215\307=\211\306=\215\305>\230\214\306>\2\213\310=\214\306" \
+ "<\202\214\305@\7\215\306A\214\306>\215\307=\214\304\77\211\310<\343\362" \
+ "\321\377\377\375\202\377\376\377\2\377\377\375\376\376\376\377\377\377" \
+ "\377\310\377\377\377\4kkm::<;;=::<\202;;=\202::<\3;;=::<\316\316\316" \
+ "\202\377\377\377\1\376\376\376\377\377\377\377\215\377\377\377\3\316" \
+ "\316\316::<;;=\202::<\1;;=\204::<\1__a\202\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377\377\271\377\377\377\4\270\333\207" \
+ "\214\306>\214\305@\214\306>\203\214\305@\1\215\305>\230\214\306>\17\215" \
+ "\306A\213\310=\212\307<\214\306>\214\306<\215\306A\214\306>\214\305@" \
+ "\213\306E\267\332\206\377\377\375\376\377\377\377\377\375\377\377\377" \
+ "\377\377\375\377\377\377\377\303\377\377\377\1\376\376\376\204\377\377" \
+ "\377\6lln;;=::<99;::<;;=\204::<\1\250\250\250\204\377\377\377\1\376\376" \
+ "\376\377\377\377\377\213\377\377\377\1\316\316\316\203::<\1;;=\205::" \
+ "<\1lln\203\377\377\377\1\376\376\376\377\377\377\377\272\377\377\377" \
+ "\10\232\315V\215\305@\212\306@\215\305>\214\306<\215\304D\215\305<\212" \
+ "\306@\230\214\306>\3\217\304@\214\306<\215\306A\202\215\305@\7\214\306" \
+ ">\214\305@\212\307>\215\305<\233\316W\376\376\377\376\377\375\203\377" \
+ "\377\377\1\376\377\377\377\377\377\377\305\377\377\377\3\376\376\376" \
+ "\377\377\377\234\234\236\203::<\2;;=99;\204::<\1\234\234\234\202\377" \
+ "\377\377\1\376\376\376\377\377\377\377\215\377\377\377\5\316\316\320" \
+ "::<;;=::<;;=\202::<\1;;=\202::<\1kkm\377\377\377\377\266\377\377\377" \
+ "\10\375\377\374\376\377\377\376\376\376\377\377\375\377\377\377\376\377" \
+ "\377\377\377\375\360\371\350\250\214\306>\4\214\305@\212\307>\360\371" \
+ "\346\376\377\375\202\377\377\377\1\377\377\375\377\377\377\377\304\377" \
+ "\377\377\1\376\376\376\203\377\377\377\1\234\234\234\211::<\1\234\234" \
+ "\234\205\377\377\377\1\376\376\376\377\377\377\377\212\377\377\377\4" \
+ "\316\316\320llnkkmlln\203kkm\1jjl\202kkm\1\221\221\223\377\377\377\377" \
+ "\270\377\377\377\1\377\376\377\202\377\377\377\3\375\376\377\377\377" \
+ "\375\341\361\315\251\214\306>\2\215\307\77\342\360\314\377\377\377\377" \
+ "\310\377\377\377\202\376\376\376\202\377\377\377\2\266\266\266kkk\210" \
+ "kkm\1\265\265\265\206\377\377\377\1\376\376\376\377\377\377\377\211\377" \
+ "\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376" \
+ "\377\377\377\377\264\377\377\377\1\377\376\377\205\377\377\377\2\375" \
+ "\377\374\310\340\246\252\214\306>\1\310\340\246\377\377\377\377\307\377" \
+ "\377\377\1\376\376\376\202\377\377\377\3\375\375\375\377\377\377\376" \
+ "\376\376\211\377\377\377\7\376\376\376\377\377\377\376\376\376\377\377" \
+ "\377\376\376\376\377\377\377\376\376\376\377\377\377\377\213\377\377" \
+ "\377\1\376\376\376\204\377\377\377\1\376\376\376\206\377\377\377\1\376" \
+ "\376\376\377\377\377\377\263\377\377\377\1\377\376\377\204\377\377\377" \
+ "\3\376\376\377\376\377\375\304\342\234\251\214\306>\7\215\305@\305\343" \
+ "\235\376\376\377\377\377\377\376\376\377\377\376\377\377\377\375\377" \
+ "\377\377\377\306\377\377\377\1\376\376\376\217\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\377\377\377\377\214\377\377\377\5\376\376" \
+ "\376\377\377\377\376\376\376\377\377\377\376\376\376\203\377\377\377" \
+ "\1\376\376\376\377\377\377\377\267\377\377\377\1\377\377\375\202\377" \
+ "\377\377\3\377\376\377\376\377\375\305\342\237\251\214\306>\3\215\305" \
+ "@\303\344\235\376\376\376\202\377\377\377\1\377\376\377\377\377\377\377" \
+ "\305\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\214\377" \
+ "\377\377\1\376\376\376\377\377\377\377\216\377\377\377\1\376\376\376" \
+ "\203\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376\377\377" \
+ "\377\377\266\377\377\377\5\376\377\377\376\376\377\377\376\377\377\377" \
+ "\377\305\342\242\251\214\306>\4\215\306A\302\341\236\377\377\375\376" \
+ "\376\376\377\377\377\377\305\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\376\376\376\214\377\377\377\1\376\376\376\377\377\377\377\231\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377\264\377" \
+ "\377\377\2\376\376\376\377\376\377\202\376\377\377\202\377\377\377\1" \
+ "\305\342\240\251\214\306>\7\214\305@\306\343\240\377\376\374\377\377" \
+ "\377\376\377\377\377\377\377\376\376\376\377\377\377\377\325\377\377" \
+ "\377\1\376\376\376\377\377\377\377\222\377\377\377\1\376\376\376\205" \
+ "\377\377\377\1\376\376\376\377\377\377\377\265\377\377\377\4\377\377" \
+ "\375\377\376\377\375\377\376\376\377\375\202\377\377\377\1\305\343\235" \
+ "\251\214\306>\4\213\310\77\306\341\234\377\376\377\377\377\377\202\376" \
+ "\377\375\377\377\377\377\311\377\377\377\1\377\377\375\215\377\377\377" \
+ "\1\376\376\376\377\377\377\377\377\377\377\377\314\377\377\377\3\377" \
+ "\377\375\377\377\377\376\377\375\203\377\377\377\11\376\377\377\345\360" \
+ "\320\214\305@\214\306>\214\305@\214\304\77\214\306<\215\305>\212\307" \
+ ">\231\214\306>\1\214\305@\202\215\307\77\205\214\306>\5\212\307>\214" \
+ "\306>\342\360\315\377\377\377\376\376\376\202\377\377\377\1\377\377\375" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\244" \
+ "\377\377\377\3\377\376\377\377\377\377\376\377\375\203\377\377\377\11" \
+ "\376\377\377\362\371\347\214\306>\214\305B\215\310<\215\306A\214\305" \
+ "@\215\307\77\214\305@\231\214\306>\4\215\307\77\213\305=\214\306>\215" \
+ "\307\77\202\214\306>\5\215\307\77\214\306>\216\306\77\215\306A\360\367" \
+ "\345\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\251\377\377\377\2\377\376\377\377\377\375\203\377\377\377\13\377\377" \
+ "\375\377\377\377\375\377\374\233\316W\214\305@\213\304\77\212\306@\215" \
+ "\307\77\214\305@\215\306A\214\305@\230\214\306>\3\215\307\77\214\306" \
+ ">\215\306A\203\214\305@\7\215\306A\214\305@\215\304B\232\315T\377\377" \
+ "\375\376\377\377\377\377\375\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\250\377\377\377\1\377\377\375\205\377\377\377" \
+ "\11\377\376\377\267\333\204\213\307A\213\307C\215\307\77\213\304\77\215" \
+ "\307\77\215\305<\212\306@\231\214\306>\1\215\307\77\203\214\305@\202" \
+ "\214\306>\7\215\307\77\212\306@\267\333\204\377\376\377\376\377\377\377" \
+ "\377\375\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\247\377\377\377\17\377\377\375\377\377\377\377\377\375" \
+ "\376\376\376\377\377\377\377\377\375\376\376\377\334\354\305\211\306" \
+ "=\213\307A\213\305;\215\306A\214\306<\215\305>\213\307A\232\214\306>" \
+ "\202\214\305@\11\214\306>\214\306<\214\306>\215\307\77\212\311=\333\355" \
+ "\305\377\376\377\377\377\377\376\376\376\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\252\377\377\377\3\377\377\375\377" \
+ "\377\377\377\376\377\203\377\377\375\7\233\314V\215\307\77\215\305>\214" \
+ "\306>\215\307\77\214\305@\212\307>\232\214\306>\14\214\305@\214\306>" \
+ "\214\306<\215\307=\215\307\77\214\305@\232\315V\374\377\373\376\376\377" \
+ "\377\377\375\377\377\377\376\376\376\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\255\377\377\377\10\377\377\375\377\376" \
+ "\377\324\353\267\214\304\77\215\305>\214\305@\212\307<\214\305@\232\214" \
+ "\306>\2\215\307\77\215\306A\202\214\306>\4\215\307\77\213\304\77\215" \
+ "\306E\316\346\254\202\377\377\377\3\377\377\375\376\376\377\376\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\247" \
+ "\377\377\377\1\376\376\376\206\377\377\377\10\377\377\373\375\376\377" \
+ "\232\315W\214\306>\215\307=\211\307>\215\306A\215\305>\232\214\306>\1" \
+ "\214\305@\202\215\307\77\13\214\305@\215\306E\227\317P\377\377\377\377" \
+ "\377\375\376\377\377\377\377\377\377\377\375\375\377\376\377\377\377" \
+ "\377\377\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\254\377\377\377\20\376\377\377\377\375\377\331\356\303\215\305" \
+ "@\213\310\77\215\305>\216\306\77\213\307A\215\306A\214\306<\214\306>" \
+ "\216\306\77\213\304\77\212\307<\214\306>\215\305@\210\214\306>\1\214" \
+ "\305@\202\215\307\77\205\214\306>\10\214\305@\212\307>\215\305>\214\305" \
+ "@\215\305>\214\305@\215\305>\331\356\305\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\264\377\377\377\20\376\376\374\377" \
+ "\377\375\376\376\374\261\330{\214\306>\216\306A\214\306>\213\307A\215" \
+ "\305>\215\306A\215\307\77\213\304A\215\307\77\214\305@\214\306<\216\306" \
+ "A\210\214\306>\4\215\307\77\213\305=\214\306>\215\307\77\202\214\306" \
+ ">\12\215\307\77\214\306>\212\307>\220\305\77\212\307>\214\306>\213\310" \
+ "=\214\306<\262\327z\376\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\265\377\377\377\17\374\377\377\377\377\377\370" \
+ "\373\362\241\321d\211\310<\215\305>\215\305@\216\306=\214\305@\214\306" \
+ ">\215\307\77\214\306>\212\307<\212\306@\212\307<\210\214\306>\3\215\307" \
+ "\77\214\306>\215\306A\203\214\305@\12\215\306A\214\305@\215\305>\212" \
+ "\307>\213\307A\216\305C\215\307=\242\322e\371\372\364\375\377\376\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\264\377" \
+ "\377\377\1\375\377\374\203\377\377\377\4\352\364\333\223\311O\212\306" \
+ "@\215\305@\202\213\310\77\202\214\306>\4\216\307F\213\305=\215\307\77" \
+ "\215\305@\211\214\306>\1\215\307\77\203\214\305@\202\214\306>\1\215\307" \
+ "\77\202\214\305@\6\216\305C\215\307\77\225\311K\351\363\332\377\377\377" \
+ "\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\265\377\377\377\17\377\375\376\377\376\377\377\377\377\377\377" \
+ "\375\352\365\327\223\313L\212\307<\215\305>\214\305@\215\307=\214\305" \
+ "@\214\306<\213\310\77\213\304\77\220\305A\212\214\306>\202\214\305@\12" \
+ "\214\306>\214\306<\214\306>\215\307\77\214\306>\213\310=\215\307=\225" \
+ "\311K\347\365\334\377\377\375\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\267\377\377\377\1\377\377\375\202\377\377\377" \
+ "\13\377\376\377\376\377\377\353\363\334\245\320d\214\305B\214\305@\215" \
+ "\306A\213\305=\214\306>\213\307A\213\310=\213\214\306>\5\214\305@\214" \
+ "\306>\214\306<\215\307=\215\307\77\202\214\305@\5\214\306<\242\322e\351" \
+ "\363\332\377\377\375\376\376\376\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\267\377\377\377\1\376\376\374\202\377\377" \
+ "\375\6\376\377\377\377\376\377\377\377\375\371\372\364\255\330|\217\304" \
+ ">\202\212\306@\2\215\306A\214\303A\202\214\305@\211\214\306>\2\215\307" \
+ "\77\215\306A\202\214\306>\6\215\307\77\213\304\77\215\306E\215\305>\262" \
+ "\327z\371\372\364\203\377\377\377\2\376\377\377\377\377\375\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\264\377\377\377" \
+ "\1\376\376\376\202\377\377\377\2\377\377\375\377\376\377\203\377\377" \
+ "\377\6\377\377\375\331\356\303\233\314W\215\310<\214\305@\215\307\77" \
+ "\214\214\306>\1\214\305@\202\215\307\77\7\214\305@\215\306E\227\317P" \
+ "\331\356\305\376\377\377\375\377\376\376\377\377\202\377\377\377\2\377" \
+ "\377\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\274\377\377\377\10\377\377\375\377\376\377\365\375\362" \
+ "\307\342\237\234\315Z\212\306@\212\307>\214\305@\202\215\307\77\16\214" \
+ "\306>\215\307\77\214\306>\215\306A\214\306>\213\310\77\214\306>\215\305" \
+ "<\216\306A\213\310\77\212\307>\232\315T\307\341\242\370\373\362\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\304\377\377" \
+ "\377\1\377\377\375\202\377\377\377\10\377\376\377\376\376\374\335\354" \
+ "\303\270\333\207\222\311J\214\305@\215\306A\213\305=\202\214\306>\13" \
+ "\215\307\77\216\306\77\215\305>\212\306@\212\307>\226\312K\270\333\211" \
+ "\334\354\307\376\377\377\376\376\376\377\377\375\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\306\377\377\377\2\376\377" \
+ "\375\376\377\377\204\377\377\377\16\350\366\334\332\354\302\311\341\245" \
+ "\306\341\234\305\342\237\304\341\237\305\342\240\305\342\237\334\355" \
+ "\303\352\364\333\377\377\375\377\375\376\377\376\377\377\377\375\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\307\377" \
+ "\377\377\15\376\376\376\377\376\377\377\377\375\377\377\373\376\377\377" \
+ "\376\377\375\376\377\377\377\377\375\377\377\377\376\376\376\376\377" \
+ "\377\376\377\375\377\377\377\202\377\376\377\204\377\377\377\1\376\376" \
+ "\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\307\377\377\377\3\376\377\377\377\377\377\376\376\376\202\377\377\377" \
+ "\1\376\376\376\210\377\377\377\3\375\377\376\376\377\377\377\377\377" \
+ "\203\377\376\377\4\376\377\375\376\377\377\377\377\377\377\376\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\304\377" \
+ "\377\377\10\377\377\375\377\376\377\377\377\373\377\377\377\375\377\376" \
+ "\376\377\377\376\376\376\377\376\377\202\376\377\377\1\377\377\377\202" \
+ "\376\376\376\202\377\377\377\202\376\377\377\5\376\377\375\377\377\377" \
+ "\376\376\374\377\377\377\377\377\375\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\307\377\377\377\1\376\376\377\202\377" \
+ "\377\377\2\377\377\375\376\376\377\202\377\377\377\2\376\377\375\377" \
+ "\377\375\204\377\377\377\202\377\377\375\1\376\377\375\202\376\377\377" \
+ "\202\377\377\375\202\377\377\377\1\377\376\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\310\377\377\377\5\377\377\375" \
+ "\377\376\377\377\377\375\376\376\377\377\376\377\207\377\377\377\202" \
+ "\377\376\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\261\377\377\377" \
+ "\1\376\376\376\210\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\331\377\377\377\1\376\376\376\204\377\377\377\1\376\376\376\257\377" \
+ "\377\377\1\376\376\376\212\377\377\377\1\376\376\376\211\377\377\377" \
+ "\1\376\376\376\221\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\205\377\377\377\1\376\376\376\312\377\377\377\1\376\376\376\214" \
+ "\377\377\377\1\376\376\376\202\377\377\377\6\377\376\375\377\377\377" \
+ "\376\377\377\377\377\377\377\376\377\376\377\377\270\377\377\377\7\376" \
+ "\377\377\377\376\377\376\377\377\377\377\375\377\377\377\377\375\377" \
+ "\377\376\377\273\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\302\377\377\377\1\376\376\376\305\377\377\377\1\376\376\376\241" \
+ "\377\377\377\1\376\376\376\214\377\377\377\1\376\376\376\235\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\252\377\377\377\1\376\376\376" \
+ "\212\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377" \
+ "\1\376\376\376\251\377\377\377\202\376\376\376\215\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376" \
+ "\224\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\232\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\206\377\377\377\1\376\376" \
+ "\376\243\377\377\377\1\376\376\376\204\377\377\377\1\376\376\376\202" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\2" \
+ "\376\376\376\377\377\377\202\377\377\375\3\377\377\377\376\377\377\377" \
+ "\377\375\202\377\376\377\1\377\377\377\270\377\376\377\14\377\377\377" \
+ "\377\376\377\377\376\374\377\377\375\375\376\377\376\377\377\377\377" \
+ "\375\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376\203" \
+ "\377\377\377\1\376\376\376\266\377\377\377\1\376\376\376\203\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\214\377\377\377\202" \
+ "\376\376\376\207\377\377\377\1\376\376\376\272\377\377\377\1\376\376" \
+ "\376\252\377\377\377\202\376\376\376\247\377\377\377\5\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376" \
+ "\376\203\377\377\377\1\376\376\376\311\377\377\377\1\376\376\376\221" \
+ "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\302\377\377" \
+ "\377\1\376\376\376\207\377\377\377\1\346\346\346\204\316\316\316\10\317" \
+ "\317\317\315\315\315\316\316\316\363\363\365\377\377\377\376\376\376" \
+ "\377\377\377\376\376\376\204\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\234\377\377\377\1\376\376\376\262\377\377\377\1\376\376" \
+ "\376\213\377\377\377\1\377\377\375\202\376\377\377\1\376\376\377\202" \
+ "\377\377\377\2\377\376\377\377\377\375\270\276\317\331\1\377\376\377" \
+ "\205\377\377\377\3\376\377\375\377\377\375\376\376\376\257\377\377\377" \
+ "\1\376\376\376\210\377\377\377\202\376\376\376\210\377\377\377\1\376" \
+ "\376\376\220\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376" \
+ "\243\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\207\377\377\377\1\376\376\376\331\377\377\377\12\376" \
+ "\376\376\377\377\377\235\235\235kkmllnkkmllnjjlkkm\346\346\346\202\377" \
+ "\377\377\1\376\376\376\237\377\377\377\2\346\346\346\317\317\317\204" \
+ "\316\316\316\2\317\317\317\346\346\346\234\377\377\377\1\376\376\376" \
+ "\203\377\377\377\1\376\376\376\202\377\377\377\1\332\332\332\203\316" \
+ "\316\316\1\317\317\317\202\316\316\316\213\377\377\377\5\346\346\346" \
+ "\317\317\317\315\315\315\316\316\316\315\315\315\252\316\316\316\1\363" \
+ "\363\363\205\377\377\377\1\376\376\376\212\377\377\377\1\376\376\376" \
+ "\211\377\377\377\4\346\346\346\250\250\250\204\204\206``b\202::<\1;;" \
+ "=\202::<\3;;=99;;;=\203::<\4lln\220\220\222\266\266\266\363\363\363\202" \
+ "\376\376\376\240\377\377\377\1\346\346\346\202\316\316\316\10\317\317" \
+ "\317\315\315\315\317\317\317\316\316\316\332\332\332\376\376\376\377" \
+ "\377\377\376\376\376\203\377\377\377\1\376\376\376\241\377\377\377\6" \
+ "\376\376\376\377\377\377\346\346\346\316\316\320\317\317\321\316\316" \
+ "\320\203\316\316\316\2\347\347\347\376\376\376\205\377\377\377\1\376" \
+ "\376\376\202\377\377\375\5\376\377\377\377\377\375\377\377\377\317\334" \
+ "\344\37V\177\270\0>i\12\37U{\317\334\344\377\376\374\377\377\375\376" \
+ "\377\377\377\376\374\376\377\377\376\376\376\377\377\377\363\363\363" \
+ "\202\316\316\316\1\315\315\315\202\317\317\317\251\316\316\316\1\332" \
+ "\332\332\202\377\377\377\1\376\376\376\203\377\377\377\202\376\376\376" \
+ "\204\377\377\377\3\346\346\346\316\316\316\316\316\320\204\316\316\316" \
+ "\2\346\346\346\376\376\376\212\377\377\377\1\347\347\347\206\316\316" \
+ "\316\2\317\317\317\363\363\363\250\377\377\377\2\376\376\376\331\331" \
+ "\331\206\316\316\316\1\332\332\332\202\377\377\377\1\376\376\376\204" \
+ "\377\377\377\1\376\376\376\203\377\377\377\3\332\332\332\316\316\316" \
+ "\316\316\320\250\316\316\316\1\363\363\363\205\377\377\377\1\376\376" \
+ "\376\242\377\377\377\4\346\346\346::<;;=99;\204::<\1\204\204\206\237" \
+ "\377\377\377\1\376\376\376\202\377\377\377\3\235\235\235::<;;=\202::" \
+ "<\3;;=::<\235\235\235\202\377\377\377\1\376\376\376\232\377\377\377\1" \
+ "\376\376\376\205\377\377\377\4kkm;;;99;;;=\202::<\1;;;\213\377\377\377" \
+ "\4\234\234\234:::::<;;=\202::<\1;;;\250::<\1\316\316\316\202\377\377" \
+ "\377\1\376\376\376\203\377\377\377\1\376\376\376\212\377\377\377\203" \
+ "\376\376\376\203\377\377\377\3\346\346\346\250\250\250```\204::<\202" \
+ ";;=\202::<\3;;=::<;;=\203::<\1;;=\202::<\5;;=::<```\265\265\265\362\362" \
+ "\362\203\377\377\377\1\376\376\376\233\377\377\377\1\234\234\236\204" \
+ "::<\5""99;;;=::<\333\333\335\376\376\376\203\377\377\377\1\376\376\376" \
+ "\241\377\377\377\4\376\376\376\377\377\377\363\363\363FFH\202::<\1;;" \
+ "=\203::<\1\234\234\234\210\377\377\377\6\376\377\377\377\377\375\375" \
+ "\376\377\356\363\366\40Vz\0\77h\270\0=i\20\0>i\22Ip\356\363\367\376\377" \
+ "\377\377\377\375\377\377\377\376\376\377\377\376\377\377\377\377\315" \
+ "\315\315:::::<;;=::<99;;;;\250::<\1kkm\205\377\377\377\1\376\376\376" \
+ "\203\377\377\377\4\376\376\376\377\377\377\376\376\376\234\234\234\203" \
+ "::<\6;;=::<:::\234\234\234\377\377\377\376\376\376\211\377\377\377\3" \
+ "\332\332\332:::;;=\202::<\202;;=\2::<\204\204\206\250\377\377\377\2\364" \
+ "\364\364FFF\204::<\202:::\1\234\234\234\206\377\377\377\1\376\376\376" \
+ "\204\377\377\377\2kkk;;=\251::<\1\316\316\316\202\377\377\377\1\376\376" \
+ "\376\203\377\377\377\1\376\376\376\240\377\377\377\6\376\376\376\234" \
+ "\234\236::<;;=::<;;=\203::<\2FFH\362\362\362\235\377\377\377\1\376\376" \
+ "\376\203\377\377\377\3\234\234\236::<;;=\202::<\3;;=::<\234\234\236\203" \
+ "\377\377\377\1\376\376\376\233\377\377\377\1\376\376\376\203\377\377" \
+ "\377\7kkm::<;;=::<;;=::<;;=\213\377\377\377\4\235\235\235::<;;=99;\202" \
+ ";;=\251::<\1\315\315\315\203\377\377\377\202\376\376\376\213\377\377" \
+ "\377\1\376\376\376\202\377\377\377\6\376\376\376\377\377\377\315\315" \
+ "\315\205\205\205::<;;=\213::<\4;;=::<;;=::<\203;;=\204::<\4FFF\204\204" \
+ "\204\346\346\346\376\376\376\234\377\377\377\3\234\234\236::<;;=\202" \
+ "::<\4;;=99;::<``b\244\377\377\377\1\376\376\376\203\377\377\377\1xxz" \
+ "\202::<\10;;=99;;;=::<;;=\233\233\235\377\377\377\376\376\376\202\377" \
+ "\377\377\1\376\376\376\203\377\377\377\4\375\377\376\377\376\373\377" \
+ "\377\375\235\267\310\202\0>i\271\0=i\4\0\77j\237\266\306\377\376\377" \
+ "\377\375\374\202\376\377\377\4\377\377\377\376\376\376\316\316\31699" \
+ ";\202;;=\2::<;;=\251::<\1kkm\203\377\377\377\1\376\376\376\210\377\377" \
+ "\377\4\235\235\235::<99;;;=\203::<\1\235\235\235\214\377\377\377\2ll" \
+ "n99;\202;;=\1::<\203;;=\2\362\362\364\376\376\376\245\377\377\377\2\376" \
+ "\376\376\250\250\250\204::<\4;;=::<:::\346\346\346\203\377\377\377\1" \
+ "\376\376\376\205\377\377\377\3\376\376\376\377\377\377jjl\252::<\1\315" \
+ "\315\315\203\377\377\377\202\376\376\376\242\377\377\377\3\362\362\364" \
+ "GGI::<\202;;=\2""99;;;=\202::<\2""99;\235\235\235\237\377\377\377\3\376" \
+ "\376\376\377\377\377\235\235\237\202::<\202;;=\202::<\3\235\235\237\377" \
+ "\377\377\376\376\376\233\377\377\377\1\376\376\376\203\377\377\377\4" \
+ "\376\376\376\377\377\377kkm;;=\202::<\5""99;;;=99;\377\377\377\376\376" \
+ "\376\211\377\377\377\1\233\233\233\202::<\3;;=::<99;\251::<\1\317\317" \
+ "\317\205\377\377\377\1\376\376\376\214\377\377\377\3\376\376\376\347" \
+ "\347\347xxz\203::<\1;;=\202::<\1;;=\204::<\1;;=\203::<\1;;=\205::<\1" \
+ ";;=\203::<\1;;=\203::<\2\234\234\236\362\362\362\233\377\377\377\2\233" \
+ "\233\235;;=\204::<\1;;=\202::<\1\234\234\236\245\377\377\377\4\376\376" \
+ "\376\302\302\304::<;;=\206::<\1\235\235\237\202\377\377\377\1\376\376" \
+ "\376\203\377\377\377\7\375\376\377\377\377\377\377\377\375\376\377\377" \
+ "\377\377\377\177\235\265\0\77k\271\0\77j\7\0\77k\0\77j~\236\265\377\376" \
+ "\377\376\377\377\375\377\374\377\377\375\202\377\377\377\5\315\315\315" \
+ ";;=::<99;;;=\252::<\3kkm\377\377\377\376\376\376\203\377\377\377\1\376" \
+ "\376\376\203\377\377\377\1\376\376\376\202\377\377\377\3\233\233\233" \
+ "::<;;=\202::<\3;;=::<\234\234\234\202\377\377\377\1\376\376\376\211\377" \
+ "\377\377\4\264\264\264;;=::<;;=\204::<\3\247\247\251\377\377\377\376" \
+ "\376\376\245\377\377\377\1SSS\203::<\1;;=\202::<\1\204\204\204\213\377" \
+ "\377\377\4\376\376\376lln::<:9>\250::<\1\317\317\317\205\377\377\377" \
+ "\1\376\376\376\241\377\377\377\1\265\265\267\204::<\1;;=\204::<\1FFF" \
+ "\241\377\377\377\2\234\234\236;;=\204::<\2;;=\234\234\236\234\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\204\377\377\377\1kkm\203:" \
+ ":<\4;;=::<;;=\376\376\376\212\377\377\377\1\234\234\234\204::<\1;;=\251" \
+ "::<\1\316\316\316\203\377\377\377\202\376\376\376\215\377\377\377\4\234" \
+ "\234\234;;=::<;;=\202::<\1""99;\204::<\1;;=\203::<\1;;=\211::<\1""99" \
+ ";\207::<\2FFF\301\301\301\232\377\377\377\2\234\234\23699;\210::<\1\333" \
+ "\333\333\241\377\377\377\6\376\376\376\377\377\377\376\376\376\363\363" \
+ "\363FFH;;=\205::<\3;;=::<\234\234\236\206\377\377\377\7\377\376\377\377" \
+ "\377\377\377\377\375\375\376\377\377\376\377\201\235\263\0>g\272\0>i" \
+ "\13\0>e\177\236\263\377\375\374\377\377\377\377\377\375\376\376\376\377" \
+ "\376\377\377\377\377\316\316\316::<;;=\202::<\2""99;;;=\250::<\1kkm\204" \
+ "\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\202\377\377\377\2\376\376\376\234\234\234\206::<\1\234\234\234\215" \
+ "\377\377\377\2RRT;;=\205::<\1SSU\246\377\377\377\2\316\316\316999\206" \
+ "::<\1\316\316\316\202\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\207\377\377\377\3jjl::<:9>\250::<\1\316\316\316\203\377\377\377\202" \
+ "\376\376\376\242\377\377\377\2SSU99;\202;;=\204::<\4;;=99;::<\264\264" \
+ "\266\240\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377" \
+ "\1kkm\206::<\213\377\377\377\2\234\234\236;;=\216::<\4""99;;;=::<;;=" \
+ "\206::<\3;;=::<;;=\222::<\1\316\316\316\205\377\377\377\1\376\376\376" \
+ "\207\377\377\377\1\376\376\376\202\377\377\377\2\346\346\350__a\202:" \
+ ":<\3;;=::<;;=\204::<\1;;=\202::<\3;;=::<;;=\203::<\1;;=\202::<\2""99" \
+ ";;;=\202::<\1;;=\204::<\7;;=::<;;=::<;;=\204\204\206\363\363\363\203" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\222\377\377\377\4" \
+ "\234\234\236::<;;=99;\204::<\3;;=::<__a\244\377\377\377\1xxx\205::<\1" \
+ ";;=\203::<\1\234\234\236\213\377\377\377\3\177\236\263\0=i\0>i\211\0" \
+ "=i\2\0>j\0=i\202\1>j\2\0\77k\0>j\232\0>i\2\0>j\0\77k\202\1>j\2\0=i\0" \
+ ">j\211\0=i\3\0>i\0=i\177\236\263\206\377\377\377\6\316\316\316:::::<" \
+ ";;=::<;;=\217::<\1;;=\203::<\1;;=\202::<\1;;=\222::<\1kkk\205\377\377" \
+ "\377\1\376\376\376\206\377\377\377\1\234\234\236\206::<\1\234\234\236" \
+ "\215\377\377\377\3\234\234\234;;=::<\202;;=\203::<\3\316\316\320\377" \
+ "\377\377\376\376\376\240\377\377\377\1\376\376\376\202\377\377\377\3" \
+ "xxz::<;;=\202::<\3;;=::<__a\215\377\377\377\1kkm\204::<\1;;=\202::<\1" \
+ ";;=\242::<\1\316\316\316\205\377\377\377\1\376\376\376\240\377\377\377" \
+ "\1\265\265\265\202::<\5;;=::<;;=::<;;=\204::<\2TTV\376\376\376\237\377" \
+ "\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206" \
+ "::<\213\377\377\377\3\234\234\23499;;;=\214::<\1""99;\207::<\1;;=\227" \
+ "::<\1\316\316\316\204\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\203\377\377\377\1\376\376\376\204\377\377\377\2\333\333\335FFH\214:" \
+ ":<\16``b\221\221\223\251\251\251\315\315\315\316\316\316\363\363\363" \
+ "\377\377\377\332\332\332\316\316\316\301\301\301\235\235\237jjlFFH;;" \
+ "=\207::<\1;;=\202::<\3;;=__a\363\363\363\227\377\377\377\4\234\234\236" \
+ "99;::<;;=\205::<\3;;=::<\233\233\233\240\377\377\377\12\376\376\376\377" \
+ "\377\377\301\301\301;;=::<;;=::<;;=::<99;\203::<\1\234\234\236\213\377" \
+ "\377\377\3\177\236\263\0=i\0>i\211\0=i\7\1>j\0=i\1>j\0=i\0>g\3>h\2=g" \
+ "\230\0=i\7\2=g\3>h\0>g\0=i\1>j\0=i\1>j\211\0=i\3\0>i\0=i\177\236\263" \
+ "\206\377\377\377\2\317\317\317:::\221::<\202;;=\202::<\3;;=::<99;\203" \
+ "::<\2;;=99;\220::<\1kkk\214\377\377\377\1\234\234\236\206::<\1\234\234" \
+ "\236\213\377\377\377\3\376\376\376\377\377\377\363\363\363\204::<\4;" \
+ ";=::<;;=xxz\202\377\377\377\1\376\376\376\236\377\377\377\1\376\376\376" \
+ "\202\377\377\377\3\346\346\346::<;;=\202::<\4;;=99;;;=\266\266\270\215" \
+ "\377\377\377\1kkm\203::<\1;;=\202::<\1;;=\243::<\1\316\316\316\204\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\232\377\377\377\1\376" \
+ "\376\376\204\377\377\377\1kkm\202;;=\202::<\202;;=\2::<;;=\204::<\3\317" \
+ "\317\317\377\377\377\376\376\376\235\377\377\377\1\234\234\234\206::" \
+ "<\1\234\234\234\243\377\377\377\1kkm\206::<\212\377\377\377\1\376\376" \
+ "\376\224\377\377\377\1lln\203::<\1;;=\202::<\1\234\234\236\234\377\377" \
+ "\377\1\376\376\376\204\377\377\377\4\376\376\376\265\265\267::<;;=\202" \
+ "::<\1;;=\202::<\1;;=\203::<\5__a\266\266\270\363\363\363\377\377\377" \
+ "\376\376\376\204\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\202\377\377\377\4\301\301\303\204\204\206;;=::<\203;;=\202::<\2" \
+ ";;=::<\202;;=\3GGI\332\332\334\376\376\376\203\377\377\377\1\376\376" \
+ "\376\221\377\377\377\2\235\235\237::<\202;;=\202::<\1;;=\202::<\4""9" \
+ "9;::<;;=\331\331\331\240\377\377\377\2\363\363\363GGI\203::<\2;;=::<" \
+ "\203;;=\202::<\1\234\234\236\213\377\377\377\3\177\236\263\0=i\0>i\210" \
+ "\0=i\10\0\77k\0=i\1>j\0>i\0\77j\0=i\0>i\0>j\230\0>i\10\0>j\0>i\0=i\0" \
+ "\77j\0>i\1>j\0=i\0\77k\210\0=i\3\0>i\0=i\177\236\263\206\377\377\377" \
+ "\1\376\376\376\217\377\377\377\1\376\376\376\203\377\377\377\1\315\315" \
+ "\317\204::<\3;;=::<kkm\240\377\377\377\1\234\234\236\206::<\1\234\234" \
+ "\236\214\377\377\377\3\376\376\376\377\377\377\204\204\206\202::<\1;" \
+ ";=\202::<\202;;=\1\345\345\345\242\377\377\377\2\376\376\376\234\234" \
+ "\234\206::<\2GGI\363\363\363\215\377\377\377\1kkm\203::<\4""99;::<;;" \
+ "=\316\316\320\311\377\377\377\2\317\317\32199;\203::<\5;;=::<FFH;;=:" \
+ ":<\202;;=\202::<\1kkm\237\377\377\377\1\234\234\234\206::<\1\234\234" \
+ "\234\243\377\377\377\1kkm\206::<\213\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\216\377\377\377\1\376\376\376\202\377\377\377\5lln:" \
+ ":<;;=::<;;=\202::<\2\234\234\234\376\376\376\227\377\377\377\1\376\376" \
+ "\376\210\377\377\377\1\264\264\266\202;;=\4::<;;=::<99;\204::<\3jjl\317" \
+ "\317\321\376\376\376\202\377\377\377\1\375\375\375\203\377\377\377\3" \
+ "\376\376\376\377\377\377\376\376\376\204\377\377\377\1\376\376\376\203" \
+ "\377\377\377\3\363\363\365\234\234\236FFH\202::<\1;;=\202::<\1;;=\203" \
+ "::<\2FFH\332\332\334\225\377\377\377\1\233\233\235\202;;=\211::<\1__" \
+ "a\240\377\377\377\2xxz;;=\202::<\3;;=::<;;=\205::<\1\234\234\236\213" \
+ "\377\377\377\3\177\236\263\0=i\0>i\211\0=i\202\0>i\5\0<h\1>j\0=i\1>j" \
+ "\0>i\230\0=i\5\0>i\1>j\0=i\1>j\0<h\202\0>i\211\0=i\3\0>i\0=i\177\236" \
+ "\263\212\377\377\377\3\376\376\376\377\377\377\376\376\376\212\377\377" \
+ "\377\1\376\376\376\202\377\377\377\10\316\316\320::<;;=::<;;=99;::<j" \
+ "jl\225\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\207\377" \
+ "\377\377\1\234\234\236\206::<\1\234\234\236\216\377\377\377\3\332\332" \
+ "\332;;=99;\202::<\4;;=::<99;\234\234\236\237\377\377\377\1\376\376\376" \
+ "\203\377\377\377\1SSU\202::<\1;;=\203::<\1\221\221\221\216\377\377\377" \
+ "\1kkm\206::<\1\316\316\316\250\377\377\377\1\376\376\376\235\377\377" \
+ "\377\1\376\376\376\202\377\377\377\5xxz::<;;=::<;;=\202::<\3\316\316" \
+ "\320RRT;;=\203::<\4;;=::<\332\332\332\376\376\376\235\377\377\377\1\234" \
+ "\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\214\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\213\377\377\377\1\376\376" \
+ "\376\204\377\377\377\4kkm;;=::<;;=\203::<\1\235\235\235\202\377\377\377" \
+ "\1\376\376\376\221\377\377\377\1\376\376\376\213\377\377\377\4\301\301" \
+ "\301;;=::<;;=\203::<\202;;=\3::<RRT\316\316\316\203\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\204\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\203\377\377\377\1\376\376\376\204\377\377\377" \
+ "\4\346\346\346xxz;;=99;\207::<\4GGI\362\362\362\377\377\377\376\376\376" \
+ "\222\377\377\377\1\234\234\236\206::<\203;;=\202::<\2;;=\233\233\235" \
+ "\236\377\377\377\10\301\301\301::<;;=:9>::<99;::<99;\202;;=\203::<\1" \
+ "\234\234\236\213\377\377\377\3\177\236\263\0=i\0>i\210\0=i\7\2=g\0>i" \
+ "\0>j\0\77j\0=i\0\77j\0=h\232\1>j\7\0=h\0\77j\0=i\0\77j\0>j\0>i\2=g\210" \
+ "\0=i\3\0>i\0=i\177\236\263\213\377\377\377\1\376\376\376\216\377\377" \
+ "\377\1\317\317\321\202::<\6;;=::<;;=::<lln\376\376\376\225\377\377\377" \
+ "\1\376\376\376\203\377\377\377\1\376\376\376\205\377\377\377\1\234\234" \
+ "\236\206::<\1\234\234\236\213\377\377\377\1\376\376\376\203\377\377\377" \
+ "\2kkm;;=\204::<\2;;=GGI\236\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\265\265\267\202::<\6;;=::<;;=::<;;=\345\345\345\216\377\377\377\1" \
+ "kkm\202::<\5;;=99;;;=99;\317\317\317\244\377\377\377\1\376\376\376\241" \
+ "\377\377\377\3\376\376\376\377\377\377\347\347\351\206::<\3``b\377\377" \
+ "\377\234\234\236\202::<\1;;=\202::<\4;;=\204\204\206\377\377\377\376" \
+ "\376\376\234\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377" \
+ "\377\1kkm\206::<\215\377\377\377\1\375\375\375\202\377\377\377\1\376" \
+ "\376\376\213\377\377\377\5\376\376\376\377\377\377\376\376\376lln;;=" \
+ "\203::<\3;;=::<\234\234\234\234\377\377\377\1\376\376\376\202\377\377" \
+ "\377\4\331\331\331FFH::<;;=\202::<\11;;=::<99;;;=\203\203\203\363\363" \
+ "\363\376\376\376\377\377\377\376\376\376\222\377\377\377\7\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377\300\300\300GGI::<\202;;=\205::<" \
+ "\4``b\362\362\362\377\377\377\376\376\376\221\377\377\377\1\234\234\236" \
+ "\204::<\202;;=\203::<\5;;=99;::<;;=\332\332\332\234\377\377\377\4\363" \
+ "\363\363GGI;;=::<\202;;=\203::<\1;;=\202::<\3;;=::<\234\234\236\213\377" \
+ "\377\377\3\177\236\263\0=i\0>i\210\0=i\10\0\77j\0>j\0\77k\0=i\3>h\2=" \
+ "g\1>j\0\77k\230\0=i\10\0\77k\1>j\2=g\3>h\0=i\0\77k\0>j\0\77j\210\0=i" \
+ "\3\0>i\0=i\177\236\263\232\377\377\377\12\316\316\316;;=::<;;=::<;;=" \
+ "::<kkm\377\377\377\376\376\376\222\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\210\377\377\377\1\234\234\236\206::<\1\234\234" \
+ "\236\214\377\377\377\1\376\376\376\202\377\377\377\2\266\266\26699;\202" \
+ "::<\202;;=\202::<\3\266\266\270\377\377\377\376\376\376\234\377\377\377" \
+ "\203\376\376\376\1lln\202;;=\204::<\3xxx\377\377\377\376\376\376\215" \
+ "\377\377\377\1kkm\205::<\2;;=\316\316\316\305\377\377\377\1\376\376\376" \
+ "\202\377\377\377\1\203\203\205\206::<\4\265\265\267\377\377\377\363\363" \
+ "\363GGG\203::<\1;;=\202::<\1\346\346\346\235\377\377\377\1\234\234\234" \
+ "\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\216\377\377\377\1\376" \
+ "\376\376\220\377\377\377\1jjl\206::<\1\234\234\234\202\377\377\377\1" \
+ "\376\376\376\232\377\377\377\3\376\376\376\364\364\364SSU\202::<\7;;" \
+ "=::<;;=99;::<;;=\265\265\265\205\377\377\377\203\376\376\376\214\377" \
+ "\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377\376\376\376" \
+ "\203\377\377\377\7\332\332\332__a::<;;=::<;;=::<\202;;=\3::<\205\205" \
+ "\207\376\376\377\222\377\377\377\3\234\234\236::<;;=\202::<\2;;=99;\202" \
+ ";;=\1""99;\202::<\3;;=::<__a\234\377\377\377\1xxz\202;;=\205::<\1;;=" \
+ "\202::<\1;;=\202::<\1\234\234\236\213\377\377\377\3\177\236\263\0=i\0" \
+ ">i\210\0=i\10\0>i\0=i\0>i\0\77k\0>j\2=g\1\77h\0>l\230\0>i\10\0>l\1\77" \
+ "h\2=g\0>j\0\77k\0>i\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\205\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\221\377\377\377\3\316" \
+ "\316\316::<;;=\204::<\1kkm\225\377\377\377\202\376\376\376\211\377\377" \
+ "\377\1\234\234\236\206::<\1\234\234\236\217\377\377\377\3\376\376\376" \
+ "TTV99;\202::<\4""99;;;=::<kkm\240\377\377\377\1\346\346\346\202::<\1" \
+ "99;\204::<\1\316\316\316\217\377\377\377\1kkm\204::<\3;;=99;\316\316" \
+ "\316\305\377\377\377\7\376\376\376\377\377\377\363\363\363::<;;=::<;" \
+ ";=\202::<\1SSU\203\377\377\377\2\204\204\204;;=\203::<\4;;=99;\222\222" \
+ "\222\376\376\376\234\377\377\377\1\234\234\234\206::<\1\234\234\234\243" \
+ "\377\377\377\1kkm\206::<\214\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\220\377\377\377\1kkm\206::<\1\234\234\236\236\377\377\377\1" \
+ "\204\204\206\203::<\1;;=\202::<\3;;=::<\265\265\267\221\377\377\377\1" \
+ "\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1\376\376" \
+ "\376\204\377\377\377\11\376\376\376\363\363\365__a::<;;=::<;;=::<;;=" \
+ "\202::<\1\301\301\303\222\377\377\377\2\234\234\236;;=\202::<\10;;=:" \
+ ":<;;=FFH::<;;=::<;;=\203::<\1\235\235\237\232\377\377\377\2\301\301\303" \
+ ";;=\205::<\2;;=RRT\204::<\3;;=::<\234\234\236\213\377\377\377\3\177\236" \
+ "\263\0=i\0>i\210\0=i\7\0>j\2=g\0>g\0>j\40V|o\224\256\177\236\262\232" \
+ "\177\236\263\7\177\236\262o\224\256\40V|\0>j\0>g\2=g\0>j\210\0=i\3\0" \
+ ">i\0=i\177\236\263\232\377\377\377\3\316\316\316::<;;=\203::<\2;;=kk" \
+ "m\232\377\377\377\1\376\376\376\205\377\377\377\1\234\234\236\206::<" \
+ "\1\234\234\236\220\377\377\377\2\233\233\235;;=\202::<\1<<>\203::<\1" \
+ "\346\346\346\237\377\377\377\1\204\204\204\206::<\2SSU\376\376\376\217" \
+ "\377\377\377\1kkm\203::<\4;;=::<;;=\316\316\320\304\377\377\377\1\376" \
+ "\376\376\202\377\377\377\2\234\234\236;;=\202::<\4;;=::<;;=\234\234\234" \
+ "\203\377\377\377\1\346\346\346\205::<\3;;=FFH\363\363\365\203\377\377" \
+ "\377\1\376\376\376\230\377\377\377\1\234\234\234\206::<\1\234\234\234" \
+ "\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236" \
+ "\235\377\377\377\2\316\316\316;;=\202::<\6;;=::<;;=::<:::\265\265\265" \
+ "\237\377\377\377\7\376\376\376\363\363\363___::<;;=::<;;=\203::<\2GG" \
+ "I\363\363\363\204\377\377\377\1\376\376\376\214\377\377\377\1\234\234" \
+ "\234\203::<\202;;=\5::<\266\266\266GGI99;;;=\202::<\1;;=\202::<\1\332" \
+ "\332\332\206\377\377\377\1\376\376\376\211\377\377\377\1\376\376\376" \
+ "\207\377\377\377\2\363\363\363FFH\206::<\3FFH\301\301\30399;\202::<\202" \
+ ";;=\2::<\234\234\236\206\377\377\377\7\377\377\375\377\377\377\377\377" \
+ "\375\376\377\377\376\376\376\200\237\263\0\77i\211\0>i\7\0>g\1>j\0>g" \
+ "_\210\236\377\377\377\376\377\377\377\376\377\231\377\377\377\10\377" \
+ "\377\375\376\377\375\377\377\377\377\377\375`\210\242\3>h\0\77j\1\77" \
+ "h\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<" \
+ "\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377\377" \
+ "\377\1\363\363\363\204::<\202;;=\2""99;\205\205\207\207\377\377\377\1" \
+ "\376\376\376\224\377\377\377\4\376\376\376\377\377\377\363\363\363FF" \
+ "H\202::<\5;;=99;;;=::<\265\265\265\220\377\377\377\1kkm\206::<\1\316" \
+ "\316\316\305\377\377\377\5\376\376\376\364\364\364FFH::<;;=\202::<\4" \
+ ";;=FFH\363\363\363\377\377\377\202\376\376\376\6\377\377\377xxz::<;;" \
+ "=::<;;=\202::<\1\234\234\236\206\377\377\377\202\376\376\376\224\377" \
+ "\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206" \
+ "::<\237\377\377\377\1kkm\206::<\1\234\234\236\225\377\377\377\1\376\376" \
+ "\376\207\377\377\377\2SSS;;=\202::<\1;;=\203::<\1\234\234\234\202\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\232\377\377\377\1\376" \
+ "\376\376\202\377\377\377\4\332\332\332FFH::<;;=\202::<\1;;=\202::<\1" \
+ "\222\222\224\205\377\377\377\1\376\376\376\213\377\377\377\3\234\234" \
+ "\234::<;;=\202::<\5""99;;;=\315\315\315\250\250\252;;=\206::<\2``b\376" \
+ "\376\376\202\377\377\377\1\376\376\376\216\377\377\377\1\376\376\376" \
+ "\205\377\377\377\2xxx;;=\202::<\1;;=\203::<\2\300\300\300\317\317\321" \
+ "\203::<\1;;=\202::<\1\234\234\236\207\377\377\377\1\377\376\377\202\377" \
+ "\377\377\4\377\376\377\201\235\263\0=j\3>j\210\0=i\5\1>j\0=j\37V\177" \
+ "\377\376\377\376\376\376\202\377\377\377\1\376\377\377\230\377\377\377" \
+ "\10\376\377\377\377\377\375\374\377\377\377\376\374\376\377\377#W\177" \
+ "\0>g\0\77i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316" \
+ "\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377" \
+ "\377\377\2\376\376\376\204\204\206\205::<\3;;=FFH\362\362\362\204\377" \
+ "\377\377\202\376\376\376\2\377\377\377\376\376\376\224\377\377\377\3" \
+ "\376\376\376\265\265\265;;=\203::<\4;;=99;FFH\363\363\363\220\377\377" \
+ "\377\1kkm\206::<\1\316\316\316\306\377\377\377\4\265\265\26599;;;=::" \
+ "<\202;;=\2""99;\222\222\224\204\377\377\377\12\376\376\376\316\316\320" \
+ ";;=::<;;=99;;;=99;SSU\376\376\376\202\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\226\377\377\377\1\234\234\234\206::<\1\234\234\234\243" \
+ "\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\234" \
+ "\377\377\377\11\234\234\234::<;;=99;;;=99;::<;;=kkm\241\377\377\377\1" \
+ "\376\376\376\202\377\377\377\1\301\301\303\203::<\6;;=99;::<;;=::<\346" \
+ "\346\350\203\377\377\377\1\376\376\376\214\377\377\377\1\234\234\234" \
+ "\203::<\202;;=\10""99;\316\316\316\377\377\377kkm::<;;=::<;;=\203::<" \
+ "\1\235\235\237\203\377\377\377\1\376\376\376\214\377\377\377\1\376\376" \
+ "\376\205\377\377\377\3\302\302\304::<;;=\202::<\7""99;;;=99;xxz\377\377" \
+ "\377\315\315\315;;=\203::<\3:9>::<\234\234\236\206\377\377\377\3\376" \
+ "\377\377\377\377\375\377\377\377\202\377\377\375\3|\237\265\0\77k\0>" \
+ "g\210\0=i\10\0@h\3<i~\236\263\376\377\377\377\377\377\377\376\377\377" \
+ "\376\374\377\376\377\230\377\377\377\10\377\375\377\377\377\375\377\376" \
+ "\374\377\377\377\376\376\374\220\251\275\2=i\0>j\210\0=i\3\0>i\0=i\177" \
+ "\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1" \
+ "\234\234\236\206::<\1\234\234\236\215\377\377\377\1\376\376\376\203\377" \
+ "\377\377\2\332\332\334;;=\206::<\2\266\266\266\376\376\376\202\377\377" \
+ "\377\1\376\376\376\202\377\377\377\1\376\376\376\222\377\377\377\1\376" \
+ "\376\376\203\377\377\377\1SSS\203::<\4""99;::<;;=\221\221\223\221\377" \
+ "\377\377\1kkm\206::<\1\316\316\316\306\377\377\377\4RRT;;=::<;;=\202" \
+ "::<\2;;=\345\345\345\202\377\377\377\1\376\376\376\203\377\377\377\2" \
+ "__a;;=\202::<\1;;=\202::<\1\264\264\264\206\377\377\377\1\376\376\376" \
+ "\224\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1" \
+ "kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\226\377\377\377" \
+ "\1\376\376\376\204\377\377\377\2\363\363\363FFH\203::<\1;;=\202::<\2" \
+ "FFH\346\346\346\204\377\377\377\1\376\376\376\233\377\377\377\1\376\376" \
+ "\376\203\377\377\377\3\376\376\376xxz99;\202::<\1""99;\202::<\4;;=\204" \
+ "\204\206\377\377\377\376\376\376\202\377\377\377\1\376\376\376\213\377" \
+ "\377\377\1\234\234\234\202::<\10;;=99;;;=::<\317\317\317\376\376\376" \
+ "\363\363\363GGI\203::<\1;;=\203::<\3\331\331\331\377\377\377\376\376" \
+ "\376\202\377\377\377\1\376\376\376\217\377\377\377\5\363\363\363GGI;" \
+ ";=::<;;=\202::<\7""99;FFH\363\363\363\377\377\377\316\316\316::<;;=\202" \
+ "::<\3:9>::<\234\234\236\207\377\377\377\7\376\377\377\376\376\376\377" \
+ "\377\377\377\377\375\377\377\377\377\375\374\376\377\377\210\377\377" \
+ "\377\10\376\376\374\376\377\377\354\364\366\377\377\375\376\377\377\377" \
+ "\376\374\377\377\375\376\377\377\230\377\377\377\10\377\377\375\376\377" \
+ "\377\377\376\375\375\376\377\376\377\377\301\317\330\0>g\0>j\210\0=i" \
+ "\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240" \
+ "\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377\377\377\5\376" \
+ "\376\376\377\377\377kkm::<;;=\202::<\3""99;::<^^`\204\377\377\377\1\376" \
+ "\376\376\227\377\377\377\1\316\316\316\202::<\203;;=\202::<\1\347\347" \
+ "\347\221\377\377\377\1kkm\206::<\1\316\316\316\303\377\377\377\12\376" \
+ "\376\376\377\377\377\301\301\301;;=::<;;=::<99;::<\204\204\206\204\377" \
+ "\377\377\4\376\376\376\377\377\377\376\376\376\266\266\266\202::<\5;" \
+ ";=::<;;=::<``b\203\377\377\377\1\376\376\376\227\377\377\377\1\234\234" \
+ "\234\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377" \
+ "\1kkm\206::<\1\234\234\236\233\377\377\377\1\265\265\267\204::<\4""9" \
+ "9;;;=::<\234\234\234\203\377\377\377\3\376\376\376\377\377\377\376\376" \
+ "\376\231\377\377\377\5\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\376\376\376\202\377\377\377\5\363\363\363GGI99;::<;;=\202::<\3;;=::" \
+ "<\346\346\346\204\377\377\377\1\376\376\376\212\377\377\377\3\234\234" \
+ "\234::<99;\202;;=\202::<\1\315\315\315\202\377\377\377\3\301\301\303" \
+ ";;=99;\202;;=\5::<;;=::<``b\376\376\376\202\377\377\377\1\376\376\376" \
+ "\215\377\377\377\6\376\376\376\377\377\377\376\376\376xxz::<;;=\203:" \
+ ":<\202;;=\1\300\300\302\202\377\377\377\3\316\316\316;;=99;\202::<\3" \
+ ";:\77::<\234\234\236\206\377\377\377\2\377\377\375\376\377\375\202\376" \
+ "\377\377\4\377\377\375\377\377\377\377\376\377\377\377\375\211\377\377" \
+ "\377\1\376\376\374\202\377\377\377\3\377\376\377\377\377\377\375\376" \
+ "\377\231\377\377\377\202\376\377\377\5\377\376\377\376\377\377\377\377" \
+ "\375\277\320\332\0\77j\211\0=i\3\0>i\0=i\177\236\263\232\377\377\377" \
+ "\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234" \
+ "\234\236\213\377\377\377\3\376\376\376\377\377\377\376\376\376\204\377" \
+ "\377\377\1\265\265\265\202::<\1;;=\204::<\1\315\315\317\204\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\220\377\377\377\1\376\376" \
+ "\376\202\377\377\377\3\204\204\204::<;;=\204::<\2yy{\376\376\376\221" \
+ "\377\377\377\1kkm\206::<\1\316\316\316\305\377\377\377\4kkm;;=::<;;=" \
+ "\203::<\1\316\316\316\210\377\377\377\1TTV\206::<\2\317\317\321\376\376" \
+ "\376\231\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377" \
+ "\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\233\377\377\377" \
+ "\1TTV\202::<\7;;=::<;;=::<RRT\377\377\377\376\376\376\203\377\377\377" \
+ "\1\376\376\376\233\377\377\377\1\376\376\376\206\377\377\377\2\233\233" \
+ "\235;;=\203::<\4;;=::<;;=\234\234\234\217\377\377\377\4\234\234\234:" \
+ ":<;;=99;\203::<\1\316\316\316\203\377\377\377\4xxz;;=::<99;\202::<\3" \
+ ";;=::<\234\234\236\216\377\377\377\1\376\376\376\202\377\377\377\16\376" \
+ "\376\376\302\302\304::<;;=::<;;=::<;;=::<\221\221\223\377\377\377\376" \
+ "\376\376\377\377\377\316\316\316\202::<\202;;=\202::<\1\234\234\236\206" \
+ "\377\377\377\2\377\376\377\377\377\377\202\377\376\377\4\376\376\376" \
+ "\353\366\374\327\355\370\323\356\371\210\326\356\372\7\325\354\372\327" \
+ "\355\372\365\372\376\376\376\376\377\377\377\376\377\377\377\377\373" \
+ "\231\377\377\377\2\377\376\377\376\377\375\202\377\377\377\4\374\377" \
+ "\377\300\316\327\0=i\1\77h\210\0=i\3\0>i\0=i\177\236\263\232\377\377" \
+ "\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1" \
+ "\234\234\236\221\377\377\377\4\376\376\376\377\377\377SSU;;=\202::<\4" \
+ ";;=99;;;=\204\204\206\203\377\377\377\1\376\376\376\226\377\377\377\11" \
+ "\363\363\36399;;;=::<;;=::<;;=::<\316\316\316\202\377\377\377\1\376\376" \
+ "\376\217\377\377\377\1kkm\206::<\1\316\316\316\304\377\377\377\1\316" \
+ "\316\316\206::<\1kkk\211\377\377\377\2\235\235\23599;\202;;=\6::<;;=" \
+ "::<kkm\377\377\377\376\376\376\203\377\377\377\1\376\376\376\224\377" \
+ "\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206" \
+ "::<\237\377\377\377\1kkm\206::<\1\234\234\236\232\377\377\377\1\332\332" \
+ "\332\204::<\1;;=\202::<\4\266\266\270\376\376\376\377\377\377\376\376" \
+ "\376\240\377\377\377\1\376\376\376\204\377\377\377\2\363\363\363FFH\202" \
+ "::<\5;;=::<;;=::<SSS\217\377\377\377\2\235\235\23599;\205::<\11\316\316" \
+ "\316\377\377\377\376\376\376\377\377\377\363\363\363FFH::<;;=99;\203" \
+ ";;=\2::<\331\331\333\220\377\377\377\2\363\363\363FFH\202::<\6;;=::<" \
+ ";;=::<TTV\364\364\364\203\377\377\377\3\316\316\316<<>99;\202::<\3;;" \
+ "=::<\234\234\236\211\377\377\377\4\377\375\376\376\377\377\254\334\363" \
+ "Z\266\347\211[\267\350\6\\\266\350X\267\347\326\354\367\377\376\377\376" \
+ "\377\377\377\377\375\232\377\377\377\3\377\377\373\375\377\376\376\377" \
+ "\377\202\377\377\375\3\276\320\336\0>g\0>i\210\0=i\3\0>i\0=i\177\236" \
+ "\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234" \
+ "\234\236\206::<\1\234\234\236\223\377\377\377\1\235\235\237\204::<\4" \
+ "<<>::<;;=\363\363\363\206\377\377\377\1\376\376\376\222\377\377\377\2" \
+ "\234\234\234;;=\205::<\1SSU\204\377\377\377\1\376\376\376\216\377\377" \
+ "\377\1kkm\206::<\1\316\316\316\304\377\377\377\1\204\204\204\203::<\1" \
+ "99;\202::<\1\265\265\265\211\377\377\377\2\363\363\363FFH\205::<\2;;" \
+ "=\346\346\346\231\377\377\377\1\234\234\234\206::<\1\234\234\234\243" \
+ "\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\232" \
+ "\377\377\377\1\222\222\222\202::<\1;;=\202::<\3;;=FFH\362\362\364\251" \
+ "\377\377\377\1\235\235\235\203::<\7;;=::<;;=;;;\331\331\331\377\377\377" \
+ "\376\376\376\214\377\377\377\2\234\234\234;;=\205::<\1\316\316\316\202" \
+ "\377\377\377\3\376\376\376\377\377\377\301\301\301\205::<\4;;=::<__a" \
+ "\376\376\376\216\377\377\377\4\376\376\376yyy::<;;=\205::<\1\316\316" \
+ "\320\204\377\377\377\2\316\316\31699;\203::<\3""99;::<\234\234\236\207" \
+ "\377\377\377\2\376\377\377\376\376\374\202\377\376\377\3\254\332\362" \
+ "Y\267\352[\267\350\210Y\270\350\7[\267\350Y\267\352\326\356\370\376\376" \
+ "\377\377\376\377\377\375\377\376\377\377\231\377\377\377\10\377\377\375" \
+ "\376\377\377\377\377\377\377\376\377\377\377\375\276\317\331\1>j\0>j" \
+ "\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1" \
+ "kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\220\377\377\377" \
+ "\1\376\376\376\202\377\377\377\4\363\363\365;;=::<;;=\204::<\1\234\234" \
+ "\234\231\377\377\377\1SSS\202::<\1;;=\203::<\1\265\265\267\223\377\377" \
+ "\377\1kkm\206::<\1\316\316\316\300\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\346\346\350\203::<\4;;=::<;;=SSU\213\377\377\377\1\204\204" \
+ "\204\203::<\1;;=\202::<\1\204\204\206\202\377\377\377\1\376\376\376\226" \
+ "\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm" \
+ "\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\227\377\377\377\1\376" \
+ "\376\376\202\377\377\377\3TTV::<;;=\203::<\2;;=\205\205\205\252\377\377" \
+ "\377\1\347\347\347\202::<\202;;=\203::<\1\235\235\237\204\377\377\377" \
+ "\1\376\376\376\211\377\377\377\1\234\234\234\206::<\1\316\316\316\205" \
+ "\377\377\377\1\205\205\205\202::<\6;;=::<;;=::<;;=\234\234\236\213\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\302\302\302\202;;=\203::<\3" \
+ ";;=::<\221\221\221\202\377\377\377\1\376\376\376\202\377\377\377\1\316" \
+ "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \
+ "\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317" \
+ "\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \
+ "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\224" \
+ "\377\377\377\4\204\204\204;;=::<;;=\203::<\1TTT\204\377\377\377\1\376" \
+ "\376\376\223\377\377\377\1\300\300\300\203::<\5;;=::<;;=FFF\363\363\363" \
+ "\223\377\377\377\1kkm\203::<\4;;=::<;;=\316\316\320\277\377\377\377\14" \
+ "\376\376\376\377\377\377\376\376\376\377\377\377\204\204\206::<;;=::" \
+ "<99;<<>99;\265\265\267\213\377\377\377\3\346\346\346::<;;=\202::<\1;" \
+ ";=\202::<\2\347\347\347\376\376\376\227\377\377\377\1\234\234\234\206" \
+ "::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206" \
+ "::<\1\234\234\236\226\377\377\377\4\376\376\376\377\377\377\376\376\376" \
+ "\346\346\350\202;;=\203::<\3""99;<<>\301\301\301\253\377\377\377\1aa" \
+ "c\202::<\1;;=\202::<\2;;=jjl\205\377\377\377\1\376\376\376\210\377\377" \
+ "\377\1\234\234\234\206::<\1\316\316\316\202\377\377\377\1\376\376\376" \
+ "\202\377\377\377\3\362\362\362SSU;;=\205::<\2;;=\332\332\332\210\377" \
+ "\377\377\1\376\376\376\203\377\377\377\2\363\363\363FFH\202::<\202;;" \
+ "=\5::<;;=SSS\363\363\363\376\376\376\204\377\377\377\1\316\316\316\206" \
+ "::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350" \
+ "\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0" \
+ ">i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::" \
+ "<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\224\377\377" \
+ "\377\1\332\332\332\207::<\1\301\301\301\227\377\377\377\1lll\204::<\3" \
+ ";;=::<\221\221\221\202\377\377\377\3\376\376\376\377\377\377\376\376" \
+ "\376\217\377\377\377\1kkm\204::<\3;;=99;\316\316\316\241\377\377\377" \
+ "\1\376\376\376\234\377\377\377\10\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\363\363\363FFH;;=::<\202;;=\3::<FFH\364\364\364\214\377" \
+ "\377\377\1xxz\204::<\3;;=::<\233\233\233\230\377\377\377\1\234\234\234" \
+ "\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377\1k" \
+ "km\206::<\1\234\234\236\224\377\377\377\1\376\376\376\204\377\377\377" \
+ "\4\266\266\270;;=::<;;=\203::<\1""99;\254\377\377\377\3\234\234\234:" \
+ ":<;;=\205::<\204\377\377\377\1\376\376\376\211\377\377\377\1\234\234" \
+ "\234\206::<\1\316\316\316\203\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\316\316\320\204::<\4;;=99;::<__a\205\377\377\377\1\376\376\376\206" \
+ "\377\377\377\4yy{;;=::<;;=\202::<\3;;=::<\316\316\316\206\377\377\377" \
+ "\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \
+ "\350\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276" \
+ "\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \
+ "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \
+ "\225\377\377\377\1__a\204;;=\5""99;::<yy{\377\377\377\376\376\376\216" \
+ "\377\377\377\1\376\376\376\205\377\377\377\1\346\346\346\202::<\203;" \
+ ";=\202::<\1\346\346\346\224\377\377\377\1kkm\205::<\2;;=\316\316\316" \
+ "\235\377\377\377\1\376\376\376\244\377\377\377\1\234\234\234\202;;=\204" \
+ "::<\2\235\235\235\376\376\376\212\377\377\377\4\376\376\376\377\377\377" \
+ "\317\317\317::<\202;;=\202::<\3;;=GGI\362\362\362\202\377\377\377\1\376" \
+ "\376\376\224\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377" \
+ "\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\231\377\377" \
+ "\377\1\220\220\222\205::<\3;;=kkm\376\376\376\253\377\377\377\3\316\316" \
+ "\316<<>99;\202::<\4;;=::<;;=\331\331\331\215\377\377\377\1\234\234\234" \
+ "\206::<\1\316\316\316\207\377\377\377\1\222\222\224\202::<\3;;=99;<<" \
+ ">\202::<\4\234\234\236\376\376\376\377\377\377\376\376\376\203\377\377" \
+ "\377\1\376\376\376\203\377\377\377\6\302\302\304;;=99;;;=::<;;=\202:" \
+ ":<\1\234\234\234\202\377\377\377\1\376\376\376\204\377\377\377\1\316" \
+ "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \
+ "\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317" \
+ "\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \
+ "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\225" \
+ "\377\377\377\2\265\265\265;;=\202::<\2""99;;;=\202::<\2\347\347\347\376" \
+ "\376\376\215\377\377\377\3\376\376\376\377\377\377\376\376\376\204\377" \
+ "\377\377\3\221\221\223;;=99;\204::<\3xxz\377\377\377\376\376\376\202" \
+ "\377\377\377\202\376\376\376\217\377\377\377\1kkm\202::<\5;;=99;;;=9" \
+ "9;\317\317\317\233\377\377\377\1\376\376\376\237\377\377\377\1\376\376" \
+ "\376\204\377\377\377\3\376\376\376\377\377\377GGI\202::<\5;;=::<;;=:" \
+ ":<\346\346\346\213\377\377\377\1\376\376\376\202\377\377\377\2``b99;" \
+ "\202;;=\203::<\3\247\247\247\377\377\377\376\376\376\225\377\377\377" \
+ "\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm\206::<\237\377" \
+ "\377\377\1kkm\206::<\1\234\234\236\231\377\377\377\10kkm::<;;=::<;;=" \
+ "99;::<\235\235\237\255\377\377\377\202::<\1;;=\204::<\1\301\301\301\215" \
+ "\377\377\377\1\234\234\234\206::<\1\316\316\316\206\377\377\377\5\376" \
+ "\376\376\364\364\364TTV::<99;\202;;=\203::<\4\332\332\334\376\376\376" \
+ "\377\377\377\376\376\376\203\377\377\377\6\376\376\376\377\377\377\363" \
+ "\363\363FFH::<;;=\204::<\1__a\210\377\377\377\1\316\316\316\206::<\1" \
+ "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270" \
+ "\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0" \
+ "=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240" \
+ "\377\377\377\1\234\234\236\206::<\1\234\234\236\224\377\377\377\5\376" \
+ "\376\376\377\377\377GGI::<;;=\203::<\4;;=\220\220\222\377\377\377\376" \
+ "\376\376\214\377\377\377\1\376\376\376\203\377\377\377\10\376\376\376" \
+ "\377\377\377\363\363\363FFH::<;;=99;;;=\202::<\1\316\316\320\202\377" \
+ "\377\377\1\376\376\376\204\377\377\377\1\376\376\376\215\377\377\377" \
+ "\1kkm\206::<\1\316\316\316\277\377\377\377\3\376\376\376\377\377\377" \
+ "\265\265\267\204::<\3;;=::<\205\205\205\213\377\377\377\1\376\376\376" \
+ "\202\377\377\377\2\376\376\376\265\265\265\202::<\5""99;<<>::<;;=SSU" \
+ "\202\377\377\377\1\376\376\376\224\377\377\377\1\234\234\234\206::<\1" \
+ "\234\234\234\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<" \
+ "\1\234\234\236\230\377\377\377\2\376\376\376SSU\204::<\3;;=::<\266\266" \
+ "\266\253\377\377\377\3\376\376\376\377\377\377^^`\206::<\1\234\234\234" \
+ "\202\377\377\377\1\376\376\376\212\377\377\377\1\234\234\234\206::<\1" \
+ "\316\316\316\205\377\377\377\6\376\376\376\377\377\377\376\376\376\315" \
+ "\315\317::<;;=\202::<\4;;=99;::<``b\210\377\377\377\4xxz99;<<>::<\202" \
+ ";;=\202::<\1\332\332\332\203\377\377\377\1\376\376\376\204\377\377\377" \
+ "\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \
+ "\350\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276" \
+ "\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \
+ "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \
+ "\226\377\377\377\1\234\234\234\206::<\2FFH\376\376\376\214\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377\3\265\265" \
+ "\265;;=99;\202;;=\202::<\1SSU\202\377\377\377\1\376\376\376\223\377\377" \
+ "\377\1kkm\203::<\4""99;::<;;=\316\316\320\275\377\377\377\202\376\376" \
+ "\376\4\377\377\377\376\376\376SSU;;=\202::<\4;;=::<;;=\332\332\332\215" \
+ "\377\377\377\5\376\376\376\377\377\377\376\376\376SSU;;=\204::<\2;;=" \
+ "\264\264\264\226\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377" \
+ "\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\231\377" \
+ "\377\377\207::<\1\316\316\316\254\377\377\377\2\376\376\376lln\202::" \
+ "<\1;;=\202::<\4;;=\233\233\233\377\377\377\376\376\376\202\377\377\377" \
+ "\1\376\376\376\210\377\377\377\1\234\234\234\206::<\1\316\316\316\203" \
+ "\377\377\377\202\376\376\376\204\377\377\377\1\234\234\234\207::<\1\234" \
+ "\234\236\205\377\377\377\4\376\376\376\300\300\302::<;;=\205::<\2\234" \
+ "\234\234\376\376\376\202\377\377\377\1\376\376\376\205\377\377\377\1" \
+ "\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \
+ "\350\211[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276" \
+ "\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \
+ "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \
+ "\226\377\377\377\1\347\347\347\204::<\5;;=99;;;=\265\265\265\376\376" \
+ "\376\222\377\377\377\2___99;\202::<\4;;=::<;;=\265\265\265\207\377\377" \
+ "\377\1\376\376\376\216\377\377\377\1kkm\203::<\1;;=\202::<\1;;=\233:" \
+ ":<\5""99;;;=::<:::\234\234\234\240\377\377\377\2\316\316\316;;=\204:" \
+ ":<\2;;=kkm\221\377\377\377\1\234\234\236\203::<\1;;=\202::<\3kkk\377" \
+ "\377\377\376\376\376\224\377\377\377\1\234\234\234\206::<\1\234\234\234" \
+ "\243\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236" \
+ "\231\377\377\377\207::<\1\316\316\316\255\377\377\377\2\221\221\221;" \
+ ";=\205::<\1\204\204\204\203\377\377\377\1\376\376\376\211\377\377\377" \
+ "\1\234\234\234\206::<\1\316\316\316\210\377\377\377\3\376\376\376\377" \
+ "\377\377``b\202::<\7;;=::<;;=::<;;=\332\332\332\376\376\376\202\377\377" \
+ "\377\3\376\376\376\363\363\363GGI\203::<\4;;=::<;;=__a\206\377\377\377" \
+ "\1\376\376\376\203\377\377\377\1\316\316\316\206::<\1\234\234\236\213" \
+ "\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[\267\350" \
+ "\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3\0>i\0=i" \
+ "\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377" \
+ "\1\234\234\236\206::<\1\234\234\236\227\377\377\377\1\204\204\206\204" \
+ "::<\3;;=::<kkk\217\377\377\377\5\376\376\376\377\377\377\376\376\376" \
+ "\333\333\333:::\202::<\1;;=\202::<\2FFH\363\363\363\226\377\377\377\1" \
+ "kkm\204::<\1;;=\202::<\1;;=\234::<\4;;=::<\234\234\234\376\376\376\237" \
+ "\377\377\377\1kkm\206::<\1\316\316\316\221\377\377\377\2\363\363\363" \
+ "GGG\204::<\3;;=::<\315\315\315\225\377\377\377\1\234\234\234\206::<\1" \
+ "\234\234\234\237\377\377\377\1\376\376\376\203\377\377\377\1kkm\206:" \
+ ":<\237\377\377\377\1kkm\206::<\1\234\234\236\230\377\377\377\2\376\376" \
+ "\376;;=\203::<\1;;=\202::<\1\363\363\363\252\377\377\377\6\376\376\376" \
+ "\377\377\377\376\376\376\234\234\23699;;;=\204::<\1kkm\215\377\377\377" \
+ "\1\234\234\234\206::<\1\316\316\316\210\377\377\377\7\377\377\375\377" \
+ "\377\377\332\332\332::<;;=::<;;=\203::<\2``b\376\376\376\202\377\377" \
+ "\377\2\376\376\376xxz\206::<\2:::\332\332\332\212\377\377\377\1\316\316" \
+ "\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211" \
+ "[\267\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331" \
+ "\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316" \
+ "\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\227\377" \
+ "\377\377\1\315\315\315\205::<\3;;=::<\332\332\334\221\377\377\377\1\204" \
+ "\204\206\205::<\2;;=\205\205\205\227\377\377\377\1kkm\203::<\3;;=::<" \
+ ";;=\234::<\1:9>\203::<\1\234\234\236\237\377\377\377\1\331\331\331\202" \
+ ";;=\204::<\1SSU\217\377\377\377\5\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\204\204\204\204::<\3;;=99;yyy\203\377\377\377\1\376\376" \
+ "\376\221\377\377\377\1\234\234\234\206::<\1\234\234\234\235\377\377\377" \
+ "\1\376\376\376\205\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206:" \
+ ":<\1\234\234\236\231\377\377\377\203::<\1;;=\203::<\202\377\377\377\1" \
+ "\376\376\376\253\377\377\377\2\233\233\235;;=\205::<\3kkm\377\377\377" \
+ "\376\376\376\202\377\377\377\1\376\376\376\210\377\377\377\1\234\234" \
+ "\234\206::<\1\316\316\316\213\377\377\377\1\234\234\236\202;;=\1""99" \
+ ";\203::<\5;;=\235\235\235\377\377\377\376\376\376\302\302\302\207::<" \
+ "\1\251\251\251\213\377\377\377\1\316\316\316\206::<\1\234\234\236\213" \
+ "\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[\267\350" \
+ "\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3\0>i\0=i" \
+ "\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377" \
+ "\1\234\234\236\206::<\1\234\234\236\223\377\377\377\1\376\376\376\204" \
+ "\377\377\377\1^^`\202::<\202;;=\3::<<<>\204\204\206\213\377\377\377\1" \
+ "\376\376\376\204\377\377\377\1\363\363\363\205::<\3;;=::<\346\346\346" \
+ "\227\377\377\377\1kkm\204::<\3;;=::<;;=\234::<\1;;=\202::<\1\234\234" \
+ "\236\237\377\377\377\4\204\204\20499;::<;;=\203::<\3\266\266\270\377" \
+ "\377\377\376\376\376\221\377\377\377\5\346\346\346;;=::<;;=::<\202;;" \
+ "=\4::<\346\346\350\377\377\377\376\376\376\202\377\377\377\1\376\376" \
+ "\376\217\377\377\377\1\234\234\234\206::<\1\234\234\234\237\377\377\377" \
+ "\202\376\376\376\202\377\377\377\1kkm\206::<\237\377\377\377\1kkm\206" \
+ "::<\1\234\234\236\224\377\377\377\6\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\376\376\376;;=\206::<\1\331\331\331\255\377\377\377\1\234" \
+ "\234\236\202::<\1;;=\203::<\2kkm\376\376\376\202\377\377\377\1\376\376" \
+ "\376\211\377\377\377\1\234\234\234\206::<\1\316\316\316\212\377\377\377" \
+ "\3\376\376\376\377\377\377___\204::<\7;;=99;::<\332\332\332\363\363\365" \
+ "FFH;;=\204::<\3;;=kkm\376\376\376\213\377\377\377\1\316\316\316\206:" \
+ ":<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350" \
+ "\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0" \
+ ">i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::" \
+ "<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\224\377\377" \
+ "\377\1\376\376\376\203\377\377\377\4\265\265\267::<;;=::<\202;;=\3::" \
+ "<FFH\363\363\363\213\377\377\377\1\376\376\376\203\377\377\377\2\251" \
+ "\251\251;;=\205::<\1lln\202\377\377\377\1\376\376\376\225\377\377\377" \
+ "\1kkm\202::<\2;;=99;\204::<\1;;=\234::<\2;;=\234\234\234\235\377\377" \
+ "\377\5\376\376\376\345\345\345;;=::<;;=\202::<\2;;=FFH\215\377\377\377" \
+ "\3\376\376\376\377\377\377\376\376\376\205\377\377\377\10xxz;;=::<;;" \
+ "=99;;;=::<\204\204\206\202\377\377\377\1\376\376\376\221\377\377\377" \
+ "\1\234\234\234\206::<\1\234\234\234\234\377\377\377\1\376\376\376\204" \
+ "\377\377\377\3\376\376\376\377\377\377kkm\206::<\237\377\377\377\1kk" \
+ "m\206::<\1\234\234\236\231\377\377\377\202::<\1;;=\204::<\1\316\316\316" \
+ "\253\377\377\377\3\376\376\376\377\377\377\220\220\222\202;;=\2::<;;" \
+ "=\202::<\1\222\222\224\215\377\377\377\1\234\234\234\206::<\1\316\316" \
+ "\316\213\377\377\377\3\376\376\376\332\332\332GGI\204::<\10;;=::<__a" \
+ "xxz::<;;=::<;;=\202::<\2FFH\346\346\346\214\377\377\377\1\316\316\316" \
+ "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267" \
+ "\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0" \
+ "=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206" \
+ "::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\231\377\377" \
+ "\377\10FFH::<;;=99;;;=::<;;=\265\265\265\216\377\377\377\4\376\376\376" \
+ "TTV99;;;=\202::<\202;;=\1\301\301\301\230\377\377\377\1kkm\202::<\1;" \
+ ";=\204::<\3;;=::<;;=\232::<\5;;=::<\234\234\234\377\377\377\376\376\376" \
+ "\232\377\377\377\3\376\376\376\377\377\377\221\221\221\202::<\1""99;" \
+ "\203::<\5\234\234\236\377\377\377\376\376\376\377\377\377\376\376\376" \
+ "\216\377\377\377\1\376\376\376\202\377\377\377\2\316\316\320::<\202;" \
+ ";=\204::<\2\363\363\363\376\376\376\202\377\377\377\1\376\376\376\217" \
+ "\377\377\377\1\234\234\234\206::<\1\234\234\234\243\377\377\377\1kkm" \
+ "\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\224\377\377\377\1\376" \
+ "\376\376\204\377\377\377\1""99;\202::<\1;;=\203::<\1\316\316\316\252" \
+ "\377\377\377\10\376\376\376\377\377\377\376\376\376kkm;;=::<;;=99;\202" \
+ "::<\1\234\234\236\215\377\377\377\1\234\234\234\206::<\1\316\316\316" \
+ "\215\377\377\377\5\247\247\247;;=99;::<;;=\210::<\5""99;::<\250\250\252" \
+ "\377\377\377\376\376\376\213\377\377\377\1\316\316\316\206::<\1\234\234" \
+ "\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[" \
+ "\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3" \
+ "\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377" \
+ "\377\377\1\234\234\236\206::<\1\234\234\236\223\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\203\377\377\377\1\234\234\236\202::<\1;" \
+ ";=\202::<\2""99;SSU\214\377\377\377\5\376\376\376\377\377\377\301\301" \
+ "\301;;=<<>\202::<\3;;=::<SSU\202\377\377\377\1\376\376\376\226\377\377" \
+ "\377\1kkm\203::<\1;;=\202::<\1\204\204\206\202\234\234\234\1\235\235" \
+ "\235\232\234\234\236\202\234\234\234\1\315\315\315\233\377\377\377\6" \
+ "\376\376\376\377\377\377\362\362\362HHJ99;;;=\204::<\2\364\364\364\376" \
+ "\376\376\220\377\377\377\1\376\376\376\204\377\377\377\1kkm\206::<\1" \
+ "\234\234\234\223\377\377\377\1\234\234\234\206::<\1\234\234\234\242\377" \
+ "\377\377\2\376\376\376lln\206::<\237\377\377\377\1kkm\206::<\1\234\234" \
+ "\236\231\377\377\377\2TTV99;\202::<\5;;=::<;;=\250\250\250\376\376\376" \
+ "\254\377\377\377\1``b\203::<\202;;=\3::<\235\235\237\376\376\376\202" \
+ "\377\377\377\1\376\376\376\211\377\377\377\1\234\234\234\206::<\1\316" \
+ "\316\316\216\377\377\377\2kkm;;=\203::<\5;;=::<;;=99;;;=\202::<\2;;=" \
+ "jjl\216\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377" \
+ "\2\255\333\363Y\270\350\211[\267\350\3Y\270\350[\267\350\326\354\371" \
+ "\242\377\377\377\3\276\317\331\0=i\0>i\210\0=i\3\0>i\0=i\177\236\263" \
+ "\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234" \
+ "\236\206::<\1\234\234\236\224\377\377\377\1\376\376\376\204\377\377\377" \
+ "\2\346\346\34699;\202::<\2;;=::<\202;;=\1\315\315\315\212\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1yy{\203::<\4;;=99;;;=\250\250\250\202" \
+ "\377\377\377\1\376\376\376\226\377\377\377\1kkm\206::<\1\317\317\317" \
+ "\240\377\377\377\1\376\376\376\234\377\377\377\1\234\234\234\202::<\2" \
+ "99;;;=\202::<\1\204\204\206\203\377\377\377\1\376\376\376\220\377\377" \
+ "\377\1\376\376\376\202\377\377\377\2\264\264\264::<\202;;=\203::<\3G" \
+ "GI\364\364\364\376\376\376\202\377\377\377\1\376\376\376\216\377\377" \
+ "\377\1\234\234\234\206::<\1\234\234\234\241\377\377\377\3\376\376\376" \
+ "\377\377\377kkm\206::<\237\377\377\377\1kkm\206::<\1\234\234\236\225" \
+ "\377\377\377\202\376\376\376\202\377\377\377\12kkm::<;;=99;::<;;=::<" \
+ "\204\204\204\377\377\377\376\376\376\251\377\377\377\4\376\376\376\377" \
+ "\377\377::<99;\202;;=\203::<\1\316\316\320\215\377\377\377\1\234\234" \
+ "\234\206::<\1\316\316\316\216\377\377\377\5\346\346\350GGI;;=::<;;=\202" \
+ "::<\2""99;;;=\202::<\3;;=GGI\346\346\350\216\377\377\377\1\316\316\316" \
+ "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267" \
+ "\350\3Y\270\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0" \
+ "=i\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206" \
+ "::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\231\377\377" \
+ "\377\2\376\376\376\205\205\205\202::<\5""99;;;=::<;;=\205\205\207\213" \
+ "\377\377\377\12\376\376\376\346\346\346::<;;=99;::<99;;;=FFH\363\363" \
+ "\363\231\377\377\377\1kkm\202::<\2;;=::<\202;;=\3\316\316\316\377\377" \
+ "\377\376\376\376\234\377\377\377\1\376\376\376\236\377\377\377\1SSS\204" \
+ "::<\3;;=99;\347\347\351\204\377\377\377\1\376\376\376\215\377\377\377" \
+ "\1\376\376\376\205\377\377\377\1SSU\203::<\4;;=99;::<\265\265\265\202" \
+ "\377\377\377\1\376\376\376\217\377\377\377\1\234\234\234\206::<\1\234" \
+ "\234\234\242\377\377\377\2\376\376\376SSU\206::<\237\377\377\377\1kk" \
+ "m\206::<\1\234\234\236\231\377\377\377\4\221\221\223;;=::<;;=\202::<" \
+ "\3;;=___\376\376\376\253\377\377\377\1\332\332\332\204::<\1;;=\202::" \
+ "<\1\346\346\350\203\377\377\377\1\376\376\376\211\377\377\377\1\234\234" \
+ "\234\206::<\1\316\316\316\217\377\377\377\1\250\250\252\204::<\202;;" \
+ "=\2::<;;=\202::<\1\265\265\267\217\377\377\377\1\316\316\316\206::<\1" \
+ "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\3Y\270" \
+ "\350[\267\350\326\354\371\242\377\377\377\3\276\317\331\0=i\0>i\210\0" \
+ "=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240" \
+ "\377\377\377\1\234\234\236\206::<\1\234\234\236\232\377\377\377\1\316" \
+ "\316\316\203::<\2""99;<<>\202::<\1\346\346\350\213\377\377\377\4\221" \
+ "\221\223;;=::<;;=\203::<\1\204\204\206\232\377\377\377\1kkm\203::<\1" \
+ ";;=\202::<\1\316\316\316\274\377\377\377\2\265\265\267;;=\205::<\1xx" \
+ "x\231\377\377\377\1\250\250\250\206::<\1TTV\222\377\377\377\1\234\234" \
+ "\234\204::<\3;;=::<\235\235\235\203\377\377\377\1\376\376\376\237\377" \
+ "\377\377\202;;=\203::<\3;;=::<\376\376\376\236\377\377\377\1kkm\206:" \
+ ":<\1\234\234\236\225\377\377\377\1\376\376\376\203\377\377\377\1\265" \
+ "\265\267\204::<\1;;=\202::<\1\363\363\363\253\377\377\377\1\250\250\250" \
+ "\204::<\3;;=::<GGI\216\377\377\377\1\234\234\234\206::<\1\316\316\316" \
+ "\220\377\377\377\4kkm;;=::<;;=\204::<\3;;=xxx\376\376\376\217\377\377" \
+ "\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363" \
+ "Y\270\350\212[\267\350\2X\266\351\326\356\370\202\377\377\377\3\377\377" \
+ "\375\377\377\377\376\377\375\234\377\377\377\4\377\377\375\276\317\327" \
+ "\0\77j\1>j\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316" \
+ "\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\233\377" \
+ "\377\377\1``b\205::<\2;;=\235\235\237\210\377\377\377\1\376\376\376\202" \
+ "\377\377\377\2FFH;;=\205::<\1\346\346\346\202\377\377\377\1\376\376\376" \
+ "\227\377\377\377\1kkm\206::<\1\316\316\316\266\377\377\377\1\376\376" \
+ "\376\205\377\377\377\5__a::<;;=::<;;=\202::<\1SSU\202kkm\1lln\203kkm" \
+ "\1lln\222kkm\4__a;;=99;;;=\204::<\3\301\301\301\377\377\377\376\376\376" \
+ "\215\377\377\377\202\376\376\376\1\235\235\235\204::<\3""99;;;=\221\221" \
+ "\221\243\377\377\377\203::<\1;;=\202::<\1""99;\237\377\377\377\1kkm\206" \
+ "::<\1\234\234\236\231\377\377\377\1\332\332\332\202::<\3;;=::<99;\202" \
+ ";;=\1\264\264\264\210\377\377\377\1\376\376\376\232\377\377\377\1\376" \
+ "\376\376\206\377\377\377\2\376\376\376xxx\202::<\1;;=\203::<\1xxz\216" \
+ "\377\377\377\1\234\234\234\206::<\1\316\316\316\220\377\377\377\3\363" \
+ "\363\365FFH;;=\202::<\1;;=\202::<\2FFH\363\363\363\220\377\377\377\1" \
+ "\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270" \
+ "\350\211[\267\350\10X\267\347Y\267\352\326\354\371\377\377\377\376\376" \
+ "\376\377\376\377\377\377\377\377\376\377\234\377\377\377\2\376\376\374" \
+ "\277\320\330\212\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \
+ "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\233" \
+ "\377\377\377\1\265\265\267\203::<\4""99;;;=::<SSU\207\377\377\377\6\376" \
+ "\376\376\377\377\377\376\376\376\265\265\265;;=99;\202;;=\4""99;;;=k" \
+ "km\377\377\377\202\376\376\376\230\377\377\377\1kkm\206::<\1\316\316" \
+ "\316\267\377\377\377\1\376\376\376\203\377\377\377\7\316\316\320<<>9" \
+ "9;::<;;=::<99;\203::<\2;;=99;\202::<\1;;=\224::<\1;;=\202::<\1;;=\203" \
+ "::<\1kkm\203\377\377\377\1\376\376\376\215\377\377\377\1\300\300\300" \
+ "\202::<\11;;=::<99;;;=jjl\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\236\377\377\377\1\346\346\350\206::<\1__a\237\377\377\377\1kkm\206" \
+ "::<\1\234\234\236\231\377\377\377\2\376\376\376SSU\206::<\2yy{\376\376" \
+ "\376\206\377\377\377\1\376\376\376\234\377\377\377\1\376\376\376\205" \
+ "\377\377\377\4\363\363\363::<<<>99;\202::<\3;;=::<\265\265\267\203\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\210\377\377\377\1\234" \
+ "\234\234\206::<\1\316\316\316\221\377\377\377\4\301\301\30199;::<;;=" \
+ "\202::<\6;;=\301\301\301\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\215\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377" \
+ "\2\255\333\363Y\270\350\211[\267\350\6Y\270\350Y\267\352\325\353\370" \
+ "\377\377\377\376\377\375\377\375\377\234\377\377\377\5\376\376\376\377" \
+ "\377\377\377\377\375\276\317\327\2\77k\211\0=i\3\0>i\0=i\177\236\263" \
+ "\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234" \
+ "\236\206::<\1\234\234\236\234\377\377\377\1GGI\203::<\1;;=\202::<\2\301" \
+ "\301\301\376\376\376\204\377\377\377\1\376\376\376\203\377\377\377\3" \
+ "lln::<;;=\202::<\202;;=\4\301\301\303\376\376\376\377\377\377\376\376" \
+ "\376\230\377\377\377\1kkm\206::<\1\316\316\316\265\377\377\377\1\376" \
+ "\376\376\205\377\377\377\3kkm::<;;=\202::<\2""99;<<>\202::<\3;;=::<;" \
+ ";=\202::<\1;;=\222::<\4""99;;;=::<;;=\203::<\1;;=\202::<\3\316\316\316" \
+ "\377\377\377\376\376\376\215\377\377\377\3\376\376\376\316\316\316;;" \
+ "=\203::<\3;;=::<FFH\234\377\377\377\202\376\376\376\202\377\377\377\3" \
+ "\376\376\376\377\377\377\316\316\320\203::<\4;;=::<;;=kkm\237\377\377" \
+ "\377\1kkm\206::<\1\234\234\236\226\377\377\377\7\376\376\376\377\377" \
+ "\377\376\376\376\377\377\377\204\204\204::<;;=\204::<\2;;=\346\346\346" \
+ "\241\377\377\377\1\376\376\376\202\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\202\377\377\377\1\250\250\250\202::<\1<<>\204::<\3\346" \
+ "\346\346\377\377\377\376\376\376\202\377\377\377\1\376\376\376\211\377" \
+ "\377\377\1\234\234\234\206::<\1\316\316\316\220\377\377\377\14\376\376" \
+ "\376\377\377\377yy{::<99;;;=::<xxz\377\377\377\376\376\376\377\377\377" \
+ "\376\376\376\203\377\377\377\1\376\376\376\212\377\377\377\1\316\316" \
+ "\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211" \
+ "[\267\350\10X\267\347Z\266\351\326\356\370\376\377\377\377\377\375\377" \
+ "\377\377\377\376\377\376\377\377\234\377\377\377\4\376\376\374\277\320" \
+ "\330\0=i\1>j\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \
+ "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\234" \
+ "\377\377\377\1\234\234\234\206::<\3jjj\377\377\377\376\376\376\204\377" \
+ "\377\377\4\376\376\376\377\377\377\332\332\33299;\203::<\3;;=::<SSU\202" \
+ "\377\377\377\1\376\376\376\231\377\377\377\1kkm\206::<\1\316\316\316" \
+ "\267\377\377\377\5\376\376\376\377\377\377\376\376\376\346\346\350;;" \
+ "=\203::<\1;;=\202::<\202;;=\202::<\3""99;::<;;=\222::<\202;;=\3""99;" \
+ "::<;;=\202::<\1;;=\203::<\2\204\204\206\376\376\376\217\377\377\377\1" \
+ "\363\363\363\203::<\6;;=::<;;=::<\347\347\347\376\376\376\234\377\377" \
+ "\377\202\376\376\376\5\377\377\377\376\376\376\234\234\236::<;;=\202" \
+ "::<\3;;=::<\234\234\236\237\377\377\377\1kkm\206::<\1\234\234\236\231" \
+ "\377\377\377\5\376\376\376\316\316\316;;=99;;;=\204::<\1\222\222\224" \
+ "\204\377\377\377\1\376\376\376\235\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\203\377\377\377\5SSU;;=::<99;;;=\202::<\3kkk\377" \
+ "\377\377\376\376\376\203\377\377\377\1\376\376\376\211\377\377\377\1" \
+ "\234\234\234\206::<\1\316\316\316\222\377\377\377\6\363\363\363GGI::" \
+ "<;;=FFH\363\363\363\205\377\377\377\1\376\376\376\214\377\377\377\1\316" \
+ "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \
+ "\212[\267\350\3Y\267\352\330\354\363\376\377\377\203\377\377\377\1\377" \
+ "\377\375\235\377\377\377\3\276\317\331\0=i\1>j\210\0=i\3\0>i\0=i\177" \
+ "\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1" \
+ "\234\234\236\206::<\1\234\234\236\233\377\377\377\2\376\376\376\347\347" \
+ "\347\202::<\2;;=::<\203;;=\1\346\346\346\207\377\377\377\5\204\204\204" \
+ "<<>99;::<;;=\202::<\2\251\251\251\376\376\376\205\377\377\377\1\376\376" \
+ "\376\225\377\377\377\1kkm\206::<\1\316\316\316\264\377\377\377\1\376" \
+ "\376\376\205\377\377\377\3\204\204\206::<;;=\203::<\1;;=\205::<\1;;=" \
+ "\225::<\3;;=::<;;=\202::<\1;;=\202::<\1;;=\202::<\1\347\347\347\220\377" \
+ "\377\377\2SSU;;=\203::<\3;;=::<\265\265\265\237\377\377\377\7\376\376" \
+ "\376\377\377\377lln99;::<;;=99;\202::<\1\265\265\267\237\377\377\377" \
+ "\1kkm\206::<\1\234\234\236\225\377\377\377\1\376\376\376\204\377\377" \
+ "\377\3\376\376\376SSU;;=\204::<\3;;=FFH\346\346\346\202\377\377\377\1" \
+ "\376\376\376\237\377\377\377\1\376\376\376\204\377\377\377\2\265\265" \
+ "\267;;=\202::<\1;;=\203::<\1\265\265\265\217\377\377\377\1\234\234\234" \
+ "\206::<\1\316\316\316\223\377\377\377\4\301\301\301::<:::\302\302\302" \
+ "\223\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2" \
+ "\255\333\363Y\270\350\212[\267\350\2Y\270\350\332\354\370\202\377\377" \
+ "\377\3\376\376\376\376\377\377\377\376\373\235\377\377\377\1\276\317" \
+ "\331\202\0>i\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316" \
+ "\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236\235" \
+ "\377\377\377\1\204\204\204\206::<\1\221\221\223\206\377\377\377\2\363" \
+ "\363\363GGI\202::<\5""99;;;=::<GGI\363\363\363\204\377\377\377\202\376" \
+ "\376\376\226\377\377\377\1kkm\206::<\1\316\316\316\266\377\377\377\1" \
+ "\376\376\376\202\377\377\377\3\346\346\350::<;;=\204::<\5""99;;;=:::" \
+ "99;;;=\203::<\3;;=99;;;=\220::<\5;;=::<;;=::<;;=\202::<\6;;=::<99;;;" \
+ "=::<\204\204\206\220\377\377\377\5yy{99;::<99;;;=\202::<\1xxz\236\377" \
+ "\377\377\10\376\376\376\377\377\377\363\363\36399;::<;;=99;;;=\202::" \
+ "<\2\346\346\350\376\376\376\236\377\377\377\1kkm\206::<\1\234\234\236" \
+ "\231\377\377\377\3\376\376\376\377\377\377\233\233\235\202::<\7;;=::" \
+ "<;;=99;;;=\204\204\204\376\376\376\245\377\377\377\2\363\363\363SSU\205" \
+ "::<\2;;=FFH\205\377\377\377\3\376\376\376\377\377\377\376\376\376\210" \
+ "\377\377\377\1\234\234\234\206::<\1\316\316\316\224\377\377\377\3\205" \
+ "\205\205\221\221\221\376\376\376\204\377\377\377\202\376\376\376\215" \
+ "\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255" \
+ "\333\363Y\270\350\212[\267\350\7Y\270\350\321\356\376\377\376\377\377" \
+ "\377\377\377\377\375\376\377\375\377\376\377\232\377\377\377\1\377\377" \
+ "\375\202\377\377\377\3\275\317\333\0\77k\0>i\210\0=i\3\0>i\0=i\177\236" \
+ "\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234" \
+ "\234\236\206::<\1\234\234\236\235\377\377\377\1\316\316\316\206::<\1" \
+ "FFH\203\377\377\377\1\376\376\376\202\377\377\377\1\250\250\250\203:" \
+ ":<\1;;=\202::<\1\204\204\206\203\377\377\377\1\376\376\376\231\377\377" \
+ "\377\1kkm\206::<\1\316\316\316\271\377\377\377\1\234\234\236\204::<\4" \
+ ";;=::<kkm\234\234\236\202\234\234\234\1\233\233\233\202\234\234\234\3" \
+ "\235\235\235\234\234\234\235\235\235\224\234\234\234\202\234\234\236" \
+ "\1\204\204\206\206::<\2FFH\363\363\363\217\377\377\377\2\250\250\252" \
+ ";;=\206::<\1\364\364\364\237\377\377\377\2\265\265\265;;=\205::<\1TT" \
+ "V\240\377\377\377\1kkm\206::<\1\234\234\236\224\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\204\377\377\377\3\364\364\366FFH;;=\203" \
+ "::<\4;;=::<:::\316\316\316\245\377\377\377\1\221\221\221\202::<\2;;=" \
+ "::<\202;;=\2::<\234\234\236\220\377\377\377\1\234\234\234\206::<\1\316" \
+ "\316\316\224\377\377\377\1\376\376\376\225\377\377\377\1\316\316\316" \
+ "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\212[\267" \
+ "\350\4[\267\346\265\340\361\377\376\377\376\376\377\202\377\377\375\1" \
+ "\374\377\377\230\377\377\377\3\376\376\376\377\377\377\377\377\375\202" \
+ "\377\377\377\3\243\265\301\0>j\0>i\210\0=i\3\0>i\0=i\177\236\263\232" \
+ "\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236" \
+ "\206::<\1\234\234\236\236\377\377\377\2__a;;=\204::<\5;;=\265\265\265" \
+ "\376\376\376\377\377\377\376\376\376\202\377\377\377\1SSU\204::<\3;;" \
+ "=::<\346\346\350\235\377\377\377\1kkm\206::<\1\316\316\316\270\377\377" \
+ "\377\2\363\363\365GGI\205::<\3;;=\333\333\333\376\376\376\237\377\377" \
+ "\377\10FFH::<;;=::<;;=99;;;=\233\233\235\217\377\377\377\5\346\346\346" \
+ "::<;;=::<;;=\203::<\1\234\234\234\210\377\377\377\1\376\376\376\217\377" \
+ "\377\377\1\376\376\376\206\377\377\377\1TTT\205::<\3;;=\221\221\221\376" \
+ "\376\376\237\377\377\377\1kkm\206::<\1\234\234\236\234\377\377\377\12" \
+ "\233\233\233::<;;=::<;;=::<;;=::<SSU\363\363\363\212\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\221\377\377\377\1\376\376\376\204\377" \
+ "\377\377\1\315\315\317\203::<\1;;=\203::<\2FFH\363\363\365\220\377\377" \
+ "\377\1\234\234\234\206::<\1\316\316\316\252\377\377\377\1\316\316\316" \
+ "\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267" \
+ "\350\6Y\270\350[\267\346\227\324\363\377\375\376\377\377\377\376\377" \
+ "\375\213\377\377\377\6\376\376\376\377\377\377\373\377\376\377\377\377" \
+ "\377\376\377\376\377\377\211\377\377\377\10\377\376\377\374\377\377\377" \
+ "\377\375\377\377\377\377\376\377_\207\240\0>l\0\77j\210\0=i\3\0>i\0=" \
+ "i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377" \
+ "\1\234\234\236\206::<\1\234\234\236\236\377\377\377\1\265\265\265\204" \
+ "::<\3;;=::<__a\204\377\377\377\1\317\317\321\206::<\1kkk\236\377\377" \
+ "\377\1kkm\206::<\1\316\316\316\267\377\377\377\3\376\376\376\250\250" \
+ "\25299;\202;;=\203::<\1kkm\233\377\377\377\1\376\376\376\205\377\377" \
+ "\377\10\234\234\236;;=::<;;=::<;;=99;GGI\204\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\210\377\377\377\5\376\376\376__a::<;;=99;\203" \
+ ";;=\2FFH\363\363\363\204\377\377\377\3\376\376\376\377\377\377\376\376" \
+ "\376\224\377\377\377\5\376\376\376\377\377\377\301\301\301:::;;=\202" \
+ "::<\202;;=\4::<\332\332\332\377\377\377\376\376\376\236\377\377\377\1" \
+ "kkm\206::<\1\234\234\236\233\377\377\377\3\376\376\376\364\364\364FF" \
+ "H\205::<\4;;=99;xxx\376\376\376\203\377\377\377\1\376\376\376\203\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\224\377\377\377" \
+ "\4\376\376\376\377\377\377\362\362\362GGI\202::<\6;;=::<;;=::<99;\250" \
+ "\250\252\221\377\377\377\1\234\234\234\206::<\1\316\316\316\252\377\377" \
+ "\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363" \
+ "Y\270\350\211[\267\350\7Y\267\352X\267\347[\266\353\301\344\367\377\377" \
+ "\377\376\376\376\376\377\377\211\377\377\377\6\377\376\377\377\377\377" \
+ "\377\375\376\377\377\377\377\377\375\377\376\377\202\377\377\377\210" \
+ "\377\376\377\10\377\377\375\376\377\377\377\377\377\376\377\375\237\266" \
+ "\306\0=i\2=g\0>e\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316" \
+ "\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234\236" \
+ "\237\377\377\377\1EEG\202::<\202;;=\11""99;;;=\332\332\332\377\377\377" \
+ "\376\376\376\377\377\377xxz::<;;=\204::<\1\302\302\302\236\377\377\377" \
+ "\1kkm\206::<\1\316\316\316\266\377\377\377\4\376\376\376\377\377\377" \
+ "SSU;;=\202::<\1;;=\202::<\1\316\316\320\235\377\377\377\15\376\376\376" \
+ "\377\377\377\376\376\376\377\377\377\363\363\365::<;;=99;;;=::<;;=::" \
+ "<\265\265\265\215\377\377\377\3\376\376\376\377\377\377\266\266\270\202" \
+ "::<\1;;=\203::<\2;;=\204\204\206\205\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\213\377\377\377\1\376\376\376\205\377\377\377\1\376" \
+ "\376\376\202\377\377\377\2\363\363\363SSU\203::<\4;;=99;;;=SSU\241\377" \
+ "\377\377\1kkm\206::<\1\234\234\236\235\377\377\377\3\265\265\265;;=9" \
+ "9;\202::<\1;;=\203::<\1\204\204\206\206\377\377\377\1\376\376\376\216" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\206\377\377\377\6" \
+ "\376\376\376\377\377\377\362\362\364``b::<;;=\202::<\1;;=\202::<\2aa" \
+ "c\376\376\376\221\377\377\377\1\234\234\234\206::<\1\316\316\316\252" \
+ "\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255" \
+ "\333\363Y\270\350\211[\267\350\10X\267\347[\267\346[\265\347[\267\346" \
+ "\230\320\361\327\360\367\325\356\365\331\355\370\210\326\354\371\10\325" \
+ "\355\367\323\355\372\366\373\377\377\376\374\376\377\375\276\320\332" \
+ "\277\320\330\301\317\330\210\276\317\331\10\276\317\327\276\320\334\301" \
+ "\316\327_\207\241\0>i\0=l\0\77k\0>i\210\0=i\3\0>i\0=i\177\236\263\232" \
+ "\377\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236" \
+ "\206::<\1\234\234\236\237\377\377\377\3\222\222\224::<;;=\202::<\3;;" \
+ "=99;\205\205\207\202\377\377\377\2\346\346\346;;=\202::<\1;;=\202::<" \
+ "\1SSU\237\377\377\377\1kkm\206::<\1\316\316\316\267\377\377\377\5\265" \
+ "\265\26799;;;=::<;;=\202::<\1TTV\243\377\377\377\1\204\204\206\205::" \
+ "<\2;;=SSU\206\377\377\377\1\376\376\376\210\377\377\377\3\376\376\376" \
+ "GGI;;=\202::<\5;;=::<;;=::<\301\301\303\203\377\377\377\1\376\376\376" \
+ "\214\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\204\377\377\377\3\204\204\206;;=::<\202;;=\203" \
+ "::<\1\265\265\265\241\377\377\377\1kkm\206::<\1\234\234\236\236\377\377" \
+ "\377\12kkk::<99;;;=::<99;;;=::<;;=\204\204\206\210\377\377\377\202\376" \
+ "\376\376\213\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376" \
+ "\202\377\377\377\1\376\376\376\202\377\377\377\2\364\364\366__a\206:" \
+ ":<\3;;=::<\332\332\332\222\377\377\377\1\234\234\234\206::<\1\316\316" \
+ "\316\252\377\377\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377" \
+ "\2\255\333\363Y\270\350\211[\267\350\3\\\266\350X\270\352\\\266\352\202" \
+ "[\267\350\3X\267\347Y\270\350Z\266\347\210Y\270\350\10[\267\350[\265" \
+ "\351\327\355\372\376\377\377\377\377\375\0>j\0>i\1\77h\210\0>i\10\0\77" \
+ "k\0>g\2=g\0=i\0\77j\0<h\0\77h\1>j\210\0=i\3\0>i\0=i\177\236\263\232\377" \
+ "\377\377\1\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206" \
+ "::<\1\234\234\236\236\377\377\377\2\376\376\376\346\346\346\202::<\10" \
+ ";;=::<99;;;=::<\363\363\363\377\377\377\234\234\236\202::<\6;;=::<;;" \
+ "=::<\250\250\250\376\376\376\236\377\377\377\1kkm\206::<\1\316\316\316" \
+ "\267\377\377\377\10kkm;;=::<;;=99;::<;;=\264\264\266\236\377\377\377" \
+ "\1\376\376\376\204\377\377\377\2\346\346\346;;=\202::<\202;;=\202::<" \
+ "\2\316\316\320\376\376\376\203\377\377\377\1\376\376\376\205\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\3\234\234" \
+ "\234::<;;=\202::<\6;;=::<;;=GGI\332\332\332\376\376\376\224\377\377\377" \
+ "\1\376\376\376\203\377\377\377\2\266\266\266;;=\202::<\6;;=::<;;=::<" \
+ "SSU\376\376\376\241\377\377\377\1kkm\206::<\1\234\234\236\236\377\377" \
+ "\377\2\363\363\363GGI\203::<\1;;=\203::<\3""99;\204\204\204\363\363\363" \
+ "\225\377\377\377\1\376\376\376\204\377\377\377\4\376\376\376\346\346" \
+ "\346``b::<\202;;=\3::<99;<<>\202::<\1\250\250\250\223\377\377\377\1\234" \
+ "\234\234\206::<\1\316\316\316\252\377\377\377\1\316\316\316\206::<\1" \
+ "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\10Y" \
+ "\270\350X\270\353Y\267\352X\266\351X\271\346[\267\350\\\266\353[\267" \
+ "\350\210Y\270\350\7X\267\345]\267\351\323\355\372\377\376\377\376\377" \
+ "\377\4=h\0>g\211\0=i\10\2=i\0@j\0>i\1>j\0>i\1\77h\0>g\0>j\210\0=i\3\0" \
+ ">i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377" \
+ "\377\377\1\234\234\236\206::<\1\234\234\236\237\377\377\377\6\376\376" \
+ "\376yy{::<;;=::<;;=\202::<\4\251\251\251\376\376\376SSU;;=\203::<\3;" \
+ ";=FFH\363\363\363\237\377\377\377\1kkm\206::<\1\316\316\316\264\377\377" \
+ "\377\5\376\376\376\377\377\377\315\315\317::<;;=\204::<\2FFH\376\376" \
+ "\376\237\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376kkm;" \
+ ";=\204::<\6""99;lln\377\377\377\376\376\376\377\377\377\376\376\376\202" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\205\377\377\377\10" \
+ "\376\376\376\377\377\377SSU::<99;;;=99;;;=\202::<\2FFF\332\332\332\203" \
+ "\377\377\377\1\376\376\376\212\377\377\377\1\376\376\376\210\377\377" \
+ "\377\1\265\265\265\206::<\3""99;::<\265\265\265\203\377\377\377\1\376" \
+ "\376\376\236\377\377\377\1kkm\206::<\1\234\234\236\233\377\377\377\1" \
+ "\376\376\376\203\377\377\377\1\331\331\331\204::<\3""99;;;=99;\202;;" \
+ "=\2^^^\332\332\332\202\377\377\377\1\376\376\376\216\377\377\377\1\376" \
+ "\376\376\206\377\377\377\5\376\376\376\316\316\316FFH::<;;=\204::<\7" \
+ "99;::<\204\204\204\377\377\377\376\376\376\377\377\377\376\376\376\220" \
+ "\377\377\377\1\234\234\234\206::<\1\316\316\316\252\377\377\377\1\316" \
+ "\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363Y\270\350" \
+ "\213[\267\350\6Y\270\350[\266\353[\267\350]\267\351X\266\351X\270\350" \
+ "\210[\267\350\10X\266\351Z\266\351\326\354\367\377\376\377\376\377\372" \
+ "\0>j\0>i\1>j\210\0=i\10\1\77h\0=h\0>i\1\77h\0>j\0=i\0>i\1>j\210\0=i\3" \
+ "\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm\240\377" \
+ "\377\377\1\234\234\236\206::<\1\234\234\236\237\377\377\377\2\376\376" \
+ "\376\316\316\316\203::<\1;;=\202::<\4SSU\265\265\267;;=99;\202::<\5;" \
+ ";=99;\204\204\204\377\377\377\376\376\376\236\377\377\377\1kkm\206::" \
+ "<\1\316\316\316\263\377\377\377\1\376\376\376\202\377\377\377\1xxz\202" \
+ "::<\1;;=\202::<\3""99;\234\234\236\376\376\376\236\377\377\377\1\375" \
+ "\375\375\202\377\377\377\1\376\376\376\202\377\377\377\5\317\317\317" \
+ "99;::<;;=::<\202;;=\2::<\332\332\332\210\377\377\377\3\376\376\376\377" \
+ "\377\377\376\376\376\204\377\377\377\2\316\316\316;;=\206::<\3;;=::<" \
+ "\250\250\252\217\377\377\377\1\376\376\376\204\377\377\377\2\363\363" \
+ "\363\222\222\224\202::<\2;;=::<\202;;=\3""99;;;=kkm\205\377\377\377\1" \
+ "\376\376\376\235\377\377\377\1kkm\206::<\1\234\234\236\235\377\377\377" \
+ "\1\376\376\376\202\377\377\377\2\266\266\26699;\202::<\3;;=::<;;=\202" \
+ "::<\3;;=FFH\234\234\234\202\377\377\377\1\376\376\376\223\377\377\377" \
+ "\2\364\364\364\204\204\206\202::<\1;;=\202::<\1;;=\202::<\3""99;``b\376" \
+ "\376\376\224\377\377\377\1\234\234\234\206::<\1\316\316\316\252\377\377" \
+ "\377\1\316\316\316\206::<\1\234\234\236\213\377\377\377\2\255\333\363" \
+ "Y\270\350\211[\267\350\10Y\271\353Z\266\347\\\267\344[\267\346X\267\347" \
+ "[\267\350X\270\353Z\266\347\210Y\270\350\10Y\267\352\\\267\346\325\355" \
+ "\371\377\377\377\376\377\377\0>g\0\77k\0>i\210\0\77j\10\0>i\3>h\0=i\0" \
+ "\77i\0=j\0>g\0=j\0=f\210\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1" \
+ "\316\316\316\206::<\1kkm\240\377\377\377\1\234\234\236\206::<\1\234\234" \
+ "\236\234\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377" \
+ "\377\2SSU;;=\202::<\202;;=\3::<SSU::<\202;;=\203::<\1\332\332\332\240" \
+ "\377\377\377\1kkm\206::<\1\316\316\316\265\377\377\377\1\346\346\346" \
+ "\203::<\1;;=\202::<\2;;=\363\363\365\235\377\377\377\1\376\376\376\210" \
+ "\377\377\377\1SSU\202;;=\204::<\1\204\204\204\202\377\377\377\202\376" \
+ "\376\376\214\377\377\377\1\221\221\221\205::<\202;;=\4::<;;=kkm\316\316" \
+ "\316\221\377\377\377\2\301\301\301SSS\210::<\2FFH\363\363\365\243\377" \
+ "\377\377\1kkm\206::<\1\234\234\236\241\377\377\377\1\266\266\270\203" \
+ "::<\1;;=\205::<\3:::RRR\265\265\265\222\377\377\377\3\363\363\363\234" \
+ "\234\234FFF\202::<\1;;=\206::<\2``b\363\363\363\225\377\377\377\1\234" \
+ "\234\234\206::<\1\316\316\316\252\377\377\377\1\316\316\316\206::<\1" \
+ "\234\234\236\213\377\377\377\2\255\333\363Y\270\350\211[\267\350\10Z" \
+ "\266\347[\267\346Z\265\352X\266\351\\\270\351[\267\346X\267\347[\265" \
+ "\347\210[\267\350\10Y\267\352[\266\345\325\355\367\376\375\377\377\377" \
+ "\375\3>j\0=i\1>j\210\0>i\10\0\77j\1\77h\0>j\0>g\3>j\0\77i\0=j\0>i\210" \
+ "\0=i\3\0>i\0=i\177\236\263\232\377\377\377\1\316\316\316\206::<\1kkm" \
+ "\240\377\377\377\1\234\234\236\206::<\1\234\234\236\241\377\377\377\6" \
+ "\266\266\270::<;;=::<99;::<\202;;=\205::<\2kkm\376\376\376\240\377\377" \
+ "\377\1kkm\206::<\1\316\316\316\265\377\377\377\4\205\205\205;;=::<;;" \
+ "=\203::<\3\204\204\206\377\377\377\376\376\376\245\377\377\377\1\265" \
+ "\265\267\207::<\2\346\346\346\376\376\376\216\377\377\377\4\376\376\376" \
+ "lll::<;;=\202::<\13;;=::<;;=::<;;=::<kkm\264\264\266\363\363\365\377" \
+ "\377\377\376\376\376\202\377\377\377\1\376\376\376\206\377\377\377\3" \
+ "\346\346\350\250\250\252TTV\204::<\3;;=::<;;=\202::<\2;;=\333\333\333" \
+ "\202\377\377\377\1\376\376\376\237\377\377\377\3\376\376\376\377\377" \
+ "\377kkm\203::<\1;;=\202::<\1\235\235\237\242\377\377\377\1\265\265\265" \
+ "\203::<\1;;=\207::<\4GGI\220\220\222\332\332\334\376\376\376\206\377" \
+ "\377\377\1\376\376\376\204\377\377\377\5\376\376\376\302\302\302\204" \
+ "\204\206::<;;=\202::<\11""99;;;=::<;;=::<;;=::<```\363\363\363\226\377" \
+ "\377\377\1\234\234\234\202::<\1;;=\202::<\2;;=\316\316\316\252\377\377" \
+ "\377\4\316\316\316::<;;=99;\203::<\3\234\234\234\377\377\377\376\376" \
+ "\376\204\377\377\377\7\373\377\376\377\376\377\377\377\377\376\377\377" \
+ "\377\376\377\253\333\362[\265\351\203[\267\352\6Y\267\352[\267\350X\267" \
+ "\345Y\270\346Y\270\350Y\267\352\220[\267\350\5X\267\347Y\270\350\325" \
+ "\355\371\377\376\377\377\377\377\202\0>g\1\1>k\220\0=i\15\0>g\1>j\0>" \
+ "i\0\77j\1>j\0=i\0\77j\0>j\0=i\1<h}\237\270\376\377\377\377\376\374\226" \
+ "\377\377\377\3\376\376\376\377\377\377\316\316\316\204::<\3""99;;;=l" \
+ "ln\240\377\377\377\5\234\234\234::<;;=::<;;=\202::<\1\235\235\237\241" \
+ "\377\377\377\10\363\363\363FFF::<;;=::<;;=::<;;=\203::<\3;;=::<\265\265" \
+ "\265\237\377\377\377\3\376\376\376\377\377\377kkm\202::<\1;;=\202::<" \
+ "\4;;=\316\316\316\377\377\377\376\376\376\250\377\377\377\1\376\376\376" \
+ "\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377" \
+ "\377\377\6\364\364\364::<99;;;=::<;;=\202::<\1\347\347\351\203\377\377" \
+ "\377\1\376\376\376\244\377\377\377\4FFH;;=::<99;\203::<\1\220\220\222" \
+ "\220\377\377\377\2\363\363\363``b\202::<\1;;=\203::<\1;;=\205::<\5__" \
+ "_\222\222\222\234\234\234\316\316\316\317\317\317\202\316\316\316\7\301" \
+ "\301\301\234\234\236\204\204\206__a;;=99;;;=\203::<\2;;=99;\203;;=\2" \
+ "::<\265\265\265\204\377\377\377\1\376\376\376\235\377\377\377\5\376\376" \
+ "\376\377\377\377\376\376\376kkm::<\202;;=\6::<;;=::<\234\234\236\377" \
+ "\377\377\376\376\376\236\377\377\377\1\376\376\376\202\377\377\377\5" \
+ "\301\301\303GGI;;=::<;;=\206::<\7;;=::<99;GGIwwy\235\235\235\300\300" \
+ "\300\202\316\316\316\10\315\315\315\317\317\317\315\315\315\265\265\265" \
+ "\234\234\234jjj<<>99;\203::<\1;;=\202::<\2""99;;;=\203::<\1\204\204\206" \
+ "\206\377\377\377\1\376\376\376\221\377\377\377\10\234\234\234;;=::<9" \
+ "9;;;=::<99;\316\316\316\252\377\377\377\4\317\317\317;;=88:;;=\202::" \
+ "<\3;;=\234\234\234\376\376\376\205\377\377\377\1\377\375\377\202\377" \
+ "\377\375\6\377\376\377\377\377\375\253\333\362Y\270\350X\267\347Z\266" \
+ "\347\202Y\270\350\1[\267\350\202Z\266\347\2[\267\350Z\266\347\220[\267" \
+ "\350\5[\267\352Z\266\351\327\355\372\377\375\376\377\376\377\202\1>j" \
+ "\1\1>k\220\0>i\202\0=i\14\0\77k\0>i\0=i\1>j\0=i\0=j\0\77k\0=i\177\236" \
+ "\263\377\377\377\376\377\377\375\376\377\224\377\377\377\1\376\376\376" \
+ "\202\377\377\377\1\316\316\316\203::<\202;;=\3""99;kkm\376\376\376\234" \
+ "\377\377\377\1\376\376\376\202\377\377\377\1\233\233\233\202::<\7;;=" \
+ "::<;;=::<\234\234\236\377\377\377\376\376\376\233\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\202\377\377\377\4\221\221\221;;=99;;;=\202" \
+ "::<\202;;=\203::<\1SSU\203\377\377\377\1\376\376\376\233\377\377\377" \
+ "\10\376\376\376\377\377\377\376\376\376kkm::<;;=::<;;=\202::<\1;;=\202" \
+ "::<\1;;=\240::<\1kkk\207\377\377\377\1\376\376\376\203\377\377\377\3" \
+ "\375\375\375\377\377\377\376\376\376\202\377\377\377\2\233\233\235::" \
+ "<\202;;=\203::<\1xxz\251\377\377\377\1\235\235\237\202::<\1;;=\203::" \
+ "<\3GGI\363\363\363\376\376\376\217\377\377\377\2\363\363\363yyy\204:" \
+ ":<\1;;=\203::<\1;;=\206::<\1""99;\203::<\1;;=\203::<\6;;=99;;;=::<;;" \
+ "=99;\202;;=\3""99;GGI\301\301\301\206\377\377\377\1\376\376\376\232\377" \
+ "\377\377\1\376\376\376\204\377\377\377\1lln\202::<\1;;=\202::<\2;;=\234" \
+ "\234\236\241\377\377\377\1\376\376\376\202\377\377\377\2\332\332\334" \
+ "__a\211::<\1;;=\205::<\1;;=\202::<\1;;=\202::<\4;;=::<99;;;=\202::<\1" \
+ ";;=\202::<\1;;=\203::<\2FFH\265\265\267\206\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\220\377\377\377\3\234\234\236::<;;=\203::<\2" \
+ ";;=\316\316\316\252\377\377\377\2\315\315\31599;\203::<\5;;=::<\234\234" \
+ "\234\377\377\377\376\376\376\205\377\377\377\7\377\377\375\375\377\376" \
+ "\377\377\377\375\376\377\255\333\365Z\266\345[\267\350\202Y\270\350\1" \
+ "X\267\347\202Y\267\352\3Z\266\351Z\266\347Y\270\350\221[\267\350\2[\267" \
+ "\352\323\355\372\202\376\377\377\1\0=j\222\0=i\204\0>i\14\1\77h\0>g\0" \
+ "=f\1>j\0\77i\0>i\177\237\266\377\377\375\377\376\375\377\377\377\376" \
+ "\377\377\377\376\377\225\377\377\377\2\316\316\316::<\202;;=\202::<\4" \
+ ";;=kkm\377\377\377\376\376\376\235\377\377\377\2\376\376\376\235\235" \
+ "\235\202::<\1;;=\202::<\2;;=\234\234\236\242\377\377\377\3\346\346\346" \
+ "::<;;=\210::<\2\235\235\237\376\376\376\234\377\377\377\1\376\376\376" \
+ "\204\377\377\377\1lln\202::<\3;;=::<;;=\203::<\2;;=99;\240::<\1kkk\210" \
+ "\377\377\377\11\376\376\376\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\377\377\377\376\376\376\364\364\366GGI\205::<\6;;=\316\316\316\377" \
+ "\377\377\376\376\376\377\377\377\376\376\376\245\377\377\377\11\345\345" \
+ "\345;;=::<;;=::<;;=::<;;=\234\234\236\222\377\377\377\7\234\234\234;" \
+ ";=::<;;=99;;;=99;\203::<\1;;=\202::<\203;;=\2::<;;=\202::<\1;;=\202:" \
+ ":<\1;;=\202::<\12;;=::<;;=99;::<``b\332\332\332\376\376\376\377\377\377" \
+ "\376\376\376\202\377\377\377\5\376\376\376\377\377\377\376\376\376\377" \
+ "\377\377\376\376\376\232\377\377\377\5\376\376\376\377\377\377\376\376" \
+ "\376kkm;;=\202::<\1;;=\202::<\1\234\234\236\236\377\377\377\1\376\376" \
+ "\376\207\377\377\377\2\234\234\236;;=\202::<\1;;=\204::<\1;;=\211::<" \
+ "\1;;=\202::<\1;;=\202::<\1;;=\202::<\1;;=\203::<\3;;=kkm\346\346\346" \
+ "\203\377\377\377\1\376\376\376\204\377\377\377\1\376\376\376\221\377" \
+ "\377\377\2\234\234\236;;=\202::<\1;;=\202::<\1\316\316\316\252\377\377" \
+ "\377\4\316\316\316;;=99;;;=\203::<\1\234\234\234\210\377\377\377\7\376" \
+ "\377\377\377\375\376\377\377\375\256\332\363Y\270\350Y\267\352[\267\352" \
+ "\202[\267\350\5X\270\350X\270\352Y\267\352Y\270\350X\267\347\220[\267" \
+ "\350\5X\267\347[\267\350\325\355\367\377\377\373\377\377\375\202\0\77" \
+ "j\1\0>g\220\0>i\1\0\77j\203\0>i\202\0=i\6\1>j\0>i\0\77h\0>g\177\236\263" \
+ "\377\377\375\203\377\377\377\1\377\376\377\222\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\316\316\316\203::<\1;;=\202::<\2kkm\376\376\376" \
+ "\233\377\377\377\1\376\376\376\203\377\377\377\5\234\234\234::<;;=::" \
+ "<;;=\202::<\1\234\234\236\235\377\377\377\202\376\376\376\202\377\377" \
+ "\377\5\376\376\376\377\377\377xxz99;;;=\204::<\4;;=::<;;=\362\362\362" \
+ "\237\377\377\377\5\376\376\376\377\377\377\376\376\376kkm;;=\207::<\2" \
+ "99;;;=\240::<\1lll\205\377\377\377\1\376\376\376\203\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\202\377\377\377\4\265\265\267" \
+ ";;=::<;;=\202::<\2;;=__a\205\377\377\377\1\376\376\376\245\377\377\377" \
+ "\3\204\204\206::<;;=\204::<\2SSU\376\376\376\215\377\377\377\1\376\376" \
+ "\376\204\377\377\377\2\316\316\316__a\206::<\1;;=\214::<\5;;=::<;;=:" \
+ ":<;;=\203::<\2\234\234\234\363\363\363\204\377\377\377\1\376\376\376" \
+ "\243\377\377\377\1lln\206::<\2\233\233\235\376\376\376\233\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\207\377\377\377\3\345\345" \
+ "\345lln;;=\204::<\5;;=99;::<99;;;=\205::<\1;;=\203::<\3""99;;;=99;\206" \
+ "::<\2TTV\265\265\265\234\377\377\377\10\234\234\234;;=::<;;=::<;;=::" \
+ "<\316\316\316\252\377\377\377\1\315\315\315\206::<\4\235\235\235\376" \
+ "\376\376\377\377\377\376\376\376\205\377\377\377\12\377\377\373\377\377" \
+ "\377\377\377\375\267\340\366[\270\344Z\266\351[\267\352Z\266\351[\265" \
+ "\347[\267\350\202Y\270\350\2\\\270\351Z\266\347\220[\267\350\10X\267" \
+ "\347X\266\351\325\355\371\377\376\377\377\377\377\0\77k\0=h\3>j\220\0" \
+ "\77j\16\1>j\0=i\1>j\0=i\0\77j\0>i\0=h\0\77j\0\77h\1<f\177\236\263\377" \
+ "\377\375\376\376\377\376\377\377\225\377\377\377\202\376\376\376\2\317" \
+ "\317\317::<\202;;=\1::<\202;;=\1kkm\235\377\377\377\1\376\376\376\202" \
+ "\377\377\377\2\234\234\234;;=\205::<\2\233\233\235\376\376\376\232\377" \
+ "\377\377\1\376\376\376\204\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\316\316\316\203::<\1;;=\204::<\3\204\204\206\377\377\377\376\376\376" \
+ "\241\377\377\377\1lln\203::<\202;;=\203::<\1;;=\241::<\1kkk\206\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\206\377\377\377\1TTV\203:" \
+ ":<\4""99;;;=99;\265\265\267\253\377\377\377\3\331\331\331;;=99;\204:" \
+ ":<\2;;=\264\264\264\217\377\377\377\1\376\376\376\204\377\377\377\2\264" \
+ "\264\266SSU\202::<\2""99;;;=\203::<\3;;=::<;;=\206::<\5;;=99;;;=::<;" \
+ ";=\20299;\6\204\204\206\346\346\346\377\377\377\376\376\376\377\377\377" \
+ "\376\376\376\203\377\377\377\202\376\376\376\202\377\377\377\1\376\376" \
+ "\376\231\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377" \
+ "\377\12lll::<;;=::<99;::<;;=\234\234\236\377\377\377\376\376\376\233" \
+ "\377\377\377\1\375\375\375\213\377\377\377\4\316\316\316xxx;;=99;\204" \
+ "::<\1;;=\202::<\1;;=\204::<\4;;=::<;;=99;\203::<\1;;=\202::<\2SSS\265" \
+ "\265\265\210\377\377\377\3\376\376\376\377\377\377\376\376\376\223\377" \
+ "\377\377\1\234\234\234\206::<\1\316\316\316\250\377\377\377\3\376\376" \
+ "\376\377\377\377\315\315\315\202::<\7;;=::<;;=::<\234\234\234\377\377" \
+ "\377\376\376\376\202\377\377\377\21\376\376\376\377\377\377\376\377\373" \
+ "\377\377\377\376\377\377\376\377\375\377\376\377\353\366\374X\266\351" \
+ "X\270\350W\267\347X\270\350X\267\347Z\266\347\\\270\347X\267\345Y\270" \
+ "\350\221[\267\350\7Z\266\347[\267\350\327\355\372\377\375\377\377\377" \
+ "\377\0>g\0\77h\221\0=i\1\0>g\202\1\77h\1\0=i\202\0>i\11\0\77j\0>g\0>" \
+ "j\0\77m\336\347\354\376\377\377\377\376\377\376\377\377\377\377\375\222" \
+ "\377\377\377\1\376\376\376\203\377\377\377\1\316\316\316\202::<\1;;=" \
+ "\203::<\2kkm\376\376\376\233\377\377\377\1\376\376\376\202\377\377\377" \
+ "\3\376\376\376\234\234\234;;=\202::<\6""99;::<;;=\234\234\236\377\377" \
+ "\377\376\376\376\237\377\377\377\1\376\376\376\202\377\377\377\1SSS\202" \
+ ";;=\1""99;\204;;=\3\331\331\331\377\377\377\376\376\376\234\377\377\377" \
+ "\3\376\376\376\377\377\377\376\376\376\202\377\377\377\3lll::<;;=\202" \
+ "::<\202;;=\203::<\1;;=\240::<\1kkk\204\377\377\377\1\376\376\376\211" \
+ "\377\377\377\3\302\302\302;;;999\202::<\3;;=::<TTT\210\377\377\377\1" \
+ "\376\376\376\244\377\377\377\2kkk;;=\202::<\203:::\1TTT\226\377\377\377" \
+ "\3\301\301\301xxz;;=\202::<\1;;=\202::<\1;;=\202::<\5;;=::<;;=::<;;=" \
+ "\202::<\5;;=99;SSU\235\235\237\347\347\351\204\377\377\377\1\376\376" \
+ "\376\207\377\377\377\3\376\376\376\377\377\377\376\376\376\235\377\377" \
+ "\377\10kkk:::::<999;;;:::;;;\233\233\233\236\377\377\377\1\376\376\376" \
+ "\211\377\377\377\1\376\376\376\202\377\377\377\3\346\346\350\251\251" \
+ "\253``b\202::<\3;;=::<;;=\202::<\1;;=\205::<\1;;=\203::<\5;;=FFH\204" \
+ "\204\204\316\316\316\376\376\376\204\377\377\377\1\376\376\376\232\377" \
+ "\377\377\1\234\234\234\202::<\5""99;;;=99;;;;\315\315\315\252\377\377" \
+ "\377\3\316\316\316:::;;;\202:::\3;;;::<\234\234\234\206\377\377\377\1" \
+ "\377\377\375\203\377\376\377\11\377\377\377\377\377\375\303\344\367W" \
+ "\270\345^\266\344X\267\347Y\271\353Z\266\351\\\266\350\202Y\270\350\221" \
+ "[\267\352\3[\267\350[\265\347\325\355\371\202\376\377\377\3\2=e\0>g\0" \
+ "\77m\220\0=i\6\0\77j\0>i\0=h\0\77j\0=i\0\77j\202\0>g\2\1\77h\240\266" \
+ "\304\204\377\377\377\2\376\376\376\377\377\375\223\377\377\377\14\376" \
+ "\376\376\377\377\377\315\315\315;;=::<:::;;;:::;;;kkk\377\377\377\376" \
+ "\376\376\233\377\377\377\1\376\376\376\202\377\377\377\10\235\235\235" \
+ "99;::<999;;;:::;;;\233\233\233\234\377\377\377\1\376\376\376\207\377" \
+ "\377\377\1\265\265\265\202::<\1;;=\203::<\1kkk\203\377\377\377\1\376" \
+ "\376\376\240\377\377\377\2kkk:::\202::<\3;;=99;;;=\244::<\1kkk\205\377" \
+ "\377\377\1\376\376\376\210\377\377\377\1\346\346\346\206\316\316\316" \
+ "\3\332\332\332\377\377\377\377\377\375\253\377\377\377\2\346\346\346" \
+ "\316\316\316\202\316\316\320\203\316\316\316\1\315\315\315\225\377\377" \
+ "\377\202\376\376\376\202\377\377\377\4\316\316\320\234\234\236kkmSSU" \
+ "\205::<\1;;=\203::<\5kkm\204\204\206\264\264\266\346\346\350\376\376" \
+ "\376\214\377\377\377\1\376\376\376\202\377\377\377\202\376\376\376\231" \
+ "\377\377\377\1\376\376\376\203\377\377\377\2\331\331\331\317\317\317" \
+ "\205\316\316\316\1\347\347\347\243\377\377\377\1\376\376\376\211\377" \
+ "\377\377\5\376\376\377\347\347\351\265\265\267\204\204\206lln\212::<" \
+ "\4``bxxz\234\234\236\332\332\332\207\377\377\377\1\376\376\376\210\377" \
+ "\377\377\1\376\376\376\222\377\377\377\1\346\346\346\203\316\316\320" \
+ "\4\316\316\316\316\316\320\315\315\315\364\364\364\251\377\377\377\2" \
+ "\376\376\376\364\364\364\205\316\316\316\2\316\316\320\346\346\346\210" \
+ "\377\377\377\16\377\376\377\377\377\375\376\377\377\377\377\377\377\375" \
+ "\377\326\354\371\241\326\366\206\310\352\200\312\357\202\312\362\204" \
+ "\310\357\204\312\356\203\311\355\205\311\360\220\204\312\356\10\203\311" \
+ "\355\201\311\361\342\360\371\376\377\377\377\377\375>n\222Bm\215@n\220" \
+ "\220@n\217\3@l\217An\217Bo\220\202An\217\5@m\214Dm\213l\223\260\277\320" \
+ "\332\376\377\377\202\377\377\377\1\377\377\375\202\377\377\377\1\376" \
+ "\377\377\225\377\377\377\3\363\363\363\317\317\321\316\316\320\204\316" \
+ "\316\316\1\332\332\332\240\377\377\377\1\346\346\346\202\316\316\320" \
+ "\204\316\316\316\1\347\347\347\243\377\377\377\3\376\376\376\363\363" \
+ "\363lln\202kkm\1lln\202kkm\1\301\301\301\240\377\377\377\1\376\376\376" \
+ "\203\377\377\377\2\331\331\331\317\317\317\202\316\316\316\202\317\317" \
+ "\317\245\316\316\316\2\332\332\332\376\376\376\351\377\377\377\5\332" \
+ "\332\332\315\315\315\316\316\316\315\315\315\363\363\363\361\377\377" \
+ "\377\202\316\316\316\1\317\317\317\202\316\316\316\2\315\315\315\363" \
+ "\363\363\377\377\377\377\377\377\377\377\377\377\377\377\334\377\377" \
+ "\377\1\376\376\376\375\377\377\377\1\376\376\376\377\377\377\377\377" \
+ "\377\377\377\377\377\377\377\340\377\377\377\1\376\376\376\370\377\377" \
+ "\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\342" \
+ "\377\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377" \
+ "\377\377\377\377\377\334\377\377\377\1\376\376\376\362\377\377\377\1" \
+ "\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\346\377" \
+ "\377\377\1\376\376\376\363\377\377\377\1\376\376\376\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\342\377\377\377\1\376\376\376\373\377" \
+ "\377\377\1\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377" \
+ "\340\377\377\377\3\376\376\376\377\377\377\376\376\376\377\377\377\377" \
+ "\377\377\377\377\377\377\377\377\377\377\377\377\243\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\203\377\377\377\1\376\376\376\233\377" \
+ "\377\377\1\376\376\376\205\377\377\377\1\376\376\376\214\377\377\377" \
+ "\1\376\376\376\205\377\377\377\1\376\376\376\260\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\300\377\377\377\1\376\376\376\306\377\377" \
+ "\377\1\376\376\376\233\377\377\377\4\376\377\377\376\376\376\377\376" \
+ "\377\377\377\377\203\376\377\375\203\377\377\377\3\377\377\375\376\377" \
+ "\375\376\377\377\265\377\377\377\4\377\377\375\377\376\377\376\377\377" \
+ "\377\377\375\202\377\376\377\210\377\377\377\7\377\377\375\376\377\377" \
+ "\377\377\377\375\377\376\376\377\377\377\376\377\376\377\377\211\377" \
+ "\377\377\4\376\377\375\377\377\377\376\376\376\377\377\375\202\377\377" \
+ "\377\2\377\377\375\376\376\376\220\377\377\377\1\376\377\375\202\377" \
+ "\377\375\5\377\376\377\377\377\373\377\377\377\375\377\376\377\377\375" \
+ "\210\377\377\377\1\377\376\377\202\377\377\375\202\377\377\377\3\376" \
+ "\377\377\377\377\375\377\376\377\213\377\377\377\3\376\377\377\376\377" \
+ "\375\377\377\375\203\377\377\377\203\376\377\375\4\377\377\377\377\376" \
+ "\377\376\376\376\376\377\377\233\377\377\377\3\376\377\377\376\377\375" \
+ "\377\377\375\203\377\377\377\203\376\377\375\4\377\377\377\377\376\377" \
+ "\376\376\376\376\377\377\210\377\377\377\1\377\376\377\203\377\377\377" \
+ "\4\376\377\377\377\377\375\377\376\377\376\377\373\211\377\377\377\4" \
+ "\376\377\377\376\376\374\377\376\377\377\375\376\226\377\377\377\5\376" \
+ "\377\377\375\377\374\377\377\375\376\375\377\377\377\375\210\377\377" \
+ "\377\1\377\377\375\202\376\377\377\1\377\377\373\242\377\377\377\1\376" \
+ "\376\376\212\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376" \
+ "\237\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\214\377" \
+ "\377\377\1\376\376\376\204\377\377\377\202\376\376\376\257\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\246\377\377\377\1\376\376\376\224\377\377\377\1\376\376\376\250" \
+ "\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\236\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\230\377\377\377\4\377\377" \
+ "\373\376\377\377\376\376\376\377\376\377\203\377\377\377\1\377\377\375" \
+ "\202\377\377\377\1\377\376\377\202\377\377\375\3\377\377\377\377\377" \
+ "\375\376\376\374\260\377\377\377\2\377\377\375\376\376\376\203\377\376" \
+ "\377\214\377\377\377\7\376\377\377\377\376\377\377\377\375\377\377\377" \
+ "\377\376\377\375\377\376\377\377\375\210\377\377\377\7\377\376\374\377" \
+ "\377\375\377\376\377\377\377\375\376\376\376\377\377\377\376\376\376" \
+ "\221\377\377\377\1\377\376\377\203\377\377\377\202\377\377\375\212\377" \
+ "\377\377\2\377\377\375\377\377\377\202\377\377\375\214\377\377\377\3" \
+ "\376\376\374\377\377\375\377\377\377\202\377\377\375\1\377\376\377\202" \
+ "\377\377\377\1\377\377\375\203\377\377\377\4\377\376\377\376\376\376" \
+ "\376\377\377\377\377\373\230\377\377\377\3\376\376\374\377\377\375\377" \
+ "\377\377\202\377\377\375\1\377\376\377\202\377\377\377\1\377\377\375" \
+ "\203\377\377\377\4\377\376\377\376\376\376\376\377\377\377\377\373\213" \
+ "\377\377\377\1\377\376\374\214\377\377\377\2\377\377\375\377\376\377" \
+ "\202\377\377\375\3\376\377\377\377\377\377\377\377\373\221\377\377\377" \
+ "\3\376\377\375\376\377\377\377\376\377\204\377\377\377\1\377\377\375" \
+ "\212\377\377\377\5\377\376\377\377\377\375\377\377\377\376\377\375\376" \
+ "\377\373\243\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376" \
+ "\204\377\377\377\1\376\376\376\242\377\377\377\1\376\376\376\205\377" \
+ "\377\377\1\376\376\376\213\377\377\377\1\376\376\376\206\377\377\377" \
+ "\1\376\376\376\263\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\270\377\377\377\1\376\376\376\312\377\377\377\1\376\376\376\234\377" \
+ "\377\377\1\377\377\375\202\376\377\377\7\377\376\377\377\377\377\376" \
+ "\377\377\377\376\377\377\377\375\377\377\377\376\377\377\202\377\376" \
+ "\377\2\376\377\375\376\377\377\262\377\377\377\10\377\377\375\376\377" \
+ "\377\377\376\377\377\377\373\377\377\377\377\376\377\376\377\375\377" \
+ "\377\375\211\377\377\377\3\376\377\377\377\376\377\377\377\375\202\377" \
+ "\377\377\2\376\377\377\376\376\376\210\377\377\377\202\377\376\377\4" \
+ "\374\377\377\376\377\377\377\376\377\377\377\375\222\377\377\377\4\377" \
+ "\376\375\376\377\377\377\377\377\376\377\377\202\377\376\377\202\377" \
+ "\377\375\210\377\377\377\4\377\377\375\377\377\377\377\377\375\377\377" \
+ "\377\202\377\376\377\2\377\377\377\376\377\377\212\377\377\377\2\376" \
+ "\377\377\376\377\375\202\377\376\377\7\376\377\377\377\377\377\377\377" \
+ "\375\377\376\377\376\377\377\377\377\377\377\376\377\202\376\377\377" \
+ "\1\377\377\375\232\377\377\377\2\376\377\377\376\377\375\202\377\376" \
+ "\377\7\376\377\377\377\377\377\377\377\375\377\376\377\376\377\377\377" \
+ "\377\377\377\376\377\202\376\377\377\1\377\377\375\210\377\377\377\1" \
+ "\377\377\375\202\377\377\377\4\377\377\375\377\376\377\377\377\377\376" \
+ "\377\377\211\377\377\377\7\375\376\377\377\377\375\377\376\377\376\376" \
+ "\377\376\377\375\375\377\376\377\377\375\222\377\377\377\6\376\377\377" \
+ "\377\376\377\377\377\377\377\377\375\377\376\377\376\377\377\213\377" \
+ "\377\377\202\377\376\377\3\377\377\375\376\377\377\376\377\375\236\377" \
+ "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\203\377\377\377\2\376\376\376\377\377\377\202\376\376" \
+ "\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\204" \
+ "\377\377\377\1\376\376\376\235\377\377\377\1\376\376\376\217\377\377" \
+ "\377\1\376\376\376\206\377\377\377\1\376\376\376\260\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\241\377\377\377\202\376\376\376\204" \
+ "\377\377\377\1\376\376\376\222\377\377\377\1\376\376\376\205\377\377" \
+ "\377\1\376\376\376\246\377\377\377\1\376\376\376\233\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\234\377\377\377\15\376\376\376\377\377" \
+ "\377\377\376\377\377\377\375\375\377\376\377\377\377\376\377\375\377" \
+ "\377\377\375\376\377\377\377\377\377\377\375\376\377\377\377\377\377" \
+ "\202\377\376\377\260\377\377\377\7\377\376\377\376\377\377\377\377\377" \
+ "\376\377\377\377\377\377\377\377\375\376\377\377\212\377\377\377\1\376" \
+ "\376\374\203\377\377\377\3\376\376\377\377\377\375\376\377\377\210\377" \
+ "\377\377\10\376\377\377\377\376\377\374\377\373\376\377\373\377\376\377" \
+ "\376\376\376\377\377\377\376\377\375\220\377\377\377\2\377\376\377\377" \
+ "\377\377\202\377\377\375\202\377\377\377\2\376\376\374\376\377\377\210" \
+ "\377\377\377\1\376\377\377\202\377\377\377\5\376\377\377\377\377\377" \
+ "\376\376\376\377\377\377\376\377\375\210\377\377\377\202\377\376\377" \
+ "\15\377\377\377\376\377\377\377\377\375\377\377\377\375\376\377\377\377" \
+ "\377\376\377\375\377\377\377\375\377\376\377\377\375\377\376\377\377" \
+ "\377\377\376\376\376\231\377\377\377\202\377\376\377\15\377\377\377\376" \
+ "\377\377\377\377\375\377\377\377\375\376\377\377\377\377\376\377\375" \
+ "\377\377\377\375\377\376\377\377\375\377\376\377\377\377\377\376\376" \
+ "\376\211\377\377\377\4\377\376\377\377\377\377\376\377\375\376\377\377" \
+ "\202\377\377\377\2\376\377\377\376\377\375\210\377\377\377\1\376\377" \
+ "\375\202\376\376\376\202\377\377\377\2\377\377\375\375\376\377\221\377" \
+ "\377\377\10\377\377\375\377\377\377\376\376\374\376\377\373\376\376\376" \
+ "\377\376\377\376\377\377\377\377\375\210\377\377\377\6\376\376\376\377" \
+ "\377\377\377\377\375\377\377\377\374\375\377\377\377\375\242\377\377" \
+ "\377\1\376\376\376\214\377\377\377\1\376\376\376\204\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\235\377\377\377\1\376\376\376\203\377" \
+ "\377\377\202\376\376\376\212\377\377\377\1\376\376\376\202\377\377\377" \
+ "\202\376\376\376\264\377\377\377\5\376\376\376\377\377\377\376\376\376" \
+ "\377\377\377\376\376\376\242\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\202\377\377\377\1\376\376\376\223\377\377\377\1\376\376\376" \
+ "\244\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\233\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\234\377\377\377" \
+ "\1\375\377\372\202\377\377\377\3\376\376\376\377\377\375\377\377\377" \
+ "\202\376\377\377\204\377\377\377\4\376\377\377\377\377\377\377\376\377" \
+ "\375\377\372\260\377\377\377\202\377\377\375\2\377\377\377\376\375\377" \
+ "\202\377\377\377\1\375\377\376\212\377\377\377\6\377\377\375\377\377" \
+ "\377\376\377\375\377\377\375\377\376\377\377\376\375\212\377\377\377" \
+ "\1\377\376\377\202\377\377\377\4\377\375\376\377\377\377\377\377\373" \
+ "\376\375\377\221\377\377\377\203\376\376\376\4\377\377\375\376\376\374" \
+ "\377\376\377\376\376\374\210\377\377\377\5\377\376\377\377\377\375\377" \
+ "\376\377\376\376\376\376\377\375\202\377\377\377\1\376\376\376\210\377" \
+ "\377\377\4\375\377\372\377\376\377\377\377\377\376\377\377\204\377\377" \
+ "\377\202\376\377\377\3\377\377\377\377\377\375\376\376\376\202\377\377" \
+ "\377\1\375\377\372\230\377\377\377\4\375\377\372\377\376\377\377\377" \
+ "\377\376\377\377\204\377\377\377\202\376\377\377\3\377\377\377\377\377" \
+ "\375\376\376\376\202\377\377\377\1\375\377\372\210\377\377\377\3\376" \
+ "\377\377\377\377\377\376\376\376\202\376\377\377\202\377\377\377\1\376" \
+ "\377\375\210\377\377\377\7\376\376\377\377\377\375\376\377\375\376\376" \
+ "\376\377\376\377\377\377\377\376\377\377\221\377\377\377\5\376\376\376" \
+ "\376\377\377\377\377\377\375\375\375\377\376\377\202\377\377\377\1\377" \
+ "\377\375\211\377\377\377\7\377\376\377\376\376\374\376\377\377\377\377" \
+ "\377\377\376\377\377\377\375\377\377\373\233\377\377\377\1\376\376\376" \
+ "\205\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\203\377" \
+ "\377\377\1\376\376\376\204\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\204\377\377\377\1\376\376\376\237\377\377\377\1\376\376\376" \
+ "\212\377\377\377\1\376\376\376\213\377\377\377\1\376\376\376\255\377" \
+ "\377\377\1\376\376\376\247\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\224\377\377\377\1\376\376\376\247\377\377\377\1\376\376" \
+ "\376\236\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\232" \
+ "\377\377\377\10\377\376\377\377\377\375\377\377\377\376\377\377\376\376" \
+ "\376\377\376\377\377\377\375\377\376\377\202\377\377\375\1\377\376\377" \
+ "\202\377\377\377\3\377\376\377\377\375\376\377\376\377\260\377\377\377" \
+ "\2\377\376\377\377\377\377\202\377\376\377\4\377\377\375\376\376\374" \
+ "\377\375\377\377\376\377\210\377\377\377\3\376\376\374\377\376\377\376" \
+ "\376\376\204\377\377\377\1\376\377\375\210\377\377\377\4\375\377\374" \
+ "\377\377\377\377\375\376\377\376\377\203\377\377\377\1\377\377\375\220" \
+ "\377\377\377\3\376\377\377\377\377\375\376\377\377\202\377\377\377\3" \
+ "\377\376\377\373\377\377\376\377\377\211\377\377\377\202\376\377\375" \
+ "\1\377\377\375\203\377\377\377\1\377\376\377\210\377\377\377\3\377\376" \
+ "\377\377\375\376\377\376\377\202\377\377\377\1\377\376\377\202\377\377" \
+ "\375\10\377\376\377\377\377\375\377\376\377\376\376\376\376\377\377\377" \
+ "\377\377\377\377\375\377\376\377\230\377\377\377\3\377\376\377\377\375" \
+ "\376\377\376\377\202\377\377\377\1\377\376\377\202\377\377\375\10\377" \
+ "\376\377\377\377\375\377\376\377\376\376\376\376\377\377\377\377\377" \
+ "\377\377\375\377\376\377\210\377\377\377\2\377\377\375\375\376\371\202" \
+ "\377\376\377\3\377\377\377\377\377\375\377\376\377\212\377\377\377\1" \
+ "\377\375\376\202\377\377\377\4\377\377\375\376\376\376\376\377\377\377" \
+ "\376\377\220\377\377\377\2\376\377\377\376\376\377\202\377\377\377\2" \
+ "\376\377\375\375\377\374\212\377\377\377\10\373\377\376\377\377\377\377" \
+ "\377\375\376\376\374\377\377\375\377\376\377\377\377\377\376\377\377" \
+ "\235\377\377\377\1\376\376\376\202\377\377\377\7\316\316\320\250\250" \
+ "\252\221\221\223llnjjlGGI99;\204::<\7TTVkkmyy{\234\234\236\265\265\267" \
+ "\332\332\332\376\376\376\237\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\222\377\377\377\1\376\376\376\205\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\255\377\377\377\1\376\376\376\246\377\377\377" \
+ "\1\376\376\376\227\377\377\377\1\376\376\376\252\377\377\377\1\376\376" \
+ "\376\233\377\377\377\1\376\376\376\236\377\377\377\17\305\344\240\303" \
+ "\342\237\304\343\240\304\343\237\307\342\237\303\342\236\305\342\240" \
+ "\303\342\236\305\342\237\304\343\240\304\343\237\304\341\237\304\343" \
+ "\237\323\352\266\376\377\375\250\377\377\377\210\305\342\240\10\305\342" \
+ "\237\303\342\234\304\343\237\306\341\236\304\343\240\322\352\270\376" \
+ "\377\377\375\377\376\211\377\377\377\5\377\376\377\376\376\376\377\376" \
+ "\377\360\371\350\305\342\237\202\304\341\236\210\305\342\240\5\304\341" \
+ "\236\327\356\302\376\377\377\377\377\373\376\377\375\202\377\377\375" \
+ "\1\377\376\377\220\377\377\377\202\377\377\375\2\376\377\377\377\377" \
+ "\377\202\377\377\375\2\304\343\237\306\341\236\210\305\342\240\5\307" \
+ "\342\237\303\342\236\304\341\236\341\357\314\377\377\375\213\377\377" \
+ "\377\17\376\377\375\323\352\266\304\343\237\304\341\237\304\343\237\304" \
+ "\343\240\305\342\237\303\342\236\305\342\240\303\342\236\307\342\237" \
+ "\304\343\237\304\343\240\303\342\237\305\344\240\231\377\377\377\17\376" \
+ "\377\375\323\352\266\304\343\237\304\341\237\304\343\237\304\343\240" \
+ "\305\342\237\303\342\236\305\342\240\303\342\236\307\342\237\304\343" \
+ "\237\304\343\240\303\342\237\305\344\240\211\377\377\377\10\360\367\347" \
+ "\306\343\241\303\342\237\307\342\237\303\342\237\304\343\235\307\341" \
+ "\240\304\343\240\210\305\342\240\7\315\347\252\376\377\375\377\375\376" \
+ "\376\377\375\377\377\377\377\377\373\376\377\377\221\377\377\377\10\377" \
+ "\377\375\376\377\375\323\352\266\307\341\240\307\342\237\305\342\240" \
+ "\307\340\236\306\341\236\210\305\342\240\4\304\343\237\311\335\236\377" \
+ "\377\377\377\376\377\203\377\377\377\1\376\377\377\230\377\377\377\1" \
+ "\376\376\376\203\377\377\377\3\346\346\346\251\251\251jjl\202;;=\210" \
+ "::<\1;;=\202::<\2;;=99;\203::<\5FFHxxx\265\265\265\363\363\363\376\376" \
+ "\376\234\377\377\377\2\376\376\376\346\346\346\214\234\234\234\1\235" \
+ "\235\235\203\234\234\234\3\235\235\235\234\234\234\250\250\250\203\316" \
+ "\316\316\1\346\346\346\263\377\377\377\202\250\250\250\245\377\377\377" \
+ "\1\316\316\316\222\234\234\234\1\302\302\302\203\316\316\316\1\363\363" \
+ "\363\247\377\377\377\3\316\316\316\234\234\234\235\235\235\240\234\234" \
+ "\234\1\316\316\316\231\377\377\377\6\215\305>\216\306A\215\305@\213\310" \
+ "=\215\305>\212\307>\202\214\305@\6\214\306>\212\306@\214\306<\215\304" \
+ "B\214\306>\252\323m\251\377\377\377\210\214\306>\10\215\305@\215\307" \
+ "\77\212\307>\217\304@\214\305@\251\323m\377\377\377\377\377\375\213\377" \
+ "\377\377\5\377\375\377\341\363\315\215\305>\212\307>\215\305@\210\214" \
+ "\306>\6\215\306A\220\305\77\350\365\333\377\377\377\376\377\377\377\376" \
+ "\377\202\376\377\377\225\377\377\377\3\377\376\377\214\306>\215\306A" \
+ "\210\214\306>\6\215\305>\212\310\77\215\305@\307\341\240\376\377\377" \
+ "\377\376\377\213\377\377\377\6\252\323m\214\306>\215\304B\214\306<\212" \
+ "\306@\214\306>\202\214\305@\6\212\307>\215\305>\213\310=\215\305@\216" \
+ "\306A\215\305>\232\377\377\377\6\252\323m\214\306>\215\304B\214\306<" \
+ "\212\306@\214\306>\202\214\305@\6\212\307>\215\305>\213\310=\215\305" \
+ "@\216\306A\215\305>\211\377\377\377\4\376\377\377\242\321a\213\307A\215" \
+ "\305>\202\214\306>\2\215\305@\215\307\77\210\214\306>\7\215\305<\332" \
+ "\354\304\377\377\377\376\377\375\376\376\376\377\376\377\376\376\376" \
+ "\221\377\377\377\10\377\376\377\342\362\316\215\305>\213\310\77\212\305" \
+ "D\212\307<\216\306\77\211\307>\211\214\306>\4\304\343\240\373\377\376" \
+ "\377\377\377\375\377\376\202\377\377\377\1\377\377\375\225\377\377\377" \
+ "\1\376\376\376\204\377\377\377\6\265\265\267__a99;;;=::<;;=\202::<\1" \
+ ";;=\202::<\1;;=\202::<\1;;=\203::<\1;;=\203::<\3;;=::<99;\202::<\2xx" \
+ "z\301\301\301\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\206\377\377\377\1\376\376\376\217\377\377\377\1\316\316\316\205" \
+ "::<\202;;=\221::<\4TTVwwy\250\250\252\346\346\350\255\377\377\377\1\316" \
+ "\316\320\202::<\1\316\316\316\244\377\377\377\1\234\234\236\204::<\1" \
+ ";;=\205::<\3;;=::<;;=\206::<\1;;=\204::<\6SSUkkm\204\204\206\250\250" \
+ "\250\316\316\316\376\376\376\206\377\377\377\1\376\376\376\231\377\377" \
+ "\377\1\234\234\234\206::<\3;;=::<;;=\222::<\1;;=\204::<\3;;=::<\234\234" \
+ "\236\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214" \
+ "\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325" \
+ "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306>" \
+ "\15\212\306@\215\307\77\233\316W\365\374\364\377\376\375\376\377\377" \
+ "\377\376\377\377\377\375\377\377\377\377\377\375\376\376\376\377\377" \
+ "\377\376\376\374\202\377\377\377\1\376\376\376\216\377\377\377\213\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\212\377\377\377\7\350\364\334\215\305>\212\307" \
+ "<\214\305@\215\304B\215\305@\213\310\77\210\214\306>\10\214\305@\225" \
+ "\311J\370\373\362\377\376\377\376\377\377\377\377\375\377\377\377\376" \
+ "\377\377\210\377\377\377\40\376\377\377\376\377\375\377\376\377\377\377" \
+ "\377\375\376\377\377\377\375\377\376\377\376\377\377\370\373\364\233" \
+ "\314W\215\307\77\214\304=\212\306@\215\307\77\213\305=\215\307\77\214" \
+ "\306>\217\304@\215\306A\212\307>\214\306<\215\306A\214\306>\211\307@" \
+ "\242\321a\377\377\377\377\376\377\376\377\377\377\376\377\377\377\377" \
+ "\376\377\377\377\376\377\223\377\377\377\7\376\376\376\377\377\377\376" \
+ "\376\376\377\377\377\363\363\365\234\234\236FFH\202::<\10;;=99;;;=::" \
+ "<;;=::<99;;;=\203::<\1;;=\203::<\2;;=99;\204::<\11""99;;;=::<;;=::<;" \
+ ";=TTV\265\265\265\363\363\363\203\377\377\377\1\376\376\376\207\377\377" \
+ "\377\1\376\376\376\215\377\377\377\1\316\316\316\205::<\3;;=::<;;=\202" \
+ "::<\1;;=\214::<\3;;=99;;;=\202::<\4lln\316\316\316\376\376\376\377\377" \
+ "\377\202\376\376\376\246\377\377\377\2\376\376\376xxz\202::<\2xxx\376" \
+ "\376\376\243\377\377\377\1\234\234\236\204::<\202;;=\205::<\1;;=\204" \
+ "::<\1;;=\202::<\1""99;\206::<\1;;=\202::<\6;;=kkk\250\250\250\346\346" \
+ "\346\377\377\377\376\376\376\205\377\377\377\1\376\376\376\225\377\377" \
+ "\377\1\234\234\234\204::<\1;;=\202::<\4;;=::<99;;;=\225::<\3;;=::<\234" \
+ "\234\236\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4" \
+ "\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250" \
+ "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306" \
+ ">\4\215\306A\213\304\77\215\305@\262\327x\202\377\377\377\1\376\377\375" \
+ "\203\377\377\375\204\377\377\377\1\376\376\376\217\377\377\377\213\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\212\377\377\377\7\376\376\376\305\342\237\212" \
+ "\307>\214\306>\212\307<\214\306>\212\307>\210\214\306>\3\214\306<\215" \
+ "\306A\300\337\221\202\377\377\377\3\377\376\377\376\376\376\377\377\375" \
+ "\210\377\377\377\1\377\375\377\202\377\377\377\2\376\376\377\376\377" \
+ "\375\202\377\376\377\30\377\377\377\277\340\221\215\306A\213\305=\215" \
+ "\305>\212\306B\214\306>\216\306\77\214\306<\212\307>\215\307=\213\305" \
+ ";\215\307\77\216\305C\214\306>\214\305@\216\306\77\347\365\333\377\376" \
+ "\377\377\377\375\376\377\377\377\376\374\377\377\377\377\377\375\222" \
+ "\377\377\377\1\376\376\376\204\377\377\377\12\265\265\267FFH;;=::<;;" \
+ "=99;::<;;=::<;;=\202::<\4<<>99;::<;;=\202::<\1;;=\203::<\1<<>\204::<" \
+ "\5<<>99;;;=99;;;=\202::<\4:::SSS\266\266\266\376\376\376\203\377\377" \
+ "\377\1\376\376\376\204\377\377\377\1\376\376\376\216\377\377\377\1\316" \
+ "\316\316\204::<\3;;=::<;;=\204::<\1;;=\214::<\1;;=\202::<\1;;=\202::" \
+ "<\2yyy\363\363\363\202\377\377\377\1\376\376\376\245\377\377\377\3\346" \
+ "\346\346::<;;=\202::<\1\347\347\347\202\377\377\377\1\376\376\376\240" \
+ "\377\377\377\1\234\234\236\203::<\4;;=99;::<;;=\202::<\7;;=::<;;=99;" \
+ ";;=::<;;=\203::<\202;;=\210::<\1""99;\202::<\4;;=xxz\317\317\317\376" \
+ "\376\376\202\377\377\377\1\376\376\376\227\377\377\377\1\234\234\234" \
+ "\204::<\1""99;\203;;=\224::<\1;;=\204::<\2<<>\234\234\236\231\377\377" \
+ "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \
+ "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \
+ "\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\10\215\305>\214\306" \
+ ">\213\307A\214\306>\315\345\253\377\377\375\377\376\377\376\377\377\226" \
+ "\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \
+ "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \
+ "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \
+ "\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377\7\377\377" \
+ "\375\377\376\377\376\376\376\241\321a\212\307>\211\305\77\215\306A\211" \
+ "\214\306>\4\213\310\77\214\305@\213\305=\342\361\320\202\377\376\377" \
+ "\2\377\377\375\377\376\377\210\377\377\377\1\377\376\377\202\377\377" \
+ "\377\30\377\377\375\376\377\377\377\377\375\376\377\377\351\366\334\214" \
+ "\305B\211\306;\215\307\77\214\306>\212\306@\215\305>\215\305@\212\307" \
+ ">\214\305@\212\306B\214\306>\213\305=\213\310\77\215\305>\215\307\77" \
+ "\314\345\253\377\375\377\377\376\374\376\377\377\203\377\377\377\1\377" \
+ "\376\374\225\377\377\377\2\345\345\345kkm\205::<\202;;=\203::<\1;;=\203" \
+ "::<\1;;=\202::<\202;;=\202::<\1;;=\210::<\2;;=99;\205::<\2```\331\331" \
+ "\331\211\377\377\377\1\376\376\376\214\377\377\377\1\316\316\316\206" \
+ "::<\5""99;::<;;=::<99;\212::<\1;;=\202::<\1;;=\204::<\4;;=::<FFF\316" \
+ "\316\316\247\377\377\377\3\205\205\207;;=99;\202::<\1\204\204\206\203" \
+ "\377\377\377\1\376\376\376\237\377\377\377\1\234\234\236\205::<\1;;=" \
+ "\204::<\1""99;\202;;=\202::<\3;;=::<;;=\203::<\1;;=\202::<\1;;=\204:" \
+ ":<\1;;=\205::<\2jjl\316\316\316\203\377\377\377\1\376\376\376\225\377" \
+ "\377\377\1\234\234\234\204::<\1;;=\202::<\3;;=::<;;=\222::<\7;;=::<;" \
+ ";=::<;;=::<\234\234\236\231\377\377\377\3\214\305@\214\306>\214\305@" \
+ "\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215" \
+ "\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214" \
+ "\305@\210\214\306>\10\215\305@\212\307>\214\305@\215\306A\214\305@\352" \
+ "\364\334\376\376\377\377\377\373\202\377\377\377\3\376\376\376\377\377" \
+ "\377\377\377\375\202\377\377\377\1\376\376\374\216\377\377\377\213\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\211\377\377\377\1\376\377\377\202\377\377\375" \
+ "\5\347\364\332\215\307\77\215\306C\214\307;\216\306\77\210\214\306>\10" \
+ "\214\305@\214\305D\215\307\77\233\314V\371\374\363\376\377\377\377\377" \
+ "\377\377\377\375\210\377\377\377\20\375\377\374\377\376\377\376\376\377" \
+ "\376\377\377\377\376\377\376\377\375\376\377\377\244\317d\212\307>\215" \
+ "\306A\215\305@\214\305@\211\306=\215\307=\215\306A\214\305@\204\214\306" \
+ ">\14\211\305A\212\307>\251\324k\377\376\377\377\375\376\376\377\377\377" \
+ "\377\377\377\377\375\377\377\377\377\377\375\377\377\377\377\377\375" \
+ "\217\377\377\377\1\376\376\376\203\377\377\377\2\265\265\267FFH\205:" \
+ ":<\1;;=\203::<\202;;=\7:::TTT\203\203\203\235\235\235\316\316\316\332" \
+ "\332\332\377\377\377\202\376\376\376\202\377\377\377\5\316\316\316\317" \
+ "\317\317\234\234\234yyyFFF\202::<\1;;=\202::<\3""99;;;=99;\204::<\2;" \
+ ";=\233\233\233\206\377\377\377\1\376\376\376\216\377\377\377\1\316\316" \
+ "\316\204::<\1;;=\205::<\1;;=\212::<\3""99;::<;;=\202::<\2;;=99;\204:" \
+ ":<\2;;=\265\265\265\245\377\377\377\4\346\346\346::<99;;;=\202::<\4""9" \
+ "9;\347\347\347\377\377\377\376\376\376\240\377\377\377\1\234\234\236" \
+ "\205::<\1;;=\203::<\202;;=\1""99;\203;;=\2::<;;=\203::<\1;;=\202::<\2" \
+ ";;=::<\202;;=\7::<;;=99;::<;;=99;;;=\202::<\3;;=xxx\362\362\362\227\377" \
+ "\377\377\1\234\234\234\205::<\202;;=\4::<;;=::<;;=\223::<\2;;=99;\202" \
+ ";;=\1\234\234\236\231\377\377\377\3\214\305@\214\306>\214\305@\207\214" \
+ "\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306" \
+ ">\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \
+ "\214\306>\12\212\307>\215\306A\214\305@\215\307\77\213\306:\226\312N" \
+ "\372\374\361\375\376\377\377\377\375\377\377\373\224\377\377\377\213" \
+ "\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p" \
+ "\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \
+ "@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>" \
+ "\3\214\305@\214\306>\214\305@\211\377\377\377\10\376\377\377\376\376" \
+ "\377\376\377\377\377\375\376\307\342\237\214\306<\215\306A\214\305@\210" \
+ "\214\306>\5\215\307\77\213\305=\216\306A\213\310\77\277\337\223\202\377" \
+ "\377\375\1\377\376\377\210\377\377\377\14\376\377\375\376\376\376\377" \
+ "\376\377\377\377\375\377\376\377\377\377\377\303\342\236\215\307\77\216" \
+ "\306A\215\305>\214\306<\215\306A\203\214\306>\20\215\307\77\212\307>" \
+ "\215\305@\216\306\77\214\305@\216\307<\223\312K\356\372\346\377\377\377" \
+ "\376\377\377\375\377\376\377\377\377\377\376\377\377\377\375\377\377" \
+ "\377\377\377\375\216\377\377\377\1\376\376\376\203\377\377\377\2\375" \
+ "\375\375\205\205\207\202::<\202;;=\3::<;;=::<\202;;=\6::<:::SSS\250\250" \
+ "\250\346\346\346\376\376\376\216\377\377\377\3\332\332\332\220\220\220" \
+ "SSS\202::<\4;;=99;::<;;=\202::<\1""99;\202;;=\2__a\332\332\334\223\377" \
+ "\377\377\1\316\316\316\204::<\6;;=RRT\235\235\237\235\235\235\233\233" \
+ "\233\234\234\234\212\234\234\236\5xxzkkm__a99;;;=\204::<\202;;=\1""9" \
+ "9;\202::<\1\316\316\316\244\377\377\377\4\204\204\206;;=::<;;=\202::" \
+ "<\2;;=\220\220\222\203\377\377\377\1\376\376\376\236\377\377\377\1\234" \
+ "\234\236\203::<\3;;=::<kkm\203\234\234\236\3\233\233\235\234\234\236" \
+ "\235\235\237\204\234\234\236\2xxzlln\202kkm\1FFH\202;;=\2""99;;;=\202" \
+ "::<\3""99;::<;;=\202::<\1;;=\205::<\3GGI\301\301\301\376\376\376\225" \
+ "\377\377\377\1\234\234\234\205::<\5lln\234\234\236\233\233\233\235\235" \
+ "\235\234\234\234\224\234\234\236\5\234\234\234\235\235\235\233\233\233" \
+ "\234\234\234\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305" \
+ "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \
+ "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \
+ "\214\305@\210\214\306>\7\212\306@\214\306<\217\307@\214\304\77\214\311" \
+ ">\214\306>\251\323m\202\376\377\377\4\376\376\374\377\377\375\377\377" \
+ "\377\376\376\376\202\377\377\377\1\376\376\376\216\377\377\377\213\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\212\377\377\377\7\377\377\375\377\376\377\376" \
+ "\377\377\377\376\377\251\323o\211\307>\214\305@\210\214\306>\7\212\307" \
+ ">\215\305>\214\305@\214\306>\215\307\77\347\365\334\377\376\377\211\377" \
+ "\377\377\2\377\376\377\375\377\374\203\377\376\377\15\352\364\333\212" \
+ "\306@\215\306A\214\306>\215\307\77\213\310\77\214\306>\216\306A\215\306" \
+ "A\214\306<\212\307>\213\310=\212\307>\202\214\305@\4\214\306>\314\345" \
+ "\253\377\376\377\376\377\377\202\377\377\375\6\377\376\377\375\376\377" \
+ "\377\377\377\377\376\377\376\377\375\377\376\377\217\377\377\377\3\376" \
+ "\376\376\362\362\362lln\20299;\1;;=\204::<\202;;=\6::<\204\204\204\317" \
+ "\317\317\376\376\376\377\377\377\376\376\376\206\377\377\377\1\376\376" \
+ "\376\213\377\377\377\2\301\301\301kkm\211::<\6;;=FFH\301\301\301\376" \
+ "\376\376\377\377\377\376\376\376\217\377\377\377\1\316\316\316\204::" \
+ "<\3;;=kkm\376\376\376\221\377\377\377\3\316\316\316\204\204\204FFF\202" \
+ "::<\1;;=\202::<\202;;=\2FFH\363\363\363\242\377\377\377\5\364\364\364" \
+ "::<;;=99;;;=\203::<\3GGI\363\363\363\376\376\376\240\377\377\377\1\234" \
+ "\234\236\205::<\1\234\234\236\210\377\377\377\1\376\376\376\204\377\377" \
+ "\377\1\376\376\376\202\377\377\377\6\362\362\362\316\316\316\265\265" \
+ "\265\234\234\234kkmFFH\202::<\2;;=99;\205::<\1;;=\202::<\1\221\221\221" \
+ "\225\377\377\377\1\234\234\234\205::<\1\234\234\236\202\377\377\377\1" \
+ "\376\376\376\225\377\377\377\1\375\375\375\235\377\377\377\3\214\305" \
+ "@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324" \
+ "p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \
+ "\202\214\306>\1\214\305@\210\214\306>\4\215\307\77\214\306>\214\304\77" \
+ "\214\306>\202\214\305@\6\215\307\77\307\341\240\376\377\375\376\377\377" \
+ "\376\376\374\377\377\373\202\377\377\377\202\377\377\375\216\377\377" \
+ "\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252" \
+ "\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214" \
+ "\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\212\377\377\377\7\377\376\377\376\376" \
+ "\377\377\377\377\376\376\377\361\372\347\222\312K\215\305>\210\214\306" \
+ ">\10\214\305@\215\306A\214\305@\214\306<\213\304A\243\322b\376\376\374" \
+ "\376\377\375\211\377\377\377\24\377\377\373\377\377\377\376\377\377\377" \
+ "\377\375\242\320c\215\307=\214\306>\213\310\77\213\304A\212\306@\215" \
+ "\307\77\215\305@\214\306>\215\307\77\212\306@\215\305>\215\307\77\213" \
+ "\310\77\213\306:\253\325q\202\377\377\377\11\377\377\375\377\376\377" \
+ "\377\377\377\377\377\375\376\377\375\377\377\375\377\375\377\376\377" \
+ "\377\377\377\375\214\377\377\377\7\376\376\376\377\377\377\376\376\376" \
+ "\363\363\363__a::<;;=\203::<\202;;=\202::<\4xxz\347\347\351\377\377\377" \
+ "\376\376\376\210\377\377\377\1\376\376\376\204\377\377\377\2\376\376" \
+ "\376\377\377\377\203\376\376\376\205\377\377\377\2\316\316\320kkm\202" \
+ "::<\3;;=::<;;=\202::<\202;;=\2:::\250\250\250\202\377\377\377\1\376\376" \
+ "\376\216\377\377\377\1\316\316\316\205::<\1kkm\203\377\377\377\1\376" \
+ "\376\376\215\377\377\377\1\376\376\376\202\377\377\377\3\363\363\363" \
+ "xxx::<\202;;=\203::<\2;;=xxz\242\377\377\377\1\234\234\234\202::<\1;" \
+ ";=\202::<\1;;=\202::<\1\234\234\234\241\377\377\377\1\234\234\236\202" \
+ "::<\10;;=::<;;=\234\234\236\377\377\377\376\376\376\377\377\377\376\376" \
+ "\376\216\377\377\377\1\376\376\376\203\377\377\377\3\332\332\332\221" \
+ "\221\223FFH\205::<\2;;=::<\202;;=\2::<\204\204\204\224\377\377\377\1" \
+ "\234\234\234\205::<\3\234\234\236\377\377\377\376\376\376\264\377\377" \
+ "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \
+ "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \
+ "\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\5\216\306\77\212" \
+ "\307>\215\307=\212\306@\214\306>\202\215\305>\5\215\305@\345\356\317" \
+ "\376\377\375\376\377\377\377\377\375\202\377\377\377\1\377\377\375\217" \
+ "\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \
+ "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \
+ "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \
+ "\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377\4\376\377" \
+ "\377\377\377\377\377\377\375\376\377\377\202\377\377\377\2\315\347\252" \
+ "\212\306@\210\214\306>\10\216\306A\212\306@\212\307>\215\305<\213\310" \
+ "\77\215\305>\307\341\240\376\377\377\212\377\377\377\10\375\377\374\377" \
+ "\377\377\305\342\237\215\305@\212\306@\216\306\77\215\307=\215\305>\202" \
+ "\214\306>\24\213\307A\213\310=\215\304B\214\306>\212\306@\215\304B\212" \
+ "\307>\225\311K\370\373\362\377\377\377\376\377\375\377\377\375\377\377" \
+ "\377\374\377\375\376\376\376\377\377\377\377\377\375\377\376\377\376" \
+ "\377\377\377\377\375\211\377\377\377\1\376\376\376\205\377\377\377\1" \
+ "___\204::<\1;;=\203::<\2SSS\316\316\316\235\377\377\377\2\317\317\317" \
+ "``b\207::<\3;;=::<\204\204\206\220\377\377\377\1\316\316\316\205::<\1" \
+ "kkm\226\377\377\377\3\204\204\206::<;;=\205::<\1\316\316\316\232\377" \
+ "\377\377\1\376\376\376\205\377\377\377\2\364\364\364FFF\202;;=\202::" \
+ "<\6;;=99;;;=::<FFH\363\363\363\240\377\377\377\1\234\234\236\205::<\1" \
+ "\234\234\234\226\377\377\377\1\376\376\376\202\377\377\377\3\265\265" \
+ "\265RRR:::\202::<\1;;=\202::<\4;;=::<;;=\204\204\204\203\377\377\377" \
+ "\1\376\376\376\217\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \
+ "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \
+ "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \
+ "\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>\2\222\313" \
+ "J\366\373\364\202\377\376\377\4\377\377\373\376\376\374\376\377\377\377" \
+ "\376\377\216\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240" \
+ "\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3" \
+ "\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305" \
+ ">\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377" \
+ "-\377\377\375\376\377\377\377\377\377\376\376\374\376\377\377\377\376" \
+ "\377\376\377\377\252\324p\212\306@\215\305>\212\307<\215\305@\215\305" \
+ "<\214\305B\215\305@\214\306<\212\307>\215\305>\214\306>\211\306=\215" \
+ "\305>\212\307>\214\306<\350\364\334\374\377\377\377\376\377\376\376\376" \
+ "\374\377\375\377\377\377\376\377\375\377\377\375\377\376\377\377\377" \
+ "\375\377\377\377\377\376\377\357\367\350\223\312K\213\310\77\215\305" \
+ ">\214\306>\215\305>\213\310\77\212\306@\214\306>\215\305@\202\214\306" \
+ ">\10\214\305@\216\306=\212\307>\215\305>\333\355\303\376\376\374\377" \
+ "\377\377\377\377\375\223\377\377\377\1\376\376\376\203\377\377\377\1" \
+ "\203\203\203\206::<\4;;=::<\204\204\206\363\363\363\230\377\377\377\1" \
+ "\376\376\376\207\377\377\377\1\235\235\237\202::<\1;;=\203::<\5;;=99" \
+ ";;;=\204\204\204\376\376\376\216\377\377\377\1\316\316\316\205::<\1k" \
+ "km\227\377\377\377\12\204\204\206::<;;=::<99;;;=::<\204\204\204\377\377" \
+ "\377\376\376\376\232\377\377\377\1\376\376\376\203\377\377\377\2\234" \
+ "\234\234;;=\203::<\1;;=\204::<\3<<>\250\250\250\376\376\376\237\377\377" \
+ "\377\1\234\234\236\205::<\1\234\234\234\231\377\377\377\10\376\376\376" \
+ "\377\377\377\265\265\265FFH::<;;=::<;;=\203::<\2;;=\204\204\204\222\377" \
+ "\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305" \
+ "@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324" \
+ "p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \
+ "\202\214\306>\1\214\305@\220\214\306>\4\216\306\77\250\322n\376\377\375" \
+ "\376\377\373\222\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \
+ "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \
+ "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377" \
+ "\377\13\376\376\377\376\377\377\377\376\377\376\376\374\374\377\377\377" \
+ "\377\375\377\376\377\356\372\346\225\311K\214\306>\213\310=\203\214\306" \
+ ">\2\213\310\77\214\306>\202\214\305@\7\214\306<\213\307A\214\304\77\214" \
+ "\305B\212\307>\244\317d\377\376\377\202\377\377\377\1\377\375\377\202" \
+ "\377\377\377\25\376\377\377\377\376\377\377\377\377\374\377\375\376\376" \
+ "\374\253\324n\214\306<\215\307\77\215\305>\211\307@\216\305C\214\305" \
+ "@\215\307\77\214\305@\214\306<\212\307<\211\306=\214\306>\214\305@\213" \
+ "\307A\263\327}\202\376\377\377\3\377\377\377\377\375\376\377\377\375" \
+ "\221\377\377\377\1\376\376\376\203\377\377\377\1\250\250\250\204::<\1" \
+ ";;=\202::<\2;;=\264\264\264\202\377\377\377\1\376\376\376\232\377\377" \
+ "\377\1\376\376\376\205\377\377\377\2\332\332\332SSS\202::<\1;;=\204:" \
+ ":<\4xxx\364\364\364\377\377\377\376\376\376\214\377\377\377\1\316\316" \
+ "\316\205::<\1kkm\227\377\377\377\2\363\363\363SSU\202::<\4;;=99;::<;" \
+ ";;\202\377\377\377\1\376\376\376\226\377\377\377\1\376\376\376\204\377" \
+ "\377\377\11\376\376\376\363\363\363FFH99;;;=::<;;=99;;;=\203::<\4""9" \
+ "9;SSU\377\377\377\376\376\376\236\377\377\377\1\234\234\236\205::<\1" \
+ "\234\234\234\225\377\377\377\1\376\376\376\204\377\377\377\10\376\376" \
+ "\376\377\377\377\363\363\363yyy::<;;=99;;;=\204::<\1\266\266\266\221" \
+ "\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214" \
+ "\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252" \
+ "\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \
+ "\320\202\214\306>\1\214\305@\220\214\306>\4\214\306<\213\307A\275\335" \
+ "\222\376\377\377\203\377\377\377\1\377\377\375\216\377\377\377\213\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\211\377\377\377\4\377\376\377\376\376\377\377" \
+ "\377\377\377\377\375\202\376\377\377\5\377\375\376\377\376\377\315\346" \
+ "\255\212\307>\214\305@\202\215\306A\22\214\305@\212\307<\214\305B\214" \
+ "\306>\213\307A\214\306>\213\305=\214\306>\215\305>\213\307A\211\310<" \
+ "\313\347\254\377\377\375\377\375\377\376\377\377\376\377\373\376\377" \
+ "\377\377\376\377\202\376\377\377\10\377\377\377\315\346\254\212\307>" \
+ "\212\306@\215\306A\216\306A\212\307>\214\306<\202\215\306A\10\215\306" \
+ "C\214\305B\215\307\77\214\306<\214\305@\213\310<\222\310L\372\373\363" \
+ "\225\377\377\377\1\376\376\376\202\377\377\377\6\376\376\376\333\333" \
+ "\333::<;;=::<;;=\202::<\3;;=FFH\315\315\315\205\377\377\377\1\376\376" \
+ "\376\225\377\377\377\202\376\376\376\202\377\377\377\1\376\376\376\202" \
+ "\377\377\377\1\376\376\376\202\377\377\377\2\363\363\363xxx\204::<\2" \
+ ";;=\203\203\203\220\377\377\377\1\316\316\316\205::<\1kkm\230\377\377" \
+ "\377\3\266\266\27099;;;=\204::<\1\316\316\316\230\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\202\377\377\377\3\265\265\267::<;" \
+ ";=\204::<\202;;=\202::<\202;;=\1\265\265\265\237\377\377\377\1\234\234" \
+ "\236\205::<\1\234\234\234\236\377\377\377\5\234\234\234::<;;=::<;;=\202" \
+ "::<\3;;=FFH\332\332\332\220\377\377\377\1\234\234\234\205::<\1\234\234" \
+ "\236\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214" \
+ "\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325" \
+ "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>" \
+ "\4\215\307\77\214\304\77\213\310\77\333\355\303\202\377\377\377\1\376" \
+ "\377\375\217\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240" \
+ "\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3" \
+ "\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305" \
+ ">\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\213\377\377\377" \
+ "\5\377\377\373\377\376\377\377\377\377\375\377\374\376\377\377\202\376" \
+ "\376\376\22\260\331{\212\307>\214\306>\215\305>\215\305@\215\307\77\215" \
+ "\307=\214\305@\214\306>\215\306A\214\306>\213\307C\214\306>\214\304;" \
+ "\213\307A\222\312K\357\370\345\377\377\375\202\377\377\377\15\377\375" \
+ "\376\377\377\375\376\376\376\377\377\375\361\367\351\222\311J\213\310" \
+ "\77\214\305B\215\310<\213\305=\216\306\77\212\307<\214\305B\202\214\306" \
+ ">\6\216\306\77\215\305@\215\306A\214\305@\215\305<\333\356\301\202\377" \
+ "\376\377\3\377\377\375\377\377\377\377\376\377\225\377\377\377\1``b\202" \
+ "::<\6;;=::<;;=::<FFH\331\331\333\233\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\206\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\205\205\207\203::<\1\204\204\206\221\377\377\377\1\316\316\316\205" \
+ "::<\1kkm\231\377\377\377\1GGI\203;;=\202::<\3\235\235\237\377\377\377" \
+ "\376\376\376\233\377\377\377\2\376\376\376SSU\203::<\5;;=99;llnkkm::" \
+ "<\202;;=\202::<\1SSU\237\377\377\377\1\234\234\236\205::<\1\234\234\234" \
+ "\224\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\203\377" \
+ "\377\377\4\376\376\376\266\266\270::<;;=\203::<\5""99;::<__a\377\377" \
+ "\377\376\376\376\216\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \
+ "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \
+ "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \
+ "\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>\10\216\306" \
+ "\77\215\306A\214\305@\224\310J\360\371\350\377\377\377\377\376\377\376" \
+ "\377\377\216\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240" \
+ "\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3" \
+ "\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305" \
+ ">\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\212\377\377\377" \
+ "\1\377\377\375\202\377\377\377\2\377\376\377\377\377\377\202\376\377" \
+ "\377\25\377\377\375\370\373\362\223\312K\212\307>\215\305>\216\306A\212" \
+ "\307<\214\305B\215\307\77\214\305@\214\306>\214\305@\212\306@\215\307" \
+ "=\216\306A\215\305>\214\306<\252\324n\376\377\377\376\376\376\377\376" \
+ "\377\202\377\377\375\4\377\376\377\376\376\377\252\324n\215\306A\202" \
+ "\214\306>\21\214\305@\215\307\77\215\305>\212\307>\214\306<\213\304A" \
+ "\215\307=\214\304=\215\307\77\212\307>\214\306>\277\337\226\377\376\377" \
+ "\376\377\375\377\377\375\377\377\377\376\376\376\225\377\377\377\3\234" \
+ "\234\236::<;;=\204::<\4;;=\265\265\267\377\377\377\376\376\376\204\377" \
+ "\377\377\202\376\376\376\202\377\377\377\1\376\376\376\225\377\377\377" \
+ "\1\376\376\376\203\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\202\377\377\377\3\250\250\250::<\204\204\206\205\377\377\377\1\376" \
+ "\376\376\214\377\377\377\1\316\316\316\205::<\1kkm\226\377\377\377\1" \
+ "\376\376\376\202\377\377\377\2kkm99;\202::<\4;;=::<\204\204\206\376\376" \
+ "\376\202\377\377\377\1\376\376\376\224\377\377\377\1\376\376\376\203" \
+ "\377\377\377\2\376\376\376\265\265\265\202::<\1;;=\202::<\3;;=\316\316" \
+ "\320\316\316\316\204::<\3;;=::<\266\266\266\236\377\377\377\1\234\234" \
+ "\236\205::<\1\234\234\234\226\377\377\377\202\376\376\376\2\377\377\377" \
+ "\376\376\376\205\377\377\377\4\376\376\376\251\251\253;;=99;\202::<\4" \
+ "<<>99;::<\250\250\252\217\377\377\377\1\234\234\234\205::<\1\234\234" \
+ "\236\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214" \
+ "\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325" \
+ "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\220\214\306>" \
+ "\202\214\305@\6\212\306@\215\307\77\243\321d\377\377\375\377\375\377" \
+ "\376\377\377\216\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \
+ "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \
+ "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\211\377\377" \
+ "\377\2\376\377\377\377\377\375\202\377\377\377\1\376\376\376\202\377" \
+ "\377\377\6\376\377\372\376\377\377\377\376\377\331\357\301\213\304\77" \
+ "\215\307=\202\214\305@\25\214\305B\214\306<\215\305@\212\307<\214\306" \
+ ">\216\306=\212\307>\212\306B\214\305@\215\306E\212\306@\313\347\255\376" \
+ "\377\375\376\376\377\376\377\377\377\376\377\377\377\377\333\355\305" \
+ "\212\307>\216\306\77\215\307\77\202\214\306>\1\215\307\77\202\214\306" \
+ ">\13\215\305<\212\306@\212\307<\215\307\77\211\306=\213\307A\233\314" \
+ "V\370\373\362\377\377\375\377\377\377\376\377\377\202\377\377\375\2\374" \
+ "\377\377\377\375\376\222\377\377\377\3\363\363\363GGI::<\202;;=\202:" \
+ ":<\2;;=\234\234\234\214\377\377\377\1\376\376\376\221\377\377\377\1\376" \
+ "\376\376\202\377\377\377\3\376\376\376\377\377\377\376\376\376\206\377" \
+ "\377\377\3\376\376\376\377\377\377\316\316\316\203\377\377\377\1\376" \
+ "\376\376\203\377\377\377\1\376\376\376\213\377\377\377\1\316\316\316" \
+ "\205::<\1kkm\227\377\377\377\5\376\376\376\377\377\377\235\235\237::" \
+ "<;;=\203::<\2lln\376\376\376\203\377\377\377\1\376\376\376\224\377\377" \
+ "\377\13\376\376\376\377\377\377\376\376\376\377\377\377RRR::<99;::<;" \
+ ";=::<kkm\202\377\377\377\1__a\203;;=\202::<\1kkk\236\377\377\377\1\234" \
+ "\234\236\205::<\1\234\234\234\241\377\377\377\2\204\204\204;;=\202::" \
+ "<\5""99;::<;;=FFH\363\363\363\216\377\377\377\1\234\234\234\205::<\1" \
+ "\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306" \
+ ">\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>" \
+ "\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\221" \
+ "\214\306>\5\213\307A\216\306\77\212\307<\214\306>\277\337\223\220\377" \
+ "\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377" \
+ "\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306" \
+ ">\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207" \
+ "\214\306>\3\214\305@\214\306>\214\305@\211\377\377\377\4\376\377\377" \
+ "\377\377\375\377\375\377\377\377\377\202\377\377\375\202\377\376\377" \
+ "\202\376\377\377\22\377\376\377\262\331~\213\304\77\213\310\77\216\306" \
+ "A\212\307<\215\306A\214\304=\213\310\77\214\305@\215\304B\214\305B\214" \
+ "\306<\212\307>\212\307<\216\306A\221\312I\370\373\362\203\377\377\377" \
+ "\13\370\373\364\226\310K\214\306>\212\307>\215\304B\214\306>\215\306" \
+ "A\213\304\77\215\306A\214\306>\215\305@\202\212\306@\13\215\307\77\213" \
+ "\310=\220\303@\336\362\315\377\376\377\377\377\377\374\377\377\377\376" \
+ "\377\377\377\377\376\376\374\376\377\375\223\377\377\377\1\204\204\206" \
+ "\203::<\4""99;;;=::<kkm\211\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\221\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\237\377\377\377\1\316\316\316\205::<\1kkm\231\377\377\377\4\234" \
+ "\234\236;;=::<;;=\202::<\3jjl\377\377\377\376\376\376\232\377\377\377" \
+ "\10\265\265\265:::::<;;=::<99;::<\316\316\316\202\377\377\377\1\265\265" \
+ "\267\204::<\3;;=::<\316\316\316\235\377\377\377\1\234\234\236\205::<" \
+ "\1\234\234\234\241\377\377\377\2\363\363\363__a\203::<\4;;=::<;;=\234" \
+ "\234\236\216\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377" \
+ "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \
+ "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \
+ "\1\342\361\320\202\214\306>\1\214\305@\220\214\306>\10\215\304B\214\306" \
+ "<\214\305@\215\305@\212\306@\215\305>\323\354\265\377\376\377\216\377" \
+ "\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377" \
+ "\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306" \
+ ">\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207" \
+ "\214\306>\3\214\305@\214\306>\214\305@\212\377\377\377\3\375\377\376" \
+ "\377\377\377\377\377\375\202\377\377\377\26\377\377\375\375\377\374\376" \
+ "\377\377\377\376\377\377\377\375\365\375\362\225\311K\212\306@\214\306" \
+ ">\214\305@\212\306@\216\306=\211\306;\215\306A\214\306>\215\307\77\217" \
+ "\304@\214\306>\212\307>\215\305@\214\305@\262\327z\203\377\377\377\13" \
+ "\260\331{\213\310\77\214\305B\214\305@\215\305@\215\307\77\212\307<\216" \
+ "\306A\213\305;\214\305@\215\305>\202\214\306>\11\215\305@\214\306<\276" \
+ "\340\224\377\376\375\377\377\375\376\377\377\377\376\375\376\377\375" \
+ "\377\376\377\202\377\377\377\1\376\377\375\221\377\377\377\1\346\346" \
+ "\346\206::<\2:::\346\346\346\202\377\377\377\1\376\376\376\276\377\377" \
+ "\377\1\316\316\316\205::<\1kkm\216\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\207\377\377\377\3\234\234\236::<;;=\203::<\1k" \
+ "km\226\377\377\377\1\376\376\376\204\377\377\377\2\376\376\376lln\205" \
+ "::<\1``b\204\377\377\377\1SSS\205::<\1kkm\235\377\377\377\1\234\234\236" \
+ "\205::<\1\234\234\234\242\377\377\377\2\316\316\316:::\202::<\5;;=::" \
+ "<;;=FFH\363\363\363\206\377\377\377\1\376\376\376\206\377\377\377\1\234" \
+ "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \
+ "\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377" \
+ "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \
+ ">\1\214\305@\210\214\306>\27\215\306A\212\307>\215\305>\215\305@\215" \
+ "\307=\217\304B\214\306<\214\305@\215\307\77\215\305@\215\307\77\214\305" \
+ "@\216\306\77\211\310<\226\312L\347\364\332\377\377\377\377\376\377\377" \
+ "\377\375\374\377\377\377\376\377\376\376\376\376\377\377\207\377\377" \
+ "\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252" \
+ "\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214" \
+ "\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\221\377\377\377\1\377\377\375\203\377" \
+ "\377\377\5\333\355\303\214\306>\212\307<\216\306A\214\305@\202\214\306" \
+ ">\15\215\305@\214\306>\212\306@\213\310\77\215\305>\216\306A\211\306" \
+ "=\212\306@\212\307<\334\354\305\377\377\375\335\354\303\212\307>\210" \
+ "\214\306>\10\216\306A\212\307;\215\306A\216\306A\214\305@\241\321a\371" \
+ "\374\361\375\376\377\223\377\377\377\1\376\376\376\204\377\377\377\2" \
+ "\376\376\376\234\234\234\203::<\1""99;\202::<\1\234\234\234\302\377\377" \
+ "\377\1\316\316\316\205::<\1kkm\217\377\377\377\1\376\376\376\202\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377\377\3\376" \
+ "\376\376\377\377\377xxz\202::<\5""99;::<;;=xxz\376\376\377\232\377\377" \
+ "\377\3\317\317\31799;;;=\202::<\5;;=::<\265\265\265\377\377\377\376\376" \
+ "\376\202\377\377\377\2\265\265\265;;=\202::<\203;;=\1\332\332\332\203" \
+ "\377\377\377\1\376\376\376\230\377\377\377\1\234\234\236\205::<\1\234" \
+ "\234\234\242\377\377\377\4\376\376\376\204\204\204::<;;=\202::<\3;;=" \
+ "::<\266\266\266\207\377\377\377\1\376\376\376\205\377\377\377\1\234\234" \
+ "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \
+ "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \
+ "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \
+ "\214\305@\211\214\306>\27\216\306A\214\306>\212\306@\214\306<\213\310" \
+ "\77\215\305@\215\307\77\213\305=\216\306\77\212\307;\212\306@\215\305" \
+ ">\215\306A\212\307>\245\320d\367\375\361\376\377\377\377\376\377\377" \
+ "\377\377\376\376\377\377\376\377\375\377\376\377\377\375\206\377\377" \
+ "\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252" \
+ "\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214" \
+ "\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\221\377\377\377\6\376\376\376\377\376" \
+ "\377\377\377\377\375\377\376\376\377\377\270\333\207\203\214\306>\17" \
+ "\211\306=\212\307<\214\306<\214\305@\215\307\77\214\305@\216\305C\214" \
+ "\306>\212\310A\215\305@\216\306\77\223\312K\360\371\346\222\311I\214" \
+ "\305@\210\214\306>\10\214\305@\212\307>\214\305@\216\306A\215\307=\350" \
+ "\364\334\375\377\376\377\376\377\225\377\377\377\7\376\376\376\377\377" \
+ "\377\376\376\376\377\377\377SSS::<;;=\203::<\5FFH\364\364\364\376\376" \
+ "\376\377\377\377\376\376\376\277\377\377\377\1\316\316\316\205::<\1k" \
+ "km\222\377\377\377\1\376\376\376\204\377\377\377\3\376\376\376\377\377" \
+ "\377SSU\205::<\1\234\234\236\202\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\376\376\376\220\377\377\377\1\376\376\376\204\377\377\377\2kk" \
+ "m;;=\202::<\5;;=::<SSU\377\377\377\376\376\376\204\377\377\377\7SSU:" \
+ ":<;;=::<;;=::<\205\205\205\234\377\377\377\1\234\234\236\205::<\1\234" \
+ "\234\234\240\377\377\377\1\376\376\376\202\377\377\377\1\346\346\346" \
+ "\202::<\1;;=\202::<\2;;=__a\205\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\376\376\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236" \
+ "\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305" \
+ "@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p" \
+ "\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\27" \
+ "\214\304=\215\305>\213\307A\212\306@\214\305B\215\305<\213\310=\215\307" \
+ "\77\215\304B\214\306<\213\307A\215\305>\216\306A\212\306@\212\307>\270" \
+ "\332\204\377\376\377\377\377\377\377\376\377\376\376\374\377\377\373" \
+ "\377\376\377\377\377\375\206\377\377\377\213\214\306>\3\215\305>\214" \
+ "\306>\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305" \
+ "@\207\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324" \
+ "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \
+ "@\223\377\377\377\1\377\377\375\202\377\377\377\2\371\372\364\232\315" \
+ "W\202\214\305@\4\214\306<\215\307\77\214\305B\215\306C\202\215\306A\1" \
+ "\214\306<\202\212\307>\6\215\305@\212\307>\215\305>\212\306B\216\306" \
+ "A\212\307>\210\214\306>\10\214\305B\215\307\77\214\306<\214\306>\304" \
+ "\341\237\377\377\377\377\376\377\377\377\375\220\377\377\377\1\376\376" \
+ "\376\203\377\377\377\1\376\376\376\203\377\377\377\10\301\301\301::<" \
+ ";;=99;;;=::<99;\234\234\236\207\377\377\377\1\376\376\376\273\377\377" \
+ "\377\1\316\316\316\205::<\1kkm\216\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\204\377\377\377\3\376\376\376\377\377\377\315" \
+ "\315\315\202;;=\203::<\6;;=\265\265\267\377\377\377\376\376\376\377\377" \
+ "\377\376\376\376\225\377\377\377\2\376\376\376\317\317\317\203::<\4;" \
+ ";=::<;;=\264\264\264\206\377\377\377\10\234\234\234;;=::<;;=99;;;=::" \
+ "<\346\346\346\233\377\377\377\1\234\234\236\205::<\1\234\234\234\237" \
+ "\377\377\377\1\376\376\376\204\377\377\377\1\204\204\206\202::<\6;;=" \
+ "99;;;=::<\346\346\346\376\376\376\204\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \
+ "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \
+ "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \
+ "\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\22\215\307" \
+ "\77\212\307>\216\306A\212\304<\215\307\77\215\305@\216\306\77\213\307" \
+ "A\214\306>\214\305@\215\307\77\213\310=\212\307>\214\306>\214\306<\214" \
+ "\306>\216\306\77\324\353\267\202\376\376\376\3\377\377\377\376\376\377" \
+ "\376\377\375\207\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \
+ "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \
+ "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\221\377\377" \
+ "\377\3\376\377\377\377\377\377\376\377\375\202\377\377\377\7\377\376" \
+ "\377\341\363\315\215\305@\214\305@\215\306A\215\305@\216\306\77\202\214" \
+ "\306>\12\214\305B\212\307<\213\304A\213\310=\216\306A\211\306;\213\310" \
+ "=\214\305@\212\307>\215\305>\210\214\306>\10\215\307\77\214\304=\212" \
+ "\307>\243\322b\377\377\377\376\377\377\377\376\377\377\377\375\226\377" \
+ "\377\377\4\376\376\376\377\377\377\204\204\206;;=\203::<\3""99;;;=\364" \
+ "\364\364\205\377\377\377\1\376\376\376\275\377\377\377\1\316\316\316" \
+ "\205::<\1kkm\217\377\377\377\202\376\376\376\202\377\377\377\1\376\376" \
+ "\376\203\377\377\377\4\376\376\376xxz;;=99;\202;;=\4::<;;=\346\346\346" \
+ "\376\376\376\204\377\377\377\1\376\376\376\224\377\377\377\1xxz\203:" \
+ ":<\3;;=::<SSU\203\377\377\377\1\376\376\376\203\377\377\377\2\363\363" \
+ "\363FFH\202::<\4;;=99;::<\204\204\206\233\377\377\377\1\234\234\236\205" \
+ "::<\1\234\234\234\244\377\377\377\1\316\316\316\202;;=\5::<;;=99;;;=" \
+ "\250\250\252\203\377\377\377\1\376\376\376\210\377\377\377\1\234\234" \
+ "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \
+ "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \
+ "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \
+ "\214\305@\210\214\306>\7\213\305=\214\306<\210\306\77\216\306\77\215" \
+ "\307=\214\306>\215\307\77\202\214\306>\14\215\307\77\214\305B\214\306" \
+ "<\212\307<\214\305@\216\306\77\215\305>\214\305@\224\313L\352\364\331" \
+ "\374\377\377\377\376\377\211\377\377\377\213\214\306>\3\215\305>\214" \
+ "\306>\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305" \
+ "@\207\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324" \
+ "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \
+ "@\222\377\377\377\1\376\377\377\202\377\377\377\24\376\376\374\376\377" \
+ "\375\377\375\377\277\337\224\214\306>\212\307>\215\307\77\214\304=\215" \
+ "\307=\213\304A\214\306<\212\307>\215\307\77\214\305@\213\304\77\215\307" \
+ "\77\215\305@\214\304=\215\305<\215\306A\210\214\306>\1\212\307>\202\215" \
+ "\306A\4\350\365\333\377\375\376\377\376\377\375\376\377\226\377\377\377" \
+ "\1\376\376\376\202\377\377\377\3TTV::<99;\202;;=\4::<\203\203\203\377" \
+ "\377\377\376\376\376\302\377\377\377\1\316\316\316\205::<\1kkm\222\377" \
+ "\377\377\1\376\376\376\204\377\377\377\3\300\300\302;;=::<\202;;=\202" \
+ "::<\2```\376\376\376\227\377\377\377\7\376\376\376\377\377\377\346\346" \
+ "\346;;=99;::<;;=\202::<\3\251\251\251\377\377\377\376\376\376\206\377" \
+ "\377\377\1\234\234\234\202::<\1;;=\202::<\2;;=\346\346\346\232\377\377" \
+ "\377\1\234\234\236\205::<\1\234\234\234\235\377\377\377\1\376\376\376" \
+ "\207\377\377\377\11SSU::<;;=99;<<>::<xxz\377\377\377\376\376\376\212" \
+ "\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214" \
+ "\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252" \
+ "\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \
+ "\320\202\214\306>\1\214\305@\210\214\306>\25\213\307A\216\306A\232\315" \
+ "W\215\306C\212\306@\214\305@\212\307;\216\306A\215\305>\215\307\77\214" \
+ "\305@\215\307\77\214\306>\214\305@\212\306B\213\307C\214\306>\215\305" \
+ "@\232\315V\372\374\367\376\376\376\202\377\377\375\1\376\376\376\206" \
+ "\377\377\377\213\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \
+ "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \
+ "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \
+ "\207\214\306>\3\214\305@\214\306>\214\305@\221\377\377\377\5\377\376" \
+ "\377\376\377\377\377\375\376\377\376\377\376\377\377\202\377\377\377" \
+ "\10\370\373\362\233\314V\213\307A\211\306=\215\307\77\212\307<\212\306" \
+ "@\215\305<\202\214\306>\7\215\307=\215\306A\214\305@\212\307>\216\306" \
+ "A\212\306@\215\307=\210\214\306>\10\212\307>\212\307<\313\347\254\376" \
+ "\377\377\377\377\377\377\376\377\376\377\377\377\377\375\223\377\377" \
+ "\377\1\376\376\376\203\377\377\377\1\332\332\332\202::<\1;;=\203::<\1" \
+ "\302\302\302\203\377\377\377\5\376\376\376\377\377\377\376\376\376\377" \
+ "\377\377\376\376\376\274\377\377\377\1\316\316\316\205::<\1kkm\217\377" \
+ "\377\377\1\376\376\376\206\377\377\377\3\332\332\334FFH;;=\205::<\1\265" \
+ "\265\265\202\377\377\377\1\376\376\376\224\377\377\377\1\376\376\376" \
+ "\202\377\377\377\1\205\205\207\202::<\1;;=\202::<\2GGI\363\363\363\202" \
+ "\377\377\377\1\376\376\376\205\377\377\377\1\363\363\363\202::<\1;;=" \
+ "\202::<\2""99;\234\234\234\203\377\377\377\1\376\376\376\226\377\377" \
+ "\377\1\234\234\236\205::<\1\234\234\234\234\377\377\377\1\376\376\376" \
+ "\210\377\377\377\3\222\222\222::<99;\202;;=\5""99;GGI\376\376\376\377" \
+ "\377\377\376\376\376\211\377\377\377\1\234\234\234\205::<\1\234\234\236" \
+ "\266\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305" \
+ "@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p" \
+ "\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306>\10" \
+ "\213\307A\214\306>\331\356\303\232\315W\215\305>\215\306A\214\305B\214" \
+ "\306>\202\214\305@\7\213\310=\214\306>\215\304B\215\306A\211\306;\213" \
+ "\310\77\214\305@\202\215\307\77\2\257\326{\376\377\373\202\377\377\377" \
+ "\1\377\377\375\206\377\377\377\213\214\306>\3\215\305>\214\306>\305\342" \
+ "\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306" \
+ ">\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215" \
+ "\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\221\377\377" \
+ "\377\6\377\377\373\377\377\375\377\377\377\376\376\377\377\376\377\373" \
+ "\377\374\202\377\376\377\4\336\362\315\220\303@\213\310=\215\307\77\202" \
+ "\212\306@\1\215\305@\202\214\306>\7\213\305=\214\306>\213\305=\214\305" \
+ "@\213\310\77\212\306@\213\307A\210\214\306>\10\215\307\77\252\324p\377" \
+ "\377\375\376\377\377\377\377\375\377\377\377\377\376\377\377\377\375" \
+ "\220\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\265\265\265\204::<\5;;=::<\363\363\363\377\377\377\376\376" \
+ "\376\302\377\377\377\1\316\316\316\205::<\1kkm\225\377\377\377\2\317" \
+ "\317\317FFH\206::<\1SSU\204\377\377\377\1\376\376\376\225\377\377\377" \
+ "\2\346\346\346;;=\203::<\3;;=::<\234\234\236\202\377\377\377\1\376\376" \
+ "\376\207\377\377\377\2\204\204\206;;=\204::<\2FFF\362\362\362\231\377" \
+ "\377\377\1\234\234\236\205::<\1\234\234\234\245\377\377\377\1\301\301" \
+ "\301\202::<\6;;=::<;;=::<\347\347\347\376\376\376\212\377\377\377\1\234" \
+ "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \
+ "\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377" \
+ "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \
+ ">\1\214\305@\210\214\306>\27\214\305@\215\305<\342\362\315\353\365\334" \
+ "\223\312K\215\305<\212\306@\215\305<\212\307>\215\306A\214\306>\212\307" \
+ ">\215\307\77\215\304B\215\307\77\215\305@\214\306>\215\305>\214\305@" \
+ "\215\305<\315\345\253\377\377\375\376\377\377\207\377\377\377\213\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\221\377\377\377\14\376\377\377\376\376\377\377" \
+ "\377\377\377\377\373\376\377\375\377\376\377\376\377\377\377\377\377" \
+ "\377\376\375\276\340\224\214\306<\215\305@\202\214\306>\12\215\305>\214" \
+ "\305@\215\305@\214\305@\213\310\77\214\306>\216\306\77\211\305\77\215" \
+ "\307=\214\305@\210\214\306>\4\223\312K\360\367\347\377\377\377\377\377" \
+ "\375\232\377\377\377\2\376\376\376\234\234\236\204::<\2;;=___\234\377" \
+ "\377\377\1\376\376\376\203\377\377\377\1\376\376\376\244\377\377\377" \
+ "\1\316\316\316\205::<\1kkm\202\377\377\377\1\376\376\376\216\377\377" \
+ "\377\4\376\376\376\377\377\377\347\347\347\204\204\204\203::<\6;;=::" \
+ "<;;=::<;;=\301\301\303\226\377\377\377\1\376\376\376\203\377\377\377" \
+ "\1\203\203\205\202;;=\5::<;;=::<GGG\363\363\363\206\377\377\377\1\376" \
+ "\376\376\203\377\377\377\3\347\347\34799;;;=\202::<\202;;=\1\234\234" \
+ "\236\231\377\377\377\1\234\234\236\205::<\1\234\234\234\245\377\377\377" \
+ "\1\363\363\363\202::<\1""99;\203::<\1\316\316\316\213\377\377\377\1\234" \
+ "\234\234\204::<\2;;=kkm\203\234\234\236\2\235\235\237\234\234\234\220" \
+ "\234\234\236\204\234\234\234\4\235\235\235\234\234\234\234\234\236\346" \
+ "\346\350\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4" \
+ "\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250" \
+ "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210\214\306" \
+ ">\40\213\307A\215\305>\341\360\317\377\375\376\324\353\267\215\304B\214" \
+ "\306>\215\307=\214\305@\212\307>\212\307<\215\305<\215\306A\214\306>" \
+ "\214\306<\212\306@\214\305@\215\307\77\216\306=\212\306B\214\306>\352" \
+ "\364\333\377\376\377\377\377\377\377\376\377\377\377\377\377\377\375" \
+ "\376\377\373\375\376\377\377\376\377\214\306>\215\307\77\211\214\306" \
+ ">\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214\306" \
+ ">\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232\377" \
+ "\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305" \
+ "@\214\306>\214\305@\232\377\377\377\7\374\377\375\242\321a\216\306A\212" \
+ "\307>\214\306>\215\307\77\212\307<\210\214\306>\16\215\307\77\214\307" \
+ ";\213\304\77\216\306A\214\305B\215\307\77\215\305>\212\307>\320\345\254" \
+ "\374\377\377\377\376\377\377\377\375\377\376\377\375\377\372\223\377" \
+ "\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377\377\377kkm\203" \
+ "::<\3<<>::<\221\221\221\305\377\377\377\1\316\316\316\204::<\2;;=jjl" \
+ "\217\377\377\377\16\316\316\316\300\300\300\234\234\234__a::<;;=::<;" \
+ ";=::<99;;;=::<;;=\204\204\206\232\377\377\377\1\362\362\362\202;;=\202" \
+ "::<\3""99;::<\235\235\235\212\377\377\377\12\376\376\376\377\377\377" \
+ "\205\205\20799;;;=::<;;=::<GGI\376\376\376\230\377\377\377\1\234\234" \
+ "\236\205::<\1\234\234\234\246\377\377\377\10EEG::<;;=::<99;;;=\234\234" \
+ "\234\377\377\377\202\376\376\376\202\377\377\377\1\376\376\376\205\377" \
+ "\377\377\1\234\234\234\205::<\2;;=99;\202;;=\2""99;;;=\221::<\1""99;" \
+ "\203::<\3;;=::<\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305" \
+ "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \
+ "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \
+ "\214\305@\210\214\306>\202\214\306<\32\342\361\322\377\377\377\377\377" \
+ "\375\266\334\205\212\306B\215\307\77\212\306@\220\306=\214\306>\215\307" \
+ "\77\214\305B\213\305=\216\306\77\215\307\77\215\305<\212\306B\215\306" \
+ "A\215\305@\216\306=\232\315V\371\373\360\377\377\375\377\377\377\375" \
+ "\376\377\377\375\377\376\376\377\202\377\377\377\2\214\305@\212\307>" \
+ "\211\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324" \
+ "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \
+ "@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>" \
+ "\3\214\305@\214\306>\214\305@\233\377\377\377\5\347\365\334\211\306=" \
+ "\215\305>\216\306=\214\305@\211\214\306>\2\215\304B\212\307>\202\214" \
+ "\306>\14\215\306A\214\306<\215\305@\252\324p\374\377\377\377\377\377" \
+ "\377\375\376\377\376\377\376\376\377\377\377\375\377\377\377\377\375" \
+ "\377\222\377\377\377\1\376\376\376\203\377\377\377\4\376\376\376lln:" \
+ ":<;;=\203::<\2\235\235\235\376\376\376\304\377\377\377\1\316\316\316" \
+ "\205::<\202;;=\2::<;;=\202::<\1;;=\211::<\202;;=\204::<\1""99;\202::" \
+ "<\5;;=::<;;=__a\376\376\376\224\377\377\377\1\376\376\376\205\377\377" \
+ "\377\1\235\235\235\206::<\3\346\346\346\377\377\377\376\376\376\207\377" \
+ "\377\377\5\376\376\376\377\377\377\376\376\376\346\346\350;;=\203::<" \
+ "\3;;=::<\265\265\265\230\377\377\377\1\234\234\236\205::<\1\234\234\234" \
+ "\246\377\377\377\1lln\202::<\4""99;;;=99;\234\234\234\213\377\377\377" \
+ "\1\234\234\234\203::<\7;;=::<;;=::<;;=::<;;=\222::<\7;;=99;;;=::<;;=" \
+ "::<\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305@\207\214" \
+ "\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306" \
+ ">\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \
+ "\214\306>\13\216\306A\213\310\77\343\361\320\377\377\375\375\377\376" \
+ "\371\374\361\242\320c\213\310\77\216\306\77\214\306>\215\306A\202\214" \
+ "\305@\2\216\306A\213\305=\204\214\306>\11\213\307A\216\306A\212\307>" \
+ "\260\331y\377\376\377\376\377\375\377\377\373\376\377\377\377\377\377" \
+ "\202\377\376\377\2\212\311=\215\306A\211\214\306>\3\215\305>\214\306" \
+ ">\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207" \
+ "\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\231" \
+ "\377\377\377\6\377\376\377\377\377\373\377\376\377\305\342\240\212\310" \
+ "\77\214\304=\202\215\305@\210\214\306>\4\215\305>\213\305=\212\306@\215" \
+ "\306A\202\214\306>\10\222\312M\370\373\362\377\376\377\377\375\376\377" \
+ "\376\377\377\377\377\376\377\375\377\377\377\202\377\376\377\221\377" \
+ "\377\377\1\376\376\376\205\377\377\377\2::<;;=\202::<\202;;=\3\300\300" \
+ "\300\377\377\377\376\376\376\235\377\377\377\1\376\376\376\245\377\377" \
+ "\377\1\316\316\316\207::<\5;;=::<;;=::<;;=\210::<\202;;=\2""99;;;=\202" \
+ "::<\3;;=::<;;=\202::<\3;;=xxz\363\363\363\225\377\377\377\3\376\376\376" \
+ "\377\377\377\376\376\376\202\377\377\377\3\363\363\363FFH::<\202;;=\202" \
+ "::<\1\204\204\206\205\377\377\377\1\376\376\376\205\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1kkm\202::<\1;;=\202::<\1SSU\230\377\377\377" \
+ "\1\234\234\236\205::<\1\234\234\234\244\377\377\377\3\376\376\376\377" \
+ "\377\377xxz\202::<\1;;=\202::<\3xxx\377\377\377\376\376\376\211\377\377" \
+ "\377\1\234\234\234\203::<\1;;=\202::<\1;;=\224::<\5;;=99;;;=::<;;=\202" \
+ "::<\1\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305@\207\214" \
+ "\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306" \
+ ">\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \
+ "\214\306>\3\214\305@\214\306<\343\361\316\202\377\377\377\26\377\376" \
+ "\374\353\365\335\223\312K\211\305\77\215\307=\215\306C\211\306;\214\306" \
+ ">\215\305@\215\307\77\214\305@\213\307A\214\306>\212\307<\216\306\77" \
+ "\212\306B\215\305>\212\306@\304\341\236\377\376\377\375\377\376\377\377" \
+ "\375\203\377\377\377\2\212\306@\214\306<\211\214\306>\3\215\305>\214" \
+ "\306>\305\342\240\215\377\377\377\4\252\324p\214\306>\215\305>\214\305" \
+ "@\207\214\306>\3\214\305@\214\306>\214\305@\232\377\377\377\4\252\324" \
+ "p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \
+ "@\231\377\377\377\2\377\377\373\376\377\377\202\377\377\377\4\241\321" \
+ "c\215\306A\215\305>\213\310\77\210\214\306>\20\215\305@\215\307=\213" \
+ "\310\77\214\304;\216\306\77\213\310\77\333\355\303\377\375\376\377\377" \
+ "\375\377\376\377\377\377\377\375\377\374\376\377\377\377\377\377\377" \
+ "\377\375\376\376\376\222\377\377\377\1\376\376\376\204\377\377\377\206" \
+ "::<\2\316\316\316\376\376\376\234\377\377\377\1\376\376\376\247\377\377" \
+ "\377\1\316\316\316\204::<\1;;=\205::<\1;;=\212::<\4""99;;;=::<;;=\203" \
+ "::<\1;;=\202::<\1\233\233\233\234\377\377\377\3\235\235\23799;;;=\203" \
+ "::<\2;;=\346\346\346\203\377\377\377\1\376\376\376\204\377\377\377\3" \
+ "\376\376\376\377\377\377\376\376\376\203\377\377\377\4\316\316\320;;" \
+ "=::<;;=\202::<\2;;=\264\264\264\227\377\377\377\1\234\234\236\205::<" \
+ "\1\234\234\234\246\377\377\377\2\234\234\236;;=\203::<\2;;=kkk\213\377" \
+ "\377\377\1\234\234\234\204::<\3;;=::<;;=\225::<\2;;=99;\202::<\3;;=:" \
+ "::\316\316\316\231\377\377\377\3\214\305@\214\306>\214\305@\207\214\306" \
+ ">\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214\306>" \
+ "\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\210" \
+ "\214\306>\14\215\307\77\215\305@\340\361\315\376\376\376\377\376\377" \
+ "\377\377\375\377\377\377\323\353\267\212\307>\215\305@\214\305@\214\311" \
+ "@\202\214\306>\22\212\307>\215\305@\214\306>\212\306@\214\305@\215\305" \
+ ">\215\307=\214\306>\214\304=\215\307\77\341\362\316\377\376\377\377\377" \
+ "\377\376\376\376\377\377\375\375\376\377\217\307@\212\306@\211\214\306" \
+ ">\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214\306" \
+ ">\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232\377" \
+ "\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305" \
+ "@\214\306>\214\305@\232\377\377\377\7\377\376\377\376\377\377\377\377" \
+ "\377\352\364\331\212\307<\215\307=\212\307>\211\214\306>\13\212\306@" \
+ "\214\306<\216\306A\214\305@\252\322q\376\376\377\376\377\373\377\376" \
+ "\377\376\376\377\377\377\375\376\377\377\203\377\377\377\1\376\377\375" \
+ "\227\377\377\377\202::<\202;;=\3::<;;=\316\316\316\233\377\377\377\1" \
+ "\375\375\375\251\377\377\377\1\316\316\316\211::<\1;;=\213::<\3;;=::" \
+ "<;;=\204::<\3""99;\205\205\207\346\346\346\233\377\377\377\4\376\376" \
+ "\376\364\364\364FFH;;=\202::<\202;;=\1\204\204\204\215\377\377\377\1" \
+ "\376\376\376\202\377\377\377\7kkm::<99;::<;;=99;TTV\227\377\377\377\1" \
+ "\234\234\236\205::<\1\234\234\234\246\377\377\377\1\234\234\236\202:" \
+ ":<\202;;=\2::<kkk\202\377\377\377\3\376\376\376\377\377\377\376\376\376" \
+ "\206\377\377\377\1\234\234\234\203::<\1;;=\202::<\2;;=::<\202;;=\223" \
+ "::<\2""99;;;=\202::<\2;;;\316\316\316\231\377\377\377\3\214\305@\214" \
+ "\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251" \
+ "\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202" \
+ "\214\306>\1\214\305@\210\214\306>\202\214\305@\15\341\362\316\377\377" \
+ "\375\376\377\375\377\377\377\373\377\374\377\376\377\271\332\211\212" \
+ "\307>\212\307<\214\305B\214\305@\216\306\77\212\307>\202\215\307\77\11" \
+ "\214\305B\215\306A\212\311=\214\303A\214\306>\215\306A\212\307>\225\311" \
+ "K\371\372\362\202\377\377\375\202\377\377\377\2\214\305@\215\306A\211" \
+ "\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p" \
+ "\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305" \
+ "@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>" \
+ "\3\214\305@\214\306>\214\305@\231\377\377\377\10\376\377\377\377\376" \
+ "\377\377\377\375\377\375\376\331\356\303\214\306>\214\305B\215\307\77" \
+ "\210\214\306>\12\215\305>\212\306B\215\304B\214\306>\215\307=\224\310" \
+ "J\364\370\351\376\376\374\375\377\372\377\377\375\203\377\377\377\3\377" \
+ "\376\377\377\377\377\376\377\375\221\377\377\377\3\376\376\376\377\377" \
+ "\377\376\376\376\203\377\377\377\7::<;;=99;::<;;=::<\315\315\315\232" \
+ "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\246\377\377" \
+ "\377\1\316\316\316\204::<\1;;=\202::<\1;;=\203::<\1;;=\210::<\1;;=\202" \
+ "::<\1;;=\202::<\4``b\233\233\235\347\347\351\376\376\376\235\377\377" \
+ "\377\2\265\265\265;;=\202::<\1;;=\202::<\1\332\332\332\216\377\377\377" \
+ "\3\376\376\376\377\377\377\302\302\302\206::<\1\315\315\315\226\377\377" \
+ "\377\1\234\234\236\205::<\1\234\234\234\245\377\377\377\2\376\376\376" \
+ "\235\235\237\205::<\1jjj\203\377\377\377\3\376\376\376\377\377\377\376" \
+ "\376\376\205\377\377\377\1\234\234\234\204::<\2;;=kkm\202\234\234\236" \
+ "\1\233\233\235\223\234\234\234\202\235\235\235\1\233\233\233\203\234" \
+ "\234\234\1\346\346\346\231\377\377\377\3\214\305@\214\306>\214\305@\207" \
+ "\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214" \
+ "\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305" \
+ "@\210\214\306>\17\212\307>\216\306A\342\360\315\376\377\377\376\376\374" \
+ "\375\377\376\377\376\377\377\376\374\377\377\375\242\320d\215\307=\214" \
+ "\306>\214\305@\215\305@\212\306@\202\214\305@\17\215\305@\212\307>\215" \
+ "\307\77\214\306<\215\306A\213\304\77\215\306A\215\307\77\252\324n\377" \
+ "\377\377\375\377\376\377\376\377\377\377\375\212\307<\215\305@\211\214" \
+ "\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\4\252\324p\214" \
+ "\306>\215\305>\214\305@\207\214\306>\3\214\305@\214\306>\214\305@\232" \
+ "\377\377\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214" \
+ "\305@\214\306>\214\305@\232\377\377\377\6\376\377\375\377\375\377\367" \
+ "\375\363\223\312H\216\306\77\215\305>\212\214\306>\2\215\305@\214\306" \
+ ">\202\212\307>\3\214\305@\247\324o\377\376\377\202\377\377\377\2\377" \
+ "\376\377\377\377\375\233\377\377\377\2::<;;=\204::<\2\316\316\316\376" \
+ "\376\376\236\377\377\377\3\316\316\316;;;:::\230::<\213\377\377\377\1" \
+ "\316\316\316\224::<\6kkmlln\205\205\207\234\234\236\301\301\303\363\363" \
+ "\363\202\377\377\377\1\376\376\376\202\377\377\377\3\376\376\376\377" \
+ "\377\377\376\376\376\231\377\377\377\1SSS\204::<\2;;=lln\213\377\377" \
+ "\377\1\376\376\376\205\377\377\377\2\376\376\376TTV\205::<\1lll\226\377" \
+ "\377\377\1\234\234\236\205::<\1\234\234\234\246\377\377\377\2\233\233" \
+ "\235;;=\204::<\2kkk\376\376\376\203\377\377\377\1\376\376\376\206\377" \
+ "\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305" \
+ "@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324" \
+ "p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \
+ "\202\214\306>\1\214\305@\210\214\306>\3\212\307>\215\305>\342\362\315" \
+ "\202\377\377\377\22\377\376\377\376\377\377\377\377\375\376\377\377\363" \
+ "\367\346\225\311K\211\307@\216\306\77\212\307>\215\305@\214\306<\212" \
+ "\307>\214\305@\214\306>\212\306@\215\306C\214\304\77\215\307\77\202\214" \
+ "\306>\7\212\306@\307\341\240\377\376\377\376\377\372\377\377\377\212" \
+ "\307>\215\305>\211\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \
+ "\377\4\252\324p\214\306>\215\305>\214\305@\207\214\306>\3\214\305@\214" \
+ "\306>\214\305@\232\377\377\377\4\252\324p\214\306>\215\305>\214\305@" \
+ "\207\214\306>\3\214\305@\214\306>\214\305@\231\377\377\377\4\377\376" \
+ "\377\376\377\375\376\377\377\257\330z\202\214\305@\1\215\307\77\211\214" \
+ "\306>\14\212\307>\215\307\77\214\305@\215\305@\212\307>\215\307=\214" \
+ "\305B\313\347\252\377\377\377\377\375\377\377\376\377\376\376\376\202" \
+ "\376\377\375\231\377\377\377\4GGI;;=::<;;=\202::<\1\233\233\235\237\377" \
+ "\377\377\3\316\316\316::<;;=\230::<\213\377\377\377\1\316\316\316\205" \
+ "::<\1kkm\202\377\377\377\2\376\376\376\250\250\250\206::<\2FFH\346\346" \
+ "\346\210\377\377\377\1\376\376\376\237\377\377\377\1\264\264\266\203" \
+ ";;=\4::<;;=;;;\316\316\316\222\377\377\377\1\265\265\265\204::<\3;;=" \
+ "::<\316\316\316\203\377\377\377\1\376\376\376\221\377\377\377\1\234\234" \
+ "\236\205::<\1\234\234\234\245\377\377\377\2\376\376\376\235\235\237\205" \
+ "::<\1lll\213\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377" \
+ "\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214" \
+ "\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \
+ "\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \
+ "\316\205\377\377\377\10\376\377\375\377\377\377\333\355\303\215\305@" \
+ "\214\306>\214\306<\214\305@\215\305>\202\214\305@\207\214\306>\6\212" \
+ "\306@\214\307;\330\355\304\377\376\377\377\377\377\215\305>\212\214\306" \
+ ">\3\215\305>\214\306>\305\342\240\215\377\377\377\17\251\323q\214\306" \
+ ">\215\307\77\214\305B\215\307\77\213\305=\215\307\77\214\305@\212\307" \
+ ">\215\305@\213\310\77\214\305@\215\305<\214\306>\376\377\377\230\377" \
+ "\377\377\6\376\377\377\253\323p\215\305@\213\307A\214\306<\212\306B\202" \
+ "\214\306>\4\214\305@\214\306>\212\307>\214\305@\202\214\306>\2\214\305" \
+ "@\376\377\375\220\377\377\377\1\377\377\375\202\377\377\377\16\376\377" \
+ "\375\377\376\377\377\375\376\374\377\377\377\377\375\376\377\375\377" \
+ "\377\377\336\355\304\214\306>\215\306A\214\306>\215\306A\212\306@\216" \
+ "\306A\202\214\305@\4\215\307\77\214\306>\215\307\77\214\306>\202\214" \
+ "\305@\16\214\306>\215\307\77\214\306>\215\307\77\214\305@\214\305B\222" \
+ "\313H\361\370\346\376\377\377\377\377\377\377\376\377\377\377\377\374" \
+ "\377\377\377\376\377\230\377\377\377\1kkm\202::<\1""99;\202::<\1\235" \
+ "\235\237\233\377\377\377\1\376\376\376\203\377\377\377\1\316\316\316" \
+ "\224::<\1;;=\205::<\213\377\377\377\1\316\316\316\205::<\1kkm\204\377" \
+ "\377\377\3wwy::<;;=\202::<\4""99;;;=``b\363\363\363\206\377\377\377\1" \
+ "\376\376\376\235\377\377\377\4\376\376\376\377\377\377\376\376\376TT" \
+ "V\205::<\1lln\223\377\377\377\10\376\376\376SSU;;=::<;;=99;::<lll\205" \
+ "\377\377\377\1\376\376\376\217\377\377\377\1\234\234\236\205::<\1\234" \
+ "\234\234\246\377\377\377\1\204\204\206\202::<\1;;=\202::<\3xxx\377\377" \
+ "\377\376\376\376\211\377\377\377\1\234\234\234\205::<\1\234\234\236\266" \
+ "\377\377\377\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215" \
+ "\305>\214\306>\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377" \
+ "\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305" \
+ "@\343\361\316\205\377\377\377\7\377\375\377\377\377\375\376\377\377\276" \
+ "\337\220\213\310\77\213\304A\216\306=\207\214\306>\3\215\307\77\214\306" \
+ ">\212\307>\202\215\305>\5\223\312J\361\371\344\377\375\377\212\307<\214" \
+ "\305@\211\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\14" \
+ "\376\376\374\252\324n\214\306>\213\305=\215\307\77\214\305@\215\306A" \
+ "\214\306>\215\307\77\213\310\77\215\305@\212\307>\202\214\306>\1\214" \
+ "\305@\232\377\377\377\3\247\324m\215\305>\214\305@\202\214\306>\1\215" \
+ "\307=\202\214\305@\6\214\306<\215\307=\214\305B\215\307\77\214\306>\214" \
+ "\305@\224\377\377\377\15\377\377\375\376\376\376\377\377\377\377\376" \
+ "\377\376\377\375\377\377\375\372\373\366\222\312M\216\306A\215\305<\214" \
+ "\306>\212\307>\215\305<\202\214\306>\2\215\307\77\213\305=\204\214\306" \
+ ">\1\214\305@\203\214\306>\14\215\307\77\214\305@\213\304\77\214\305B" \
+ "\253\324n\376\376\377\376\377\377\377\376\377\377\377\377\376\377\375" \
+ "\377\377\375\376\377\375\227\377\377\377\3lln::<;;=\203::<\2kkm\376\376" \
+ "\376\236\377\377\377\2\316\316\316;;=\226::<\3;;=::<kkm\213\377\377\377" \
+ "\1\316\316\316\204::<\2;;=kkm\204\377\377\377\3\363\363\363__a;;=\203" \
+ "::<\4;;=99;\205\205\207\376\376\376\202\377\377\377\1\376\376\376\203" \
+ "\377\377\377\1\376\376\376\236\377\377\377\1\301\301\301\204::<\4;;=" \
+ "::<wwy\235\235\237\223\234\234\236\1kkm\204::<\5;;=99;\345\345\345\377" \
+ "\377\377\376\376\376\222\377\377\377\1\234\234\236\205::<\1\234\234\234" \
+ "\246\377\377\377\1kkm\204::<\2;;=\234\234\234\213\377\377\377\1\234\234" \
+ "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \
+ "@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377" \
+ "\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1" \
+ "\214\305@\211\214\306>\2\214\305@\343\361\316\205\377\377\377\2\377\377" \
+ "\375\377\375\377\202\377\377\377\1\242\322b\202\214\305@\2\214\305B\215" \
+ "\307\77\205\214\306>\12\215\307\77\214\306>\215\306A\214\306>\212\306" \
+ "@\215\307=\241\321c\377\377\377\215\304B\212\307>\211\214\306>\3\215" \
+ "\305>\214\306>\305\342\240\214\377\377\377\5\376\377\375\251\323o\215" \
+ "\307\77\214\306>\215\307\77\202\214\305@\2\214\306>\215\307\77\202\214" \
+ "\306>\5\213\310\77\215\305>\214\305@\214\306>\377\376\377\230\377\377" \
+ "\377\12\377\376\377\247\326p\213\304\77\215\307\77\214\305B\214\306<" \
+ "\214\306>\215\307\77\214\305@\214\306>\202\215\307\77\3\214\306>\215" \
+ "\306A\216\306\77\223\377\377\377\5\376\377\372\377\377\375\376\376\376" \
+ "\377\377\377\377\377\375\202\377\376\377\4\250\325p\212\307<\214\305" \
+ "@\215\307\77\202\214\305@\3\214\307;\215\307=\214\306>\202\214\305@\202" \
+ "\214\306>\1\215\307\77\207\214\306>\202\214\305@\5\212\307>\307\341\240" \
+ "\376\376\374\377\377\377\377\376\377\202\377\377\377\1\376\376\374\227" \
+ "\377\377\377\7\234\234\236;;=99;<<>99;::<;;=\237\377\377\377\1\316\316" \
+ "\316\223::<\7;;=99;;;=99;::<;;=kkm\213\377\377\377\1\316\316\316\205" \
+ "::<\2mmo\376\376\377\204\377\377\377\12\332\332\332FFH;;=::<;;=99;<<" \
+ ">::<\266\266\270\376\376\376\203\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\376\376\376\230\377\377\377\3\376\376\376\377\377\377\376\376" \
+ "\376\202\377\377\377\1kkm\205::<\202;;=\224::<\10;;=::<;;=::<;;=88:;" \
+ ";=\205\205\205\224\377\377\377\1\234\234\236\205::<\1\234\234\234\246" \
+ "\377\377\377\3SSU;;=::<\203;;=\1\234\234\234\206\377\377\377\1\376\376" \
+ "\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377" \
+ "\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306" \
+ ">\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1" \
+ "\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \
+ "\316\205\377\377\377\10\376\376\374\376\377\375\377\375\377\377\377\377" \
+ "\367\372\357\224\313L\214\305B\215\305<\203\214\306>\202\215\307\77\204" \
+ "\214\306>\6\215\306A\213\307A\214\306>\212\306@\277\337\223\215\305>" \
+ "\212\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\2\376\377" \
+ "\377\251\322r\202\215\307\77\1\214\305B\202\214\306>\202\215\307\77\7" \
+ "\214\306>\215\307\77\214\306>\214\304\77\212\306@\215\307\77\377\376" \
+ "\377\230\377\377\377\7\377\377\375\215\305@\214\306>\214\305@\214\306" \
+ ">\216\306\77\214\306<\203\214\305@\6\215\306C\215\307=\214\305@\215\306" \
+ "A\233\314V\377\377\375\220\377\377\377\5\376\376\376\377\377\377\377" \
+ "\376\377\377\375\377\377\377\375\202\376\377\377\21\377\376\377\314\346" \
+ "\251\212\306B\215\307=\212\307>\216\306\77\215\306C\212\307>\215\306" \
+ "C\214\305@\215\307\77\213\304\77\215\306A\214\306>\214\305@\215\307\77" \
+ "\215\306A\203\214\306>\1\215\307\77\202\214\306>\202\215\307\77\10\214" \
+ "\306>\214\305@\350\364\334\377\377\375\377\376\377\377\377\377\376\376" \
+ "\376\377\376\377\222\377\377\377\1\376\376\376\204\377\377\377\1\301" \
+ "\301\301\202::<\2""99;;;=\202::<\1\316\316\316\233\377\377\377\1\376" \
+ "\376\376\202\377\377\377\2\316\316\316;;;\222::<\7""99;;;=::<;;=::<9" \
+ "9;\204\204\206\213\377\377\377\1\316\316\316\205::<\1jjl\202\377\377" \
+ "\377\202\376\376\376\202\377\377\377\1\265\265\267\202::<\202;;=\202" \
+ "::<\2FFH\332\332\332\205\377\377\377\1\376\376\376\234\377\377\377\2" \
+ "\376\376\376\317\317\317\202::<\1;;=\204::<\3;;=::<;;=\222::<\2""99;" \
+ ";;=\202::<\1;;=\203::<\3\346\346\346\377\377\377\376\376\376\221\377" \
+ "\377\377\1\234\234\236\205::<\1\234\234\234\246\377\377\377\1;;=\203" \
+ "::<\4;;=::<\316\316\316\376\376\376\203\377\377\377\1\376\376\376\206" \
+ "\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214" \
+ "\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306>\252" \
+ "\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \
+ "\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\205" \
+ "\377\377\377\203\376\377\377\202\377\376\377\2\341\361\315\214\305@\203" \
+ "\215\307\77\202\214\306>\1\215\307\77\203\214\306>\10\214\305@\215\307" \
+ "\77\214\306>\212\307>\216\306A\213\305;\214\305@\215\305<\211\214\306" \
+ ">\3\215\305>\214\306>\305\342\240\214\377\377\377\2\376\377\377\252\324" \
+ "p\202\214\306>\3\214\305B\214\306<\215\307\77\203\214\306>\6\214\306" \
+ "<\214\307;\217\307@\212\307>\214\305@\376\377\377\231\377\377\377\10" \
+ "\215\307=\214\305B\213\304A\216\310@\214\304\77\215\307=\214\305@\215" \
+ "\307\77\203\214\306>\3\215\307\77\214\306>\247\324o\222\377\377\377\3" \
+ "\377\377\375\377\377\377\377\375\376\203\377\377\377\20\360\371\346\223" \
+ "\312K\216\306\77\213\304A\215\306A\213\305=\215\305@\212\307>\215\305" \
+ "<\214\305B\214\305@\214\306>\214\306<\214\306>\215\307\77\213\305=\204" \
+ "\214\306>\202\215\307\77\203\214\306>\10\215\306A\212\307<\243\321d\377" \
+ "\377\373\375\377\376\377\376\377\377\377\377\376\376\374\223\377\377" \
+ "\377\5\375\375\375\377\377\377\376\376\376\377\377\377\346\346\346\202" \
+ "::<\1;;=\203::<\1\221\221\221\235\377\377\377\3\376\376\376\377\377\377" \
+ "\376\376\376\222\377\377\377\1__a\204::<\2;;=\234\234\234\213\377\377" \
+ "\377\1\316\316\316\205::<\3jjl\377\377\377\376\376\376\205\377\377\377" \
+ "\2\204\204\206;;=\204::<\3;;=RRT\363\363\363\237\377\377\377\1\376\376" \
+ "\376\202\377\377\377\2jjl;;=\206::<\4;;=::<99;;;=\223::<\1;;=\205::<" \
+ "\1\204\204\206\203\377\377\377\1\376\376\376\217\377\377\377\1\234\234" \
+ "\236\205::<\1\234\234\234\245\377\377\377\3\315\315\315;;=99;\202::<" \
+ "\5""99;;;=\346\346\346\377\377\377\376\376\376\211\377\377\377\1\234" \
+ "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \
+ "\305@\207\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377" \
+ "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \
+ ">\1\214\305@\211\214\306>\2\214\305@\343\361\316\207\377\377\377\202" \
+ "\377\377\375\4\376\377\377\377\377\375\303\342\237\212\306@\202\214\305" \
+ "@\206\214\306>\7\216\306\77\213\305;\214\305@\216\306A\214\306>\215\307" \
+ "\77\213\307A\212\214\306>\3\215\305>\214\306>\305\342\240\215\377\377" \
+ "\377\17\252\323k\215\306A\214\306>\215\307\77\214\306>\215\307\77\214" \
+ "\305@\214\306>\213\304A\215\306C\214\305@\213\304A\213\310=\214\306<" \
+ "\342\357\321\230\377\377\377\6\360\371\346\214\305B\212\307<\215\307" \
+ "=\213\305=\215\307\77\202\214\305@\7\215\306A\214\306>\214\306<\214\305" \
+ "@\214\306>\214\305@\252\324p\222\377\377\377\11\377\376\377\376\377\377" \
+ "\377\377\377\377\377\375\376\376\374\377\377\377\253\323p\215\307\77" \
+ "\211\306;\202\215\306A\6\214\306>\214\306<\215\305>\216\305C\215\307" \
+ "\77\213\304\77\202\215\307\77\2\215\307=\213\305;\202\215\307\77\2\214" \
+ "\306>\215\307\77\205\214\306>\5\215\307\77\212\306@\214\306>\215\307" \
+ "\77\304\341\236\202\377\377\377\2\376\376\377\374\377\377\230\377\377" \
+ "\377\7SSU;;=99;::<;;=::<FFH\232\377\377\377\1\376\376\376\205\377\377" \
+ "\377\1\376\376\376\220\377\377\377\2\376\376\376;;=\202::<\1;;=\202:" \
+ ":<\1\316\316\316\213\377\377\377\1\316\316\316\205::<\1kkm\210\377\377" \
+ "\377\2__a;;=\204::<\2;;=xxz\202\377\377\377\1\376\376\376\233\377\377" \
+ "\377\1\376\376\376\202\377\377\377\2\315\315\315;;=\206::<\2;;=99;\203" \
+ ";;=\223::<\1;;=\205::<\6FFH\363\363\363\377\377\377\376\376\376\377\377" \
+ "\377\376\376\376\216\377\377\377\1\234\234\236\205::<\1\234\234\234\244" \
+ "\377\377\377\4\376\376\376\223\223\22399;;;=\202::<\4;;=EEG\377\377\377" \
+ "\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376" \
+ "\376\204\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377" \
+ "\3\214\305@\214\306>\214\305@\207\214\306>\4\214\305@\215\305>\214\306" \
+ ">\252\324p\251\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1" \
+ "\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \
+ "\316\206\377\377\377\13\377\376\377\377\377\377\376\377\375\377\377\377" \
+ "\377\376\377\376\377\377\253\324l\214\305B\213\304\77\214\305@\215\307" \
+ "\77\203\214\306>\11\214\305@\214\306<\216\306=\214\306>\212\306@\215" \
+ "\306C\214\304;\212\307>\214\305@\211\214\306>\3\215\305>\214\306>\305" \
+ "\342\240\215\377\377\377\1\261\330\177\202\214\306>\2\214\306<\215\306" \
+ "A\203\214\306>\7\215\307\77\214\306>\214\306<\215\307=\214\306>\215\306" \
+ "C\323\353\267\230\377\377\377\4\340\361\315\215\305@\215\306A\214\305" \
+ "@\202\214\306>\2\213\305=\215\306A\202\214\305@\5\214\306>\215\307\77" \
+ "\214\306>\214\305@\260\330x\221\377\377\377\3\376\376\376\377\377\373" \
+ "\375\377\376\202\377\377\377\25\376\377\377\314\345\253\214\305@\213" \
+ "\304\77\216\306\77\212\307>\215\305@\214\306>\214\305@\215\305>\214\305" \
+ "@\214\306>\214\306<\214\305@\215\306A\214\305@\215\306C\214\306>\214" \
+ "\305@\214\306>\215\307\77\207\214\306>\7\212\306@\220\306=\215\306C\350" \
+ "\364\336\376\377\373\377\377\375\376\377\377\230\377\377\377\1\221\221" \
+ "\223\203::<\1;;=\202::<\1\265\265\265\230\377\377\377\1\376\376\376\227" \
+ "\377\377\377\1\316\316\316\202::<\1;;=\203::<\1\363\363\363\213\377\377" \
+ "\377\1\316\316\316\205::<\1kkm\204\377\377\377\1\376\376\376\203\377" \
+ "\377\377\2\346\346\346FFH\206::<\2\234\234\236\376\376\376\237\377\377" \
+ "\377\1\205\205\205\206::<\3;;=::<;;=\223::<\1;;=\203::<\202;;=\204::" \
+ "<\2\234\234\234\376\376\376\221\377\377\377\1\234\234\236\205::<\1\234" \
+ "\234\234\245\377\377\377\1RRR\204::<\2""99;yy{\203\377\377\377\1\376" \
+ "\376\376\202\377\377\377\202\376\376\376\204\377\377\377\1\234\234\234" \
+ "\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305@\207" \
+ "\214\306>\4\214\305@\215\305>\214\306>\252\324p\251\377\377\377\215\214" \
+ "\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305" \
+ "@\211\214\306>\2\214\305@\343\361\316\205\377\377\377\30\377\377\375" \
+ "\377\377\377\375\377\376\377\377\377\377\376\377\377\377\377\376\377" \
+ "\377\371\372\365\222\313H\214\305B\214\305@\215\307\77\214\306>\215\307" \
+ "\77\214\306>\214\305@\212\306B\214\305@\212\307>\216\306\77\212\307>" \
+ "\215\307\77\214\306<\214\305@\211\214\306>\3\215\305>\214\306>\305\342" \
+ "\240\214\377\377\377\20\377\376\377\301\345\237\215\305>\215\306A\213" \
+ "\304\77\215\306C\214\306>\214\306<\216\306\77\214\306>\214\305B\215\307" \
+ "\77\214\306>\215\307\77\214\305@\271\332\211\230\377\377\377\10\307\341" \
+ "\240\215\305>\214\305@\214\306>\215\305<\212\307>\214\305B\214\306<\202" \
+ "\214\306>\5\215\305<\214\305B\215\307\77\214\306>\303\344\235\222\377" \
+ "\377\377\6\376\376\377\377\377\375\376\377\377\377\376\377\352\364\333" \
+ "\215\305@\202\215\307\77\16\214\306>\215\307\77\214\306>\215\307\77\214" \
+ "\306<\216\306A\213\310\77\214\305D\215\3108\214\305@\215\305>\223\312" \
+ "K\236\323a\215\307\77\207\214\306>\202\214\305@\10\214\306>\215\307\77" \
+ "\212\307>\212\307<\241\321c\377\376\377\377\375\376\377\375\377\230\377" \
+ "\377\377\3\332\332\332:::;;=\204::<\1SSU\203\377\377\377\1\376\376\376" \
+ "\247\377\377\377\1\376\376\376\204\377\377\377\1\221\221\221\202::<\1" \
+ ";:\77\202::<\1RRT\214\377\377\377\1\316\316\316\205::<\1kkm\211\377\377" \
+ "\377\2\316\316\316;;=\202::<\5;;=::<;;=::<\316\316\316\210\377\377\377" \
+ "\1\376\376\376\215\377\377\377\1\376\376\376\207\377\377\377\2\346\346" \
+ "\350::<\202;;=\202::<\2:::xxx\230\234\234\234\3\235\235\235\234\234\234" \
+ "kkm\203::<\4;;=::<FFH\364\364\364\203\377\377\377\1\376\376\376\215\377" \
+ "\377\377\1\234\234\236\205::<\1\234\234\234\241\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\332\332\334\206::<\1\250\250\252\214\377\377\377" \
+ "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \
+ ">\214\305@\204\214\306>\2\213\307A\213\310\77\204\214\306>\1\252\324" \
+ "p\232\377\377\377\1\377\377\375\216\377\377\377\215\214\306>\1\250\325" \
+ "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>" \
+ "\2\214\305@\343\361\316\215\377\377\377\10\352\363\336\214\306>\212\306" \
+ "B\215\307\77\212\307<\215\305>\214\305@\215\307\77\221\214\306>\3\215" \
+ "\305>\214\306>\305\342\240\214\377\377\377\30\377\376\377\313\347\254" \
+ "\215\307\77\214\304=\215\307\77\212\306@\215\307\77\215\306A\214\305" \
+ "@\214\306>\215\307\77\214\306>\215\307\77\214\305@\214\305B\222\313H" \
+ "\377\376\377\377\375\376\377\376\377\377\377\377\377\376\377\377\377" \
+ "\373\376\377\377\377\376\377\211\377\377\377\26\377\377\375\377\376\377" \
+ "\377\377\377\376\377\377\377\377\375\376\377\375\377\377\377\241\323" \
+ "b\215\304D\214\307;\215\307\77\214\305B\215\307\77\214\306<\215\306A" \
+ "\212\307>\215\305@\214\306>\213\310=\215\305@\215\306A\323\352\264\221" \
+ "\377\377\377\11\376\377\377\376\376\374\376\377\377\377\376\374\377\376" \
+ "\377\242\320c\215\307\77\215\306A\214\306>\202\214\305@\203\214\306>" \
+ "\25\214\305@\215\306A\214\305@\215\307\77\214\306>\215\307=\315\345\253" \
+ "\361\370\346\215\307\77\214\306>\212\306@\216\306A\214\306>\215\305>" \
+ "\215\305@\214\305@\212\307>\215\305@\212\306@\215\305<\215\305@\202\214" \
+ "\306>\12\277\337\223\377\377\377\376\377\375\377\376\377\377\377\375" \
+ "\376\377\377\377\377\377\376\376\376\377\377\377\377\377\375\222\377" \
+ "\377\377\1___\202::<\202;;=\202::<\1\266\266\266\250\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\203\377\377\377\1SSU\203::<\3" \
+ ";;=::<\221\221\223\214\377\377\377\1\316\316\316\205::<\1kkm\210\377" \
+ "\377\377\3\376\376\376\377\377\377\233\233\233\203::<\5;;=::<;;=FFH\364" \
+ "\364\364\210\377\377\377\1\376\376\376\213\377\377\377\2\376\376\376" \
+ "\377\377\377\202\376\376\376\205\377\377\377\1\204\204\206\202::<\1;" \
+ ";=\202::<\3FFF\363\363\363\376\376\376\231\377\377\377\3\346\346\346" \
+ "::<;;=\204::<\3\234\234\234\377\377\377\376\376\376\217\377\377\377\1" \
+ "\234\234\236\205::<\1\234\234\234\234\377\377\377\1\376\376\376\207\377" \
+ "\377\377\3\205\205\207::<;;=\204::<\1\346\346\350\214\377\377\377\1\234" \
+ "\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214" \
+ "\305@\205\214\306>\7\214\306<\214\306>\215\307\77\214\305@\214\306>\252" \
+ "\324p\376\377\375\230\377\377\377\203\377\376\377\203\377\377\377\1\376" \
+ "\376\377\211\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342" \
+ "\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316" \
+ "\215\377\377\377\2\376\377\375\313\347\254\203\214\306>\3\214\305@\216" \
+ "\306\77\211\306=\221\214\306>\3\215\305>\214\306>\305\342\240\214\377" \
+ "\377\377\11\375\376\377\343\361\316\215\305>\215\307\77\213\304A\215" \
+ "\307\77\215\305>\214\306<\214\305@\203\214\306>\14\215\307\77\214\305" \
+ "@\213\304\77\214\305B\322\353\264\377\377\377\377\377\375\377\377\377" \
+ "\377\376\377\376\377\377\377\377\377\376\377\377\210\377\377\377\13\377" \
+ "\377\375\377\377\377\376\377\375\377\376\377\376\376\374\377\377\375" \
+ "\377\377\377\350\364\334\215\304D\215\305>\215\307\77\202\214\305@\202" \
+ "\214\306>\10\214\305@\215\306A\214\306<\215\306C\214\304=\215\307=\212" \
+ "\307<\351\366\332\222\377\377\377\14\377\377\375\377\377\377\377\377" \
+ "\375\304\343\237\214\306>\212\307>\217\307@\214\305@\215\307\77\214\306" \
+ ">\214\305@\215\306A\202\214\306>\5\214\306<\215\305>\211\307>\216\306" \
+ "=\251\323o\202\376\377\377\31\304\341\241\212\306@\215\306A\212\307>" \
+ "\215\307\77\214\306<\216\305C\212\307<\216\306A\214\306<\215\307\77\215" \
+ "\305>\212\307>\216\306A\214\305@\216\306A\341\361\315\377\376\377\377" \
+ "\377\375\376\377\377\377\376\377\376\376\376\377\377\377\377\376\377" \
+ "\376\377\375\222\377\377\377\1\265\265\265\202;;=\204::<\2SSU\364\364" \
+ "\364\203\377\377\377\1\376\376\376\245\377\377\377\1\376\376\376\203" \
+ "\377\377\377\1\316\316\316\203::<\1;;=\202::<\1\302\302\302\214\377\377" \
+ "\377\1\316\316\316\205::<\1kkm\213\377\377\377\1lln\204::<\3;;=::<__" \
+ "a\202\377\377\377\1\376\376\376\206\377\377\377\1\376\376\376\213\377" \
+ "\377\377\1\376\376\376\202\377\377\377\1\376\376\376\203\377\377\377" \
+ "\3\346\346\346::<;;=\204::<\1\234\234\234\234\377\377\377\1\204\204\206" \
+ "\202;;=\202::<\2;;=SSU\221\377\377\377\1\234\234\236\205::<\1\234\234" \
+ "\234\235\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202" \
+ "\377\377\377\2\346\346\346::<\202;;=\4""99;;;=::<kkm\215\377\377\377" \
+ "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \
+ ">\214\305@\204\214\306>\10\214\305@\215\306A\215\305@\213\305=\214\306" \
+ ">\215\307\77\252\324p\376\377\377\230\377\377\377\1\376\376\376\205\377" \
+ "\377\377\2\376\377\377\376\377\375\210\377\377\377\215\214\306>\1\250" \
+ "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306" \
+ ">\2\214\305@\343\361\316\215\377\377\377\10\377\377\375\377\375\376\262" \
+ "\331|\214\305@\215\306A\214\306>\214\305B\215\307\77\221\214\306>\3\215" \
+ "\305>\214\306>\305\342\240\214\377\377\377\10\376\377\375\377\377\377" \
+ "\214\304\77\212\307>\216\306A\214\306>\215\305@\215\307\77\206\214\306" \
+ ">\202\214\305@\3\233\316X\376\376\377\376\377\373\202\377\377\377\3\377" \
+ "\375\376\377\377\375\377\376\377\210\377\377\377\12\377\376\377\376\377" \
+ "\375\377\375\376\376\376\374\377\377\377\377\377\375\377\377\377\257" \
+ "\330x\214\307;\215\307\77\202\214\305@\2\215\307\77\213\305=\202\214" \
+ "\306>\1\215\305>\202\214\306>\5\216\306\77\215\306A\215\305@\376\377" \
+ "\375\377\376\377\220\377\377\377\11\377\377\375\377\377\377\376\377\377" \
+ "\350\364\334\212\307>\213\310\77\216\306\77\212\307>\214\305@\202\214" \
+ "\306>%\215\306A\214\306>\213\305=\214\306>\215\307\77\215\305@\211\307" \
+ ">\223\311M\363\367\350\376\377\375\377\377\377\377\377\375\242\320d\212" \
+ "\307<\215\306A\214\305@\212\306@\215\306A\214\306>\212\307>\215\307\77" \
+ "\217\304@\211\310<\215\305>\213\310\77\212\307>\214\306>\234\315W\367" \
+ "\372\363\376\377\377\377\376\377\377\377\375\377\377\377\376\376\376" \
+ "\377\377\375\377\377\377\376\377\375\222\377\377\377\1RRR\202::<\203" \
+ ";;=\2::<\234\234\236\204\377\377\377\1\376\376\376\246\377\377\377\3" \
+ "\376\376\376\377\377\377kkk\202::<\4;;=99;;;=FFH\215\377\377\377\1\316" \
+ "\316\316\205::<\1kkm\211\377\377\377\5\376\376\376\377\377\377\363\363" \
+ "\363SSU;;=\202::<\202;;=\2""99;\222\222\222\207\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\214\377\377\377\1\376\376\376\204\377\377" \
+ "\377\3\204\204\204;;=99;\202;;=\3::<FFH\363\363\363\230\377\377\377\1" \
+ "\376\376\376\202\377\377\377\2\376\376\376\317\317\317\203::<\4;;=::" \
+ "<;;=\266\266\266\220\377\377\377\1\234\234\236\205::<\1\234\234\234\243" \
+ "\377\377\377\2\204\204\204;;=\204::<\2""99;\264\264\264\215\377\377\377" \
+ "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \
+ ">\214\305@\204\214\306>\2\214\305@\214\306>\203\215\306A\2\215\307\77" \
+ "\251\323q\231\377\377\377\203\377\377\375\202\377\377\377\1\377\375\376" \
+ "\202\377\376\377\210\377\377\377\215\214\306>\1\250\325p\216\377\377" \
+ "\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343" \
+ "\361\316\215\377\377\377\7\376\376\376\377\377\375\366\373\364\233\316" \
+ "X\215\305@\215\307=\215\305>\222\214\306>\3\215\305>\214\306>\305\342" \
+ "\240\216\377\377\377\6\243\322b\214\306>\215\305@\215\307\77\215\305" \
+ "@\215\306A\203\214\306>\1\215\307\77\202\214\306>\202\215\307\77\2\214" \
+ "\306>\315\346\254\202\377\377\377\4\377\376\375\376\377\375\376\376\377" \
+ "\377\376\377\212\377\377\377\7\377\377\375\377\376\377\377\377\373\377" \
+ "\377\375\327\356\304\214\306>\215\307\77\202\214\305@\203\214\306>\12" \
+ "\215\307\77\214\306>\214\305@\216\306\77\214\306<\214\304\77\212\307" \
+ ">\260\331{\376\377\375\377\376\377\220\377\377\377\13\376\377\377\377" \
+ "\377\375\370\373\362\233\315Z\216\306A\214\305@\212\307>\215\306A\214" \
+ "\306>\214\305@\215\306A\202\214\306>\6\215\307\77\214\305@\214\305B\214" \
+ "\306>\215\307=\313\347\254\202\377\377\377\23\377\376\377\377\377\375" \
+ "\350\364\334\212\307>\220\306=\214\305@\216\306=\214\306>\214\305@\214" \
+ "\306>\212\306@\215\305>\212\306@\215\307\77\212\307>\215\307\77\214\305" \
+ "@\212\306@\277\340\221\202\377\377\377\1\377\377\375\203\377\377\377" \
+ "\2\377\376\377\377\377\375\220\377\377\377\4\376\376\376\377\377\377" \
+ "\265\265\265::<\202;;=\5""99;::<;;=99;\317\317\317\250\377\377\377\1" \
+ "\376\376\376\202\377\377\377\2\316\316\31699;\202::<\202;;=\2::<\221" \
+ "\221\223\215\377\377\377\1\316\316\316\205::<\1kkm\207\377\377\377\1" \
+ "\376\376\376\204\377\377\377\1\332\332\334\203::<\5;;=::<;;=99;\302\302" \
+ "\302\202\377\377\377\1\376\376\376\216\377\377\377\1\376\376\376\202" \
+ "\377\377\377\1\376\376\376\204\377\377\377\4\362\362\362FFH::<;;=\202" \
+ "::<\2;;=\221\221\223\204\377\377\377\202\376\376\376\224\377\377\377" \
+ "\1\376\376\376\203\377\377\377\1kkm\202;;=\203::<\1SSU\220\377\377\377" \
+ "\1\234\234\236\205::<\1\234\234\234\240\377\377\377\3\376\376\376\377" \
+ "\377\377\315\315\315\203::<\1;;=\202::<\1SSU\216\377\377\377\1\234\234" \
+ "\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305" \
+ "@\204\214\306>\3\215\306A\214\306<\215\307=\202\214\305@\3\214\306>\253" \
+ "\324n\377\377\375\230\377\377\377\2\375\376\377\376\376\376\203\377\377" \
+ "\377\1\377\377\375\212\377\377\377\215\214\306>\1\250\325p\216\377\377" \
+ "\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343" \
+ "\361\316\220\377\377\377\5\350\365\333\214\306>\214\305@\214\306>\215" \
+ "\306A\221\214\306>\3\215\305>\214\306>\305\342\240\215\377\377\377\7" \
+ "\377\377\375\277\337\224\212\306@\215\305@\212\307>\215\306A\215\307" \
+ "\77\203\214\306>\202\215\307\77\203\214\306>\3\214\306<\214\306>\351" \
+ "\363\330\202\377\377\377\3\376\376\376\374\377\377\376\377\377\211\377" \
+ "\377\377\1\376\377\377\202\377\377\377\7\375\376\377\351\365\337\223" \
+ "\311M\215\307=\214\305B\214\305@\215\307\77\202\214\306>\12\215\306A" \
+ "\214\305@\214\306>\212\307>\215\306A\214\306>\215\307=\213\310\77\316" \
+ "\345\255\376\377\377\221\377\377\377\7\376\377\377\377\377\375\300\337" \
+ "\223\216\306A\213\305=\215\307=\215\305>\202\214\306>\1\215\307\77\203" \
+ "\214\306>\202\214\305@\5\215\307\77\213\307A\251\322r\377\377\377\377" \
+ "\377\375\202\377\377\377\14\377\376\377\377\377\377\305\342\237\212\307" \
+ "<\220\305\77\214\306>\212\306@\215\306A\214\306<\214\305@\214\306<\216" \
+ "\305C\202\214\306>\7\215\305<\214\306>\215\305>\214\305@\342\362\316" \
+ "\377\377\377\377\377\375\202\377\377\377\3\376\377\377\377\376\377\376" \
+ "\376\376\221\377\377\377\3\376\376\376\377\377\377___\205::<\4;;=FFH" \
+ "\363\363\363\377\377\377\202\376\376\376\246\377\377\377\3\363\363\363" \
+ "SSU;;=\204::<\4;;=\345\345\345\377\377\377\376\376\376\213\377\377\377" \
+ "\1\316\316\316\205::<\1kkm\211\377\377\377\1\376\376\376\203\377\377" \
+ "\377\4\264\264\266;;=99;::<\202;;=\3::<GGI\332\332\332\206\377\377\377" \
+ "\1\376\376\376\215\377\377\377\1\376\376\376\203\377\377\377\3\234\234" \
+ "\236::<;;=\204::<\2\346\346\346\376\376\376\202\377\377\377\1\376\376" \
+ "\376\202\377\377\377\202\376\376\376\220\377\377\377\1\376\376\376\204" \
+ "\377\377\377\2\376\376\376\317\317\317\204::<\3;;=::<\265\265\265\217" \
+ "\377\377\377\1\234\234\236\205::<\1\234\234\234\235\377\377\377\1\376" \
+ "\376\376\203\377\377\377\2\363\363\363TTV\203::<\5;;=99;::<\235\235\235" \
+ "\376\376\376\215\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377" \
+ "\377\377\3\214\305@\214\306>\214\305@\204\214\306>\2\212\306@\213\310" \
+ "\77\202\214\305@\3\215\307\77\214\306<\251\323o\231\377\377\377\4\377" \
+ "\376\377\377\377\375\377\377\377\376\376\377\214\377\377\377\215\214" \
+ "\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305" \
+ "@\211\214\306>\2\214\305@\343\361\316\215\377\377\377\1\377\377\375\203" \
+ "\377\377\377\4\323\353\267\212\307<\214\306<\212\306B\221\214\306>\3" \
+ "\215\305>\214\306>\305\342\240\214\377\377\377\7\376\377\377\377\376" \
+ "\377\350\365\331\215\307\77\215\305>\214\306>\212\307>\202\214\306>\1" \
+ "\215\307\77\205\214\306>\11\215\307\77\213\304A\212\307>\222\312M\343" \
+ "\361\316\376\376\377\377\376\377\377\377\377\377\375\377\210\377\377" \
+ "\377\1\377\376\377\202\377\377\375\12\377\376\377\350\364\334\220\313" \
+ "K\216\306=\215\305<\215\307\77\214\306>\213\305=\214\306>\215\306A\202" \
+ "\214\306>\1\214\305@\202\212\307>\6\214\305@\215\306C\215\305>\360\370" \
+ "\351\377\377\373\376\377\377\221\377\377\377\7\345\360\322\215\305@\214" \
+ "\305@\215\307=\214\304=\213\310=\215\305>\202\214\306>\2\213\305=\215" \
+ "\307\77\202\214\305@\7\215\307\77\214\307;\214\305@\363\367\346\376\377" \
+ "\377\377\377\373\377\376\377\202\377\377\377\30\376\377\375\377\376\377" \
+ "\241\321a\216\306\77\212\306@\213\310=\215\305@\213\307A\217\304>\215" \
+ "\305@\214\306<\216\306A\215\306A\212\307>\214\306<\214\306>\212\307<" \
+ "\233\314W\366\373\365\377\377\375\377\377\377\377\376\377\373\377\377" \
+ "\377\376\377\224\377\377\377\1\317\317\317\205::<\4;;=::<``b\362\362" \
+ "\362\247\377\377\377\2\376\376\376\221\221\221\206::<\3\204\204\206\377" \
+ "\377\377\376\376\376\214\377\377\377\1\316\316\316\205::<\1kkm\212\377" \
+ "\377\377\6\376\376\376\377\377\377\376\376\376\377\377\377\203\203\203" \
+ ";;=\205::<\3``b\363\363\363\376\376\376\216\377\377\377\1\376\376\376" \
+ "\206\377\377\377\3\363\363\363FFH;;=\203::<\2;;=\203\203\203\203\377" \
+ "\377\377\3\376\376\376\377\377\377\376\376\376\225\377\377\377\1\376" \
+ "\376\376\204\377\377\377\3kkk::<<<>\202::<\2;;=kkm\217\377\377\377\1" \
+ "\234\234\236\205::<\1\234\234\234\236\377\377\377\4\376\376\376\377\377" \
+ "\377\376\376\376kkk\202::<\5;;=::<99;;;=TTV\202\377\377\377\1\376\376" \
+ "\376\214\377\377\377\1\234\234\234\205::<\1\234\234\236\266\377\377\377" \
+ "\3\214\305@\214\306>\214\305@\204\214\306>\10\214\306<\214\306>\214\305" \
+ "@\214\306>\215\307\77\214\306>\252\324r\376\377\377\230\377\377\377\1" \
+ "\377\377\375\202\377\377\377\2\377\377\375\376\376\374\203\377\376\377" \
+ "\210\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320" \
+ "\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\215\377" \
+ "\377\377\10\375\377\374\377\376\377\375\377\376\376\376\377\377\377\377" \
+ "\270\333\207\214\305@\215\307\77\221\214\306>\3\215\305>\214\306>\305" \
+ "\342\240\214\377\377\377\12\375\376\377\377\376\377\376\377\377\234\313" \
+ "Y\215\306A\214\305@\212\307>\214\305@\214\306>\215\307\77\206\214\306" \
+ ">\7\215\307\77\214\306>\215\305@\213\310\77\304\343\240\371\372\364\376" \
+ "\377\377\212\377\377\377\10\376\377\377\377\376\377\315\345\251\223\311" \
+ "M\214\306>\216\306\77\214\305B\214\306<\202\214\306>\15\215\306A\214" \
+ "\305@\214\306>\215\307\77\214\305@\214\306<\214\305@\215\307\77\213\304" \
+ "A\263\330{\377\377\377\376\376\376\377\377\375\220\377\377\377\7\370" \
+ "\373\364\232\315V\216\306=\212\311=\214\306>\216\306A\213\307A\202\214" \
+ "\305@\202\214\306>\202\214\305@\10\215\307\77\215\305>\215\304D\304\341" \
+ "\237\376\377\377\377\376\377\376\376\377\377\377\375\202\377\376\377" \
+ "\24\376\377\377\377\377\373\350\365\333\215\305>\214\306<\214\306>\212" \
+ "\306@\215\307\77\213\305=\215\305@\215\307\77\214\306>\215\305>\215\306" \
+ "A\211\305A\215\305@\214\305B\213\310=\262\327z\374\377\377\202\377\377" \
+ "\377\2\377\377\375\373\377\376\225\377\377\377\1\221\221\223\203::<\6" \
+ ";;=99;;;=::<``b\362\362\362\246\377\377\377\2\265\265\265:::\202::<\1" \
+ ";;=\203::<\1\346\346\350\216\377\377\377\1\316\316\316\205::<\1kkm\216" \
+ "\377\377\377\6\363\363\363__a::<;;=::<;;=\202::<\1\204\204\204\204\377" \
+ "\377\377\1\376\376\376\221\377\377\377\1\234\234\234\204::<\3;;=::<\347" \
+ "\347\347\202\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376" \
+ "\225\377\377\377\3\376\376\376\377\377\377\265\265\265\202::<\202;;=" \
+ "\3::<;;=\316\316\316\216\377\377\377\1\234\234\236\205::<\1\234\234\234" \
+ "\240\377\377\377\2\204\204\204:::\206::<\1\301\301\303\217\377\377\377" \
+ "\1\234\234\234\205::<\1\234\234\236\266\377\377\377\3\214\305@\214\306" \
+ ">\214\305@\205\214\306>\7\214\305@\216\306A\215\307=\213\304\77\213\307" \
+ "A\242\321a\345\356\317\230\342\362\316\7\341\361\315\342\361\322\342" \
+ "\361\320\343\361\315\345\360\322\365\373\357\376\377\377\211\377\377" \
+ "\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214\306" \
+ ">\1\214\305@\211\214\306>\2\214\305@\343\361\316\216\377\377\377\7\376" \
+ "\377\375\377\377\375\377\377\377\377\376\377\371\374\365\242\322d\215" \
+ "\306A\221\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\10" \
+ "\377\377\375\377\377\377\377\377\373\312\346\253\215\307=\212\307>\214" \
+ "\305B\216\306=\206\214\306>\202\214\305@\10\214\306>\212\307>\216\306" \
+ "\77\214\306>\212\307>\233\316W\306\340\237\361\370\346\210\377\377\377" \
+ "\12\361\370\350\314\345\253\233\314W\214\306>\213\310\77\215\305<\214" \
+ "\305@\212\307<\215\306A\214\305@\203\214\306>\202\214\305@\202\214\306" \
+ ">\4\216\306A\212\306@\213\310\77\333\356\301\202\377\377\377\1\377\377" \
+ "\375\220\377\377\377\26\270\332\204\215\306A\212\306B\214\306>\213\307" \
+ "A\215\305@\214\306<\214\306>\215\306A\214\306<\215\307\77\214\305B\215" \
+ "\307\77\214\307;\215\304D\241\323b\377\377\375\376\377\377\377\377\377" \
+ "\377\377\373\377\377\377\376\377\377\202\377\377\375\16\377\377\377\376" \
+ "\377\377\277\337\224\214\305@\215\306A\214\306>\215\305>\212\310\77\214" \
+ "\305@\215\307\77\212\307>\214\305B\216\306=\215\306A\202\214\306<\6\214" \
+ "\306>\213\307C\331\356\305\377\376\377\377\377\373\376\376\376\227\377" \
+ "\377\377\3__a::<;:\77\205::<\2__a\363\363\363\203\377\377\377\1\376\376" \
+ "\376\213\377\377\377\1\376\376\376\203\377\377\377\3\376\376\376\377" \
+ "\377\377\376\376\376\213\377\377\377\1\376\376\376\202\377\377\377\1" \
+ "\265\265\267\205::<\3;;=:::\234\234\234\217\377\377\377\1\316\316\316" \
+ "\205::<\1kkm\217\377\377\377\4\332\332\332GGI::<;;=\204::<\1\250\250" \
+ "\252\225\377\377\377\1FFH\205::<\1\204\204\204\242\377\377\377\1TTV\205" \
+ "::<\4lln\376\376\376\377\377\377\376\376\376\203\377\377\377\1\376\376" \
+ "\376\207\377\377\377\1\234\234\236\205::<\1\235\235\237\221\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\202\377\377\377\202\376" \
+ "\376\376\205\377\377\377\3\363\363\365\204\204\206;;=\204::<\3;;=:::" \
+ "xxx\220\377\377\377\1\234\234\234\203::<\3;;=::<\234\234\234\204\377" \
+ "\377\377\1\376\376\376\261\377\377\377\3\214\305@\214\306>\214\305@\250" \
+ "\214\306>\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250" \
+ "\325p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306" \
+ ">\2\214\305@\343\361\316\216\377\377\377\11\375\376\377\377\376\377\377" \
+ "\377\375\376\377\377\377\376\377\351\365\335\223\311M\212\307<\214\306" \
+ ">\202\216\306A\4\212\307<\215\306A\215\305>\215\307\77\211\214\306>\3" \
+ "\215\305>\214\306>\305\342\240\214\377\377\377\20\377\376\377\377\377" \
+ "\375\377\376\377\365\374\364\223\312J\217\304>\215\307\77\212\307;\215" \
+ "\306A\214\305B\214\305@\215\307\77\214\306<\213\310\77\214\305@\215\305" \
+ ">\210\214\306>\10\234\315Z\257\327~\304\343\235\306\340\237\307\341\240" \
+ "\304\343\237\257\327\177\241\321a\210\214\306>\20\217\304>\215\306A\212" \
+ "\306@\212\307>\213\305;\216\306A\213\305=\215\306C\211\310<\216\306A" \
+ "\214\306>\234\314V\377\377\377\375\377\374\376\377\377\377\376\377\211" \
+ "\377\377\377\7\377\376\377\376\377\375\376\377\377\376\377\375\377\376" \
+ "\377\377\377\377\333\355\303\210\214\306>\10\215\306A\214\305@\216\306" \
+ "=\214\306>\215\307\77\214\305@\215\307\77\352\364\334\211\377\377\377" \
+ "\6\377\376\377\367\375\363\232\315V\215\307\77\214\306>\214\305@\212" \
+ "\214\306>\6\212\307>\223\311M\366\373\364\377\376\377\377\377\377\376" \
+ "\377\373\221\377\377\377\1\376\376\376\204\377\377\377\2\346\346\346" \
+ "FFH\203::<\1""99;\203::<\2__a\332\332\332\211\377\377\377\1\376\376\376" \
+ "\203\377\377\377\1\376\376\376\205\377\377\377\1\376\376\376\206\377" \
+ "\377\377\1\376\376\376\207\377\377\377\1\265\265\267\202::<\1;;=\204" \
+ "::<\2```\376\376\376\217\377\377\377\1\316\316\316\205::<\1kkm\216\377" \
+ "\377\377\4\376\376\376\377\377\377\301\301\301;;=\205::<\2;;=\331\331" \
+ "\331\202\377\377\377\3\376\376\376\377\377\377\376\376\376\216\377\377" \
+ "\377\1\265\265\267\205::<\3;;=\332\332\332\376\376\376\241\377\377\377" \
+ "\1\266\266\270\205::<\2""99;\316\316\320\215\377\377\377\1\234\234\236" \
+ "\203::<\5;;=::<\234\234\234\377\377\377\376\376\376\220\377\377\377\1" \
+ "\376\376\376\206\377\377\377\1\376\376\376\203\377\377\377\2\346\346" \
+ "\346``b\202::<\2""99;;;=\203::<\4FFF\363\363\363\377\377\377\376\376" \
+ "\376\216\377\377\377\1\234\234\234\204::<\3;;=\234\234\234\376\376\376" \
+ "\265\377\377\377\3\214\305@\214\306>\214\305@\250\214\306>\2\215\307" \
+ "\77\342\362\316\212\377\377\377\215\214\306>\1\250\325p\216\377\377\377" \
+ "\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361" \
+ "\316\215\377\377\377\16\377\376\377\376\377\377\377\376\377\377\377\377" \
+ "\376\377\377\377\376\377\375\377\374\323\353\267\215\305<\215\306C\215" \
+ "\305<\213\306:\213\310\77\212\306@\202\214\305@\211\214\306>\3\215\305" \
+ ">\214\306>\305\342\240\215\377\377\377\4\376\377\377\377\377\375\377" \
+ "\376\377\305\342\242\202\214\305@\5\216\306A\214\306>\215\307=\215\307" \
+ "\77\213\304A\202\214\305@\2\214\306>\212\306@\210\214\306>\7\214\306" \
+ "<\215\307=\215\307\77\213\305=\214\306>\215\307\77\213\305=\211\214\306" \
+ ">\11\215\306A\215\305>\212\307;\213\304\77\215\306A\211\306=\215\306" \
+ "A\212\307<\216\306A\202\215\307\77\4\343\361\320\376\377\375\377\377" \
+ "\375\376\376\377\212\377\377\377\1\377\376\377\202\377\377\377\4\377" \
+ "\376\377\376\377\377\367\375\363\225\311J\210\214\306>\10\215\307=\213" \
+ "\310\77\214\305@\216\306\77\214\305@\212\307>\307\341\240\376\377\375" \
+ "\210\377\377\377\5\377\376\377\374\377\375\377\376\377\343\361\320\212" \
+ "\306@\202\214\306>\1\213\310\77\210\214\306>\10\215\306A\215\305>\214" \
+ "\305@\260\327z\377\376\374\374\377\377\377\377\377\377\376\377\226\377" \
+ "\377\377\1\332\332\332\210::<\2GGI\250\250\250\223\377\377\377\3\376" \
+ "\376\376\377\377\377\376\376\376\202\377\377\377\1\376\376\376\202\377" \
+ "\377\377\1\376\376\376\204\377\377\377\2\250\250\252;;=\204::<\202;;" \
+ "=\2EEG\331\331\331\220\377\377\377\1\316\316\316\205::<\1kkm\221\377" \
+ "\377\377\5\222\222\224::<;;=::<;;=\202::<\5SSU\364\364\364\376\376\376" \
+ "\377\377\377\376\376\376\216\377\377\377\2\376\376\376TTV\203::<\4;;" \
+ "=99;lln\376\376\376\243\377\377\377\1TTV\204::<\5;;=\204\204\206\376" \
+ "\376\376\377\377\377\376\376\376\212\377\377\377\1\234\234\236\202::" \
+ "<\1;;=\202::<\1\234\234\234\215\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\376\376\376\212\377\377\377\6\376\376\376\250\250\252FFH99;::" \
+ "<;;=\205::<\1\316\316\316\221\377\377\377\1\234\234\234\203::<\3;;=:" \
+ ":<\234\234\236\266\377\377\377\3\214\305@\214\306>\214\305@\250\214\306" \
+ ">\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325p\216" \
+ "\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214" \
+ "\305@\343\361\316\215\377\377\377\3\377\376\377\376\377\375\376\377\377" \
+ "\202\377\377\377\13\377\377\375\377\376\377\376\376\374\271\332\211\215" \
+ "\306A\211\306;\216\306A\212\307>\213\307A\215\306A\212\307>\211\214\306" \
+ ">\3\215\305>\214\306>\305\342\240\214\377\377\377\20\376\377\375\377" \
+ "\377\377\377\377\375\377\377\377\371\370\364\233\316U\214\306>\214\305" \
+ "@\215\306A\214\306>\214\305@\215\307=\214\306>\215\305@\215\304B\213" \
+ "\310=\210\214\306>\3\215\305@\214\306>\213\305=\202\213\310\77\3\214" \
+ "\306>\215\307\77\215\305@\210\214\306>\20\212\306@\212\307;\216\306\77" \
+ "\215\307\77\212\306@\214\306<\215\305>\215\307\77\220\305\77\211\307" \
+ ">\263\330{\377\376\377\377\377\375\376\377\377\377\377\377\376\376\376" \
+ "\211\377\377\377\7\377\377\373\377\377\377\377\375\376\377\377\377\377" \
+ "\377\375\257\330|\213\310\77\211\214\306>\6\215\306C\211\306=\214\305" \
+ "@\214\306>\242\322e\377\377\375\212\377\377\377\7\376\377\377\377\377" \
+ "\375\377\375\376\277\337\224\216\307B\212\307>\214\305@\210\214\306>" \
+ "\2\214\305@\216\306\77\202\212\307>\4\332\360\302\376\376\374\376\376" \
+ "\376\377\376\377\227\377\377\377\1\266\266\266\202::<\1;;=\202::<\2;" \
+ ";=::<\202;;=\2kkm\346\346\350\202\377\377\377\1\376\376\376\207\377\377" \
+ "\377\1\376\376\376\203\377\377\377\5\376\376\376\377\377\377\376\376" \
+ "\376\377\377\377\376\376\376\202\377\377\377\3\376\376\376\377\377\377" \
+ "\376\376\376\204\377\377\377\2\364\364\364yy{\203::<\2;;=99;\203::<\3" \
+ "\265\265\267\377\377\377\376\376\376\217\377\377\377\1\316\316\316\205" \
+ "::<\1kkm\222\377\377\377\1kkm\203::<\1;;=\202::<\5kkm\377\377\377\376" \
+ "\376\376\377\377\377\376\376\376\212\377\377\377\5\376\376\376\377\377" \
+ "\377\376\376\376\265\265\267;;=\204::<\2;;=\315\315\315\244\377\377\377" \
+ "\11\234\234\234::<99;;;=::<;;=::<\347\347\347\376\376\376\213\377\377" \
+ "\377\1\234\234\236\204::<\2;;=\233\233\233\217\377\377\377\1\376\376" \
+ "\376\206\377\377\377\6\376\376\376\377\377\377\376\376\376\377\377\377" \
+ "\265\265\265TTT\202::<\202;;=\203::<\3;;=::<\266\266\270\202\377\377" \
+ "\377\1\376\376\376\217\377\377\377\1\234\234\234\204::<\4;;=\235\235" \
+ "\237\377\377\377\376\376\376\224\377\377\377\1\376\376\376\203\377\377" \
+ "\377\1\376\376\376\233\377\377\377\3\214\305@\214\306>\214\305@\250\214" \
+ "\306>\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325" \
+ "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>" \
+ "\2\214\305@\343\361\316\215\377\377\377\202\377\377\375\16\377\377\377" \
+ "\377\377\375\377\377\377\376\377\375\376\376\374\377\376\377\375\377" \
+ "\376\241\322_\215\306A\212\306B\215\305>\215\307\77\214\306<\214\305" \
+ "B\211\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\1\377" \
+ "\376\377\202\377\377\375\15\376\377\377\377\375\376\340\361\317\214\306" \
+ ">\212\307>\214\306>\215\307\77\214\306>\212\307<\215\307\77\215\305>" \
+ "\216\306=\213\305=\210\214\306>\1\212\307>\202\214\305@\202\214\306>" \
+ "\3\214\305@\215\306A\212\307>\210\214\306>\20\212\307>\213\304\77\214" \
+ "\306>\211\310<\214\306>\216\306A\212\306@\215\305@\214\306>\223\313N" \
+ "\367\372\363\376\377\377\377\377\377\377\376\377\376\377\373\377\376" \
+ "\377\212\377\377\377\202\376\377\377\3\377\375\376\324\353\265\215\306" \
+ "A\211\214\306>\7\215\305>\213\305=\215\307\77\215\306A\212\307>\351\363" \
+ "\333\377\377\375\211\377\377\377\10\377\376\377\375\377\376\376\377\377" \
+ "\377\376\377\370\373\362\233\314W\215\307\77\215\305<\210\214\306>\1" \
+ "\215\307\77\202\214\306>\4\214\306<\225\310O\360\366\350\377\376\377" \
+ "\221\377\377\377\3\376\376\376\377\377\377\376\376\376\205\377\377\377" \
+ "\1\266\266\266\202::<\4;;=99;::<;;=\202::<\4;;=::<\204\204\206\346\346" \
+ "\350\207\377\377\377\1\376\376\376\206\377\377\377\202\376\376\376\202" \
+ "\377\377\377\1\376\376\376\203\377\377\377\1\376\376\376\202\377\377" \
+ "\377\3\251\251\251FFF99;\202::<\1""99;\202::<\5;;=::<\234\234\236\377" \
+ "\377\377\376\376\376\220\377\377\377\1\316\316\316\205::<\1kkm\222\377" \
+ "\377\377\11\363\363\363GGI99;::<99;;;=::<;;=\234\234\234\214\377\377" \
+ "\377\1\376\376\376\203\377\377\377\1SSU\202::<\1;;=\202::<\1kkm\245\377" \
+ "\377\377\5\362\362\362GGI;;=::<;;=\202::<\1\204\204\206\206\377\377\377" \
+ "\1\376\376\376\205\377\377\377\1\234\234\236\203::<\3""99;::<\234\234" \
+ "\234\223\377\377\377\1\376\376\376\203\377\377\377\3\331\331\331\222" \
+ "\222\222SSU\203::<\2;;=::<\202;;=\4::<;;=::<\265\265\267\202\377\377" \
+ "\377\1\376\376\376\203\377\377\377\1\376\376\376\214\377\377\377\1\234" \
+ "\234\234\205::<\1\234\234\236\203\377\377\377\1\376\376\376\223\377\377" \
+ "\377\1\376\376\376\236\377\377\377\3\214\305@\214\306>\214\305@\250\214" \
+ "\306>\2\215\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325" \
+ "p\216\377\377\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>" \
+ "\2\214\305@\343\361\316\216\377\377\377\17\377\376\377\377\377\377\376" \
+ "\376\376\377\376\377\377\377\375\376\377\377\375\377\376\377\377\377" \
+ "\363\367\350\222\312K\214\305@\213\310\77\214\304\77\215\307\77\216\306" \
+ "A\211\214\306>\3\215\305>\214\306>\305\342\240\214\377\377\377\14\377" \
+ "\376\377\376\377\375\376\377\377\377\376\377\376\377\377\376\377\375" \
+ "\307\342\237\214\305@\214\306<\215\304D\214\306>\214\305D\202\212\307" \
+ "<\2\212\307>\213\307A\210\214\306>\3\215\307\77\214\306>\215\307\77\202" \
+ "\214\305@\213\214\306>\12\213\305;\215\306A\212\306@\214\306>\213\307" \
+ "C\212\307>\215\305>\212\307>\215\305>\333\356\301\202\377\377\377\3\377" \
+ "\377\375\377\377\377\377\376\377\211\377\377\377\10\376\377\375\377\377" \
+ "\375\376\377\375\374\377\375\362\371\347\225\311M\215\307\77\215\305" \
+ "<\210\214\306>\2\214\305@\216\306=\202\212\306@\2\305\342\237\377\375" \
+ "\376\212\377\377\377\1\376\376\374\203\377\377\377\4\376\376\376\337" \
+ "\363\316\215\306C\215\305<\211\214\306>\1\215\307\77\202\214\305@\4\214" \
+ "\306<\253\324n\375\377\374\377\377\375\224\377\377\377\1\376\376\376" \
+ "\204\377\377\377\2\301\301\301FFH\202::<\2;;=99;\202;;=\2::<;;=\202:" \
+ ":<\2\204\204\206\316\316\320\207\377\377\377\1\376\376\376\203\377\377" \
+ "\377\1\376\376\376\206\377\377\377\6\376\376\376\377\377\377\364\364" \
+ "\364\265\265\267SSU::<\202;;=\202::<\5;;=::<;;=::<\204\204\204\223\377" \
+ "\377\377\1\316\316\316\205::<\1kkm\223\377\377\377\11\315\315\315;;=" \
+ "::<;;=::<;;=::<99;\302\302\302\216\377\377\377\5\301\301\303::<;;=::" \
+ "<;;=\202::<\2\316\316\316\377\377\377\202\376\376\376\241\377\377\377" \
+ "\14\376\376\376\377\377\377\234\234\234;;=::<;;=::<;;=::<\347\347\351" \
+ "\377\377\377\376\376\376\211\377\377\377\1\234\234\236\203::<\3;;=::" \
+ "<\234\234\236\216\377\377\377\202\376\376\376\1\377\377\377\202\316\316" \
+ "\316\6\250\250\250\234\234\234jjjFFF;;=99;\202;;=\2::<;;=\202::<\5<<" \
+ ">99;;;=::<\265\265\267\204\377\377\377\1\376\376\376\217\377\377\377" \
+ "\1\234\234\234\204::<\2;;=\234\234\236\202\377\377\377\1\376\376\376" \
+ "\223\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\234\377" \
+ "\377\377\3\214\305@\214\306>\214\305@\250\214\306>\2\215\307\77\342\362" \
+ "\316\212\377\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361" \
+ "\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\215" \
+ "\377\377\377\202\377\376\377\16\377\377\375\376\377\377\377\377\377\377" \
+ "\377\375\377\376\377\376\376\376\377\376\377\377\377\377\333\354\302" \
+ "\212\307>\213\310\77\214\306<\213\310=\215\305@\211\214\306>\3\215\305" \
+ ">\214\306>\305\342\240\214\377\377\377\1\377\376\377\202\376\377\377" \
+ "\202\377\377\375\13\376\377\377\377\375\376\271\333\205\215\305>\214" \
+ "\306>\212\307>\214\306>\215\306A\214\306>\212\306@\214\305@\210\214\306" \
+ ">\3\214\305@\215\307\77\214\306>\202\212\307>\3\214\306>\215\307\77\215" \
+ "\306A\210\214\306>\4\216\306A\211\306=\214\306<\216\306A\202\212\307" \
+ ">\202\215\306A\10\322\352\270\377\377\375\376\376\374\377\377\377\376" \
+ "\377\377\377\376\377\377\377\375\376\377\377\210\377\377\377\10\377\377" \
+ "\375\377\377\377\377\376\377\374\376\373\250\325n\216\306\77\212\307" \
+ ">\214\305B\210\214\306>\202\212\307>\6\214\305@\242\322d\376\376\374" \
+ "\377\377\375\375\377\376\377\376\377\210\377\377\377\10\376\377\377\377" \
+ "\377\375\377\375\376\377\377\375\375\376\377\376\377\375\270\333\207" \
+ "\211\310<\210\214\306>\10\214\304=\216\307B\214\306>\212\307>\216\306" \
+ "A\215\307\77\313\350\250\376\376\377\221\377\377\377\1\376\376\376\203" \
+ "\377\377\377\1\376\376\376\204\377\377\377\7\332\332\332RRT;;=::<;;=" \
+ "::<;;=\202::<\1;;=\203::<\3RRT\221\221\223\317\317\321\214\377\377\377" \
+ "\11\376\376\376\377\377\377\364\364\364\301\301\301\204\204\206EEG;;" \
+ "=99;;;=\204::<\1""99;\202::<\1\251\251\251\207\377\377\377\1\376\376" \
+ "\376\214\377\377\377\1\316\316\316\205::<\1kkm\224\377\377\377\1\247" \
+ "\247\247\203::<\5;;=::<;;=FFH\345\345\345\214\377\377\377\2\376\376\376" \
+ "kkm\205::<\1SSU\202\377\377\377\1\376\376\376\244\377\377\377\2\363\363" \
+ "\363FFH\204::<\2;;=\221\221\223\213\377\377\377\1\234\234\236\204::<" \
+ "\4;;=SSUkkmlln\213kkm\5;;=::<;;=::<;;=\204::<\2;;=99;\202;;=\2::<;;=" \
+ "\202::<\7;;=99;::<FFH\301\301\301\377\377\377\376\376\376\223\377\377" \
+ "\377\1\234\234\234\205::<\1SSU\202kkm\1lln\223kkm\1lln\205kkm\1\332\332" \
+ "\334\231\377\377\377\3\214\305@\214\306>\214\305@\250\214\306>\2\215" \
+ "\307\77\342\362\316\212\377\377\377\215\214\306>\1\250\325p\216\377\377" \
+ "\377\1\342\361\320\202\214\306>\1\214\305@\211\214\306>\2\214\305@\343" \
+ "\361\316\215\377\377\377\1\377\376\377\202\377\377\375\202\377\377\377" \
+ "\202\377\376\377\11\377\377\375\377\377\377\376\377\377\377\376\377\276" \
+ "\336\223\214\306<\213\310\77\214\304=\215\306A\211\214\306>\3\215\305" \
+ ">\214\306>\305\342\240\214\377\377\377\20\377\377\375\376\377\375\376" \
+ "\376\376\377\376\377\375\377\376\377\375\377\376\377\377\376\377\375" \
+ "\270\333\207\217\305<\212\307>\214\305@\216\306\77\213\305=\214\305@" \
+ "\216\306=\211\214\306>\2\215\306A\215\305@\202\216\306\77\3\215\305@" \
+ "\214\305@\215\307\77\210\214\306>\13\213\305=\215\306A\215\305>\212\306" \
+ "@\215\305>\215\306A\220\305A\323\352\266\376\377\375\377\376\377\377" \
+ "\377\375\202\377\377\377\3\376\377\377\377\375\377\376\377\375\213\377" \
+ "\377\377\5\316\347\256\212\307>\213\305;\216\306A\212\307<\210\214\306" \
+ ">\10\212\307>\216\306\77\215\305>\350\364\336\377\376\377\376\376\374" \
+ "\377\377\377\377\376\377\210\377\377\377\1\377\376\377\202\377\377\377" \
+ "\5\377\376\377\376\377\375\377\376\377\370\373\360\225\311K\210\214\306" \
+ ">\10\216\306=\214\305@\215\310<\212\307>\214\306>\214\305@\223\312J\356" \
+ "\371\350\231\377\377\377\4\376\376\376\377\377\377\363\363\363xxz\202" \
+ "::<\1""99;\202::<\1;;=\203::<\202;;=\203::<\4__a\205\205\205\234\234" \
+ "\234\250\250\250\205\316\316\316\4\250\250\250\234\234\234xxx___\202" \
+ "::<\3""99;;;=99;\203::<\1;;=\203::<\2FFH\265\265\265\205\377\377\377" \
+ "\1\376\376\376\217\377\377\377\1\316\316\316\205::<\1kkm\225\377\377" \
+ "\377\3xxx::<;;=\204::<\1```\213\377\377\377\4\376\376\376\317\317\317" \
+ "::<;;=\204::<\1\266\266\270\203\377\377\377\1\376\376\376\241\377\377" \
+ "\377\1\377\377\375\202\377\377\377\1\204\204\206\202::<\1;;=\202::<\2" \
+ "GGI\363\363\363\212\377\377\377\1\234\234\236\203::<\1;;=\202::<\1;;" \
+ "=\221::<\1;;=\207::<\1;;=\202::<\1;;=\202::<\2``b\346\346\350\210\377" \
+ "\377\377\1\376\376\376\215\377\377\377\1\234\234\234\207::<\3;;=::<;" \
+ ";=\221::<\1;;=\203::<\1;;=\202::<\1\316\316\320\231\377\377\377\3\214" \
+ "\305@\214\306>\214\305@\250\214\306>\2\215\307\77\342\362\316\212\377" \
+ "\377\377\215\214\306>\1\250\325p\216\377\377\377\1\342\361\320\202\214" \
+ "\306>\1\214\305@\211\214\306>\2\214\305@\343\361\316\215\377\377\377" \
+ "\7\377\377\375\376\377\375\377\377\377\377\376\377\376\376\374\376\377" \
+ "\377\377\377\377\202\376\377\377\202\377\377\375\4\377\377\377\242\320" \
+ "d\211\306=\215\305@\212\214\306>\3\215\305>\214\306>\305\342\240\214" \
+ "\377\377\377\6\377\376\377\377\377\377\377\377\375\377\375\377\376\377" \
+ "\372\375\376\377\202\377\377\377\10\376\377\377\304\343\240\215\305@" \
+ "\214\306>\216\306A\215\307\77\212\307>\215\307\77\212\214\306>\3\215" \
+ "\307\77\214\306>\214\305@\202\215\307\77\211\214\306>\12\215\306C\212" \
+ "\307<\215\307\77\215\305@\213\310\77\215\306A\323\352\266\377\376\377" \
+ "\377\377\377\376\377\377\204\377\377\377\2\377\377\375\377\376\377\210" \
+ "\377\377\377\10\376\377\377\377\376\377\361\370\346\225\311K\212\307" \
+ ">\215\306A\214\305@\215\305>\210\214\306>\3\214\305@\214\306>\307\341" \
+ "\240\203\376\377\377\2\377\377\375\376\377\377\210\377\377\377\5\376" \
+ "\377\377\377\376\372\376\377\375\376\376\376\377\377\377\202\377\376" \
+ "\377\1\334\355\301\210\214\306>\10\215\306A\213\310\77\215\305@\214\306" \
+ ">\214\306<\215\306A\214\306>\254\322o\232\377\377\377\6\376\376\376\377" \
+ "\377\377\376\376\376\302\302\302FFH;;=\206::<\1;;=\202::<\202;;=\203" \
+ "::<\1;;=\204::<\3;;=::<;;=\202::<\1;;=\202::<\1;;=\203::<\2;;=::<\202" \
+ ";;=\2__a\332\332\332\226\377\377\377\3\316\316\316::<;;=\203::<\1kkm" \
+ "\222\377\377\377\7\376\376\376\377\377\377\376\376\376\363\363\363__" \
+ "a::<;;=\204::<\1\203\203\203\202\377\377\377\2\376\376\376\377\377\377" \
+ "\202\376\376\376\205\377\377\377\1kkm\202::<\1;;=\202::<\5TTV\377\377" \
+ "\377\376\376\376\377\377\377\376\376\376\245\377\377\377\2\347\347\347" \
+ "99;\202::<\1;;=\202::<\1\235\235\237\206\377\377\377\1\376\376\376\202" \
+ "\377\377\377\2\376\376\376\234\234\234\224::<\1;;=\202::<\3""99;::<;" \
+ ";=\204::<\1;;=\204::<\3;;=GGI\250\250\252\230\377\377\377\2\234\234\236" \
+ ";;=\232::<\10;;=99;;;=::<;;=::<:::\316\316\316\230\377\377\377\10\377" \
+ "\376\377\212\306@\214\305@\213\310=\214\306<\215\306A\214\307;\215\306" \
+ "A\240\214\306>\10\214\305@\212\307<\214\306<\214\305@\212\306@\342\360" \
+ "\315\376\377\377\377\376\377\210\377\377\377\212\214\306>\4\216\306\77" \
+ "\212\306B\214\306>\250\325n\202\377\376\377\210\377\377\377\1\377\376" \
+ "\377\202\377\377\377\5\376\377\375\342\362\316\214\305B\215\305@\214" \
+ "\306<\210\214\306>\202\212\307>\5\343\361\320\377\377\377\377\377\375" \
+ "\376\377\377\377\376\377\223\377\377\377\6\377\376\377\377\377\375\371" \
+ "\372\364\223\312J\212\306@\215\305@\210\214\306>\10\214\305@\215\305" \
+ ">\212\307>\304\343\240\377\377\375\377\377\377\377\377\375\377\376\377" \
+ "\220\377\377\377\11\376\377\377\377\377\377\333\355\303\226\310K\213" \
+ "\310\77\214\306>\215\305@\215\306A\214\305@\203\214\306>\7\215\305>\215" \
+ "\305@\214\305@\212\307>\215\305>\215\307\77\215\306A\202\214\306<\5\215" \
+ "\306A\213\305=\215\305@\215\307\77\213\305;\202\215\305@\13\215\307\77" \
+ "\213\310\77\214\305@\215\307\77\212\307>\215\305>\214\306>\212\306@\235" \
+ "\315U\347\365\334\377\376\377\220\377\377\377\15\376\376\376\377\377" \
+ "\375\377\377\377\244\317c\213\307A\214\306<\213\307A\215\305>\215\305" \
+ "<\215\307\77\214\306<\215\307\77\214\305@\202\215\307\77\12\214\305@" \
+ "\215\306A\215\305@\234\315W\367\375\363\377\376\377\376\377\377\377\377" \
+ "\375\376\377\377\377\376\377\220\377\377\377\10\260\331{\215\307=\212" \
+ "\307>\213\307A\214\306>\215\305@\215\307\77\215\305>\210\214\306>\3\314" \
+ "\345\253\377\377\377\376\377\375\202\377\376\377\2\377\377\377\376\377" \
+ "\377\222\377\377\377\3\376\376\376\377\377\377\376\376\376\202\377\377" \
+ "\377\3\364\364\364\220\220\220;;=\211::<\2;;=::<\202;;=\2::<;;=\202:" \
+ ":<\4;;=::<;;=99;\203::<\2;;=99;\206::<\2GGI\247\247\251\203\377\377\377" \
+ "\1\376\376\376\222\377\377\377\6\376\376\376\377\377\377\316\316\316" \
+ ";;=99;;;=\202::<\2lln\376\376\376\202\377\377\377\1\376\376\376\221\377" \
+ "\377\377\4\376\376\376\333\333\333FFH;;=\202::<\1;;=\202::<\1\265\265" \
+ "\265\202\377\377\377\1\376\376\376\202\377\377\377\5\376\376\376\377" \
+ "\377\377\376\376\376\377\377\377\316\316\320\202::<\2;;=99;\202;;=\1" \
+ "\264\264\266\202\377\377\377\1\376\376\376\244\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\205\205\207\204::<\3;;=FFH\363\363\363\206\377" \
+ "\377\377\1\376\376\376\202\377\377\377\3\233\233\233::<;;=\220::<\3""9" \
+ "9;;;=99;\202::<\1;;=\203::<\1;;=\204::<\7;;=::<SSU\250\250\252\362\362" \
+ "\364\377\377\377\376\376\376\225\377\377\377\3\376\376\376\377\377\377" \
+ "\235\235\237\202::<\1;;=\231::<\2;;=99;\204::<\1\316\316\316\230\377" \
+ "\377\377\10\377\377\373\212\311=\212\306@\216\306A\215\305>\215\307\77" \
+ "\214\306>\215\306A\240\214\306>\7\214\306<\214\306>\216\306\77\214\306" \
+ ">\214\305@\343\361\320\377\377\375\211\377\377\377\210\214\306>\10\213" \
+ "\307A\212\306@\215\305@\212\307<\215\307\77\247\324o\375\377\376\376" \
+ "\377\377\211\377\377\377\7\376\377\375\377\377\377\377\377\375\342\360" \
+ "\315\214\305@\213\305=\215\307\77\210\214\306>\10\215\305>\215\307\77" \
+ "\343\361\316\376\376\376\377\376\377\376\377\377\377\377\375\376\377" \
+ "\372\220\377\377\377\10\376\377\377\377\376\377\377\377\375\377\376\374" \
+ "\376\377\375\343\362\321\212\307>\214\307;\210\214\306>\4\215\307=\215" \
+ "\304B\213\307A\305\342\240\203\377\377\377\1\376\377\377\222\377\377" \
+ "\377\21\377\376\377\367\374\365\267\332\206\215\306A\212\306@\214\306" \
+ "<\214\306>\215\306A\215\307\77\214\306>\214\305@\212\306B\212\306@\212" \
+ "\307<\215\307\77\214\306>\214\305@\202\215\305@\5\214\305@\214\306>\214" \
+ "\305@\212\307>\215\306A\202\214\305@\11\214\307;\214\306>\215\306A\214" \
+ "\305@\215\305>\212\306@\222\311I\306\343\240\366\373\364\224\377\377" \
+ "\377\6\303\342\237\217\304@\214\306<\214\306>\215\306C\212\306B\204\214" \
+ "\305@\1\215\306A\202\214\305@\11\215\306A\214\306<\214\306>\341\361\314" \
+ "\377\377\377\376\377\375\377\377\377\377\375\377\377\377\375\221\377" \
+ "\377\377\10\370\373\364\224\307N\215\305@\215\305>\212\307<\215\306A" \
+ "\212\307<\215\306A\210\214\306>\10\215\307=\346\364\332\376\377\375\376" \
+ "\377\373\377\377\377\376\376\377\377\376\377\377\377\375\230\377\377" \
+ "\377\5\346\346\350\204\204\206GGI::<;;=\202::<\5;;=::<;;=::<;;=\202:" \
+ ":<\3;;=::<;;=\202::<\5;;=99;;;=::<;;=\207::<\3FFH\234\234\234\363\363" \
+ "\363\203\377\377\377\1\376\376\376\222\377\377\377\1\376\376\376\202" \
+ "\377\377\377\4\316\316\316::<;;=99;\202;;=\1kkm\202\377\377\377\1\376" \
+ "\376\376\220\377\377\377\1\376\376\376\202\377\377\377\5\376\376\376" \
+ "\266\266\26699;;;=::<\202;;=\3::<GGG\332\332\332\207\377\377\377\2\376" \
+ "\376\376\204\204\206\202;;=\4::<;;=::<SSU\252\377\377\377\2\376\376\376" \
+ "\346\346\350\202::<\5;;=::<99;;;;\266\266\266\203\377\377\377\1\376\376" \
+ "\376\205\377\377\377\3\235\235\235::<99;\220::<\1;;=\205::<\203;;=\1" \
+ "99;\203::<\3SSS\221\221\221\316\316\316\205\377\377\377\1\376\376\376" \
+ "\222\377\377\377\1\376\376\376\203\377\377\377\3\234\234\236::<;;=\232" \
+ "::<\7""99;::<;:\77::<;;=99;\317\317\321\230\377\377\377\7\377\375\377" \
+ "\214\306<\213\307A\215\305>\215\307\77\212\307>\216\306\77\241\214\306" \
+ ">\1\215\306C\202\215\305@\5\212\306@\215\307=\343\361\320\377\377\377" \
+ "\377\376\377\210\377\377\377\210\214\306>\10\215\305<\215\307\77\216" \
+ "\306\77\214\306>\216\305C\252\324r\377\377\377\377\377\373\211\377\377" \
+ "\377\7\375\377\376\377\377\377\377\375\376\343\361\316\215\307=\212\307" \
+ ">\215\305>\210\214\306>\10\214\305@\215\305<\342\362\316\377\377\375" \
+ "\377\376\377\375\377\374\376\376\377\376\377\377\222\377\377\377\1\375" \
+ "\377\372\202\377\377\377\3\377\376\377\304\341\237\215\307\77\210\214" \
+ "\306>\10\212\307;\215\307\77\213\305=\305\342\240\377\377\377\377\376" \
+ "\374\377\377\375\376\377\377\221\377\377\377\22\377\376\377\377\377\375" \
+ "\376\377\377\377\375\376\361\367\351\270\334\204\214\306>\215\307\77" \
+ "\214\305@\212\306@\213\307A\212\306@\213\310\77\214\306>\215\304B\214" \
+ "\306>\212\307<\214\306>\202\216\306A\6\214\306>\213\310\77\214\305@\215" \
+ "\305<\215\305>\215\307=\202\213\310\77\10\215\306A\214\306>\215\306A" \
+ "\222\311I\300\336\226\361\370\346\376\376\376\377\377\377\202\377\376" \
+ "\377\1\376\377\373\217\377\377\377\10\377\377\375\347\365\333\214\307" \
+ ";\211\305A\213\304\77\215\307\77\215\305<\213\310\77\202\214\306>\1\215" \
+ "\307\77\203\214\306>\4\215\307\77\214\306>\215\306A\275\337\223\202\377" \
+ "\377\377\5\377\376\377\377\377\377\376\377\375\377\376\377\376\377\377" \
+ "\220\377\377\377\10\375\377\376\331\357\301\215\307\77\215\305>\216\305" \
+ "C\211\306=\220\305A\211\307@\210\214\306>\10\214\305@\246\321e\377\377" \
+ "\377\377\376\377\376\377\377\377\377\375\376\377\377\377\376\377\227" \
+ "\377\377\377\1\376\376\376\202\377\377\377\3\363\363\363\266\266\270" \
+ "__a\207::<\202;;=\203::<\2;;=99;\202;;=\2""99;::<\202;;=\1::<\203;;=" \
+ "\3^^^\250\250\250\363\363\363\203\377\377\377\1\376\376\376\202\377\377" \
+ "\377\1\376\376\376\224\377\377\377\4\316\316\316999::<;;=\202::<\1ll" \
+ "l\205\377\377\377\1\376\376\376\217\377\377\377\6\376\376\376\377\377" \
+ "\377\376\376\376\204\204\204::<;;=\203::<\3:::TTT\363\363\363\206\377" \
+ "\377\377\10\347\347\347;;;99;::<;;=::<:::\234\234\236\253\377\377\377" \
+ "\3\376\376\376lln;;=\202::<\3;;=999SSS\202\377\377\377\1\376\376\376" \
+ "\203\377\377\377\4\376\376\376\377\377\377\376\376\376\234\234\234\223" \
+ "::<\1""99;\202::<\1;;=\203::<\5kkmxxz\235\235\237\301\301\301\346\346" \
+ "\346\207\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\221" \
+ "\377\377\377\1\376\376\376\202\377\377\377\3\235\235\235::<;;=\232::" \
+ "<\2;;=99;\202::<\3;;=::<\316\316\316\230\377\377\377\10\373\377\376\216" \
+ "\306A\214\306<\213\304A\212\306@\214\305@\214\304\77\215\307\77\240\214" \
+ "\306>\6\214\306<\215\306A\215\305@\216\310@\217\304@\341\361\314\212" \
+ "\377\377\377\210\214\306>\7\215\307\77\213\310\77\213\305=\215\307\77" \
+ "\214\304\77\253\323r\374\377\373\211\377\377\377\1\377\376\377\203\377" \
+ "\377\377\3\342\362\315\215\305@\215\307=\211\214\306>\10\214\306<\215" \
+ "\304B\341\363\313\374\377\375\376\376\377\377\377\377\377\375\376\377" \
+ "\377\375\221\377\377\377\7\376\377\375\376\376\377\377\377\377\375\377" \
+ "\374\377\377\377\377\377\375\253\323p\210\214\306>\5\215\307\77\215\305" \
+ ">\217\304@\305\342\237\376\377\375\202\377\377\377\1\377\377\375\220" \
+ "\377\377\377\1\376\377\377\202\377\376\377\202\376\377\375\202\377\377" \
+ "\377\5\360\370\351\311\347\247\245\320e\215\305>\212\307>\202\214\306" \
+ ">\5\215\306A\212\307>\215\305@\214\306>\214\306<\202\214\306>\2\214\306" \
+ "<\214\306>\202\216\306A\14\214\306>\215\306A\215\305<\214\306>\213\305" \
+ "=\255\331x\323\353\267\366\374\362\377\377\377\377\377\375\377\377\377" \
+ "\376\377\377\217\377\377\377\2\376\376\376\377\377\377\202\377\377\375" \
+ "\11\244\317d\214\306>\213\307A\214\306>\214\305@\214\306>\215\306A\214" \
+ "\306<\215\307\77\202\214\306>\202\214\305@\13\215\305<\215\305@\230\316" \
+ "V\370\373\360\376\377\375\377\377\377\377\376\377\376\376\376\377\377" \
+ "\375\377\376\377\376\377\377\220\377\377\377\10\376\376\376\377\376\377" \
+ "\262\327x\214\306>\216\306A\215\307=\215\305<\215\306A\211\214\306>\6" \
+ "\215\306C\307\341\240\376\377\373\376\377\377\376\377\375\376\376\374" \
+ "\236\377\377\377\4\346\346\350\266\266\270\204\204\206SSU\202::<\1;;" \
+ "=\202::<\1;;=\202::<\202;;=\3""99;::<;;=\203::<\4GGIxxz\247\247\247\347" \
+ "\347\347\212\377\377\377\1\376\376\376\223\377\377\377\1\364\364\364" \
+ "\205\316\316\316\1\332\332\332\203\377\377\377\202\376\376\376\221\377" \
+ "\377\377\1\376\376\376\202\377\377\377\202\316\316\316\203\316\316\320" \
+ "\3\316\316\316\317\317\317\346\346\346\206\377\377\377\5\346\346\346" \
+ "\316\316\316\317\317\317\316\316\316\315\315\315\202\316\316\316\1\363" \
+ "\363\363\250\377\377\377\1\376\376\376\203\377\377\377\3\346\346\346" \
+ "\315\315\315\317\317\317\202\316\316\320\3\317\317\317\315\315\315\363" \
+ "\363\363\202\377\377\377\202\376\376\376\204\377\377\377\3\346\346\346" \
+ "\316\316\316\316\316\320\224\316\316\316\1\315\315\315\203\377\377\377" \
+ "\1\376\376\376\215\377\377\377\1\376\376\376\225\377\377\377\2\346\346" \
+ "\346\317\317\317\232\316\316\316\1\317\317\317\203\316\316\316\4\317" \
+ "\317\317\315\315\315\316\316\316\363\363\363\231\377\377\377\3\340\361" \
+ "\317\342\360\317\342\362\316\202\343\361\316\2\342\360\315\343\361\316" \
+ "\240\342\361\320\10\342\362\316\342\361\320\343\363\317\341\360\317\342" \
+ "\361\320\370\373\364\376\377\375\376\377\377\210\377\377\377\210\342" \
+ "\361\320\7\341\360\317\342\362\316\343\361\316\342\360\314\342\361\320" \
+ "\350\364\336\377\376\374\211\377\377\377\10\377\376\377\377\377\375\377" \
+ "\377\377\377\377\375\370\373\362\341\360\321\340\357\316\342\362\316" \
+ "\210\342\361\320\3\342\362\316\342\361\320\371\373\360\203\377\377\377" \
+ "\202\377\376\377\220\377\377\377\4\377\377\375\376\376\376\377\376\377" \
+ "\376\377\375\203\377\377\377\1\365\375\362\210\342\361\320\4\341\360" \
+ "\321\342\361\322\343\363\317\360\367\345\224\377\377\377\7\376\377\377" \
+ "\376\377\375\377\377\375\377\376\377\377\377\375\377\375\376\377\376" \
+ "\377\202\377\377\377\30\376\376\377\364\370\351\333\354\277\277\337\224" \
+ "\247\324k\224\313K\214\305@\214\306>\212\306@\214\306>\214\305B\215\306" \
+ "C\215\307\77\212\306@\214\306>\215\307\77\241\321c\257\330|\304\342\242" \
+ "\341\361\315\377\377\377\377\376\377\376\377\373\377\377\377\202\377" \
+ "\377\375\1\377\376\377\203\377\377\377\1\376\377\377\212\377\377\377" \
+ "\1\376\376\376\203\377\377\377\13\376\376\374\372\372\370\342\361\320" \
+ "\343\361\316\342\362\316\341\360\317\342\361\320\341\360\317\342\362" \
+ "\316\342\361\322\342\361\320\202\341\361\315\6\342\361\320\341\360\317" \
+ "\343\361\315\343\361\320\356\371\350\377\376\377\203\377\377\377\1\376" \
+ "\377\375\202\377\377\377\1\376\377\375\222\377\377\377\6\366\373\364" \
+ "\342\361\320\342\362\316\342\360\317\341\362\316\343\361\320\210\342" \
+ "\361\320\10\341\362\316\341\361\315\352\364\334\377\377\377\377\376\377" \
+ "\377\377\377\376\377\377\376\377\375\222\377\377\377\202\376\376\376" \
+ "\202\377\377\377\1\376\376\376\202\377\377\377\1\376\376\376\202\377" \
+ "\377\377\3\376\376\376\377\377\377\375\375\375\202\377\377\377\5\363" \
+ "\363\363\316\316\316\264\264\264\235\235\235\233\233\233\202kkk\202k" \
+ "km\3llnkkmyy{\202\234\234\236\6\316\316\320\346\346\346\377\377\377\376" \
+ "\376\376\377\377\377\376\376\376\204\377\377\377\1\376\376\376\204\377" \
+ "\377\377\1\376\376\376\240\377\377\377\1\376\376\376\231\377\377\377" \
+ "\1\375\375\375\203\377\377\377\1\376\376\376\214\377\377\377\1\376\376" \
+ "\376\202\377\377\377\1\376\376\376\242\377\377\377\1\376\376\376\206" \
+ "\377\377\377\3\376\376\376\377\377\377\376\376\376\204\377\377\377\1" \
+ "\376\376\376\202\377\377\377\202\376\376\376\225\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\202\377\377\377\3\376\376\376\377\377\377" \
+ "\376\376\376\214\377\377\377\3\376\376\376\377\377\377\376\376\376\265" \
+ "\377\377\377\1\375\375\375\234\377\377\377\7\376\377\377\377\376\377" \
+ "\376\377\377\376\376\374\377\376\377\377\377\377\377\377\375\240\377" \
+ "\377\377\1\377\377\375\202\377\377\377\5\377\376\377\376\376\376\377" \
+ "\376\377\376\376\377\377\377\375\221\377\377\377\7\375\376\377\377\377" \
+ "\377\377\376\377\377\377\375\376\377\377\377\377\373\377\376\377\210" \
+ "\377\377\377\5\377\376\377\377\377\377\376\376\374\376\377\377\377\377" \
+ "\377\202\377\377\375\1\376\377\377\210\377\377\377\6\376\377\377\375" \
+ "\376\377\377\376\377\377\377\377\376\377\377\377\377\377\202\377\377" \
+ "\375\224\377\377\377\202\377\376\377\2\374\377\377\377\376\377\210\377" \
+ "\377\377\3\376\377\377\376\376\376\376\377\377\202\377\377\377\3\375" \
+ "\377\376\377\377\377\377\376\377\220\377\377\377\202\377\376\377\2\376" \
+ "\377\377\375\376\377\202\377\377\377\4\377\377\375\377\376\377\377\377" \
+ "\377\377\377\375\202\376\377\377\7\377\377\377\377\376\377\377\377\377" \
+ "\376\377\375\370\373\364\344\357\315\342\361\320\202\342\362\315\14\340" \
+ "\357\316\345\360\316\376\377\373\376\376\376\377\377\377\377\375\376" \
+ "\377\377\375\377\377\377\375\377\376\377\377\377\377\376\377\377\377" \
+ "\375\202\376\377\375\5\376\377\377\377\377\377\377\377\375\376\376\376" \
+ "\377\376\377\214\377\377\377\1\376\376\376\202\377\377\377\5\377\377" \
+ "\375\376\375\377\377\377\377\376\376\377\377\377\375\204\377\377\377" \
+ "\1\377\377\375\205\377\377\377\202\377\376\377\2\377\377\377\377\377" \
+ "\375\202\377\377\377\202\376\377\377\222\377\377\377\5\377\377\375\377" \
+ "\377\377\377\377\375\377\377\377\377\377\375\202\377\377\377\1\377\376" \
+ "\372\212\377\377\377\1\377\375\377\202\377\377\377\3\377\376\377\377" \
+ "\377\377\377\377\375\225\377\377\377\1\376\376\376\211\377\377\377\1" \
+ "\376\376\376\204\377\377\377\1\376\376\376\205\377\377\377\1\376\376" \
+ "\376\206\377\377\377\3\376\376\376\377\377\377\376\376\376\206\377\377" \
+ "\377\1\376\376\376\233\377\377\377\1\376\376\376\203\377\377\377\5\376" \
+ "\376\376\377\377\377\376\376\376\377\377\377\376\376\376\223\377\377" \
+ "\377\3\376\376\376\377\377\377\376\376\376\205\377\377\377\3\376\376" \
+ "\376\377\377\377\376\376\376\203\377\377\377\3\376\376\376\377\377\377" \
+ "\376\376\376\203\377\377\377\1\376\376\376\205\377\377\377\1\376\376" \
+ "\376\246\377\377\377\3\376\376\376\377\377\377\376\376\376\220\377\377" \
+ "\377\1\376\376\376\246\377\377\377\1\376\376\376\225\377\377\377\1\376" \
+ "\376\376\202\377\377\377\1\376\376\376\240\377\377\377\1\376\376\376" \
+ "\230\377\377\377\6\377\377\375\377\377\377\377\376\377\376\377\375\374" \
+ "\377\377\376\375\377\242\377\377\377\202\377\376\377\6\376\376\376\375" \
+ "\376\377\377\377\377\377\377\375\377\377\377\376\377\375\220\377\377" \
+ "\377\7\377\377\375\377\377\377\377\377\375\377\375\376\376\377\375\376" \
+ "\377\377\376\376\376\212\377\377\377\4\377\376\377\377\377\375\377\377" \
+ "\377\377\377\375\203\377\376\377\210\377\377\377\5\377\377\375\377\377" \
+ "\377\377\375\376\377\376\377\377\377\375\202\377\377\377\1\376\377\377" \
+ "\221\377\377\377\1\375\376\377\203\377\377\375\2\376\377\375\377\375" \
+ "\376\211\377\377\377\204\377\376\377\4\377\377\377\376\377\375\377\377" \
+ "\375\377\376\377\221\377\377\377\5\376\377\377\376\376\376\377\377\373" \
+ "\376\376\377\376\377\377\202\377\377\377\2\377\376\377\377\377\375\202" \
+ "\377\377\377\7\377\377\375\377\376\377\376\376\377\377\377\377\376\377" \
+ "\377\376\377\375\376\377\377\202\377\377\377\203\376\377\377\2\377\377" \
+ "\377\376\376\374\202\377\376\377\13\376\376\376\377\377\375\377\377\377" \
+ "\377\375\376\376\377\377\377\377\377\376\376\377\377\376\377\376\376" \
+ "\374\376\377\377\377\377\375\221\377\377\377\203\377\377\375\4\377\377" \
+ "\377\377\377\375\377\376\377\376\376\376\210\377\377\377\1\377\377\373" \
+ "\203\377\377\377\1\377\377\375\202\376\377\377\222\377\377\377\1\377" \
+ "\377\375\202\377\376\377\3\377\377\377\377\376\377\377\376\374\202\376" \
+ "\377\377\210\377\377\377\4\377\377\375\377\377\377\376\377\375\377\375" \
+ "\377\202\376\377\377\1\377\376\375\227\377\377\377\1\376\376\376\207" \
+ "\377\377\377\1\376\376\376\217\377\377\377\1\376\376\376\205\377\377" \
+ "\377\1\376\376\376\204\377\377\377\1\376\376\376\233\377\377\377\1\376" \
+ "\376\376\211\377\377\377\1\376\376\376\222\377\377\377\1\376\376\376" \
+ "\206\377\377\377\1\376\376\376\207\377\377\377\1\376\376\376\262\377" \
+ "\377\377\1\376\376\376\212\377\377\377\1\376\376\376\202\377\377\377" \
+ "\1\376\376\376\202\377\377\377\1\376\376\376\225\377\377\377\1\376\376" \
+ "\376\306\377\377\377\1\376\376\376\235\377\377\377\7\377\376\377\376" \
+ "\377\377\377\377\377\377\377\375\376\375\377\377\377\375\377\376\377" \
+ "\241\377\377\377\1\376\377\377\203\377\377\377\3\377\377\375\377\375" \
+ "\376\377\376\377\221\377\377\377\202\376\377\377\5\377\377\377\377\377" \
+ "\375\377\377\377\377\376\377\377\377\375\211\377\377\377\203\377\377" \
+ "\375\202\377\377\377\202\376\377\377\1\377\377\375\212\377\377\377\202" \
+ "\376\377\375\3\376\377\377\377\377\375\377\376\377\223\377\377\377\6" \
+ "\377\377\375\377\376\377\374\377\377\377\377\377\377\376\377\376\377" \
+ "\375\210\377\377\377\3\377\377\375\376\377\377\377\377\375\202\377\377" \
+ "\377\1\377\377\375\223\377\377\377\4\376\376\376\377\377\375\376\376" \
+ "\376\377\376\377\202\377\377\375\1\376\376\376\206\377\377\377\1\377" \
+ "\377\375\215\377\377\377\1\377\377\375\202\377\377\377\5\376\377\377" \
+ "\377\377\377\376\376\374\377\377\377\377\376\377\202\377\377\377\1\376" \
+ "\376\376\221\377\377\377\7\376\377\375\377\375\377\377\377\377\376\377" \
+ "\377\377\377\377\377\377\373\377\376\377\202\377\377\377\1\377\377\375" \
+ "\202\377\377\377\1\377\377\375\204\377\377\377\6\376\376\377\377\377" \
+ "\375\376\377\377\377\377\375\377\376\377\375\377\374\222\377\377\377" \
+ "\3\376\377\375\377\377\377\376\377\375\203\376\377\377\1\377\376\377" \
+ "\211\377\377\377\7\377\377\373\377\376\377\377\377\375\377\377\377\377" \
+ "\376\377\376\376\376\376\377\377")
+
+
diff --git a/meta-agl-profile-core/recipes-core/psplash/files/psplash-quit.service b/meta-agl-profile-core/recipes-core/psplash/files/psplash-quit.service
new file mode 100644
index 000000000..14bd4994b
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/files/psplash-quit.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Terminate Psplash Boot Screen
+After=psplash-start.service
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/psplash-write QUIT
+TimeoutSec=20
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-agl-profile-core/recipes-core/psplash/files/psplash-start.service b/meta-agl-profile-core/recipes-core/psplash/files/psplash-start.service
new file mode 100644
index 000000000..d3b6940d0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/files/psplash-start.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Start Psplash Boot Screen
+Wants=systemd-vconsole-setup.service
+After=systemd-vconsole-setup.service systemd-udev-trigger.service systemd-udevd.service
+DefaultDependencies=no
+
+[Service]
+ExecStartPre=/bin/sh -c "if [ -e /sys/class/graphics/fbcon/cursor_blink ]; then echo 0 > /sys/class/graphics/fbcon/cursor_blink; fi"
+ExecStart=/bin/bash -c "/usr/bin/psplash-anim -n -a 90"
+
+[Install]
+WantedBy=sysinit.target
diff --git a/meta-agl-profile-core/recipes-core/psplash/psplash_git.bbappend b/meta-agl-profile-core/recipes-core/psplash/psplash_git.bbappend
new file mode 100644
index 000000000..bdc196b6f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/psplash/psplash_git.bbappend
@@ -0,0 +1,27 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://psplash-colors.h \
+ file://psplash-start.service \
+ file://psplash-quit.service \
+ file://psplash-anim \
+ "
+
+SPLASH_IMAGES="file://psplash-poky-img.h;outsuffix=default"
+
+inherit systemd
+
+SYSTEMD_PACKAGES = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${PN}', '', d)}"
+SYSTEMD_SERVICE_${PN} = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'psplash-start.service psplash-quit.service', '', d)}"
+
+do_configure_append () {
+ cd ${S}
+ cp ../psplash-colors.h ./
+}
+
+do_install_append () {
+ if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
+ install -d ${D}${systemd_unitdir}/system
+ install -m 644 ${WORKDIR}/*.service ${D}/${systemd_unitdir}/system
+ fi
+ install -m 755 ${WORKDIR}/psplash-anim ${D}/${bindir}
+}
diff --git a/meta-agl-profile-core/recipes-core/systemd/.appends.core b/meta-agl-profile-core/recipes-core/systemd/.appends.core
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/systemd/.appends.core
diff --git a/meta-agl-profile-core/recipes-core/systemd/systemd/0001-Switch-Smack-label-earlier.patch b/meta-agl-profile-core/recipes-core/systemd/systemd/0001-Switch-Smack-label-earlier.patch
new file mode 100644
index 000000000..46445be73
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/systemd/systemd/0001-Switch-Smack-label-earlier.patch
@@ -0,0 +1,52 @@
+From 6cc74075797edb6f698cb7f312bb1c3d8cc6cb28 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jose.bollo@iot.bzh>
+Date: Thu, 12 Oct 2017 17:17:56 +0200
+Subject: [PATCH] Switch Smack label earlier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Switching label after removing capability isn't
+possible.
+
+Change-Id: Ib7dac8f071f36119520ed3205d743c1e3df3cd5e
+Signed-off-by: José Bollo <jose.bollo@iot.bzh>
+---
+ src/core/execute.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index d72e5bf08..0abffd569 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -2707,6 +2707,13 @@ static int exec_child(
+ }
+ }
+
++ r = setup_smack(context, command);
++ if (r < 0) {
++ *exit_status = EXIT_SMACK_PROCESS_LABEL;
++ *error_message = strdup("Failed to set SMACK process label");
++ return r;
++ }
++
+ if (!cap_test_all(context->capability_bounding_set)) {
+ r = capability_bounding_set_drop(context->capability_bounding_set, false);
+ if (r < 0) {
+@@ -2775,13 +2782,6 @@ static int exec_child(
+ }
+ #endif
+
+- r = setup_smack(context, command);
+- if (r < 0) {
+- *exit_status = EXIT_SMACK_PROCESS_LABEL;
+- *error_message = strdup("Failed to set SMACK process label");
+- return r;
+- }
+-
+ #ifdef HAVE_APPARMOR
+ if (context->apparmor_profile && mac_apparmor_use()) {
+ r = aa_change_onexec(context->apparmor_profile);
+--
+2.14.3
+
diff --git a/meta-agl-profile-core/recipes-core/systemd/systemd/e2fsck.conf b/meta-agl-profile-core/recipes-core/systemd/systemd/e2fsck.conf
new file mode 100644
index 000000000..b774f9ebf
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/systemd/systemd/e2fsck.conf
@@ -0,0 +1,3 @@
+[options]
+# This will prevent e2fsck from stopping boot just because the clock is wrong
+broken_system_clock = 1
diff --git a/meta-agl-profile-core/recipes-core/systemd/systemd/wired.network b/meta-agl-profile-core/recipes-core/systemd/systemd/wired.network
new file mode 100644
index 000000000..3559b0155
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/systemd/systemd/wired.network
@@ -0,0 +1,5 @@
+[Match]
+Name=eth* en*
+
+[Network]
+DHCP=yes
diff --git a/meta-agl-profile-core/recipes-core/systemd/systemd_%.bbappend b/meta-agl-profile-core/recipes-core/systemd/systemd_%.bbappend
new file mode 100644
index 000000000..f64ca8c8a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/systemd/systemd_%.bbappend
@@ -0,0 +1,26 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "\
+ file://e2fsck.conf \
+ ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','file://wired.network','',d)} \
+"
+
+# enable networkd/resolved support
+PACKAGECONFIG_append_pn-systemd = " \
+ ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','networkd resolved','',d)} \
+"
+
+do_install_append() {
+ # Install /etc/e2fsck.conf to avoid boot stuck by wrong clock time
+ install -m 644 -p -D ${WORKDIR}/e2fsck.conf ${D}${sysconfdir}/e2fsck.conf
+
+ if ${@bb.utils.contains('VIRTUAL-RUNTIME_net_manager','systemd','true','false',d)}; then
+ # Install DHCP configuration for Ethernet adapters
+ install -m 644 ${WORKDIR}/wired.network ${D}${sysconfdir}/systemd/network
+ fi
+}
+
+FILES_${PN} += "${sysconfdir}/e2fsck.conf "
+
+# SPEC-737: connmand also has a NTP client which races with systemd-timesyncd
+PACKAGECONFIG_remove = "timesyncd"
diff --git a/meta-agl-profile-core/recipes-core/systemd/systemd_234.bbappend b/meta-agl-profile-core/recipes-core/systemd/systemd_234.bbappend
new file mode 100644
index 000000000..4df7684d0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-core/systemd/systemd_234.bbappend
@@ -0,0 +1,6 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "\
+ file://0001-Switch-Smack-label-earlier.patch \
+"
+
diff --git a/meta-agl-profile-core/recipes-devtools/gdb/gdb_%.bbappend b/meta-agl-profile-core/recipes-devtools/gdb/gdb_%.bbappend
new file mode 100644
index 000000000..7cba933af
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/gdb/gdb_%.bbappend
@@ -0,0 +1 @@
+PACKAGECONFIG_remove = "readline"
diff --git a/meta-agl-profile-core/recipes-devtools/low-level-can-generator/low-level-can-generator_git.bb b/meta-agl-profile-core/recipes-devtools/low-level-can-generator/low-level-can-generator_git.bb
new file mode 100644
index 000000000..d364939b5
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/low-level-can-generator/low-level-can-generator_git.bb
@@ -0,0 +1,16 @@
+SUMMARY = "Low level CAN generator"
+DESCRIPTION = "Generator used to customize low level CAN service with customs signals"
+SECTION = "devel"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+inherit cmake pkgconfig
+BBCLASSEXTEND = "nativesdk"
+
+SRC_URI = "gitsm://gerrit.automotivelinux.org/gerrit/src/low-level-can-generator;protocol=https;branch=${AGL_BRANCH}"
+SRCREV = "92f95384ce4b4a198b1fea93272201421f7b9a39"
+
+PV = "4.0+git${SRCPV}"
+S = "${WORKDIR}/git"
+
diff --git a/meta-agl-profile-core/recipes-devtools/packagegroups/nativesdk-packagegroup-sdk-host.bbappend b/meta-agl-profile-core/recipes-devtools/packagegroups/nativesdk-packagegroup-sdk-host.bbappend
new file mode 100644
index 000000000..504a019b4
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/packagegroups/nativesdk-packagegroup-sdk-host.bbappend
@@ -0,0 +1 @@
+RDEPENDS_${PN} += "nativesdk-low-level-can-generator"
diff --git a/meta-agl-profile-core/recipes-devtools/packagegroups/packagegroup-agl-devel.bb b/meta-agl-profile-core/recipes-devtools/packagegroups/packagegroup-agl-devel.bb
new file mode 100644
index 000000000..ade8560ab
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/packagegroups/packagegroup-agl-devel.bb
@@ -0,0 +1,24 @@
+SUMMARY = "Provides a set of tools for development for AGL DISTRO"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+RDEPENDS_${PN} = "\
+ strace \
+ ldd \
+ less \
+ vim \
+ lsof \
+ gdb \
+ valgrind \
+ perf \
+ htop \
+ powertop \
+ latencytop \
+ systemtap \
+ screen \
+ usbutils \
+ rsync \
+ tree \
+ pstree \
+ "
diff --git a/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts b/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts
new file mode 100755
index 000000000..1d1a5a059
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Copyright 2017 IoT.bzh.
+
+# Author: Ronan Le Martret <ronan.lemartret@iot.bzh>
+#
+
+# The following script will run all the scriptlets found in #SYSCONFDIR#/agl-postinsts.
+
+agl_pi_dir="#SYSCONFDIR#/agl-postinsts"
+
+POSTINST_LOGGING=1
+LOGFILE=/var/log/agl-postinstall.log
+
+[ -e $LOGFILE ] && mv ${LOGFILE} ${LOGFILE}.old.$(date +%F--%H%M.%S)
+
+append_log=">>$LOGFILE 2>&1"
+
+exec_postinst_scriptlets() {
+ for i in `ls $agl_pi_dir`; do
+ i=$agl_pi_dir/$i
+ echo "Running postinst $i..."
+ [ "$POSTINST_LOGGING" = "1" ] && eval echo "Running postinst $i..." $append_log
+ if [ -x $i ]; then
+ eval sh -c $i $append_log
+ if [ $? -eq 0 ]; then
+ rm $i
+ else
+ echo "ERROR: postinst $i failed."
+ [ "$POSTINST_LOGGING" = "1" ] && eval echo "ERROR: postinst $i failed." $append_log
+ remove_agl_pi_dir=0
+ fi
+ else
+ echo "ERROR: postinst $i do not exists or do not have execute permission."
+ [ "$POSTINST_LOGGING" = "1" ] && eval echo "ERROR: postinst $i do not exists or do not have execute permission." $append_log
+ remove_agl_pi_dir=0
+ fi
+ done
+}
+
+remove_agl_pi_dir=1
+exec_postinst_scriptlets
+systemctl daemon-reload
+
+# since all postinstalls executed successfully, remove the postinstalls directory
+if [ $remove_agl_pi_dir = 1 ]; then
+ rm -rf $agl_pi_dir
+fi
diff --git a/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts.service b/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts.service
new file mode 100644
index 000000000..8f8667db6
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts/run-agl-postinsts.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Run pending agl postinsts
+DefaultDependencies=no
+After=#SYSTEMD_SERVICE_AFTER#
+Before=#SYSTEMD_SERVICE_BEFORE#
+ConditionPathExists=#SYSCONFDIR#/agl-postinsts
+
+[Service]
+Type=oneshot
+StandardOutput=journal+console
+ExecStart=#SBINDIR#/run-agl-postinsts
+ExecStartPost=#BASE_BINDIR#/systemctl disable run-agl-postinsts.service
+RemainAfterExit=No
+TimeoutSec=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts_1.0.bb b/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts_1.0.bb
new file mode 100644
index 000000000..b1ecccf85
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/run-agl-postinsts/run-agl-postinsts_1.0.bb
@@ -0,0 +1,46 @@
+SUMMARY = "Runs AGL postinstall scripts on first boot of the target device"
+SECTION = "devel"
+
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
+
+SRC_URI = "file://run-agl-postinsts \
+ file://run-agl-postinsts.service"
+
+S = "${WORKDIR}"
+
+inherit allarch systemd
+
+SYSTEMD_SERVICE_${PN} = "run-agl-postinsts.service"
+
+SYSTEMD_SERVICE_AFTER ?= "dbus.service cynara.service"
+
+SYSTEMD_SERVICE_BEFORE ?= "systemd-user-sessions.service"
+
+do_configure() {
+ :
+}
+
+do_compile () {
+ :
+}
+
+do_install() {
+ install -d ${D}${sbindir}
+ install -m 0755 ${WORKDIR}/run-agl-postinsts ${D}${sbindir}/
+
+ install -d ${D}${systemd_unitdir}/system/
+ install -m 0644 ${WORKDIR}/run-agl-postinsts.service ${D}${systemd_unitdir}/system/
+
+ sed -i -e 's:#SYSCONFDIR#:${sysconfdir}:g' \
+ -e 's:#SBINDIR#:${sbindir}:g' \
+ -e 's:#BASE_BINDIR#:${base_bindir}:g' \
+ -e 's:#LOCALSTATEDIR#:${localstatedir}:g' \
+ ${D}${sbindir}/run-agl-postinsts \
+ ${D}${systemd_unitdir}/system/run-agl-postinsts.service
+
+ sed -i -e 's:#SYSTEMD_SERVICE_AFTER#:${SYSTEMD_SERVICE_AFTER}:g' \
+ -e 's:#SYSTEMD_SERVICE_BEFORE#:${SYSTEMD_SERVICE_BEFORE}:g' \
+ ${D}${systemd_unitdir}/system/run-agl-postinsts.service
+}
+
diff --git a/meta-agl-profile-core/recipes-devtools/run-postinsts/run-postinsts_%.bbappend b/meta-agl-profile-core/recipes-devtools/run-postinsts/run-postinsts_%.bbappend
new file mode 100644
index 000000000..fc327b6ef
--- /dev/null
+++ b/meta-agl-profile-core/recipes-devtools/run-postinsts/run-postinsts_%.bbappend
@@ -0,0 +1,5 @@
+do_configure_append() {
+ if ! grep -q StandardOutput= ${WORKDIR}/run-postinsts.service; then
+ sed -i '/ExecStart=/iStandardOutput=journal+console' ${WORKDIR}/run-postinsts.service
+ fi
+}
diff --git a/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-crosssdk.bb b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-crosssdk.bb
new file mode 100644
index 000000000..0303d051d
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-crosssdk.bb
@@ -0,0 +1,19 @@
+SUMMARY = "Cross SDK of AGL Distribution for IVI profile"
+
+DESCRIPTION = "Basic image for baseline of AGL Distribution for IVI profile. \
+It includes the full meta-toolchain, plus developement headers and libraries \
+to form a standalone cross SDK."
+
+require agl-image-ivi.bb
+
+LICENSE = "MIT"
+
+IMAGE_FEATURES += "dev-pkgs"
+IMAGE_INSTALL += "kernel-dev"
+
+inherit populate_sdk
+
+# Task do_populate_sdk and do_rootfs can't be exec simultaneously.
+# Both exec "createrepo" on the same directory, and so one of them
+# can failed (randomly).
+addtask do_populate_sdk after do_rootfs
diff --git a/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-qa.bb b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-qa.bb
new file mode 100644
index 000000000..017439454
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi-qa.bb
@@ -0,0 +1,14 @@
+SUMMARY = "A basic system of AGL distribution of IVI profile for Quality Assurance(QA)"
+
+DESCRIPTION = "A basic set of AGL Distribution. This image also has additional \
+packages (e.g. commandline tools) for Quality Assurance(QA)."
+
+require agl-image-ivi.bb
+
+LICENSE = "MIT"
+
+IMAGE_INSTALL_append = " \
+ packagegroup-agl-test \
+ packagegroup-ivi-common-test \
+ "
+
diff --git a/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.bb b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.bb
new file mode 100644
index 000000000..dd4f89b15
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.bb
@@ -0,0 +1,17 @@
+SUMMARY = "A basic system of AGL distribution of IVI profile"
+
+DESCRIPTION = "Basic image for baseline of AGL Distribution for IVI profile."
+
+require agl-image-ivi.inc
+
+LICENSE = "MIT"
+
+IMAGE_INSTALL_append = "\
+ packagegroup-agl-image-ivi \
+ "
+
+DISTRO_FEATURES_append = " agl-core-image-profile"
+
+IMAGE_INSTALL += "\
+ agl-desktop-config \
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.inc b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.inc
new file mode 100644
index 000000000..0b564840b
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/images/agl-image-ivi.inc
@@ -0,0 +1,3 @@
+require recipes-core/images/agl-image-minimal.inc
+
+IMAGE_FEATURES += "splash package-management ssh-server-dropbear"
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-image-ivi.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-image-ivi.bb
new file mode 100644
index 000000000..075af913a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-image-ivi.bb
@@ -0,0 +1,31 @@
+SUMMARY = "The middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required for AGL Distribution"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-image-ivi \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ packagegroup-agl-image-minimal \
+"
+
+RDEPENDS_${PN} += "\
+ packagegroup-agl-ivi-automotive \
+ packagegroup-agl-ivi-connectivity \
+ packagegroup-agl-ivi-graphics \
+ packagegroup-agl-ivi-multimedia \
+ packagegroup-agl-ivi-navi-lbs \
+ packagegroup-agl-ivi-os-commonlibs \
+ packagegroup-agl-ivi-speech-services \
+ packagegroup-agl-ivi-security \
+ packagegroup-agl-ivi-kernel \
+ "
+
+RDEPENDS_${PN} += "\
+ agl-login-manager \
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-automotive.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-automotive.bb
new file mode 100644
index 000000000..f7221517f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-automotive.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Automotive Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-automotive \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb
new file mode 100644
index 000000000..664180d55
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb
@@ -0,0 +1,19 @@
+SUMMARY = "The middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Connectivity Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-connectivity \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ ofono \
+ rtl-sdr \
+ rygel \
+ rygel-plugin-media-export \
+ rygel-plugin-lms \
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-graphics.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-graphics.bb
new file mode 100644
index 000000000..d7650564b
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-graphics.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Graphics Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-graphics \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-kernel.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-kernel.bb
new file mode 100644
index 000000000..be51817b7
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-kernel.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Kernel Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-kernel \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb
new file mode 100644
index 000000000..11536405e
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb
@@ -0,0 +1,17 @@
+SUMMARY = "The middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Multimedia Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-multimedia \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ gstreamer1.0-plugins-base-meta \
+ gstreamer1.0-plugins-good-meta \
+ lightmediascanner-meta \
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-navi-lbs.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-navi-lbs.bb
new file mode 100644
index 000000000..b7f47eecc
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-navi-lbs.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The packages of middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Navigation and Location Based Services Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-navi-lbs \
+ "
+
+RDEPENDS_${PN} += "\
+ gpsd \
+ geoclue \
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-os-commonlibs.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-os-commonlibs.bb
new file mode 100644
index 000000000..0a9de8d5f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-os-commonlibs.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The packages of middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Operating System and Common libraries Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-os-commonlibs \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-security.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-security.bb
new file mode 100644
index 000000000..f651c50cd
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-security.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The packages of middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Security Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-security \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-speech-services.bb b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-speech-services.bb
new file mode 100644
index 000000000..eccebee9f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-ivi/packagegroups/packagegroup-agl-ivi-speech-services.bb
@@ -0,0 +1,14 @@
+SUMMARY = "The packages of middlewares for AGL IVI profile"
+DESCRIPTION = "The set of packages required by Speech Services Subsystem"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-ivi-speech-services \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ "
diff --git a/meta-agl-profile-core/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend b/meta-agl-profile-core/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend
new file mode 100644
index 000000000..86a181fbb
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/gstreamer1.0-plugins-good/gstreamer1.0-plugins-good_%.bbappend
@@ -0,0 +1,2 @@
+# libv4l2 is useful for making more efficient use of cameras via v4l2src.
+PACKAGECONFIG_append = " libv4l2"
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/.appends.meta-efl b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/.appends.meta-efl
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/.appends.meta-efl
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch
new file mode 100644
index 000000000..15d4b3f0e
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/0001-Define-comparison_fn_t-for-non-glibc-systems.patch
@@ -0,0 +1,33 @@
+From 5bc5b8c5dad3edec6736fd7e7ce61250c4ce3725 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 12 Jul 2017 17:13:19 -0700
+Subject: [PATCH] Define comparison_fn_t for non-glibc systems
+
+lightmediascanner.c:324:12: error: 'comparison_fn_t' undeclared (first use in this function)
+ (comparison_fn_t)_plugin_sort);
+ ^~~~~~~~~~~~~~~
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/lib/lightmediascanner.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/lib/lightmediascanner.c b/src/lib/lightmediascanner.c
+index 344b247..b866883 100644
+--- a/src/lib/lightmediascanner.c
++++ b/src/lib/lightmediascanner.c
+@@ -37,6 +37,11 @@
+ #define DEFAULT_SLAVE_TIMEOUT 1000
+ #define DEFAULT_COMMIT_INTERVAL 100
+
++#if !defined(__GLIBC__)
++typedef int (*__compar_fn_t) (const void*, const void*);
++typedef __compar_fn_t comparison_fn_t;
++#endif
++
+ #ifdef HAVE_MAGIC_H
+ static magic_t _magic_handle;
+
+--
+2.13.2
+
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/dbus-lightmediascanner.conf b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/dbus-lightmediascanner.conf
new file mode 100644
index 000000000..9cb321ba9
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/dbus-lightmediascanner.conf
@@ -0,0 +1,7 @@
+<?xml version="1.0"?> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy context="default">
+ <allow send_destination="org.lightmediascanner"/>
+ <allow receive_type="signal" receive_sender="org.lightmediascanner" receive_interface="org.freedesktop.DBus.Properties"/>
+ </policy>
+</busconfig>
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch
new file mode 100644
index 000000000..9528bec79
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch
@@ -0,0 +1,11 @@
+--- a/src/plugins/Makefile.am 2015-10-25 16:12:29.331415823 +0000
++++ b/src/plugins/Makefile.am 2015-10-25 16:14:37.593415808 +0000
+@@ -93,7 +93,7 @@
+ id3_id3_la_SOURCES = id3/id3.c id3/id3v1_genres.c
+ id3_id3_la_LIBADD = $(PLUGINS_LIBADD)
+
+-id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk
++$(srcdir)/id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk
+ $(AWK) -f $(srcdir)/id3/id3v1_genres_gen.awk $(srcdir)/id3/id3v1_genres.def > $@
+
+ EXTRA_DIST += id3/id3v1_genres.def id3/id3v1_genres_gen.awk
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/lightmediascanner.service b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/lightmediascanner.service
new file mode 100644
index 000000000..33cf27ed0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/lightmediascanner.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Lightmediascanner (LMS)
+
+[Service]
+Type=dbus
+BusName=org.lightmediascanner
+ExecStart=/usr/bin/lightmediascannerd --startup-scan --directory=/media --directory=${HOME}/Music --directory=${HOME}/Videos
+
+[Install]
+WantedBy=default.target
+Alias=dbus-org.lightmediascanner.service
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/plugin-ogg-fix-chucksize-issue.patch b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/plugin-ogg-fix-chucksize-issue.patch
new file mode 100644
index 000000000..6a0b8ff93
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/files/plugin-ogg-fix-chucksize-issue.patch
@@ -0,0 +1,53 @@
+From 3e66b97221440b17a184feb48692dce7e0561cac Mon Sep 17 00:00:00 2001
+From: Matt Ranostay <matt.ranostay@konsulko.com>
+Date: Wed, 8 Mar 2017 16:30:01 -0800
+Subject: [PATCH] plugin: ogg: fix chucksize issue
+
+There are some OGG files that have metadata chucks that go over the
+hardcoded 10 * 4096 size due to album art. This patchset just parses
+each chuck and continues till it runs out of valid chunks.
+
+Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com>
+---
+ src/plugins/ogg/ogg.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/src/plugins/ogg/ogg.c b/src/plugins/ogg/ogg.c
+index 1c0818e..c94dc38 100644
+--- a/src/plugins/ogg/ogg.c
++++ b/src/plugins/ogg/ogg.c
+@@ -47,8 +47,6 @@
+ int CHUNKSIZE = 4096;
+ #endif
+
+-#define MAX_CHUNKS_PER_PAGE 10
+-
+ struct stream {
+ struct lms_stream base;
+ int serial;
+@@ -122,10 +120,8 @@ _set_lms_info(struct lms_string_size *info, const char *tag)
+
+ static bool _ogg_read_page(FILE *fp, ogg_sync_state *osync, ogg_page *page)
+ {
+- int i;
+-
+- for (i = 0; i < MAX_CHUNKS_PER_PAGE && ogg_sync_pageout(osync, page) != 1;
+- i++) {
++ while(ogg_sync_pageout(osync, page) != 1)
++ {
+ lms_ogg_buffer_t buffer = lms_get_ogg_sync_buffer(osync, CHUNKSIZE);
+ int bytes = fread(buffer, 1, CHUNKSIZE, fp);
+
+@@ -136,9 +132,6 @@ static bool _ogg_read_page(FILE *fp, ogg_sync_state *osync, ogg_page *page)
+ ogg_sync_wrote(osync, bytes);
+ }
+
+- if (i > MAX_CHUNKS_PER_PAGE)
+- return false;
+-
+ return true;
+ }
+
+--
+2.7.4
+
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend
new file mode 100644
index 000000000..cf248d3fd
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend
@@ -0,0 +1,33 @@
+# Disable everything but the roygalty-free formats
+PACKAGECONFIG = "ogg flac wave m3u pls jpeg png"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://lightmediascanner.service \
+ file://plugin-ogg-fix-chucksize-issue.patch \
+ file://dbus-lightmediascanner.conf \
+ "
+
+CFLAGS_append = " -D_FILE_OFFSET_BITS=64"
+
+inherit systemd
+
+do_install_append() {
+ # Install LMS systemd service
+ if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
+ install -m 644 -p -D ${WORKDIR}/lightmediascanner.service ${D}${systemd_user_unitdir}/lightmediascanner.service
+
+ # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb)
+ # because it does not support systemd's user mode.
+ mkdir -p ${D}/etc/systemd/user/default.target.wants/
+ ln -sf ${systemd_user_unitdir}/lightmediascanner.service ${D}/etc/systemd/user/dbus-org.lightmediascanner.service
+ ln -sf ${systemd_user_unitdir}/lightmediascanner.service ${D}/etc/systemd/user/default.target.wants/lightmediascanner.service
+ fi
+
+ install -d ${D}/etc/dbus-1/session.d
+ install -m 0644 ${WORKDIR}/dbus-lightmediascanner.conf ${D}/etc/dbus-1/session.d/lightmediascanner.conf
+}
+
+FILES_${PN} += " \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/lightmediascanner.service', '', d)} \
+ "
diff --git a/meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb
new file mode 100644
index 000000000..f2158760f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb
@@ -0,0 +1,63 @@
+SUMMARY = "Lightweight media scanner"
+DESCRIPTION = "Lightweight media scanner meant to be used in not-so-powerful devices, like embedded systems or old machines."
+SECTION = "libs/multimedia"
+
+LICENSE = "LGPLv2.1+"
+LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343 \
+ file://src/lib/lightmediascanner.c;endline=21;md5=6d8889bccb4c6c27e8b786342a3eb267"
+
+DEPENDS = "file gawk glib-2.0 sqlite3"
+
+PV = "0.5.1+git${SRCPV}"
+SRCREV = "adfddb3486276a5ed2f5008c9e43a811e1271cc9"
+SRC_URI = "git://github.com/profusion/lightmediascanner.git \
+ file://id3-plugin-support-out-of-tree-build.patch \
+ file://0001-Define-comparison_fn_t-for-non-glibc-systems.patch \
+ "
+
+S = "${WORKDIR}/git"
+
+inherit autotools pkgconfig
+
+EXTRA_OECONF = "--enable-static --disable-mp4"
+
+PACKAGECONFIG ??= "ogg flac wave id3 m3u pls asf rm jpeg png"
+PACKAGECONFIG[generic] = "--enable-generic,--disable-generic,libav"
+PACKAGECONFIG[ogg] = "--enable-ogg,--disable-ogg,libogg libvorbis libtheora"
+PACKAGECONFIG[flac] = "--enable-flac,--disable-flac,flac"
+PACKAGECONFIG[wave] = "--enable-wave,--disable-wave"
+PACKAGECONFIG[id3] = "--enable-id3,--disable-id3"
+PACKAGECONFIG[m3u] = "--enable-m3u,--disable-m3u"
+PACKAGECONFIG[pls] = "--enable-pls,--disable-pls"
+PACKAGECONFIG[asf] = "--enable-asf,--disable-asf"
+PACKAGECONFIG[rm] = "--enable-rm,--disable-rm"
+PACKAGECONFIG[jpeg] = "--enable-jpeg,--disable-jpeg"
+PACKAGECONFIG[png] = "--enable-png,--disable-png"
+
+do_install_append() {
+ # Install "test" binary for corresponding package
+ install -d ${D}/${bindir}
+ install -m 755 ${B}/src/bin/.libs/test ${D}/${bindir}/test-lms
+ # Remove .la files for loadable modules
+ rm -f ${D}/${libdir}/${PN}/plugins/*.la
+}
+
+FILES_${PN} += "${datadir}/dbus-1"
+FILES_${PN}-dbg += "${libdir}/${PN}/plugins/.debug"
+
+PACKAGES_prepend = "${PN}-test "
+FILES_${PN}-test_prepend = "${bindir}/test-lms "
+
+PACKAGES += "${PN}-meta"
+ALLOW_EMPTY_${PN}-meta = "1"
+
+PACKAGES_DYNAMIC = "${PN}-plugin-*"
+
+python populate_packages_prepend () {
+ lms_libdir = d.expand('${libdir}/${PN}')
+ pkgs = []
+
+ pkgs += do_split_packages(d, oe.path.join(lms_libdir, "plugins"), '^(.*)\.so$', d.expand('${PN}-plugin-%s'), 'LightMediaScanner plugin for %s', prepend=True, extra_depends=d.expand('${PN}'))
+ metapkg = d.getVar('PN') + '-meta'
+ d.setVar('RDEPENDS_' + metapkg, ' '.join(pkgs))
+}
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/agl-audio-plugin_0.1.bb b/meta-agl-profile-core/recipes-multimedia/pulseaudio/agl-audio-plugin_0.1.bb
new file mode 100644
index 000000000..633a3e248
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/agl-audio-plugin_0.1.bb
@@ -0,0 +1,28 @@
+SUMMARY = "AGL Audio Policy Plugin"
+DESCRIPTION = "AGL PulseAudio Routing plugin, forked from the Tizen IVI \
+PulseAudio Routing plugin, also known as module-murphy-ivi. This is a \
+stripped-down version of the former, not needing Murphy anymore and using \
+either a JSON configuration file or its own embedded configuration."
+HOMEPAGE = "http://www.iot.bzh"
+
+LICENSE = "LGPL-2.1"
+LIC_FILES_CHKSUM = "file://COPYING;md5=2d5025d4aa3495befef8f17206a5b0a1"
+
+DEPENDS = "json-c pulseaudio"
+RDEPENDS_${PN} = "pulseaudio-server pulseaudio-module-null-sink pulseaudio-module-loopback"
+
+SRCREV = "952d404e87ca6001e546fe9105bdb6760c468760"
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/staging/agl-audio-plugin;protocol=https;branch=${AGL_BRANCH}"
+
+S = "${WORKDIR}/git"
+
+inherit cmake pkgconfig
+
+FULL_OPTIMIZATION = "-O1 -pipe ${DEBUG_FLAGS}"
+
+PULSE_PV="9.0"
+
+EXTRA_OECMAKE_append = " -DPULSE_PV:STRING=${PULSE_PV}"
+
+FILES_${PN} += "${libdir}/pulse-${PULSE_PV}/modules/* ${sysconfdir}/pulse/*"
+FILES_${PN}-dbg += "${libdir}/pulse-${PULSE_PV}/modules/.debug/*"
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0001-install-files-for-a-module-development.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0001-install-files-for-a-module-development.patch
new file mode 100644
index 000000000..8c5f9efd4
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0001-install-files-for-a-module-development.patch
@@ -0,0 +1,78 @@
+From 53281e2d11f84e2dae0704e0167369710ee2cb30 Mon Sep 17 00:00:00 2001
+From: Yannick Gicquel <yannick.gicquel@iot.bzh>
+Date: Fri, 23 Sep 2016 14:26:03 +0200
+Subject: [PATCH 1/6] install files for a module development
+
+Signed-off-by: Yannick Gicquel <yannick.gicquel@iot.bzh>
+---
+ Makefile.am | 14 +++++++++++++-
+ configure.ac | 1 +
+ pulseaudio-module-devel.pc.in | 12 ++++++++++++
+ 3 files changed, 26 insertions(+), 1 deletion(-)
+ create mode 100644 pulseaudio-module-devel.pc.in
+
+diff --git a/Makefile.am b/Makefile.am
+index 13bc469..f0d68a2 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -53,7 +53,16 @@ dist_vapi_DATA = \
+ vala/libpulse-simple.deps vala/libpulse-simple.vapi
+
+ pkgconfigdir = $(libdir)/pkgconfig
+-pkgconfig_DATA = libpulse.pc libpulse-simple.pc
++pkgconfig_DATA = libpulse.pc libpulse-simple.pc pulseaudio-module-devel.pc
++
++moduledev_DATA = pulsecore-config.h $(top_srcdir)/src/pulsecore/*.h
++moduledevdir = $(includedir)/pulsemodule/pulsecore
++
++moduledevfilter_DATA = $(top_srcdir)/src/pulsecore/filter/*.h
++moduledevfilterdir = $(includedir)/pulsemodule/pulsecore/filter
++
++moduledevinternal_DATA = src/pulse/internal.h src/pulse/client-conf.h src/pulse/fork-detect.h
++moduledevinternaldir = $(includedir)/pulsemodule/pulse
+
+ if HAVE_GLIB20
+ pkgconfig_DATA += \
+@@ -107,6 +116,9 @@ dist-hook:
+ check-daemon:
+ $(MAKE) -C src check-daemon
+
++pulsecore-config.h: config.h
++ cp $< $@
++
+ .PHONY: homepage distcleancheck doxygen
+
+ # see git-version-gen
+diff --git a/configure.ac b/configure.ac
+index 9250c05..f9201ee 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1502,6 +1502,7 @@ man/pulse-client.conf.5.xml
+ man/default.pa.5.xml
+ man/pulse-cli-syntax.5.xml
+ man/start-pulseaudio-x11.1.xml
++pulseaudio-module-devel.pc
+ ])
+
+ AC_CONFIG_FILES([src/esdcompat:src/daemon/esdcompat.in], [chmod +x src/esdcompat])
+diff --git a/pulseaudio-module-devel.pc.in b/pulseaudio-module-devel.pc.in
+new file mode 100644
+index 0000000..85aadbc
+--- /dev/null
++++ b/pulseaudio-module-devel.pc.in
+@@ -0,0 +1,12 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++modlibexecdir=@modlibexecdir@
++
++Name: pulseaudio-module-devel
++Description: PulseAudio Module Development Interface
++Version: @PACKAGE_VERSION@
++Libs: -L${libdir} -L${libdir}/pulseaudio -L${modlibexecdir} -lpulsecommon-@PA_MAJORMINOR@ -lpulsecore-@PA_MAJORMINOR@ -lprotocol-native
++Libs.private:
++Cflags: -I${includedir}/pulsemodule -D_REENTRANT
+--
+1.9.1
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0002-volume-ramp-additions-to-the-low-level-infra.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0002-volume-ramp-additions-to-the-low-level-infra.patch
new file mode 100644
index 000000000..9cee6f5de
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0002-volume-ramp-additions-to-the-low-level-infra.patch
@@ -0,0 +1,566 @@
+From 7757059ffc6e63ea20ba9013682d72d619e7aefc Mon Sep 17 00:00:00 2001
+From: Sangchul Lee <sangchul1011@gmail.com>
+Date: Sat, 27 Aug 2016 21:33:16 +0900
+Subject: [PATCH 2/6] volume ramp: additions to the low level infra
+
+The original patch is
+ - https://review.tizen.org/git/?p=platform/upstream/pulseaudio.git;a=commit;h=df1c4275ed79e0b708c75b92f9d247e0492bc1f0
+ - by Jaska Uimonen <jaska.uimonen <at> helsinki.fi>
+
+Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
+---
+ src/map-file | 4 +
+ src/pulse/def.h | 13 ++-
+ src/pulse/volume.c | 74 ++++++++++++-
+ src/pulse/volume.h | 33 ++++++
+ src/pulsecore/mix.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/pulsecore/mix.h | 27 +++++
+ 6 files changed, 459 insertions(+), 2 deletions(-)
+
+diff --git a/src/map-file b/src/map-file
+index 93a62b8..ef9b57d 100644
+--- a/src/map-file
++++ b/src/map-file
+@@ -138,6 +138,10 @@ pa_cvolume_max_mask;
+ pa_cvolume_merge;
+ pa_cvolume_min;
+ pa_cvolume_min_mask;
++pa_cvolume_ramp_equal;
++pa_cvolume_ramp_init;
++pa_cvolume_ramp_set;
++pa_cvolume_ramp_channel_ramp_set;
+ pa_cvolume_remap;
+ pa_cvolume_scale;
+ pa_cvolume_scale_mask;
+diff --git a/src/pulse/def.h b/src/pulse/def.h
+index 680bdc9..bc3cedd 100644
+--- a/src/pulse/def.h
++++ b/src/pulse/def.h
+@@ -347,11 +347,15 @@ typedef enum pa_stream_flags {
+ * consider absolute when the sink is in flat volume mode,
+ * relative otherwise. \since 0.9.20 */
+
+- PA_STREAM_PASSTHROUGH = 0x80000U
++ PA_STREAM_PASSTHROUGH = 0x80000U,
+ /**< Used to tag content that will be rendered by passthrough sinks.
+ * The data will be left as is and not reformatted, resampled.
+ * \since 1.0 */
+
++ PA_STREAM_START_RAMP_MUTED = 0x100000U
++ /**< Used to tag content that the stream will be started ramp volume
++ * muted so that you can nicely fade it in */
++
+ } pa_stream_flags_t;
+
+ /** \cond fulldocs */
+@@ -380,6 +384,7 @@ typedef enum pa_stream_flags {
+ #define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND
+ #define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME
+ #define PA_STREAM_PASSTHROUGH PA_STREAM_PASSTHROUGH
++#define PA_STREAM_START_RAMP_MUTED PA_STREAM_START_RAMP_MUTED
+
+ /** \endcond */
+
+@@ -1047,6 +1052,12 @@ typedef enum pa_port_available {
+ /** \endcond */
+ #endif
+
++/** \cond fulldocs */
++#define PA_VOLUMER_RAMP_TYPE_LINEAR PA_VOLUMER_RAMP_TYPE_LINEAR
++#define PA_VOLUMER_RAMP_TYPE_LOGARITHMIC PA_VOLUMER_RAMP_TYPE_LOGARITHMIC
++#define PA_VOLUMER_RAMP_TYPE_CUBIC PA_VOLUMER_RAMP_TYPE_CUBIC
++/** \endcond */
++
+ PA_C_DECL_END
+
+ #endif
+diff --git a/src/pulse/volume.c b/src/pulse/volume.c
+index 1667b94..85072c1 100644
+--- a/src/pulse/volume.c
++++ b/src/pulse/volume.c
+@@ -445,7 +445,10 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) {
+ unsigned c;
+ pa_assert(a);
+
+- pa_return_val_if_fail(pa_cvolume_valid(a), 0);
++ if (pa_cvolume_valid(a) == 0)
++ abort();
++
++ /* pa_return_val_if_fail(pa_cvolume_valid(a), 0); */
+ pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0);
+
+ for (c = 0; c < a->channels; c++)
+@@ -977,3 +980,72 @@ pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
+
+ return pa_cvolume_scale(v, m);
+ }
++
++int pa_cvolume_ramp_equal(const pa_cvolume_ramp *a, const pa_cvolume_ramp *b) {
++ int i;
++ pa_assert(a);
++ pa_assert(b);
++
++ if (PA_UNLIKELY(a == b))
++ return 1;
++
++ if (a->channels != b->channels)
++ return 0;
++
++ for (i = 0; i < a->channels; i++) {
++ if (a->ramps[i].type != b->ramps[i].type ||
++ a->ramps[i].length != b->ramps[i].length ||
++ a->ramps[i].target != b->ramps[i].target)
++ return 0;
++ }
++
++ return 1;
++}
++
++pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp) {
++ unsigned c;
++
++ pa_assert(ramp);
++
++ ramp->channels = 0;
++
++ for (c = 0; c < PA_CHANNELS_MAX; c++) {
++ ramp->ramps[c].type = PA_VOLUME_RAMP_TYPE_LINEAR;
++ ramp->ramps[c].length = 0;
++ ramp->ramps[c].target = PA_VOLUME_INVALID;
++ }
++
++ return ramp;
++}
++
++pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channels, pa_volume_ramp_type_t type, long time, pa_volume_t vol) {
++ int i;
++
++ pa_assert(ramp);
++ pa_assert(channels > 0);
++ pa_assert(time >= 0);
++ pa_assert(channels <= PA_CHANNELS_MAX);
++
++ ramp->channels = (uint8_t) channels;
++
++ for (i = 0; i < ramp->channels; i++) {
++ ramp->ramps[i].type = type;
++ ramp->ramps[i].length = time;
++ ramp->ramps[i].target = PA_CLAMP_VOLUME(vol);
++ }
++
++ return ramp;
++}
++
++pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol) {
++
++ pa_assert(ramp);
++ pa_assert(channel <= ramp->channels);
++ pa_assert(time >= 0);
++
++ ramp->ramps[channel].type = type;
++ ramp->ramps[channel].length = time;
++ ramp->ramps[channel].target = PA_CLAMP_VOLUME(vol);
++
++ return ramp;
++}
+diff --git a/src/pulse/volume.h b/src/pulse/volume.h
+index 8cf4fa4..2ae3451 100644
+--- a/src/pulse/volume.h
++++ b/src/pulse/volume.h
+@@ -431,6 +431,39 @@ pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
+ * the channels are kept. \since 0.9.16 */
+ pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec);
+
++/** Volume ramp type
++*/
++typedef enum pa_volume_ramp_type {
++ PA_VOLUME_RAMP_TYPE_LINEAR = 0, /**< linear */
++ PA_VOLUME_RAMP_TYPE_LOGARITHMIC = 1, /**< logarithmic */
++ PA_VOLUME_RAMP_TYPE_CUBIC = 2,
++} pa_volume_ramp_type_t;
++
++/** A structure encapsulating a volume ramp */
++typedef struct pa_volume_ramp_t {
++ pa_volume_ramp_type_t type;
++ long length;
++ pa_volume_t target;
++} pa_volume_ramp_t;
++
++/** A structure encapsulating a multichannel volume ramp */
++typedef struct pa_cvolume_ramp {
++ uint8_t channels;
++ pa_volume_ramp_t ramps[PA_CHANNELS_MAX];
++} pa_cvolume_ramp;
++
++/** Return non-zero when *a == *b */
++int pa_cvolume_ramp_equal(const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
++
++/** Init volume ramp struct */
++pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp);
++
++/** Set first n channels of ramp struct to certain value */
++pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
++
++/** Set individual channel in the channel struct */
++pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
++
+ PA_C_DECL_END
+
+ #endif
+diff --git a/src/pulsecore/mix.c b/src/pulsecore/mix.c
+index 59622d7..1e4cc1e 100644
+--- a/src/pulsecore/mix.c
++++ b/src/pulsecore/mix.c
+@@ -724,3 +724,313 @@ void pa_volume_memchunk(
+
+ pa_memblock_release(c->memblock);
+ }
++
++static void calc_linear_integer_volume_no_mapping(int32_t linear[], float volume[], unsigned nchannels) {
++ unsigned channel, padding;
++
++ pa_assert(linear);
++ pa_assert(volume);
++
++ for (channel = 0; channel < nchannels; channel++)
++ linear[channel] = (int32_t) lrint(volume[channel] * 0x10000U);
++
++ for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
++ linear[channel] = linear[padding];
++}
++
++static void calc_linear_float_volume_no_mapping(float linear[], float volume[], unsigned nchannels) {
++ unsigned channel, padding;
++
++ pa_assert(linear);
++ pa_assert(volume);
++
++ for (channel = 0; channel < nchannels; channel++)
++ linear[channel] = volume[channel];
++
++ for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
++ linear[channel] = linear[padding];
++}
++
++typedef void (*pa_calc_volume_no_mapping_func_t) (void *volumes, float *volume, int channels);
++
++static const pa_calc_volume_no_mapping_func_t calc_volume_table_no_mapping[] = {
++ [PA_SAMPLE_U8] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_ALAW] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_ULAW] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S16LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S16BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_FLOAT32LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_float_volume_no_mapping,
++ [PA_SAMPLE_FLOAT32BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_float_volume_no_mapping,
++ [PA_SAMPLE_S32LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S32BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24_32LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24_32BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping
++};
++
++static const unsigned format_sample_size_table[] = {
++ [PA_SAMPLE_U8] = 1,
++ [PA_SAMPLE_ALAW] = 1,
++ [PA_SAMPLE_ULAW] = 1,
++ [PA_SAMPLE_S16LE] = 2,
++ [PA_SAMPLE_S16BE] = 2,
++ [PA_SAMPLE_FLOAT32LE] = 4,
++ [PA_SAMPLE_FLOAT32BE] = 4,
++ [PA_SAMPLE_S32LE] = 4,
++ [PA_SAMPLE_S32BE] = 4,
++ [PA_SAMPLE_S24LE] = 3,
++ [PA_SAMPLE_S24BE] = 3,
++ [PA_SAMPLE_S24_32LE] = 4,
++ [PA_SAMPLE_S24_32BE] = 4
++};
++
++static float calc_volume_ramp_linear(pa_volume_ramp_int_t *ramp) {
++ pa_assert(ramp);
++ pa_assert(ramp->length > 0);
++
++ /* basic linear interpolation */
++ return ramp->start + (ramp->length - ramp->left) * (ramp->end - ramp->start) / (float) ramp->length;
++}
++
++static float calc_volume_ramp_logarithmic(pa_volume_ramp_int_t *ramp) {
++ float x_val, s, e;
++ long temp;
++
++ pa_assert(ramp);
++ pa_assert(ramp->length > 0);
++
++ if (ramp->end > ramp->start) {
++ temp = ramp->left;
++ s = ramp->end;
++ e = ramp->start;
++ } else {
++ temp = ramp->length - ramp->left;
++ s = ramp->start;
++ e = ramp->end;
++ }
++
++ x_val = temp == 0 ? 0.0 : powf(temp, 10);
++
++ /* base 10 logarithmic interpolation */
++ return s + x_val * (e - s) / powf(ramp->length, 10);
++}
++
++static float calc_volume_ramp_cubic(pa_volume_ramp_int_t *ramp) {
++ float x_val, s, e;
++ long temp;
++
++ pa_assert(ramp);
++ pa_assert(ramp->length > 0);
++
++ if (ramp->end > ramp->start) {
++ temp = ramp->left;
++ s = ramp->end;
++ e = ramp->start;
++ } else {
++ temp = ramp->length - ramp->left;
++ s = ramp->start;
++ e = ramp->end;
++ }
++
++ x_val = temp == 0 ? 0.0 : cbrtf(temp);
++
++ /* cubic interpolation */
++ return s + x_val * (e - s) / cbrtf(ramp->length);
++}
++
++typedef float (*pa_calc_volume_ramp_func_t) (pa_volume_ramp_int_t *);
++
++static const pa_calc_volume_ramp_func_t calc_volume_ramp_table[] = {
++ [PA_VOLUME_RAMP_TYPE_LINEAR] = (pa_calc_volume_ramp_func_t) calc_volume_ramp_linear,
++ [PA_VOLUME_RAMP_TYPE_LOGARITHMIC] = (pa_calc_volume_ramp_func_t) calc_volume_ramp_logarithmic,
++ [PA_VOLUME_RAMP_TYPE_CUBIC] = (pa_calc_volume_ramp_func_t) calc_volume_ramp_cubic
++};
++
++static void calc_volume_ramps(pa_cvolume_ramp_int *ram, float *vol)
++{
++ int i;
++
++ for (i = 0; i < ram->channels; i++) {
++ if (ram->ramps[i].left <= 0) {
++ if (ram->ramps[i].target == PA_VOLUME_NORM) {
++ vol[i] = 1.0;
++ }
++ } else {
++ vol[i] = ram->ramps[i].curr = calc_volume_ramp_table[ram->ramps[i].type] (&ram->ramps[i]);
++ ram->ramps[i].left--;
++ }
++ }
++}
++
++void pa_volume_ramp_memchunk(
++ pa_memchunk *c,
++ const pa_sample_spec *spec,
++ pa_cvolume_ramp_int *ramp) {
++
++ void *ptr;
++ volume_val linear[PA_CHANNELS_MAX + VOLUME_PADDING];
++ float vol[PA_CHANNELS_MAX + VOLUME_PADDING];
++ pa_do_volume_func_t do_volume;
++ long length_in_frames;
++ int i;
++
++ pa_assert(c);
++ pa_assert(spec);
++ pa_assert(pa_frame_aligned(c->length, spec));
++ pa_assert(ramp);
++
++ length_in_frames = c->length / format_sample_size_table[spec->format] / spec->channels;
++
++ if (pa_memblock_is_silence(c->memblock)) {
++ for (i = 0; i < ramp->channels; i++) {
++ if (ramp->ramps[i].length > 0)
++ ramp->ramps[i].length -= length_in_frames;
++ }
++ return;
++ }
++
++ if (spec->format < 0 || spec->format >= PA_SAMPLE_MAX) {
++ pa_log_warn("Unable to change volume of format");
++ return;
++ }
++
++ do_volume = pa_get_volume_func(spec->format);
++ pa_assert(do_volume);
++
++ ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
++
++ for (i = 0; i < length_in_frames; i++) {
++ calc_volume_ramps(ramp, vol);
++ calc_volume_table_no_mapping[spec->format] ((void *)linear, vol, spec->channels);
++
++ /* we only process one frame per iteration */
++ do_volume (ptr, (void *)linear, spec->channels, format_sample_size_table[spec->format] * spec->channels);
++
++ /* pa_log_debug("1: %d 2: %d", linear[0], linear[1]); */
++
++ ptr = (uint8_t*)ptr + format_sample_size_table[spec->format] * spec->channels;
++ }
++
++ pa_memblock_release(c->memblock);
++}
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_convert(const pa_cvolume_ramp *src, pa_cvolume_ramp_int *dst, int sample_rate) {
++
++ int i, j, channels, remaining_channels;
++ float temp;
++
++ if (dst->channels < src->channels) {
++ channels = dst->channels;
++ remaining_channels = 0;
++ }
++ else {
++ channels = src->channels;
++ remaining_channels = dst->channels;
++ }
++
++ for (i = 0; i < channels; i++) {
++ dst->ramps[i].type = src->ramps[i].type;
++ /* ms to samples */
++ dst->ramps[i].length = src->ramps[i].length * sample_rate / 1000;
++ dst->ramps[i].left = dst->ramps[i].length;
++ dst->ramps[i].start = dst->ramps[i].end;
++ dst->ramps[i].target = src->ramps[i].target;
++ /* scale to pulse internal mapping so that when ramp is over there's no glitch in volume */
++ temp = src->ramps[i].target / (float)0x10000U;
++ dst->ramps[i].end = temp * temp * temp;
++ }
++
++ j = i;
++
++ for (i--; j < remaining_channels; j++) {
++ dst->ramps[j].type = dst->ramps[i].type;
++ dst->ramps[j].length = dst->ramps[i].length;
++ dst->ramps[j].left = dst->ramps[i].left;
++ dst->ramps[j].start = dst->ramps[i].start;
++ dst->ramps[j].target = dst->ramps[i].target;
++ dst->ramps[j].end = dst->ramps[i].end;
++ }
++
++ return dst;
++}
++
++bool pa_cvolume_ramp_active(pa_cvolume_ramp_int *ramp) {
++ int i;
++
++ for (i = 0; i < ramp->channels; i++) {
++ if (ramp->ramps[i].left > 0)
++ return true;
++ }
++
++ return false;
++}
++
++bool pa_cvolume_ramp_target_active(pa_cvolume_ramp_int *ramp) {
++ int i;
++
++ for (i = 0; i < ramp->channels; i++) {
++ if (ramp->ramps[i].target != PA_VOLUME_NORM)
++ return true;
++ }
++
++ return false;
++}
++
++pa_cvolume * pa_cvolume_ramp_get_targets(pa_cvolume_ramp_int *ramp, pa_cvolume *volume) {
++ int i = 0;
++
++ volume->channels = ramp->channels;
++
++ for (i = 0; i < ramp->channels; i++)
++ volume->values[i] = ramp->ramps[i].target;
++
++ return volume;
++}
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_start_from(pa_cvolume_ramp_int *src, pa_cvolume_ramp_int *dst) {
++ int i;
++
++ for (i = 0; i < src->channels; i++) {
++ /* if new vols are invalid, copy old ramp i.e. no effect */
++ if (dst->ramps[i].target == PA_VOLUME_INVALID)
++ dst->ramps[i] = src->ramps[i];
++ /* if there's some old ramp still left */
++ else if (src->ramps[i].left > 0)
++ dst->ramps[i].start = src->ramps[i].curr;
++ }
++
++ return dst;
++}
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_int_init(pa_cvolume_ramp_int *src, pa_volume_t vol, int channels) {
++ int i;
++ float temp;
++
++ src->channels = channels;
++
++ for (i = 0; i < channels; i++) {
++ src->ramps[i].type = PA_VOLUME_RAMP_TYPE_LINEAR;
++ src->ramps[i].length = 0;
++ src->ramps[i].left = 0;
++ if (vol == PA_VOLUME_NORM) {
++ src->ramps[i].start = 1.0;
++ src->ramps[i].end = 1.0;
++ src->ramps[i].curr = 1.0;
++ }
++ else if (vol == PA_VOLUME_MUTED) {
++ src->ramps[i].start = 0.0;
++ src->ramps[i].end = 0.0;
++ src->ramps[i].curr = 0.0;
++ }
++ else {
++ temp = vol / (float)0x10000U;
++ src->ramps[i].start = temp * temp * temp;
++ src->ramps[i].end = src->ramps[i].start;
++ src->ramps[i].curr = src->ramps[i].start;
++ }
++ src->ramps[i].target = vol;
++ }
++
++ return src;
++}
+diff --git a/src/pulsecore/mix.h b/src/pulsecore/mix.h
+index 8102bcd..0f86b6f 100644
+--- a/src/pulsecore/mix.h
++++ b/src/pulsecore/mix.h
+@@ -59,4 +59,31 @@ void pa_volume_memchunk(
+ const pa_sample_spec *spec,
+ const pa_cvolume *volume);
+
++typedef struct pa_volume_ramp_int_t {
++ pa_volume_ramp_type_t type;
++ long length;
++ long left;
++ float start;
++ float end;
++ float curr;
++ pa_volume_t target;
++} pa_volume_ramp_int_t;
++
++typedef struct pa_cvolume_ramp_int {
++ uint8_t channels;
++ pa_volume_ramp_int_t ramps[PA_CHANNELS_MAX];
++} pa_cvolume_ramp_int;
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_convert(const pa_cvolume_ramp *src, pa_cvolume_ramp_int *dst, int sample_rate);
++bool pa_cvolume_ramp_active(pa_cvolume_ramp_int *ramp);
++bool pa_cvolume_ramp_target_active(pa_cvolume_ramp_int *ramp);
++pa_cvolume_ramp_int* pa_cvolume_ramp_start_from(pa_cvolume_ramp_int *src, pa_cvolume_ramp_int *dst);
++pa_cvolume_ramp_int* pa_cvolume_ramp_int_init(pa_cvolume_ramp_int *src, pa_volume_t vol, int channels);
++pa_cvolume * pa_cvolume_ramp_get_targets(pa_cvolume_ramp_int *ramp, pa_cvolume *volume);
++
++void pa_volume_ramp_memchunk(
++ pa_memchunk *c,
++ const pa_sample_spec *spec,
++ pa_cvolume_ramp_int *ramp);
++
+ #endif
+--
+1.9.1
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0003-volume-ramp-adding-volume-ramping-to-sink-input.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0003-volume-ramp-adding-volume-ramping-to-sink-input.patch
new file mode 100644
index 000000000..eb485ca7c
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0003-volume-ramp-adding-volume-ramping-to-sink-input.patch
@@ -0,0 +1,189 @@
+From e4469df7c69316b49cad93dd288badc98fa1cad5 Mon Sep 17 00:00:00 2001
+From: Sangchul Lee <sangchul1011@gmail.com>
+Date: Sat, 27 Aug 2016 21:33:17 +0900
+Subject: [PATCH 3/6] volume ramp: adding volume ramping to sink-input
+
+The original patch is
+ - https://review.tizen.org/git/?p=platform/upstream/pulseaudio.git;a=commit;h=98042248fd67ce0ab3807c5c472c0d5d8b0f99d3
+ - by Jaska Uimonen <jaska.uimonen <at> helsinki.fi>
+
+Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
+---
+ src/pulsecore/sink-input.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/pulsecore/sink-input.h | 11 ++++++++-
+ 2 files changed, 71 insertions(+), 1 deletion(-)
+
+diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
+index 8ec63b5..cc8953f 100644
+--- a/src/pulsecore/sink-input.c
++++ b/src/pulsecore/sink-input.c
+@@ -526,6 +526,11 @@ int pa_sink_input_new(
+ reset_callbacks(i);
+ i->userdata = NULL;
+
++ if (data->flags & PA_SINK_INPUT_START_RAMP_MUTED)
++ pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_MUTED, data->sample_spec.channels);
++ else
++ pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_NORM, data->sample_spec.channels);
++
+ i->thread_info.state = i->state;
+ i->thread_info.attached = false;
+ pa_atomic_store(&i->thread_info.drained, 1);
+@@ -542,6 +547,8 @@ int pa_sink_input_new(
+ i->thread_info.playing_for = 0;
+ i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
++ i->thread_info.ramp = i->ramp;
++
+ pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
+ pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
+
+@@ -923,6 +930,8 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa
+ while (tchunk.length > 0) {
+ pa_memchunk wchunk;
+ bool nvfs = need_volume_factor_sink;
++ pa_cvolume target;
++ pa_bool_t tmp;
+
+ wchunk = tchunk;
+ pa_memblock_ref(wchunk.memblock);
+@@ -959,6 +968,16 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa
+ pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
+ }
+
++ /* check for possible volume ramp */
++ if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
++ pa_memchunk_make_writable(&wchunk, 0);
++ pa_volume_ramp_memchunk(&wchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
++ } else if ((tmp = pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
++ pa_memchunk_make_writable(&wchunk, 0);
++ pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
++ pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &target);
++ }
++
+ pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
+ } else {
+ pa_memchunk rchunk;
+@@ -975,6 +994,16 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa
+ pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
+ }
+
++ /* check for possible volume ramp */
++ if (pa_cvolume_ramp_active(&(i->thread_info.ramp))) {
++ pa_memchunk_make_writable(&rchunk, 0);
++ pa_volume_ramp_memchunk(&rchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
++ } else if (pa_cvolume_ramp_target_active(&(i->thread_info.ramp))) {
++ pa_memchunk_make_writable(&rchunk, 0);
++ pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
++ pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &target);
++ }
++
+ pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
+ pa_memblock_unref(rchunk.memblock);
+ }
+@@ -1339,6 +1368,31 @@ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
+ return 0;
+ }
+
++/* Called from main thread */
++void pa_sink_input_set_volume_ramp(
++ pa_sink_input *i,
++ const pa_cvolume_ramp *ramp,
++ pa_bool_t send_msg,
++ pa_bool_t save) {
++
++ pa_sink_input_assert_ref(i);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
++ pa_assert(ramp);
++
++ pa_cvolume_ramp_convert(ramp, &i->ramp, i->sample_spec.rate);
++
++ pa_log_debug("setting volume ramp with target vol:%d and length:%ld",
++ i->ramp.ramps[0].target,
++ i->ramp.ramps[0].length);
++
++
++ /* This tells the sink that volume ramp changed */
++ if (send_msg)
++ pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
++ NULL, 0, NULL) == 0);
++}
++
+ /* Called from main context */
+ static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
+ pa_sink_input_assert_ref(i);
+@@ -1932,6 +1986,13 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t
+ }
+ return 0;
+
++ case PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP:
++ /* we have ongoing ramp where we take current start values */
++ pa_cvolume_ramp_start_from(&i->thread_info.ramp, &i->ramp);
++ i->thread_info.ramp = i->ramp;
++ pa_sink_input_request_rewind(i, 0, true, false, false);
++ return 0;
++
+ case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
+ if (i->thread_info.muted != i->muted) {
+ i->thread_info.muted = i->muted;
+diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
+index 86deab2..6e1b211 100644
+--- a/src/pulsecore/sink-input.h
++++ b/src/pulsecore/sink-input.h
+@@ -32,6 +32,7 @@
+ #include <pulsecore/client.h>
+ #include <pulsecore/sink.h>
+ #include <pulsecore/core.h>
++#include <pulsecore/mix.h>
+
+ typedef enum pa_sink_input_state {
+ PA_SINK_INPUT_INIT, /*< The stream is not active yet, because pa_sink_input_put() has not been called yet */
+@@ -58,7 +59,8 @@ typedef enum pa_sink_input_flags {
+ PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
+ PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,
+ PA_SINK_INPUT_KILL_ON_SUSPEND = 1024,
+- PA_SINK_INPUT_PASSTHROUGH = 2048
++ PA_SINK_INPUT_PASSTHROUGH = 2048,
++ PA_SINK_INPUT_START_RAMP_MUTED = 4096,
+ } pa_sink_input_flags_t;
+
+ struct pa_sink_input {
+@@ -121,6 +123,9 @@ struct pa_sink_input {
+ * this.*/
+ bool save_sink:1, save_volume:1, save_muted:1;
+
++ /* for volume ramps */
++ pa_cvolume_ramp_int ramp;
++
+ pa_resample_method_t requested_resample_method, actual_resample_method;
+
+ /* Returns the chunk of audio data and drops it from the
+@@ -249,6 +254,8 @@ struct pa_sink_input {
+ pa_usec_t requested_sink_latency;
+
+ pa_hashmap *direct_outputs;
++
++ pa_cvolume_ramp_int ramp;
+ } thread_info;
+
+ void *userdata;
+@@ -265,6 +272,7 @@ enum {
+ PA_SINK_INPUT_MESSAGE_SET_STATE,
+ PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY,
+ PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY,
++ PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
+ PA_SINK_INPUT_MESSAGE_MAX
+ };
+
+@@ -370,6 +378,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, bool s
+ void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa_cvolume *volume_factor);
+ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
+ pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, bool absolute);
++void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, pa_bool_t send_msg, pa_bool_t save);
+
+ void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
+
+--
+1.9.1
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0004-sink-input-Code-cleanup-regarding-volume-ramping.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0004-sink-input-Code-cleanup-regarding-volume-ramping.patch
new file mode 100644
index 000000000..64d7b141d
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0004-sink-input-Code-cleanup-regarding-volume-ramping.patch
@@ -0,0 +1,62 @@
+From 49d8943b151a73be3dd726561a720c0f4bfdccac Mon Sep 17 00:00:00 2001
+From: Sangchul Lee <sangchul1011@gmail.com>
+Date: Sat, 27 Aug 2016 21:33:18 +0900
+Subject: [PATCH 4/6] sink-input: Code cleanup regarding volume ramping
+
+Remove unused parameter of pa_sink_input_set_volume_ramp().
+Use bool instead of pa_bool_t.
+
+Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
+---
+ src/pulsecore/sink-input.c | 7 ++-----
+ src/pulsecore/sink-input.h | 2 +-
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
+index cc8953f..e1968e0 100644
+--- a/src/pulsecore/sink-input.c
++++ b/src/pulsecore/sink-input.c
+@@ -931,7 +931,6 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa
+ pa_memchunk wchunk;
+ bool nvfs = need_volume_factor_sink;
+ pa_cvolume target;
+- pa_bool_t tmp;
+
+ wchunk = tchunk;
+ pa_memblock_ref(wchunk.memblock);
+@@ -972,7 +971,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa
+ if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
+ pa_memchunk_make_writable(&wchunk, 0);
+ pa_volume_ramp_memchunk(&wchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
+- } else if ((tmp = pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
++ } else if ((pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
+ pa_memchunk_make_writable(&wchunk, 0);
+ pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
+ pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &target);
+@@ -1372,9 +1371,7 @@ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
+ void pa_sink_input_set_volume_ramp(
+ pa_sink_input *i,
+ const pa_cvolume_ramp *ramp,
+- pa_bool_t send_msg,
+- pa_bool_t save) {
+-
++ bool send_msg) {
+ pa_sink_input_assert_ref(i);
+ pa_assert_ctl_context();
+ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
+index 6e1b211..92f61c3 100644
+--- a/src/pulsecore/sink-input.h
++++ b/src/pulsecore/sink-input.h
+@@ -378,7 +378,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, bool s
+ void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa_cvolume *volume_factor);
+ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
+ pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, bool absolute);
+-void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, pa_bool_t send_msg, pa_bool_t save);
++void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, bool send_msg);
+
+ void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
+
+--
+1.9.1
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0005-sink-input-volume-Add-support-for-volume-ramp-factor.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0005-sink-input-volume-Add-support-for-volume-ramp-factor.patch
new file mode 100644
index 000000000..e371b7ec5
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0005-sink-input-volume-Add-support-for-volume-ramp-factor.patch
@@ -0,0 +1,299 @@
+From a98e78ccc4f12d6efad2832a09202651e2a8b6cd Mon Sep 17 00:00:00 2001
+From: Sangchul Lee <sangchul1011@gmail.com>
+Date: Sat, 27 Aug 2016 21:33:19 +0900
+Subject: [PATCH 5/6] sink-input, volume: Add support for volume ramp factor
+
+Previously, using pa_sink_input_set_volume_ramp() is hard to manage
+if there are several callers. These new volume ramp factor APIs make it
+easy for caller to use and to set more than one volume ramp factor.
+New volume ramp factor will be applied by the multiplication of the other
+ramp factors that have been already set.
+
+APIs are added as below.
+ - pa_sink_input_add_volume_ramp_factor()
+ - pa_sink_input_remove_volume_ramp_factor()
+ - pa_cvolume_ramp_compatible()
+ - pa_sw_cvolume_ramp_multiply()
+ - pa_cvolume_ramp_valid()
+
+Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
+---
+ src/map-file | 3 ++
+ src/pulse/volume.c | 44 ++++++++++++++++++
+ src/pulse/volume.h | 9 ++++
+ src/pulsecore/sink-input.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
+ src/pulsecore/sink-input.h | 5 +++
+ 5 files changed, 169 insertions(+)
+
+diff --git a/src/map-file b/src/map-file
+index ef9b57d..7577c14 100644
+--- a/src/map-file
++++ b/src/map-file
+@@ -142,6 +142,8 @@ pa_cvolume_ramp_equal;
+ pa_cvolume_ramp_init;
+ pa_cvolume_ramp_set;
+ pa_cvolume_ramp_channel_ramp_set;
++pa_cvolume_ramp_compatible;
++pa_cvolume_ramp_valid;
+ pa_cvolume_remap;
+ pa_cvolume_scale;
+ pa_cvolume_scale_mask;
+@@ -344,6 +346,7 @@ pa_sw_cvolume_divide_scalar;
+ pa_sw_cvolume_multiply;
+ pa_sw_cvolume_multiply_scalar;
+ pa_sw_cvolume_snprint_dB;
++pa_sw_cvolume_ramp_multiply;
+ pa_sw_volume_divide;
+ pa_sw_volume_from_dB;
+ pa_sw_volume_from_linear;
+diff --git a/src/pulse/volume.c b/src/pulse/volume.c
+index 85072c1..8d99150 100644
+--- a/src/pulse/volume.c
++++ b/src/pulse/volume.c
+@@ -1049,3 +1049,47 @@ pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigne
+
+ return ramp;
+ }
++
++int pa_cvolume_ramp_compatible(const pa_cvolume_ramp *ramp, const pa_sample_spec *ss) {
++
++ pa_assert(ramp);
++ pa_assert(ss);
++
++ pa_return_val_if_fail(pa_cvolume_ramp_valid(ramp), 0);
++ pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
++
++ return ramp->channels == ss->channels;
++}
++
++pa_cvolume_ramp *pa_sw_cvolume_ramp_multiply(pa_cvolume_ramp *dest, const pa_cvolume_ramp *a, const pa_cvolume_ramp *b) {
++ unsigned i;
++
++ pa_assert(dest);
++ pa_assert(a);
++ pa_assert(b);
++
++ pa_return_val_if_fail(pa_cvolume_ramp_valid(a), NULL);
++ pa_return_val_if_fail(pa_cvolume_ramp_valid(b), NULL);
++
++ for (i = 0; i < a->channels && i < b->channels; i++)
++ dest->ramps[i].target = pa_sw_volume_multiply(a->ramps[i].target, b->ramps[i].target);
++
++ dest->channels = (uint8_t) i;
++
++ return dest;
++}
++
++int pa_cvolume_ramp_valid(const pa_cvolume_ramp *ramp) {
++ unsigned c;
++
++ pa_assert(ramp);
++
++ if (!pa_channels_valid(ramp->channels))
++ return 0;
++
++ for (c = 0; c < ramp->channels; c++)
++ if (!PA_VOLUME_IS_VALID(ramp->ramps[c].target))
++ return 0;
++
++ return 1;
++}
+diff --git a/src/pulse/volume.h b/src/pulse/volume.h
+index 2ae3451..65fcb08 100644
+--- a/src/pulse/volume.h
++++ b/src/pulse/volume.h
+@@ -458,12 +458,21 @@ int pa_cvolume_ramp_equal(const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
+ /** Init volume ramp struct */
+ pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp);
+
++/** Set the volume ramp of the first n channels to PA_VOLUME_NORM */
++#define pa_cvolume_ramp_reset(a, n, t, l) pa_cvolume_ramp_set((a), (n), (t), (l), PA_VOLUME_NORM)
++
+ /** Set first n channels of ramp struct to certain value */
+ pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
+
+ /** Set individual channel in the channel struct */
+ pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
+
++int pa_cvolume_ramp_compatible(const pa_cvolume_ramp *ramp, const pa_sample_spec *ss);
++
++int pa_cvolume_ramp_valid(const pa_cvolume_ramp *ramp);
++
++pa_cvolume_ramp *pa_sw_cvolume_ramp_multiply(pa_cvolume_ramp *dest, const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
++
+ PA_C_DECL_END
+
+ #endif
+diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
+index e1968e0..6f89aa1 100644
+--- a/src/pulsecore/sink-input.c
++++ b/src/pulsecore/sink-input.c
+@@ -53,6 +53,11 @@ struct volume_factor_entry {
+ pa_cvolume volume;
+ };
+
++struct volume_ramp_factor_entry {
++ char *key;
++ pa_cvolume_ramp ramp;
++};
++
+ static struct volume_factor_entry *volume_factor_entry_new(const char *key, const pa_cvolume *volume) {
+ struct volume_factor_entry *entry;
+
+@@ -83,6 +88,37 @@ static void volume_factor_from_hashmap(pa_cvolume *v, pa_hashmap *items, uint8_t
+ pa_sw_cvolume_multiply(v, v, &entry->volume);
+ }
+
++static struct volume_ramp_factor_entry *volume_ramp_factor_entry_new(const char *key, const pa_cvolume_ramp *ramp) {
++ struct volume_ramp_factor_entry *entry;
++
++ pa_assert(key);
++ pa_assert(ramp);
++
++ entry = pa_xnew(struct volume_ramp_factor_entry, 1);
++ entry->key = pa_xstrdup(key);
++
++ entry->ramp = *ramp;
++
++ return entry;
++}
++
++static void volume_ramp_factor_entry_free(struct volume_ramp_factor_entry *ramp_entry) {
++ pa_assert(ramp_entry);
++
++ pa_xfree(ramp_entry->key);
++ pa_xfree(ramp_entry);
++}
++
++static void volume_ramp_factor_from_hashmap(pa_cvolume_ramp *r, pa_hashmap *items, uint8_t channels, pa_volume_ramp_type_t type, long length) {
++ struct volume_ramp_factor_entry *entry;
++ void *state = NULL;
++
++ pa_cvolume_ramp_reset(r, channels, type, length);
++ PA_HASHMAP_FOREACH(entry, items, state)
++ pa_sw_cvolume_ramp_multiply(r, r, &entry->ramp);
++
++}
++
+ static void sink_input_free(pa_object *o);
+ static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
+
+@@ -500,6 +536,8 @@ int pa_sink_input_new(
+ i->volume_factor_sink_items = data->volume_factor_sink_items;
+ data->volume_factor_sink_items = NULL;
+ volume_factor_from_hashmap(&i->volume_factor_sink, i->volume_factor_sink_items, i->sink->sample_spec.channels);
++ i->ramp_factor_items = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
++ (pa_free_cb_t) volume_ramp_factor_entry_free);
+
+ i->real_ratio = i->reference_ratio = data->volume;
+ pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
+@@ -764,6 +802,9 @@ static void sink_input_free(pa_object *o) {
+ if (i->volume_factor_sink_items)
+ pa_hashmap_free(i->volume_factor_sink_items);
+
++ if (i->ramp_factor_items)
++ pa_hashmap_free(i->ramp_factor_items);
++
+ pa_xfree(i->driver);
+ pa_xfree(i);
+ }
+@@ -1367,6 +1408,73 @@ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
+ return 0;
+ }
+
++void pa_sink_input_add_volume_ramp_factor(pa_sink_input *i, const char *key, const pa_cvolume_ramp *ramp_factor, bool send_msg) {
++ struct volume_ramp_factor_entry *r;
++
++ pa_sink_input_assert_ref(i);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
++ pa_assert(ramp_factor);
++ pa_assert(key);
++ pa_assert(pa_cvolume_ramp_valid(ramp_factor));
++ pa_assert(ramp_factor->channels == 1 || pa_cvolume_ramp_compatible(ramp_factor, &i->sample_spec));
++
++ r = volume_ramp_factor_entry_new(key, ramp_factor);
++ if (!pa_cvolume_ramp_compatible(ramp_factor, &i->sample_spec))
++ pa_cvolume_ramp_set(&r->ramp, i->sample_spec.channels, ramp_factor->ramps[0].type, ramp_factor->ramps[0].length, ramp_factor->ramps[0].target);
++
++ pa_assert_se(pa_hashmap_put(i->ramp_factor_items, r->key, r) >= 0);
++ if (pa_hashmap_size(i->ramp_factor_items) == 1)
++ pa_cvolume_ramp_set(&i->ramp_factor, i->sample_spec.channels, r->ramp.ramps[0].type, r->ramp.ramps[0].length, r->ramp.ramps[0].target);
++ else
++ pa_sw_cvolume_ramp_multiply(&i->ramp_factor, &i->ramp_factor, &r->ramp);
++
++ pa_cvolume_ramp_convert(&i->ramp_factor, &i->ramp, i->sample_spec.rate);
++
++ if (send_msg)
++ pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP, NULL, 0, NULL) == 0);
++
++ return 0;
++}
++
++/* Returns 0 if an entry was removed and -1 if no entry for the given key was
++ * found. */
++int pa_sink_input_remove_volume_ramp_factor(pa_sink_input *i, const char *key, bool send_msg) {
++ struct volume_ramp_factor_entry *r;
++
++ pa_sink_input_assert_ref(i);
++ pa_assert(key);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
++
++ r = pa_hashmap_remove(i->ramp_factor_items, key);
++ if (!r)
++ return -1;
++
++ switch (pa_hashmap_size(i->ramp_factor_items)) {
++ case 0:
++ pa_cvolume_ramp_reset(&i->ramp_factor, i->sample_spec.channels, r->ramp.ramps[0].type, r->ramp.ramps[0].length);
++ break;
++ case 1: {
++ struct volume_ramp_factor_entry *rf;
++ rf = pa_hashmap_first(i->ramp_factor_items);
++ pa_cvolume_ramp_set(&i->ramp_factor, i->sample_spec.channels, r->ramp.ramps[0].type, r->ramp.ramps[0].length, rf->ramp.ramps[0].target);
++ break;
++ }
++ default:
++ volume_ramp_factor_from_hashmap(&i->ramp_factor, i->ramp_factor_items, i->ramp_factor.channels, i->ramp_factor.ramps[0].type, i->ramp_factor.ramps[0].length);
++ }
++
++ volume_ramp_factor_entry_free(r);
++
++ pa_cvolume_ramp_convert(&i->ramp_factor, &i->ramp, i->sample_spec.rate);
++
++ if (send_msg)
++ pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP, NULL, 0, NULL) == 0);
++
++ return 0;
++}
++
+ /* Called from main thread */
+ void pa_sink_input_set_volume_ramp(
+ pa_sink_input *i,
+diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
+index 92f61c3..5430d53 100644
+--- a/src/pulsecore/sink-input.h
++++ b/src/pulsecore/sink-input.h
+@@ -113,6 +113,9 @@ struct pa_sink_input {
+ pa_cvolume volume_factor_sink; /* A second volume factor in format of the sink this stream is connected to. */
+ pa_hashmap *volume_factor_sink_items;
+
++ pa_cvolume_ramp ramp_factor;
++ pa_hashmap *ramp_factor_items;
++
+ bool volume_writable:1;
+
+ bool muted:1;
+@@ -379,6 +382,8 @@ void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa
+ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
+ pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, bool absolute);
+ void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, bool send_msg);
++void pa_sink_input_add_volume_ramp_factor(pa_sink_input *i, const char *key, const pa_cvolume_ramp *ramp_factor, bool send_msg);
++int pa_sink_input_remove_volume_ramp_factor(pa_sink_input *i, const char *key, bool send_msg);
+
+ void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
+
+--
+1.9.1
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0006-sink-input-Remove-pa_sink_input_set_volume_ramp.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0006-sink-input-Remove-pa_sink_input_set_volume_ramp.patch
new file mode 100644
index 000000000..50110bd14
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/0006-sink-input-Remove-pa_sink_input_set_volume_ramp.patch
@@ -0,0 +1,63 @@
+From ac9a99505fd768b66dd92e9091e80b576cabc00d Mon Sep 17 00:00:00 2001
+From: Sangchul Lee <sangchul1011@gmail.com>
+Date: Sat, 27 Aug 2016 21:33:20 +0900
+Subject: [PATCH 6/6] sink-input: Remove pa_sink_input_set_volume_ramp()
+
+Please use pa_sink_input_add_volume_ramp_factor() or
+pa_sink_input_remove_volume_ramp_factor() instead of it.
+
+Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
+---
+ src/pulsecore/sink-input.c | 23 -----------------------
+ src/pulsecore/sink-input.h | 1 -
+ 2 files changed, 24 deletions(-)
+
+diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
+index 6f89aa1..4c7c568 100644
+--- a/src/pulsecore/sink-input.c
++++ b/src/pulsecore/sink-input.c
+@@ -1475,29 +1475,6 @@ int pa_sink_input_remove_volume_ramp_factor(pa_sink_input *i, const char *key, b
+ return 0;
+ }
+
+-/* Called from main thread */
+-void pa_sink_input_set_volume_ramp(
+- pa_sink_input *i,
+- const pa_cvolume_ramp *ramp,
+- bool send_msg) {
+- pa_sink_input_assert_ref(i);
+- pa_assert_ctl_context();
+- pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+- pa_assert(ramp);
+-
+- pa_cvolume_ramp_convert(ramp, &i->ramp, i->sample_spec.rate);
+-
+- pa_log_debug("setting volume ramp with target vol:%d and length:%ld",
+- i->ramp.ramps[0].target,
+- i->ramp.ramps[0].length);
+-
+-
+- /* This tells the sink that volume ramp changed */
+- if (send_msg)
+- pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
+- NULL, 0, NULL) == 0);
+-}
+-
+ /* Called from main context */
+ static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
+ pa_sink_input_assert_ref(i);
+diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
+index 5430d53..5fef3d5 100644
+--- a/src/pulsecore/sink-input.h
++++ b/src/pulsecore/sink-input.h
+@@ -381,7 +381,6 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, bool s
+ void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa_cvolume *volume_factor);
+ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
+ pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, bool absolute);
+-void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, bool send_msg);
+ void pa_sink_input_add_volume_ramp_factor(pa_sink_input *i, const char *key, const pa_cvolume_ramp *ramp_factor, bool send_msg);
+ int pa_sink_input_remove_volume_ramp_factor(pa_sink_input *i, const char *key, bool send_msg);
+
+--
+1.9.1
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/enable-ofono-hfp-backend.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/enable-ofono-hfp-backend.patch
new file mode 100644
index 000000000..85b1ae03d
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio-10.0/enable-ofono-hfp-backend.patch
@@ -0,0 +1,11 @@
+--- pulseaudio-9.0/src/daemon/default.pa.in.orig 2017-05-17 17:26:20.415369638 +0000
++++ pulseaudio-9.0/src/daemon/default.pa.in 2017-05-17 17:26:49.995316383 +0000
+@@ -82,7 +82,7 @@
+ .endif
+
+ .ifexists module-bluetooth-discover@PA_SOEXT@
+-load-module module-bluetooth-discover
++load-module module-bluetooth-discover headset=ofono
+ .endif
+ ])dnl
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0008-install-files-for-a-module-development.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0008-install-files-for-a-module-development.patch
new file mode 100644
index 000000000..ac164d643
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0008-install-files-for-a-module-development.patch
@@ -0,0 +1,53 @@
+--- a/Makefile.am 2016-04-12 11:28:10.832997230 +0200
++++ b/Makefile.am 2016-04-12 11:32:41.868996777 +0200
+@@ -49,7 +49,13 @@
+ vala/libpulse-simple.deps vala/libpulse-simple.vapi
+
+ pkgconfigdir = $(libdir)/pkgconfig
+-pkgconfig_DATA = libpulse.pc libpulse-simple.pc
++pkgconfig_DATA = libpulse.pc libpulse-simple.pc pulseaudio-module-devel.pc
++
++moduledev_DATA = pulsecore-config.h $(top_srcdir)/src/pulsecore/*.h
++moduledevdir = $(includedir)/pulsemodule/pulsecore
++
++moduledevinternal_DATA = src/pulse/internal.h src/pulse/client-conf.h src/pulse/fork-detect.h
++moduledevinternaldir = $(includedir)/pulsemodule/pulse
+
+ if HAVE_GLIB20
+ pkgconfig_DATA += \
+@@ -103,6 +109,9 @@
+ check-daemon:
+ $(MAKE) -C src check-daemon
+
++pulsecore-config.h: config.h
++ cp $< $@
++
+ .PHONY: homepage distcleancheck doxygen
+
+ # see git-version-gen
+--- a/configure.ac 2016-04-12 11:34:10.605996629 +0200
++++ b/configure.ac 2016-04-12 11:37:43.502996274 +0200
+@@ -1464,6 +1464,7 @@
+ man/default.pa.5.xml
+ man/pulse-cli-syntax.5.xml
+ man/start-pulseaudio-x11.1.xml
++pulseaudio-module-devel.pc
+ ])
+
+ AC_CONFIG_FILES([src/esdcompat:src/daemon/esdcompat.in], [chmod +x src/esdcompat])
+--- /dev/null 2016-03-15 16:08:23.302999643 +0100
++++ b/pulseaudio-module-devel.pc.in 2016-03-17 16:16:58.427977484 +0100
+@@ -0,0 +1,12 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++modlibexecdir=@modlibexecdir@
++
++Name: pulseaudio-module-devel
++Description: PulseAudio Module Development Interface
++Version: @PACKAGE_VERSION@
++Libs: -L${libdir} -L${libdir}/pulseaudio -L${modlibexecdir} -lpulsecommon-@PA_MAJORMINOR@ -lpulsecore-@PA_MAJORMINOR@ -lprotocol-native
++Libs.private:
++Cflags: -I${includedir}/pulsemodule -D_REENTRANT
+
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0010-volume-ramp-additions-to-the-low-level-infra.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0010-volume-ramp-additions-to-the-low-level-infra.patch
new file mode 100644
index 000000000..e249bc438
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0010-volume-ramp-additions-to-the-low-level-infra.patch
@@ -0,0 +1,503 @@
+--- a/src/map-file 2016-04-12 15:03:17.009975690 +0200
++++ b/src/map-file 2016-04-12 15:03:52.389975631 +0200
+@@ -136,6 +136,9 @@
+ pa_cvolume_merge;
+ pa_cvolume_min;
+ pa_cvolume_min_mask;
++pa_cvolume_ramp_init;
++pa_cvolume_ramp_set;
++pa_cvolume_ramp_channel_ramp_set;
+ pa_cvolume_remap;
+ pa_cvolume_scale;
+ pa_cvolume_scale_mask;
+--- a/src/pulse/def.h 2016-04-12 15:05:58.245975421 +0200
++++ b/src/pulse/def.h 2016-04-12 15:13:19.424974685 +0200
+@@ -347,11 +347,15 @@
+ * consider absolute when the sink is in flat volume mode,
+ * relative otherwise. \since 0.9.20 */
+
+- PA_STREAM_PASSTHROUGH = 0x80000U
++ PA_STREAM_PASSTHROUGH = 0x80000U,
+ /**< Used to tag content that will be rendered by passthrough sinks.
+ * The data will be left as is and not reformatted, resampled.
+ * \since 1.0 */
+
++ PA_STREAM_START_RAMP_MUTED = 0x100000U
++ /**< Used to tag content that the stream will be started ramp volume
++ * muted so that you can nicely fade it in */
++
+ } pa_stream_flags_t;
+
+ /** \cond fulldocs */
+@@ -380,6 +384,7 @@
+ #define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND
+ #define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME
+ #define PA_STREAM_PASSTHROUGH PA_STREAM_PASSTHROUGH
++#define PA_STREAM_START_RAMP_MUTED PA_STREAM_START_RAMP_MUTED
+
+ /** \endcond */
+
+@@ -1047,6 +1052,13 @@
+ /** \endcond */
+ #endif
+
++/** \cond fulldocs */
++#define PA_VOLUMER_RAMP_TYPE_LINEAR PA_VOLUMER_RAMP_TYPE_LINEAR
++#define PA_VOLUMER_RAMP_TYPE_LOGARITHMIC PA_VOLUMER_RAMP_TYPE_LOGARITHMIC
++#define PA_VOLUMER_RAMP_TYPE_CUBIC PA_VOLUMER_RAMP_TYPE_CUBIC
++
++/** \endcond */
++
+ PA_C_DECL_END
+
+ #endif
+--- a/src/pulse/volume.c 2016-04-12 15:13:38.598974653 +0200
++++ b/src/pulse/volume.c 2016-04-12 15:27:57.729973219 +0200
+@@ -445,7 +445,10 @@
+ unsigned c;
+ pa_assert(a);
+
+- pa_return_val_if_fail(pa_cvolume_valid(a), 0);
++ if (pa_cvolume_valid(a) == 0)
++ abort();
++
++ /* pa_return_val_if_fail(pa_cvolume_valid(a), 0); */
+ pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0);
+
+ for (c = 0; c < a->channels; c++)
+@@ -986,3 +989,51 @@
+
+ return pa_cvolume_scale(v, m);
+ }
++
++pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp) {
++ unsigned c;
++
++ pa_assert(ramp);
++
++ ramp->channels = 0;
++
++ for (c = 0; c < PA_CHANNELS_MAX; c++) {
++ ramp->ramps[c].type = PA_VOLUME_RAMP_TYPE_LINEAR;
++ ramp->ramps[c].length = 0;
++ ramp->ramps[c].target = PA_VOLUME_INVALID;
++ }
++
++ return ramp;
++}
++
++pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channels, pa_volume_ramp_type_t type, long time, pa_volume_t vol) {
++ int i;
++
++ pa_assert(ramp);
++ pa_assert(channels > 0);
++ pa_assert(time >= 0);
++ pa_assert(channels <= PA_CHANNELS_MAX);
++
++ ramp->channels = (uint8_t) channels;
++
++ for (i = 0; i < ramp->channels; i++) {
++ ramp->ramps[i].type = type;
++ ramp->ramps[i].length = time;
++ ramp->ramps[i].target = PA_CLAMP_VOLUME(vol);
++ }
++
++ return ramp;
++}
++
++pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol) {
++
++ pa_assert(ramp);
++ pa_assert(channel <= ramp->channels);
++ pa_assert(time >= 0);
++
++ ramp->ramps[channel].type = type;
++ ramp->ramps[channel].length = time;
++ ramp->ramps[channel].target = PA_CLAMP_VOLUME(vol);
++
++ return ramp;
++}
+--- a/src/pulse/volume.h 2016-04-12 15:40:34.989971955 +0200
++++ b/src/pulse/volume.h 2016-04-12 15:38:50.708972129 +0200
+@@ -413,6 +413,36 @@
+ * the channels are kept. \since 0.9.16 */
+ pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec);
+
++/** Volume ramp type
++*/
++typedef enum pa_volume_ramp_type {
++ PA_VOLUME_RAMP_TYPE_LINEAR = 0, /**< linear */
++ PA_VOLUME_RAMP_TYPE_LOGARITHMIC = 1, /**< logarithmic */
++ PA_VOLUME_RAMP_TYPE_CUBIC = 2,
++} pa_volume_ramp_type_t;
++
++/** A structure encapsulating a volume ramp */
++typedef struct pa_volume_ramp_t {
++ pa_volume_ramp_type_t type;
++ long length;
++ pa_volume_t target;
++} pa_volume_ramp_t;
++
++/** A structure encapsulating a multichannel volume ramp */
++typedef struct pam_cvolume_ramp {
++ uint8_t channels;
++ pa_volume_ramp_t ramps[PA_CHANNELS_MAX];
++} pa_cvolume_ramp;
++
++/** Init volume ramp struct */
++pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp);
++
++/** Set first n channels of ramp struct to certain value */
++pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
++
++/** Set individual channel in the channel struct */
++pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
++
+ PA_C_DECL_END
+
+ #endif
+--- a/src/pulsecore/sample-util.c 2016-04-12 15:41:51.812971827 +0200
++++ b/src/pulsecore/sample-util.c 2016-04-12 16:31:56.795966812 +0200
+@@ -41,6 +41,13 @@
+
+ #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
+
++#define VOLUME_PADDING 32
++
++typedef union {
++ float f;
++ uint32_t i;
++} volume_val;
++
+ pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) {
+ void *data;
+
+@@ -403,3 +410,292 @@
+ usec = pa_bytes_to_usec_round_up(size, from);
+ return pa_usec_to_bytes_round_up(usec, to);
+ }
++
++static void calc_linear_integer_volume_no_mapping(int32_t linear[], float volume[], unsigned nchannels) {
++ unsigned channel, padding;
++
++ pa_assert(linear);
++ pa_assert(volume);
++
++ for (channel = 0; channel < nchannels; channel++)
++ linear[channel] = (int32_t) lrint(volume[channel] * 0x10000U);
++
++ for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
++ linear[channel] = linear[padding];
++}
++
++static void calc_linear_float_volume_no_mapping(float linear[], float volume[], unsigned nchannels) {
++ unsigned channel, padding;
++
++ pa_assert(linear);
++ pa_assert(volume);
++
++ for (channel = 0; channel < nchannels; channel++)
++ linear[channel] = volume[channel];
++
++ for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
++ linear[channel] = linear[padding];
++}
++
++typedef void (*pa_calc_volume_no_mapping_func_t) (void *volumes, float *volume, int channels);
++
++static const pa_calc_volume_no_mapping_func_t calc_volume_table_no_mapping[] = {
++ [PA_SAMPLE_U8] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_ALAW] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_ULAW] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S16LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S16BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_FLOAT32LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_float_volume_no_mapping,
++ [PA_SAMPLE_FLOAT32BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_float_volume_no_mapping,
++ [PA_SAMPLE_S32LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S32BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24_32LE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping,
++ [PA_SAMPLE_S24_32BE] = (pa_calc_volume_no_mapping_func_t) calc_linear_integer_volume_no_mapping
++};
++
++static const unsigned format_sample_size_table[] = {
++ [PA_SAMPLE_U8] = 1,
++ [PA_SAMPLE_ALAW] = 1,
++ [PA_SAMPLE_ULAW] = 1,
++ [PA_SAMPLE_S16LE] = 2,
++ [PA_SAMPLE_S16BE] = 2,
++ [PA_SAMPLE_FLOAT32LE] = 4,
++ [PA_SAMPLE_FLOAT32BE] = 4,
++ [PA_SAMPLE_S32LE] = 4,
++ [PA_SAMPLE_S32BE] = 4,
++ [PA_SAMPLE_S24LE] = 3,
++ [PA_SAMPLE_S24BE] = 3,
++ [PA_SAMPLE_S24_32LE] = 4,
++ [PA_SAMPLE_S24_32BE] = 4
++};
++
++static float calc_volume_ramp_linear(pa_volume_ramp_int_t *ramp) {
++ pa_assert(ramp);
++ pa_assert(ramp->length > 0);
++
++ /* basic linear interpolation */
++ return ramp->start + (ramp->length - ramp->left) * (ramp->end - ramp->start) / (float) ramp->length;
++}
++
++static float calc_volume_ramp_logarithmic(pa_volume_ramp_int_t *ramp) {
++ float x_val, s, e;
++ long temp;
++
++ pa_assert(ramp);
++ pa_assert(ramp->length > 0);
++
++ if (ramp->end > ramp->start) {
++ temp = ramp->left;
++ s = ramp->end;
++ e = ramp->start;
++ } else {
++ temp = ramp->length - ramp->left;
++ s = ramp->start;
++ e = ramp->end;
++ }
++
++ x_val = temp == 0 ? 0.0 : powf(temp, 10);
++
++ /* base 10 logarithmic interpolation */
++ return s + x_val * (e - s) / powf(ramp->length, 10);
++}
++
++static float calc_volume_ramp_cubic(pa_volume_ramp_int_t *ramp) {
++ float x_val, s, e;
++ long temp;
++
++ pa_assert(ramp);
++ pa_assert(ramp->length > 0);
++
++ if (ramp->end > ramp->start) {
++ temp = ramp->left;
++ s = ramp->end;
++ e = ramp->start;
++ } else {
++ temp = ramp->length - ramp->left;
++ s = ramp->start;
++ e = ramp->end;
++ }
++
++ x_val = temp == 0 ? 0.0 : cbrtf(temp);
++
++ /* cubic interpolation */
++ return s + x_val * (e - s) / cbrtf(ramp->length);
++}
++
++typedef float (*pa_calc_volume_ramp_func_t) (pa_volume_ramp_int_t *);
++
++static const pa_calc_volume_ramp_func_t calc_volume_ramp_table[] = {
++ [PA_VOLUME_RAMP_TYPE_LINEAR] = (pa_calc_volume_ramp_func_t) calc_volume_ramp_linear,
++ [PA_VOLUME_RAMP_TYPE_LOGARITHMIC] = (pa_calc_volume_ramp_func_t) calc_volume_ramp_logarithmic,
++ [PA_VOLUME_RAMP_TYPE_CUBIC] = (pa_calc_volume_ramp_func_t) calc_volume_ramp_cubic
++};
++
++static void calc_volume_ramps(pa_cvolume_ramp_int *ram, float *vol)
++{
++ int i;
++
++ for (i = 0; i < ram->channels; i++) {
++ if (ram->ramps[i].left <= 0) {
++ if (ram->ramps[i].target == PA_VOLUME_NORM) {
++ vol[i] = 1.0;
++ }
++ } else {
++ vol[i] = ram->ramps[i].curr = calc_volume_ramp_table[ram->ramps[i].type] (&ram->ramps[i]);
++ ram->ramps[i].left--;
++ }
++ }
++}
++
++void pa_volume_ramp_memchunk(
++ pa_memchunk *c,
++ const pa_sample_spec *spec,
++ pa_cvolume_ramp_int *ramp) {
++
++ void *ptr;
++ volume_val linear[PA_CHANNELS_MAX + VOLUME_PADDING];
++ float vol[PA_CHANNELS_MAX + VOLUME_PADDING];
++ pa_do_volume_func_t do_volume;
++ long length_in_frames;
++ int i;
++
++ pa_assert(c);
++ pa_assert(spec);
++ pa_assert(pa_frame_aligned(c->length, spec));
++ pa_assert(ramp);
++
++ length_in_frames = c->length / format_sample_size_table[spec->format] / spec->channels;
++
++ if (pa_memblock_is_silence(c->memblock)) {
++ for (i = 0; i < ramp->channels; i++) {
++ if (ramp->ramps[i].length > 0)
++ ramp->ramps[i].length -= length_in_frames;
++ }
++ return;
++ }
++
++ if (spec->format < 0 || spec->format >= PA_SAMPLE_MAX) {
++ pa_log_warn("Unable to change volume of format");
++ return;
++ }
++
++ do_volume = pa_get_volume_func(spec->format);
++ pa_assert(do_volume);
++
++ ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
++
++ for (i = 0; i < length_in_frames; i++) {
++ calc_volume_ramps(ramp, vol);
++ calc_volume_table_no_mapping[spec->format] ((void *)linear, vol, spec->channels);
++
++ /* we only process one frame per iteration */
++ do_volume (ptr, (void *)linear, spec->channels, format_sample_size_table[spec->format] * spec->channels);
++
++ /* pa_log_debug("1: %d 2: %d", linear[0], linear[1]); */
++
++ ptr = (uint8_t*)ptr + format_sample_size_table[spec->format] * spec->channels;
++ }
++
++ pa_memblock_release(c->memblock);
++}
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_convert(const pa_cvolume_ramp *src, pa_cvolume_ramp_int *dst, int sample_rate) {
++ int i;
++ float temp;
++
++ for (i = 0; i < dst->channels; i++) {
++ dst->ramps[i].type = src->ramps[i].type;
++ /* ms to samples */
++ dst->ramps[i].length = src->ramps[i].length * sample_rate / 1000;
++ dst->ramps[i].left = dst->ramps[i].length;
++ dst->ramps[i].start = dst->ramps[i].end;
++ dst->ramps[i].target = src->ramps[i].target;
++ /* scale to pulse internal mapping so that when ramp is over there's no glitch in volume */
++ temp = src->ramps[i].target / (float)0x10000U;
++ dst->ramps[i].end = temp * temp * temp;
++ }
++
++ return dst;
++}
++
++bool pa_cvolume_ramp_active(pa_cvolume_ramp_int *ramp) {
++ int i;
++
++ for (i = 0; i < ramp->channels; i++) {
++ if (ramp->ramps[i].left > 0)
++ return true;
++ }
++
++ return false;
++}
++
++bool pa_cvolume_ramp_target_active(pa_cvolume_ramp_int *ramp) {
++ int i;
++
++ for (i = 0; i < ramp->channels; i++) {
++ if (ramp->ramps[i].target != PA_VOLUME_NORM)
++ return true;
++ }
++
++ return false;
++}
++
++pa_cvolume * pa_cvolume_ramp_get_targets(pa_cvolume_ramp_int *ramp, pa_cvolume *volume) {
++ int i = 0;
++
++ volume->channels = ramp->channels;
++
++ for (i = 0; i < ramp->channels; i++)
++ volume->values[i] = ramp->ramps[i].target;
++
++ return volume;
++}
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_start_from(pa_cvolume_ramp_int *src, pa_cvolume_ramp_int *dst) {
++ int i;
++
++ for (i = 0; i < src->channels; i++) {
++ /* if new vols are invalid, copy old ramp i.e. no effect */
++ if (dst->ramps[i].target == PA_VOLUME_INVALID)
++ dst->ramps[i] = src->ramps[i];
++ /* if there's some old ramp still left */
++ else if (src->ramps[i].left > 0)
++ dst->ramps[i].start = src->ramps[i].curr;
++ }
++
++ return dst;
++}
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_int_init(pa_cvolume_ramp_int *src, pa_volume_t vol, int channels) {
++ int i;
++ float temp;
++
++ src->channels = channels;
++
++ for (i = 0; i < channels; i++) {
++ src->ramps[i].type = PA_VOLUME_RAMP_TYPE_LINEAR;
++ src->ramps[i].length = 0;
++ src->ramps[i].left = 0;
++ if (vol == PA_VOLUME_NORM) {
++ src->ramps[i].start = 1.0;
++ src->ramps[i].end = 1.0;
++ src->ramps[i].curr = 1.0;
++ }
++ else if (vol == PA_VOLUME_MUTED) {
++ src->ramps[i].start = 0.0;
++ src->ramps[i].end = 0.0;
++ src->ramps[i].curr = 0.0;
++ }
++ else {
++ temp = vol / (float)0x10000U;
++ src->ramps[i].start = temp * temp * temp;
++ src->ramps[i].end = src->ramps[i].start;
++ src->ramps[i].curr = src->ramps[i].start;
++ }
++ src->ramps[i].target = vol;
++ }
++
++ return src;
++}
+--- a/src/pulsecore/sample-util.h 2016-04-12 15:53:06.327970701 +0200
++++ b/src/pulsecore/sample-util.h 2016-04-12 16:24:16.356967580 +0200
+@@ -45,6 +45,33 @@
+
+ pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool, pa_memchunk* ret, const pa_sample_spec *spec, size_t length);
+
++typedef struct pa_volume_ramp_int_t {
++ pa_volume_ramp_type_t type;
++ long length;
++ long left;
++ float start;
++ float end;
++ float curr;
++ pa_volume_t target;
++} pa_volume_ramp_int_t;
++
++typedef struct pa_cvolume_ramp_int {
++ uint8_t channels;
++ pa_volume_ramp_int_t ramps[PA_CHANNELS_MAX];
++} pa_cvolume_ramp_int;
++
++pa_cvolume_ramp_int* pa_cvolume_ramp_convert(const pa_cvolume_ramp *src, pa_cvolume_ramp_int *dst, int sample_rate);
++bool pa_cvolume_ramp_active(pa_cvolume_ramp_int *ramp);
++bool pa_cvolume_ramp_target_active(pa_cvolume_ramp_int *ramp);
++pa_cvolume_ramp_int* pa_cvolume_ramp_start_from(pa_cvolume_ramp_int *src, pa_cvolume_ramp_int *dst);
++pa_cvolume_ramp_int* pa_cvolume_ramp_int_init(pa_cvolume_ramp_int *src, pa_volume_t vol, int channels);
++pa_cvolume * pa_cvolume_ramp_get_targets(pa_cvolume_ramp_int *ramp, pa_cvolume *volume);
++
++void pa_volume_ramp_memchunk(
++ pa_memchunk *c,
++ const pa_sample_spec *spec,
++ pa_cvolume_ramp_int *ramp);
++
+ size_t pa_frame_align(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
+
+ bool pa_frame_aligned(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0011-volume-ramp-adding-volume-ramping-to-sink-input.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0011-volume-ramp-adding-volume-ramping-to-sink-input.patch
new file mode 100644
index 000000000..08fb79248
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0011-volume-ramp-adding-volume-ramping-to-sink-input.patch
@@ -0,0 +1,159 @@
+--- a/src/pulsecore/sink-input.c 2016-04-12 16:50:41.311964935 +0200
++++ b/src/pulsecore/sink-input.c 2016-04-12 17:22:40.420961732 +0200
+@@ -525,6 +525,11 @@
+ reset_callbacks(i);
+ i->userdata = NULL;
+
++ if (data->flags & PA_SINK_INPUT_START_RAMP_MUTED)
++ pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_MUTED, data->sample_spec.channels);
++ else
++ pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_NORM, data->sample_spec.channels);
++
+ i->thread_info.state = i->state;
+ i->thread_info.attached = false;
+ pa_atomic_store(&i->thread_info.drained, 1);
+@@ -541,6 +546,8 @@
+ i->thread_info.playing_for = 0;
+ i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
++ i->thread_info.ramp = i->ramp;
++
+ pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
+ pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
+
+@@ -922,6 +929,8 @@
+ while (tchunk.length > 0) {
+ pa_memchunk wchunk;
+ bool nvfs = need_volume_factor_sink;
++ pa_cvolume target;
++ bool tmp;
+
+ wchunk = tchunk;
+ pa_memblock_ref(wchunk.memblock);
+@@ -958,6 +967,16 @@
+ pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
+ }
+
++ /* check for possible volume ramp */
++ if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
++ pa_memchunk_make_writable(&wchunk, 0);
++ pa_volume_ramp_memchunk(&wchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
++ } else if ((tmp = pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
++ pa_memchunk_make_writable(&wchunk, 0);
++ pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
++ pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &target);
++ }
++
+ pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
+ } else {
+ pa_memchunk rchunk;
+@@ -974,6 +993,16 @@
+ pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
+ }
+
++ /* check for possible volume ramp */
++ if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
++ pa_memchunk_make_writable(&wchunk, 0);
++ pa_volume_ramp_memchunk(&wchunk, &i->sink->sample_spec, &(i->thread_info.ramp));
++ } else if ((tmp = pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
++ pa_memchunk_make_writable(&wchunk, 0);
++ pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
++ pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &target);
++ }
++
+ pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
+ pa_memblock_unref(rchunk.memblock);
+ }
+@@ -1338,6 +1367,31 @@
+ return 0;
+ }
+
++/* Called from main thread */
++void pa_sink_input_set_volume_ramp(
++ pa_sink_input *i,
++ const pa_cvolume_ramp *ramp,
++ bool send_msg,
++ bool save) {
++
++ pa_sink_input_assert_ref(i);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
++ pa_assert(ramp);
++
++ pa_cvolume_ramp_convert(ramp, &i->ramp, i->sample_spec.rate);
++
++ pa_log_debug("setting volume ramp with target vol:%d and length:%ld",
++ i->ramp.ramps[0].target,
++ i->ramp.ramps[0].length);
++
++
++ /* This tells the sink that volume ramp changed */
++ if (send_msg)
++ pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
++ NULL, 0, NULL) == 0);
++}
++
+ /* Called from main context */
+ static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
+ pa_sink_input_assert_ref(i);
+@@ -1929,6 +1983,12 @@
+ }
+ return 0;
+
++ case PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP:
++ /* we have ongoing ramp where we take current start values */
++ pa_cvolume_ramp_start_from(&i->thread_info.ramp, &i->ramp);
++ i->thread_info.ramp = i->ramp;
++ return 0;
++
+ case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
+ if (i->thread_info.muted != i->muted) {
+ i->thread_info.muted = i->muted;
+--- a/src/pulsecore/sink-input.h 2016-04-12 16:50:46.712964926 +0200
++++ b/src/pulsecore/sink-input.h 2016-04-12 17:30:24.289960958 +0200
+@@ -59,7 +59,8 @@
+ PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
+ PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,
+ PA_SINK_INPUT_KILL_ON_SUSPEND = 1024,
+- PA_SINK_INPUT_PASSTHROUGH = 2048
++ PA_SINK_INPUT_PASSTHROUGH = 2048,
++ PA_SINK_INPUT_START_RAMP_MUTED = 4096,
+ } pa_sink_input_flags_t;
+
+ struct pa_sink_input {
+@@ -122,6 +123,9 @@
+ * this.*/
+ bool save_sink:1, save_volume:1, save_muted:1;
+
++ /* for volume ramps */
++ pa_cvolume_ramp_int ramp;
++
+ pa_resample_method_t requested_resample_method, actual_resample_method;
+
+ /* Returns the chunk of audio data and drops it from the
+@@ -250,6 +254,8 @@
+ pa_usec_t requested_sink_latency;
+
+ pa_hashmap *direct_outputs;
++
++ pa_cvolume_ramp_int ramp;
+ } thread_info;
+
+ void *userdata;
+@@ -266,6 +272,7 @@
+ PA_SINK_INPUT_MESSAGE_SET_STATE,
+ PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY,
+ PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY,
++ PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
+ PA_SINK_INPUT_MESSAGE_MAX
+ };
+
+@@ -374,6 +381,8 @@
+
+ void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
+
++void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, bool send_msg, bool save);
++
+ void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p);
+
+ pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0012-volume-ramp-add-volume-ramping-to-sink.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0012-volume-ramp-add-volume-ramping-to-sink.patch
new file mode 100644
index 000000000..43e8283ef
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0012-volume-ramp-add-volume-ramping-to-sink.patch
@@ -0,0 +1,159 @@
+--- a/src/pulsecore/sink.c 2016-04-12 18:01:23.403957855 +0200
++++ b/src/pulsecore/sink.c 2016-04-12 18:44:49.677953506 +0200
+@@ -324,6 +324,8 @@
+ &s->sample_spec,
+ 0);
+
++ pa_cvolume_ramp_int_init(&s->ramp, PA_VOLUME_NORM, data->sample_spec.channels);
++
+ s->thread_info.rtpoll = NULL;
+ s->thread_info.inputs = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
+ (pa_free_cb_t) pa_sink_input_unref);
+@@ -347,6 +349,8 @@
+ s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
+ s->thread_info.latency_offset = s->latency_offset;
+
++ s->thread_info.ramp = s->ramp;
++
+ /* FIXME: This should probably be moved to pa_sink_put() */
+ pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
+
+@@ -1182,6 +1186,7 @@
+
+ } else if (n == 1) {
+ pa_cvolume volume;
++ pa_cvolume target;
+
+ *result = info[0].chunk;
+ pa_memblock_ref(result->memblock);
+@@ -1198,9 +1203,20 @@
+ result,
+ &s->sample_spec,
+ result->length);
+- } else if (!pa_cvolume_is_norm(&volume)) {
++ } else if (!pa_cvolume_is_norm(&volume) || pa_cvolume_ramp_target_active(&s->thread_info.ramp) || pa_cvolume_ramp_active(&s->thread_info.ramp)) {
+ pa_memchunk_make_writable(result, 0);
+- pa_volume_memchunk(result, &s->sample_spec, &volume);
++ if (!pa_cvolume_ramp_active(&s->thread_info.ramp)) {
++ if (!pa_cvolume_is_norm(&volume))
++ pa_volume_memchunk(result, &s->sample_spec, &volume);
++ pa_volume_ramp_memchunk(result, &s->sample_spec, &(s->thread_info.ramp));
++ }
++ else {
++ if (pa_cvolume_ramp_target_active(&s->thread_info.ramp)) {
++ pa_cvolume_ramp_get_targets(&s->thread_info.ramp, &target);
++ pa_sw_cvolume_multiply(&volume, &volume, &target);
++ }
++ pa_volume_memchunk(result, &s->sample_spec, &volume);
++ }
+ }
+ } else {
+ void *ptr;
+@@ -1290,6 +1306,7 @@
+
+ } else {
+ void *ptr;
++ pa_cvolume target_vol;
+
+ ptr = pa_memblock_acquire(target->memblock);
+
+@@ -1299,6 +1316,15 @@
+ &s->thread_info.soft_volume,
+ s->thread_info.soft_muted);
+
++ if (pa_cvolume_ramp_target_active(&s->thread_info.ramp) || pa_cvolume_ramp_active(&s->thread_info.ramp)) {
++ if (pa_cvolume_ramp_active(&s->thread_info.ramp))
++ pa_volume_ramp_memchunk(target, &s->sample_spec, &(s->thread_info.ramp));
++ else {
++ pa_cvolume_ramp_get_targets(&s->thread_info.ramp, &target_vol);
++ pa_volume_memchunk(target, &s->sample_spec, &target_vol);
++ }
++ }
++
+ pa_memblock_release(target->memblock);
+ }
+
+@@ -2058,6 +2084,32 @@
+ pa_assert_se(pa_asyncmsgq_send(root_sink->asyncmsgq, PA_MSGOBJECT(root_sink), PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
+ }
+
++/* Called from main thread */
++void pa_sink_set_volume_ramp(
++ pa_sink *s,
++ const pa_cvolume_ramp *ramp,
++ bool send_msg,
++ bool save) {
++
++ pa_sink_assert_ref(s);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_IS_LINKED(s->state));
++ pa_assert(ramp);
++
++ /* make sure we don't change the volume when a PASSTHROUGH input is connected ...
++ * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
++ if (pa_sink_is_passthrough(s)) {
++ pa_log_warn("Cannot do volume ramp, Sink is connected to PASSTHROUGH input");
++ return;
++ }
++
++ pa_cvolume_ramp_convert(ramp, &s->ramp, s->sample_spec.rate);
++
++ /* This tells the sink that volume ramp changed */
++ if (send_msg)
++ pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_RAMP, NULL, 0, NULL) == 0);
++}
++
+ /* Called from the io thread if sync volume is used, otherwise from the main thread.
+ * Only to be called by sink implementor */
+ void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
+@@ -2713,6 +2765,12 @@
+ sync_input_volumes_within_thread(s);
+ return 0;
+
++ case PA_SINK_MESSAGE_SET_VOLUME_RAMP:
++ /* if we have ongoing ramp where we take current start values */
++ pa_cvolume_ramp_start_from(&s->thread_info.ramp, &s->ramp);
++ s->thread_info.ramp = s->ramp;
++ return 0;
++
+ case PA_SINK_MESSAGE_GET_VOLUME:
+
+ if ((s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume) {
+--- a/src/pulsecore/sink.h 2016-04-12 18:01:42.117957824 +0200
++++ b/src/pulsecore/sink.h 2016-04-12 18:23:29.394955642 +0200
+@@ -105,6 +105,9 @@
+ pa_cvolume saved_volume;
+ bool saved_save_volume:1;
+
++ /* for volume ramps */
++ pa_cvolume_ramp_int ramp;
++
+ pa_asyncmsgq *asyncmsgq;
+
+ pa_memchunk silence;
+@@ -300,6 +303,8 @@
+ uint32_t volume_change_safety_margin;
+ /* Usec delay added to all volume change events, may be negative. */
+ int32_t volume_change_extra_delay;
++
++ pa_cvolume_ramp_int ramp;
+ } thread_info;
+
+ void *userdata;
+@@ -333,6 +338,7 @@
+ PA_SINK_MESSAGE_SET_MAX_REQUEST,
+ PA_SINK_MESSAGE_SET_PORT,
+ PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE,
++ PA_SINK_MESSAGE_SET_VOLUME_RAMP,
+ PA_SINK_MESSAGE_SET_LATENCY_OFFSET,
+ PA_SINK_MESSAGE_MAX
+ } pa_sink_message_t;
+@@ -453,6 +459,8 @@
+ void pa_sink_set_mute(pa_sink *sink, bool mute, bool save);
+ bool pa_sink_get_mute(pa_sink *sink, bool force_refresh);
+
++void pa_sink_set_volume_ramp(pa_sink *s, const pa_cvolume_ramp *ramp, bool send_msg, bool save);
++
+ bool pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p);
+
+ int pa_sink_set_port(pa_sink *s, const char *name, bool save);
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0013-add-internal-corking-state-for-sink-input.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0013-add-internal-corking-state-for-sink-input.patch
new file mode 100644
index 000000000..cb68e26af
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0013-add-internal-corking-state-for-sink-input.patch
@@ -0,0 +1,72 @@
+--- a/src/pulsecore/sink-input.c 2016-04-13 11:44:04.389999429 +0200
++++ b/src/pulsecore/sink-input.c 2016-04-13 11:52:45.167998560 +0200
+@@ -786,6 +786,9 @@
+ update_n_corked(i, state);
+ i->state = state;
+
++ i->corked = false;
++ i->corked_internal = false;
++
+ /* We might need to update the sink's volume if we are in flat volume mode. */
+ if (pa_sink_flat_volume_enabled(i->sink))
+ pa_sink_set_volume(i->sink, NULL, false, i->save_volume);
+@@ -1493,13 +1496,38 @@
+ }
+ }
+
++static void pa_sink_input_cork_really(pa_sink_input *i, bool b) {
++ pa_sink_input_assert_ref(i);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
++
++ if (i->corked_internal == false && i->corked == false)
++ b = false;
++ else
++ b = true;
++
++ sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
++}
++
+ /* Called from main context */
+ void pa_sink_input_cork(pa_sink_input *i, bool b) {
+ pa_sink_input_assert_ref(i);
+ pa_assert_ctl_context();
+ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+
+- sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
++ i->corked = b;
++
++ pa_sink_input_cork_really(i, b);
++}
++
++void pa_sink_input_cork_internal(pa_sink_input *i, bool b) {
++ pa_sink_input_assert_ref(i);
++ pa_assert_ctl_context();
++ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
++
++ i->corked_internal = b;
++
++ pa_sink_input_cork_really(i, b);
+ }
+
+ /* Called from main context */
+--- a/src/pulsecore/sink-input.h 2016-04-13 11:44:28.035999390 +0200
++++ b/src/pulsecore/sink-input.h 2016-04-13 11:53:56.325998441 +0200
+@@ -126,6 +126,9 @@
+ /* for volume ramps */
+ pa_cvolume_ramp_int ramp;
+
++ bool corked;
++ bool corked_internal;
++
+ pa_resample_method_t requested_resample_method, actual_resample_method;
+
+ /* Returns the chunk of audio data and drops it from the
+@@ -357,6 +360,7 @@
+ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes, bool rewrite, bool flush, bool dont_rewind_render);
+
+ void pa_sink_input_cork(pa_sink_input *i, bool b);
++void pa_sink_input_cork_internal(pa_sink_input *i, bool b);
+
+ int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate);
+ int pa_sink_input_update_rate(pa_sink_input *i);
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0020-core-util-Add-pa_join.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0020-core-util-Add-pa_join.patch
new file mode 100644
index 000000000..891a5b83a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0020-core-util-Add-pa_join.patch
@@ -0,0 +1,37 @@
+--- a/src/pulsecore/core-util.c 2016-04-13 16:17:33.314016929 +0200
++++ b/src/pulsecore/core-util.c 2016-04-13 16:18:31.186016833 +0200
+@@ -1104,6 +1104,24 @@
+ return pa_xstrndup(current, l);
+ }
+
++char *pa_join(const char * const *strings, unsigned n_strings, const char *delimiter) {
++ pa_strbuf *buf;
++ unsigned i;
++
++ pa_assert(strings || n_strings == 0);
++
++ buf = pa_strbuf_new();
++
++ for (i = 0; i < n_strings; i++) {
++ if (i > 0 && delimiter)
++ pa_strbuf_puts(buf, delimiter);
++
++ pa_strbuf_puts(buf, strings[i]);
++ }
++
++ return pa_strbuf_tostring_free(buf);
++}
++
+ PA_STATIC_TLS_DECLARE(signame, pa_xfree);
+
+ /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
+--- a/src/pulsecore/core-util.h 2016-04-13 16:17:39.177016919 +0200
++++ b/src/pulsecore/core-util.h 2016-04-13 16:19:09.141016769 +0200
+@@ -108,6 +108,7 @@
+ char *pa_split(const char *c, const char*delimiters, const char **state);
+ const char *pa_split_in_place(const char *c, const char*delimiters, int *n, const char **state);
+ char *pa_split_spaces(const char *c, const char **state);
++char *pa_join(const char * const *strings, unsigned n_strings, const char *delimiter);
+
+ char *pa_strip_nl(char *s);
+ char *pa_strip(char *s);
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0021-dynarray-Add-pa_dynarray_get_raw_array.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0021-dynarray-Add-pa_dynarray_get_raw_array.patch
new file mode 100644
index 000000000..040913c8f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0021-dynarray-Add-pa_dynarray_get_raw_array.patch
@@ -0,0 +1,21 @@
+--- a/src/pulsecore/dynarray.c 2016-04-13 16:25:38.628016119 +0200
++++ b/src/pulsecore/dynarray.c 2016-04-13 16:26:54.694015992 +0200
+@@ -91,3 +91,9 @@
+
+ return array->n_entries;
+ }
++
++void * const *pa_dynarray_get_raw_array(pa_dynarray *array) {
++ pa_assert(array);
++
++ return array->data;
++}
+--- a/src/pulsecore/dynarray.h 2016-04-13 16:25:43.225016112 +0200
++++ b/src/pulsecore/dynarray.h 2016-04-13 16:27:47.414015904 +0200
+@@ -52,5 +52,5 @@
+ void *pa_dynarray_steal_last(pa_dynarray *array);
+
+ unsigned pa_dynarray_size(pa_dynarray *array);
+-
++void * const *pa_dynarray_get_raw_array(pa_dynarray *array);
+ #endif
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0022-device-port-Add-pa_device_port.active.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0022-device-port-Add-pa_device_port.active.patch
new file mode 100644
index 000000000..4a8143f61
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0022-device-port-Add-pa_device_port.active.patch
@@ -0,0 +1,198 @@
+--- a/src/pulsecore/core.h 2016-04-13 16:38:56.392014788 +0200
++++ b/src/pulsecore/core.h 2016-04-13 16:41:50.331014498 +0200
+@@ -125,6 +125,7 @@
+ PA_CORE_HOOK_CARD_PROFILE_ADDED,
+ PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED,
+ PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
++ PA_CORE_HOOK_PORT_ACTIVE_CHANGED,
+ PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED,
+ PA_CORE_HOOK_MAX
+ } pa_core_hook_t;
+--- a/src/pulsecore/device-port.c 2016-04-13 16:39:37.411014719 +0200
++++ b/src/pulsecore/device-port.c 2016-04-13 17:06:47.393011999 +0200
+@@ -175,6 +175,21 @@
+ pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], p);
+ }
+
++void pa_device_port_active_changed(pa_device_port *port, bool new_active) {
++ bool old_active;
++
++ pa_assert(port);
++
++ old_active = port->active;
++
++ if (new_active == old_active)
++ return;
++
++ port->active = new_active;
++ pa_log_debug("Port %s %s.", port->name, new_active ? "activated" : "deactivated");
++ pa_hook_fire(&port->core->hooks[PA_CORE_HOOK_PORT_ACTIVE_CHANGED], port);
++}
++
+ pa_device_port *pa_device_port_find_best(pa_hashmap *ports)
+ {
+ void *state;
+--- a/src/pulsecore/device-port.h 2016-04-13 16:39:51.603014696 +0200
++++ b/src/pulsecore/device-port.h 2016-04-13 17:07:12.649011957 +0200
+@@ -46,6 +46,7 @@
+
+ unsigned priority;
+ pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
++ bool active;
+
+ pa_proplist *proplist;
+ pa_hashmap *profiles; /* Does not own the profiles */
+--- a/src/pulsecore/sink.c 2016-04-13 16:40:11.131014663 +0200
++++ b/src/pulsecore/sink.c 2016-04-13 17:14:30.963011225 +0200
+@@ -658,6 +658,9 @@
+ else
+ pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
+
++ if (s->active_port)
++ pa_device_port_active_changed(s->active_port, true);
++
+ pa_source_put(s->monitor_source);
+
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
+@@ -685,6 +688,9 @@
+ if (linked)
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
+
++ if (s->active_port)
++ pa_device_port_active_changed(s->active_port, false);
++
+ if (s->state != PA_SINK_UNLINKED)
+ pa_namereg_unregister(s->core, s->name);
+ pa_idxset_remove_by_data(s->core->sinks, s, NULL);
+@@ -3297,6 +3303,7 @@
+ /* Called from main context */
+ int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
+ pa_device_port *port;
++ pa_device_port *old_port;
+ int ret;
+
+ pa_sink_assert_ref(s);
+@@ -3313,11 +3320,15 @@
+ if (!(port = pa_hashmap_get(s->ports, name)))
+ return -PA_ERR_NOENTITY;
+
+- if (s->active_port == port) {
++ old_port = s->active_port;
++
++ if (port == old_port) {
+ s->save_port = s->save_port || save;
+ return 0;
+ }
+
++ pa_device_port_active_changed(old_port, false);
++
+ if (s->flags & PA_SINK_DEFERRED_VOLUME) {
+ struct sink_message_set_port msg = { .port = port, .ret = 0 };
+ pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+@@ -3326,17 +3337,26 @@
+ else
+ ret = s->set_port(s, port);
+
+- if (ret < 0)
+- return -PA_ERR_NOENTITY;
++ if (ret < 0) {
++ pa_log("Failed to set the port of sink %s from %s to %s.", s->name, old_port->name, port->name);
++
++ /* We don't know the real state of the device, but let's assume that
++ * the old port is still active, because s->active_port is left to
++ * point to the old port anyway. */
++ pa_device_port_active_changed(old_port, true);
++
++ return ret;
++ }
+
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+
+- pa_log_info("Changed port of sink %u \"%s\" to %s", s->index, s->name, port->name);
++ pa_log_info("Changed port of sink %u \"%s\" from %s to %s", s->index, s->name, old_port->name, port->name);
+
+ s->active_port = port;
+ s->save_port = save;
+
+ pa_sink_set_latency_offset(s, s->active_port->latency_offset);
++ pa_device_port_active_changed(port, true);
+
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
+
+--- a/src/pulsecore/source.c 2016-04-13 16:40:25.290014640 +0200
++++ b/src/pulsecore/source.c 2016-04-13 17:21:26.051010533 +0200
+@@ -603,6 +603,9 @@
+ else
+ pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
+
++ if (s->active_port)
++ pa_device_port_active_changed(s->active_port, true);
++
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
+ }
+@@ -623,6 +626,9 @@
+ if (linked)
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s);
+
++ if (s->active_port)
++ pa_device_port_active_changed(s->active_port, false);
++
+ if (s->state != PA_SOURCE_UNLINKED)
+ pa_namereg_unregister(s->core, s->name);
+ pa_idxset_remove_by_data(s->core->sources, s, NULL);
+@@ -2576,6 +2582,7 @@
+ /* Called from main context */
+ int pa_source_set_port(pa_source *s, const char *name, bool save) {
+ pa_device_port *port;
++ pa_device_port *old_port;
+ int ret;
+
+ pa_source_assert_ref(s);
+@@ -2592,11 +2599,15 @@
+ if (!(port = pa_hashmap_get(s->ports, name)))
+ return -PA_ERR_NOENTITY;
+
+- if (s->active_port == port) {
++ old_port = s->active_port;
++
++ if (port == old_port) {
+ s->save_port = s->save_port || save;
+ return 0;
+ }
+
++ pa_device_port_active_changed(old_port, false);
++
+ if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
+ struct source_message_set_port msg = { .port = port, .ret = 0 };
+ pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+@@ -2605,16 +2616,26 @@
+ else
+ ret = s->set_port(s, port);
+
+- if (ret < 0)
+- return -PA_ERR_NOENTITY;
++ if (ret < 0) {
++ pa_log("Failed to set the port of sink %s from %s to %s.", s->name, old_port->name, port->name);
++
++ /* We don't know the real state of the device, but let's assume that
++ * the old port is still active, because s->active_port is left to
++ * point to the old port anyway. */
++ pa_device_port_active_changed(old_port, true);
++
++ return ret;
++ }
+
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+
+- pa_log_info("Changed port of source %u \"%s\" to %s", s->index, s->name, port->name);
++ pa_log_info("Changed port of source %u \"%s\" from %s to %s", s->index, s->name, old_port->name, port->name);
+
+ s->active_port = port;
+ s->save_port = save;
+
++ pa_device_port_active_changed(port, true);
++
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
+
+ return 0;
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0030-volume-api-Add-libvolume-api.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0030-volume-api-Add-libvolume-api.patch
new file mode 100644
index 000000000..b904ac315
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0030-volume-api-Add-libvolume-api.patch
@@ -0,0 +1,6118 @@
+From 0223ac3e092249c792bedcab2bf5dbaec443f960 Mon Sep 17 00:00:00 2001
+From: Tanu Kaskinen <tanu.kaskinen@linux.intel.com>
+Date: Wed, 21 May 2014 11:51:27 +0300
+Subject: [PATCH 1/1] volume-api: Add libvolume-api.so
+
+This library implements the "core" of the new volume system, which
+will be used by several modules.
+
+Change-Id: Ib25ada1392e83237a3908e6064ee0ad6dff7afaf
+Signed-off-by: Jaska Uimonen <jaska.uimonen@intel.com>
+---
+ Makefile.am | 3 +
+ src/Makefile.am | 19 +-
+ src/map-file | 15 +
+ src/modules/volume-api/audio-group.c | 448 +++++++++++++
+ src/modules/volume-api/audio-group.h | 85 +++
+ src/modules/volume-api/binding.c | 386 +++++++++++
+ src/modules/volume-api/binding.h | 128 ++++
+ src/modules/volume-api/bvolume.h | 43 ++
+ src/modules/volume-api/device-creator.c | 1108 +++++++++++++++++++++++++++++++
+ src/modules/volume-api/device-creator.h | 32 +
+ src/modules/volume-api/device.c | 293 ++++++++
+ src/modules/volume-api/device.h | 76 +++
+ src/modules/volume-api/mute-control.c | 306 +++++++++
+ src/modules/volume-api/mute-control.h | 102 +++
+ src/modules/volume-api/sstream.c | 366 ++++++++++
+ src/modules/volume-api/sstream.h | 108 +++
+ src/modules/volume-api/stream-creator.c | 691 +++++++++++++++++++
+ src/modules/volume-api/stream-creator.h | 32 +
+ src/modules/volume-api/volume-api.c | 647 ++++++++++++++++++
+ src/modules/volume-api/volume-api.h | 163 +++++
+ src/modules/volume-api/volume-control.c | 363 ++++++++++
+ src/modules/volume-api/volume-control.h | 112 ++++
+ src/pulse/ext-volume-api.c | 275 ++++++++
+ src/pulse/ext-volume-api.h | 68 ++
+ 24 files changed, 5868 insertions(+), 1 deletion(-)
+ create mode 100644 src/modules/volume-api/audio-group.c
+ create mode 100644 src/modules/volume-api/audio-group.h
+ create mode 100644 src/modules/volume-api/binding.c
+ create mode 100644 src/modules/volume-api/binding.h
+ create mode 100644 src/modules/volume-api/bvolume.h
+ create mode 100644 src/modules/volume-api/device-creator.c
+ create mode 100644 src/modules/volume-api/device-creator.h
+ create mode 100644 src/modules/volume-api/device.c
+ create mode 100644 src/modules/volume-api/device.h
+ create mode 100644 src/modules/volume-api/mute-control.c
+ create mode 100644 src/modules/volume-api/mute-control.h
+ create mode 100644 src/modules/volume-api/sstream.c
+ create mode 100644 src/modules/volume-api/sstream.h
+ create mode 100644 src/modules/volume-api/stream-creator.c
+ create mode 100644 src/modules/volume-api/stream-creator.h
+ create mode 100644 src/modules/volume-api/volume-api.c
+ create mode 100644 src/modules/volume-api/volume-api.h
+ create mode 100644 src/modules/volume-api/volume-control.c
+ create mode 100644 src/modules/volume-api/volume-control.h
+ create mode 100644 src/pulse/ext-volume-api.c
+ create mode 100644 src/pulse/ext-volume-api.h
+
+diff --git a/Makefile.am b/Makefile.am
+index 9431d4a..cf4a648 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -57,6 +57,9 @@
+ moduledevinternal_DATA = src/pulse/internal.h src/pulse/client-conf.h src/pulse/fork-detect.h
+ moduledevinternaldir = $(includedir)/pulsemodule/pulse
+
++moduledevvolumeapi_DATA = $(top_srcdir)/src/modules/volume-api/*.h
++moduledevvolumeapidir = $(includedir)/pulsemodule/modules/volume-api
++
+ if HAVE_GLIB20
+ pkgconfig_DATA += \
+ libpulse-mainloop-glib.pc
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 22b9b81..bc41dca 100644
+--- a/src/Makefile.am 2016-04-13 15:51:34.439019531 +0200
++++ b/src/Makefile.am 2016-04-13 15:53:03.721019382 +0200
+@@ -792,6 +792,7 @@
+ pulse/ext-device-manager.h \
+ pulse/ext-device-restore.h \
+ pulse/ext-stream-restore.h \
++ pulse/ext-volume-api.h \
+ pulse/format.h \
+ pulse/gccmacro.h \
+ pulse/introspect.h \
+@@ -838,6 +839,7 @@
+ pulse/ext-device-manager.c pulse/ext-device-manager.h \
+ pulse/ext-device-restore.c pulse/ext-device-restore.h \
+ pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
++ pulse/ext-volume-api.c pulse/ext-volume-api.h \
+ pulse/format.c pulse/format.h \
+ pulse/gccmacro.h \
+ pulse/internal.h \
+@@ -1018,7 +1020,8 @@ modlibexec_LTLIBRARIES = \
+ libprotocol-cli.la \
+ libprotocol-simple.la \
+ libprotocol-http.la \
+- libprotocol-native.la
++ libprotocol-native.la \
++ libvolume-api.la
+
+ if HAVE_WEBRTC
+ modlibexec_LTLIBRARIES += libwebrtc-util.la
+@@ -1065,6 +1068,20 @@ libprotocol_native_la_CFLAGS += $(DBUS_CFLAGS)
+ libprotocol_native_la_LIBADD += $(DBUS_LIBS)
+ endif
+
++libvolume_api_la_SOURCES = \
++ modules/volume-api/audio-group.c modules/volume-api/audio-group.h \
++ modules/volume-api/binding.c modules/volume-api/binding.h \
++ modules/volume-api/bvolume.h \
++ modules/volume-api/device.c modules/volume-api/device.h \
++ modules/volume-api/device-creator.c modules/volume-api/device-creator.h \
++ modules/volume-api/mute-control.c modules/volume-api/mute-control.h \
++ modules/volume-api/sstream.c modules/volume-api/sstream.h \
++ modules/volume-api/stream-creator.c modules/volume-api/stream-creator.h \
++ modules/volume-api/volume-api.c modules/volume-api/volume-api.h \
++ modules/volume-api/volume-control.c modules/volume-api/volume-control.h
++libvolume_api_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
++libvolume_api_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
++
+ if HAVE_ESOUND
+ libprotocol_esound_la_SOURCES = pulsecore/protocol-esound.c pulsecore/protocol-esound.h pulsecore/esound.h
+ libprotocol_esound_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+diff --git a/src/map-file b/src/map-file
+index fbf3f22..1f64a2f 100644
+--- a/src/map-file
++++ b/src/map-file
+@@ -172,6 +172,21 @@
+ pa_ext_stream_restore_subscribe;
+ pa_ext_stream_restore_test;
+ pa_ext_stream_restore_write;
++pa_ext_volume_api_balance_valid;
++pa_ext_volume_api_bvolume_copy_balance;
++pa_ext_volume_api_bvolume_get_left_right_balance;
++pa_ext_volume_api_bvolume_get_rear_front_balance;
++pa_ext_volume_api_bvolume_equal;
++pa_ext_volume_api_bvolume_from_cvolume;
++pa_ext_volume_api_bvolume_init_invalid;
++pa_ext_volume_api_bvolume_init_mono;
++pa_ext_volume_api_bvolume_remap;
++pa_ext_volume_api_bvolume_reset_balance;
++pa_ext_volume_api_bvolume_set_left_right_balance;
++pa_ext_volume_api_bvolume_set_rear_front_balance;
++pa_ext_volume_api_bvolume_snprint_balance;
++pa_ext_volume_api_bvolume_to_cvolume;
++pa_ext_volume_api_bvolume_valid;
+ pa_format_info_copy;
+ pa_format_info_free;
+ pa_format_info_from_string;
+diff --git a/src/modules/volume-api/audio-group.c b/src/modules/volume-api/audio-group.c
+new file mode 100644
+index 0000000..76bfa69
+--- /dev/null
++++ b/src/modules/volume-api/audio-group.c
+@@ -0,0 +1,448 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "audio-group.h"
++
++#include <modules/volume-api/sstream.h>
++
++#include <pulsecore/core-util.h>
++
++int pa_audio_group_new(pa_volume_api *api, const char *name, const char *description, pa_audio_group **group) {
++ pa_audio_group *group_local;
++ int r;
++
++ pa_assert(api);
++ pa_assert(name);
++ pa_assert(description);
++ pa_assert(group);
++
++ group_local = pa_xnew0(pa_audio_group, 1);
++ group_local->volume_api = api;
++ group_local->index = pa_volume_api_allocate_audio_group_index(api);
++
++ r = pa_volume_api_register_name(api, name, true, &group_local->name);
++ if (r < 0)
++ goto fail;
++
++ group_local->description = pa_xstrdup(description);
++ group_local->proplist = pa_proplist_new();
++ group_local->volume_streams = pa_hashmap_new(NULL, NULL);
++ group_local->mute_streams = pa_hashmap_new(NULL, NULL);
++
++ *group = group_local;
++
++ return 0;
++
++fail:
++ pa_audio_group_free(group_local);
++
++ return r;
++}
++
++void pa_audio_group_put(pa_audio_group *group) {
++ const char *prop_key;
++ void *state = NULL;
++
++ pa_assert(group);
++
++ pa_volume_api_add_audio_group(group->volume_api, group);
++
++ group->linked = true;
++
++ pa_log_debug("Created audio group #%u.", group->index);
++ pa_log_debug(" Name: %s", group->name);
++ pa_log_debug(" Description: %s", group->description);
++ pa_log_debug(" Volume control: %s", group->volume_control ? group->volume_control->name : "(unset)");
++ pa_log_debug(" Mute control: %s", group->mute_control ? group->mute_control->name : "(unset)");
++ pa_log_debug(" Properties:");
++
++ while ((prop_key = pa_proplist_iterate(group->proplist, &state)))
++ pa_log_debug(" %s = %s", prop_key, pa_strnull(pa_proplist_gets(group->proplist, prop_key)));
++
++ pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT], group);
++}
++
++void pa_audio_group_unlink(pa_audio_group *group) {
++ pas_stream *stream;
++
++ pa_assert(group);
++
++ if (group->unlinked) {
++ pa_log_debug("Unlinking audio group %s (already unlinked, this is a no-op).", group->name);
++ return;
++ }
++
++ group->unlinked = true;
++
++ pa_log_debug("Unlinking audio group %s.", group->name);
++
++ if (group->linked)
++ pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK], group);
++
++ pa_volume_api_remove_audio_group(group->volume_api, group);
++
++ while ((stream = pa_hashmap_first(group->mute_streams)))
++ pas_stream_set_audio_group_for_mute(stream, NULL);
++
++ while ((stream = pa_hashmap_first(group->volume_streams)))
++ pas_stream_set_audio_group_for_volume(stream, NULL);
++
++ if (group->mute_control_binding) {
++ pa_binding_free(group->mute_control_binding);
++ group->mute_control_binding = NULL;
++ }
++
++ if (group->volume_control_binding) {
++ pa_binding_free(group->volume_control_binding);
++ group->volume_control_binding = NULL;
++ }
++
++ pa_audio_group_set_have_own_mute_control(group, false);
++ pa_audio_group_set_have_own_volume_control(group, false);
++
++ if (group->mute_control) {
++ pa_mute_control_remove_audio_group(group->mute_control, group);
++ group->mute_control = NULL;
++ }
++
++ if (group->volume_control) {
++ pa_volume_control_remove_audio_group(group->volume_control, group);
++ group->volume_control = NULL;
++ }
++}
++
++void pa_audio_group_free(pa_audio_group *group) {
++ pa_assert(group);
++
++ if (!group->unlinked)
++ pa_audio_group_unlink(group);
++
++ if (group->mute_streams)
++ pa_hashmap_free(group->mute_streams);
++
++ if (group->volume_streams)
++ pa_hashmap_free(group->volume_streams);
++
++ if (group->proplist)
++ pa_proplist_free(group->proplist);
++
++ pa_xfree(group->description);
++
++ if (group->name)
++ pa_volume_api_unregister_name(group->volume_api, group->name);
++
++ pa_xfree(group);
++}
++
++const char *pa_audio_group_get_name(pa_audio_group *group) {
++ pa_assert(group);
++
++ return group->name;
++}
++
++static int volume_control_set_volume_cb(pa_volume_control *control, const pa_bvolume *volume, bool set_volume,
++ bool set_balance) {
++ pa_audio_group *group;
++ pas_stream *stream;
++ void *state;
++
++ pa_assert(control);
++ pa_assert(volume);
++
++ group = control->userdata;
++
++ PA_HASHMAP_FOREACH(stream, group->volume_streams, state) {
++ if (stream->own_volume_control)
++ pa_volume_control_set_volume(stream->own_volume_control, volume, set_volume, set_balance);
++ }
++
++ return 0;
++}
++
++static void volume_control_set_initial_volume_cb(pa_volume_control *control) {
++ pa_audio_group *group;
++ pas_stream *stream;
++ void *state;
++
++ pa_assert(control);
++
++ group = control->userdata;
++
++ PA_HASHMAP_FOREACH(stream, group->volume_streams, state) {
++ if (stream->own_volume_control)
++ pa_volume_control_set_volume(stream->own_volume_control, &control->volume, true, true);
++ }
++}
++
++void pa_audio_group_set_have_own_volume_control(pa_audio_group *group, bool have) {
++ pa_assert(group);
++
++ if (have == group->have_own_volume_control)
++ return;
++
++ if (have) {
++ pa_bvolume initial_volume;
++
++ if (group->volume_api->core->flat_volumes)
++ /* Usually the initial volume should get overridden by some module
++ * that manages audio group volume levels, but if there's no such
++ * module, let's try to avoid too high volume in flat volume
++ * mode. */
++ pa_bvolume_init_mono(&initial_volume, 0.3 * PA_VOLUME_NORM);
++ else
++ pa_bvolume_init_mono(&initial_volume, PA_VOLUME_NORM);
++
++ pa_assert(!group->own_volume_control);
++ group->own_volume_control = pa_volume_control_new(group->volume_api, "audio-group-volume-control",
++ group->description, false, false);
++ pa_volume_control_set_owner_audio_group(group->own_volume_control, group);
++ group->own_volume_control->set_volume = volume_control_set_volume_cb;
++ group->own_volume_control->userdata = group;
++ pa_volume_control_put(group->own_volume_control, &initial_volume, volume_control_set_initial_volume_cb);
++ } else {
++ pa_volume_control_free(group->own_volume_control);
++ group->own_volume_control = NULL;
++ }
++
++ group->have_own_volume_control = have;
++}
++
++static int mute_control_set_mute_cb(pa_mute_control *control, bool mute) {
++ pa_audio_group *group;
++ pas_stream *stream;
++ void *state;
++
++ pa_assert(control);
++
++ group = control->userdata;
++
++ PA_HASHMAP_FOREACH(stream, group->mute_streams, state) {
++ if (stream->own_mute_control)
++ pa_mute_control_set_mute(stream->own_mute_control, mute);
++ }
++
++ return 0;
++}
++
++static void mute_control_set_initial_mute_cb(pa_mute_control *control) {
++ pa_audio_group *group;
++ pas_stream *stream;
++ void *state;
++
++ pa_assert(control);
++
++ group = control->userdata;
++
++ PA_HASHMAP_FOREACH(stream, group->mute_streams, state) {
++ if (stream->own_mute_control)
++ pa_mute_control_set_mute(stream->own_mute_control, control->mute);
++ }
++}
++
++void pa_audio_group_set_have_own_mute_control(pa_audio_group *group, bool have) {
++ pa_assert(group);
++
++ if (have == group->have_own_mute_control)
++ return;
++
++ group->have_own_mute_control = have;
++
++ if (have) {
++ pa_assert(!group->own_mute_control);
++ group->own_mute_control = pa_mute_control_new(group->volume_api, "audio-group-mute-control", group->description);
++ pa_mute_control_set_owner_audio_group(group->own_mute_control, group);
++ group->own_mute_control->set_mute = mute_control_set_mute_cb;
++ group->own_mute_control->userdata = group;
++ pa_mute_control_put(group->own_mute_control, false, true, mute_control_set_initial_mute_cb);
++ } else {
++ pa_mute_control_free(group->own_mute_control);
++ group->own_mute_control = NULL;
++ }
++}
++
++static void set_volume_control_internal(pa_audio_group *group, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(group);
++
++ old_control = group->volume_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control)
++ pa_volume_control_remove_audio_group(old_control, group);
++
++ group->volume_control = control;
++
++ if (control)
++ pa_volume_control_add_audio_group(control, group);
++
++ if (!group->linked || group->unlinked)
++ return;
++
++ pa_log_debug("The volume control of audio group %s changed from %s to %s.", group->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_VOLUME_CONTROL_CHANGED], group);
++}
++
++void pa_audio_group_set_volume_control(pa_audio_group *group, pa_volume_control *control) {
++ pa_assert(group);
++
++ if (group->volume_control_binding) {
++ pa_binding_free(group->volume_control_binding);
++ group->volume_control_binding = NULL;
++ }
++
++ set_volume_control_internal(group, control);
++}
++
++static void set_mute_control_internal(pa_audio_group *group, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(group);
++
++ old_control = group->mute_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control)
++ pa_mute_control_remove_audio_group(old_control, group);
++
++ group->mute_control = control;
++
++ if (control)
++ pa_mute_control_add_audio_group(control, group);
++
++ if (!group->linked || group->unlinked)
++ return;
++
++ pa_log_debug("The mute control of audio group %s changed from %s to %s.", group->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_MUTE_CONTROL_CHANGED], group);
++}
++
++void pa_audio_group_set_mute_control(pa_audio_group *group, pa_mute_control *control) {
++ pa_assert(group);
++
++ if (group->mute_control_binding) {
++ pa_binding_free(group->mute_control_binding);
++ group->mute_control_binding = NULL;
++ }
++
++ set_mute_control_internal(group, control);
++}
++
++void pa_audio_group_bind_volume_control(pa_audio_group *group, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = group,
++ .set_value = (pa_binding_set_value_cb_t) set_volume_control_internal,
++ };
++
++ pa_assert(group);
++ pa_assert(target_info);
++
++ if (group->volume_control_binding)
++ pa_binding_free(group->volume_control_binding);
++
++ group->volume_control_binding = pa_binding_new(group->volume_api, &owner_info, target_info);
++}
++
++void pa_audio_group_bind_mute_control(pa_audio_group *group, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = group,
++ .set_value = (pa_binding_set_value_cb_t) set_mute_control_internal,
++ };
++
++ pa_assert(group);
++ pa_assert(target_info);
++
++ if (group->mute_control_binding)
++ pa_binding_free(group->mute_control_binding);
++
++ group->mute_control_binding = pa_binding_new(group->volume_api, &owner_info, target_info);
++}
++
++void pa_audio_group_add_volume_stream(pa_audio_group *group, pas_stream *stream) {
++ pa_assert(group);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_put(group->volume_streams, stream, stream) >= 0);
++
++ if (stream->own_volume_control && group->own_volume_control)
++ pa_volume_control_set_volume(stream->own_volume_control, &group->own_volume_control->volume, true, true);
++
++ pa_log_debug("Stream %s added to audio group %s (volume).", stream->name, group->name);
++}
++
++void pa_audio_group_remove_volume_stream(pa_audio_group *group, pas_stream *stream) {
++ pa_assert(group);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_remove(group->volume_streams, stream));
++
++ pa_log_debug("Stream %s removed from audio group %s (volume).", stream->name, group->name);
++}
++
++void pa_audio_group_add_mute_stream(pa_audio_group *group, pas_stream *stream) {
++ pa_assert(group);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_put(group->mute_streams, stream, stream) >= 0);
++
++ if (stream->own_mute_control && group->own_mute_control)
++ pa_mute_control_set_mute(stream->own_mute_control, group->own_mute_control->mute);
++
++ pa_log_debug("Stream %s added to audio group %s (mute).", stream->name, group->name);
++}
++
++void pa_audio_group_remove_mute_stream(pa_audio_group *group, pas_stream *stream) {
++ pa_assert(group);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_remove(group->mute_streams, stream));
++
++ pa_log_debug("Stream %s removed from audio group %s (mute).", stream->name, group->name);
++}
++
++pa_binding_target_type *pa_audio_group_create_binding_target_type(pa_volume_api *api) {
++ pa_binding_target_type *type;
++
++ pa_assert(api);
++
++ type = pa_binding_target_type_new(PA_AUDIO_GROUP_BINDING_TARGET_TYPE, api->audio_groups,
++ &api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT],
++ &api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK],
++ (pa_binding_target_type_get_name_cb_t) pa_audio_group_get_name);
++ pa_binding_target_type_add_field(type, PA_AUDIO_GROUP_BINDING_TARGET_FIELD_VOLUME_CONTROL,
++ PA_BINDING_CALCULATE_FIELD_OFFSET(pa_audio_group, volume_control));
++ pa_binding_target_type_add_field(type, PA_AUDIO_GROUP_BINDING_TARGET_FIELD_MUTE_CONTROL,
++ PA_BINDING_CALCULATE_FIELD_OFFSET(pa_audio_group, mute_control));
++
++ return type;
++}
+diff --git a/src/modules/volume-api/audio-group.h b/src/modules/volume-api/audio-group.h
+new file mode 100644
+index 0000000..41591ba
+--- /dev/null
++++ b/src/modules/volume-api/audio-group.h
+@@ -0,0 +1,85 @@
++#ifndef fooaudiogrouphfoo
++#define fooaudiogrouphfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/binding.h>
++#include <modules/volume-api/mute-control.h>
++#include <modules/volume-api/volume-control.h>
++
++#include <pulse/proplist.h>
++
++#include <inttypes.h>
++
++typedef struct pa_audio_group pa_audio_group;
++
++#define PA_AUDIO_GROUP_BINDING_TARGET_TYPE "AudioGroup"
++#define PA_AUDIO_GROUP_BINDING_TARGET_FIELD_VOLUME_CONTROL "volume_control"
++#define PA_AUDIO_GROUP_BINDING_TARGET_FIELD_MUTE_CONTROL "mute_control"
++
++struct pa_audio_group {
++ pa_volume_api *volume_api;
++ uint32_t index;
++ const char *name;
++ char *description;
++ pa_proplist *proplist;
++ pa_volume_control *volume_control;
++ pa_mute_control *mute_control;
++ bool have_own_volume_control;
++ bool have_own_mute_control;
++ pa_volume_control *own_volume_control;
++ pa_mute_control *own_mute_control;
++
++ pa_binding *volume_control_binding;
++ pa_binding *mute_control_binding;
++ pa_hashmap *volume_streams; /* pas_stream -> pas_stream (hashmap-as-a-set) */
++ pa_hashmap *mute_streams; /* pas_stream -> pas_stream (hashmap-as-a-set) */
++
++ bool linked;
++ bool unlinked;
++};
++
++int pa_audio_group_new(pa_volume_api *api, const char *name, const char *description, pa_audio_group **group);
++void pa_audio_group_put(pa_audio_group *group);
++void pa_audio_group_unlink(pa_audio_group *group);
++void pa_audio_group_free(pa_audio_group *group);
++
++const char *pa_audio_group_get_name(pa_audio_group *group);
++
++/* Called by policy modules. */
++void pa_audio_group_set_have_own_volume_control(pa_audio_group *group, bool have);
++void pa_audio_group_set_have_own_mute_control(pa_audio_group *group, bool have);
++void pa_audio_group_set_volume_control(pa_audio_group *group, pa_volume_control *control);
++void pa_audio_group_set_mute_control(pa_audio_group *group, pa_mute_control *control);
++void pa_audio_group_bind_volume_control(pa_audio_group *group, pa_binding_target_info *target_info);
++void pa_audio_group_bind_mute_control(pa_audio_group *group, pa_binding_target_info *target_info);
++
++/* Called from sstream.c only. */
++void pa_audio_group_add_volume_stream(pa_audio_group *group, pas_stream *stream);
++void pa_audio_group_remove_volume_stream(pa_audio_group *group, pas_stream *stream);
++void pa_audio_group_add_mute_stream(pa_audio_group *group, pas_stream *stream);
++void pa_audio_group_remove_mute_stream(pa_audio_group *group, pas_stream *stream);
++
++/* Called from volume-api.c only. */
++pa_binding_target_type *pa_audio_group_create_binding_target_type(pa_volume_api *api);
++
++#endif
+diff --git a/src/modules/volume-api/binding.c b/src/modules/volume-api/binding.c
+new file mode 100644
+index 0000000..6e73119
+--- /dev/null
++++ b/src/modules/volume-api/binding.c
+@@ -0,0 +1,386 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "binding.h"
++
++#include <pulse/def.h>
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core-util.h>
++#include <pulsecore/macro.h>
++
++struct field_entry {
++ char *name;
++ size_t offset;
++};
++
++static void set_target_type(pa_binding *binding, pa_binding_target_type *type);
++static void set_target_object(pa_binding *binding, void *object);
++
++pa_binding_owner_info *pa_binding_owner_info_new(pa_binding_set_value_cb_t set_value, void *userdata) {
++ pa_binding_owner_info *info;
++
++ pa_assert(set_value);
++
++ info = pa_xnew0(pa_binding_owner_info, 1);
++ info->set_value = set_value;
++ info->userdata = userdata;
++
++ return info;
++}
++
++pa_binding_owner_info *pa_binding_owner_info_copy(const pa_binding_owner_info *info) {
++ pa_assert(info);
++
++ return pa_binding_owner_info_new(info->set_value, info->userdata);
++}
++
++void pa_binding_owner_info_free(pa_binding_owner_info *info) {
++ pa_assert(info);
++
++ pa_xfree(info);
++}
++
++pa_binding_target_info *pa_binding_target_info_new(const char *type, const char *name, const char *field) {
++ pa_binding_target_info *info;
++
++ pa_assert(type);
++ pa_assert(name);
++ pa_assert(field);
++
++ info = pa_xnew0(pa_binding_target_info, 1);
++ info->type = pa_xstrdup(type);
++ info->name = pa_xstrdup(name);
++ info->field = pa_xstrdup(field);
++
++ return info;
++}
++
++int pa_binding_target_info_new_from_string(const char *str, const char *field, pa_binding_target_info **info) {
++ const char *colon;
++ char *type = NULL;
++ char *name = NULL;
++
++ pa_assert(str);
++ pa_assert(field);
++ pa_assert(info);
++
++ if (!pa_startswith(str, "bind:"))
++ goto fail;
++
++ colon = strchr(str + 5, ':');
++ if (!colon)
++ goto fail;
++
++ type = pa_xstrndup(str + 5, colon - (str + 5));
++
++ if (!*type)
++ goto fail;
++
++ name = pa_xstrdup(colon + 1);
++
++ if (!*name)
++ goto fail;
++
++ *info = pa_binding_target_info_new(type, name, field);
++ pa_xfree(name);
++ pa_xfree(type);
++
++ return 0;
++
++fail:
++ pa_log("Invalid binding target: %s", str);
++ pa_xfree(name);
++ pa_xfree(type);
++
++ return -PA_ERR_INVALID;
++}
++
++pa_binding_target_info *pa_binding_target_info_copy(const pa_binding_target_info *info) {
++ pa_assert(info);
++
++ return pa_binding_target_info_new(info->type, info->name, info->field);
++}
++
++void pa_binding_target_info_free(pa_binding_target_info *info) {
++ pa_assert(info);
++
++ pa_xfree(info->field);
++ pa_xfree(info->name);
++ pa_xfree(info->type);
++ pa_xfree(info);
++}
++
++static void field_entry_free(struct field_entry *entry) {
++ pa_assert(entry);
++
++ pa_xfree(entry->name);
++ pa_xfree(entry);
++}
++
++pa_binding_target_type *pa_binding_target_type_new(const char *name, pa_hashmap *objects, pa_hook *put_hook,
++ pa_hook *unlink_hook, pa_binding_target_type_get_name_cb_t get_name) {
++ pa_binding_target_type *type;
++
++ pa_assert(name);
++ pa_assert(objects);
++ pa_assert(put_hook);
++ pa_assert(unlink_hook);
++ pa_assert(get_name);
++
++ type = pa_xnew0(pa_binding_target_type, 1);
++ type->name = pa_xstrdup(name);
++ type->objects = objects;
++ type->put_hook = put_hook;
++ type->unlink_hook = unlink_hook;
++ type->get_name = get_name;
++ type->fields = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) field_entry_free);
++
++ return type;
++}
++
++void pa_binding_target_type_free(pa_binding_target_type *type) {
++ pa_assert(type);
++
++ if (type->fields)
++ pa_hashmap_free(type->fields);
++
++ pa_xfree(type->name);
++ pa_xfree(type);
++}
++
++void pa_binding_target_type_add_field(pa_binding_target_type *type, const char *name, size_t offset) {
++ struct field_entry *entry;
++
++ pa_assert(type);
++ pa_assert(name);
++
++ entry = pa_xnew0(struct field_entry, 1);
++ entry->name = pa_xstrdup(name);
++ entry->offset = offset;
++
++ pa_assert_se(pa_hashmap_put(type->fields, entry->name, entry) >= 0);
++}
++
++int pa_binding_target_type_get_field_offset(pa_binding_target_type *type, const char *field, size_t *offset) {
++ struct field_entry *entry;
++
++ pa_assert(type);
++ pa_assert(field);
++ pa_assert(offset);
++
++ entry = pa_hashmap_get(type->fields, field);
++ if (!entry)
++ return -PA_ERR_NOENTITY;
++
++ *offset = entry->offset;
++
++ return 0;
++}
++
++static pa_hook_result_t target_type_added_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_binding_target_type *type = call_data;
++ pa_binding *binding = userdata;
++
++ pa_assert(type);
++ pa_assert(binding);
++
++ if (!pa_streq(type->name, binding->target_info->type))
++ return PA_HOOK_OK;
++
++ set_target_type(binding, type);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t target_type_removed_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_binding_target_type *type = call_data;
++ pa_binding *binding = userdata;
++
++ pa_assert(type);
++ pa_assert(binding);
++
++ if (type != binding->target_type)
++ return PA_HOOK_OK;
++
++ set_target_type(binding, NULL);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t target_put_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_binding *binding = userdata;
++
++ pa_assert(call_data);
++ pa_assert(binding);
++
++ if (!pa_streq(binding->target_type->get_name(call_data), binding->target_info->name))
++ return PA_HOOK_OK;
++
++ set_target_object(binding, call_data);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t target_unlink_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_binding *binding = userdata;
++
++ pa_assert(call_data);
++ pa_assert(binding);
++
++ if (call_data != binding->target_object)
++ return PA_HOOK_OK;
++
++ set_target_object(binding, NULL);
++
++ return PA_HOOK_OK;
++}
++
++static void set_target_object(pa_binding *binding, void *object) {
++ pa_assert(binding);
++
++ binding->target_object = object;
++
++ if (object) {
++ if (binding->target_put_slot) {
++ pa_hook_slot_free(binding->target_put_slot);
++ binding->target_put_slot = NULL;
++ }
++
++ if (!binding->target_unlink_slot)
++ binding->target_unlink_slot = pa_hook_connect(binding->target_type->unlink_hook, PA_HOOK_NORMAL, target_unlink_cb,
++ binding);
++
++ if (binding->target_field_offset_valid)
++ binding->owner_info->set_value(binding->owner_info->userdata,
++ *((void **) (((uint8_t *) object) + binding->target_field_offset)));
++ else
++ binding->owner_info->set_value(binding->owner_info->userdata, NULL);
++ } else {
++ if (binding->target_unlink_slot) {
++ pa_hook_slot_free(binding->target_unlink_slot);
++ binding->target_unlink_slot = NULL;
++ }
++
++ if (binding->target_type) {
++ if (!binding->target_put_slot)
++ binding->target_put_slot = pa_hook_connect(binding->target_type->put_hook, PA_HOOK_NORMAL, target_put_cb, binding);
++ } else {
++ if (binding->target_put_slot) {
++ pa_hook_slot_free(binding->target_put_slot);
++ binding->target_put_slot = NULL;
++ }
++ }
++
++ binding->owner_info->set_value(binding->owner_info->userdata, NULL);
++ }
++}
++
++static void set_target_type(pa_binding *binding, pa_binding_target_type *type) {
++ pa_assert(binding);
++
++ binding->target_type = type;
++
++ if (type) {
++ int r;
++
++ if (binding->target_type_added_slot) {
++ pa_hook_slot_free(binding->target_type_added_slot);
++ binding->target_type_added_slot = NULL;
++ }
++
++ if (!binding->target_type_removed_slot)
++ binding->target_type_removed_slot =
++ pa_hook_connect(&binding->volume_api->hooks[PA_VOLUME_API_HOOK_BINDING_TARGET_TYPE_REMOVED],
++ PA_HOOK_NORMAL, target_type_removed_cb, binding);
++
++ r = pa_binding_target_type_get_field_offset(type, binding->target_info->field, &binding->target_field_offset);
++ if (r >= 0)
++ binding->target_field_offset_valid = true;
++ else {
++ pa_log_warn("Reference to non-existing field \"%s\" in binding target type \"%s\".", binding->target_info->field,
++ type->name);
++ binding->target_field_offset_valid = false;
++ }
++
++ set_target_object(binding, pa_hashmap_get(type->objects, binding->target_info->name));
++ } else {
++ if (binding->target_type_removed_slot) {
++ pa_hook_slot_free(binding->target_type_removed_slot);
++ binding->target_type_removed_slot = NULL;
++ }
++
++ if (!binding->target_type_added_slot)
++ binding->target_type_added_slot =
++ pa_hook_connect(&binding->volume_api->hooks[PA_VOLUME_API_HOOK_BINDING_TARGET_TYPE_ADDED],
++ PA_HOOK_NORMAL, target_type_added_cb, binding);
++
++ binding->target_field_offset_valid = false;
++
++ set_target_object(binding, NULL);
++ }
++}
++
++pa_binding *pa_binding_new(pa_volume_api *api, const pa_binding_owner_info *owner_info,
++ const pa_binding_target_info *target_info) {
++ pa_binding *binding;
++
++ pa_assert(api);
++ pa_assert(owner_info);
++ pa_assert(target_info);
++
++ binding = pa_xnew0(pa_binding, 1);
++ binding->volume_api = api;
++ binding->owner_info = pa_binding_owner_info_copy(owner_info);
++ binding->target_info = pa_binding_target_info_copy(target_info);
++
++ set_target_type(binding, pa_hashmap_get(api->binding_target_types, target_info->type));
++
++ return binding;
++}
++
++void pa_binding_free(pa_binding *binding) {
++ pa_assert(binding);
++
++ if (binding->target_unlink_slot)
++ pa_hook_slot_free(binding->target_unlink_slot);
++
++ if (binding->target_put_slot)
++ pa_hook_slot_free(binding->target_put_slot);
++
++ if (binding->target_type_removed_slot)
++ pa_hook_slot_free(binding->target_type_removed_slot);
++
++ if (binding->target_type_added_slot)
++ pa_hook_slot_free(binding->target_type_added_slot);
++
++ if (binding->target_info)
++ pa_binding_target_info_free(binding->target_info);
++
++ if (binding->owner_info)
++ pa_binding_owner_info_free(binding->owner_info);
++
++ pa_xfree(binding);
++}
+diff --git a/src/modules/volume-api/binding.h b/src/modules/volume-api/binding.h
+new file mode 100644
+index 0000000..ba4dea8
+--- /dev/null
++++ b/src/modules/volume-api/binding.h
+@@ -0,0 +1,128 @@
++#ifndef foobindinghfoo
++#define foobindinghfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/volume-api.h>
++
++typedef struct pa_binding pa_binding;
++typedef struct pa_binding_owner_info pa_binding_owner_info;
++typedef struct pa_binding_target_info pa_binding_target_info;
++typedef struct pa_binding_target_type pa_binding_target_type;
++
++typedef void (*pa_binding_set_value_cb_t)(void *userdata, void *value);
++
++struct pa_binding_owner_info {
++ /* This is the object that has the variable that the binding is created
++ * for. */
++ void *userdata;
++
++ /* Called when the owner object's value needs to be updated. The userdata
++ * parameter of the callback is the same as the userdata field in this
++ * struct, and the value parameter is the new value for whatever variable
++ * the binding was created for. */
++ pa_binding_set_value_cb_t set_value;
++};
++
++pa_binding_owner_info *pa_binding_owner_info_new(pa_binding_set_value_cb_t set_value, void *userdata);
++pa_binding_owner_info *pa_binding_owner_info_copy(const pa_binding_owner_info *info);
++void pa_binding_owner_info_free(pa_binding_owner_info *info);
++
++struct pa_binding_target_info {
++ /* The target type name as registered with
++ * pa_binding_target_type_register(). */
++ char *type;
++
++ /* The target object name as returned by the get_name callback of
++ * pa_binding_target_type. */
++ char *name;
++
++ /* The target field of the target object. */
++ char *field;
++};
++
++pa_binding_target_info *pa_binding_target_info_new(const char *type, const char *name, const char *field);
++
++/* The string format is "bind:TYPE:NAME". */
++int pa_binding_target_info_new_from_string(const char *str, const char *field, pa_binding_target_info **info);
++
++pa_binding_target_info *pa_binding_target_info_copy(const pa_binding_target_info *info);
++void pa_binding_target_info_free(pa_binding_target_info *info);
++
++typedef const char *(*pa_binding_target_type_get_name_cb_t)(void *object);
++
++struct pa_binding_target_type {
++ /* Identifier for this target type. */
++ char *name;
++
++ /* name -> object. Points directly to some "master" object hashmap, so the
++ * hashmap is not owned by pa_binding_target_type. */
++ pa_hashmap *objects;
++
++ /* The hook that notifies of new objects if this target type. The call data
++ * of the hook must be a pointer to the new object (this should be true for
++ * all PUT hooks, so don't worry too much). */
++ pa_hook *put_hook;
++
++ /* The hook that notifies of unlinked objects of this target type. The call
++ * data of the hook must be a pointer to the removed object (this should be
++ * true for all UNLINK hooks, so don't worry too much). */
++ pa_hook *unlink_hook;
++
++ /* Function for getting the name of an object of this target type. */
++ pa_binding_target_type_get_name_cb_t get_name;
++
++ pa_hashmap *fields;
++};
++
++pa_binding_target_type *pa_binding_target_type_new(const char *name, pa_hashmap *objects, pa_hook *put_hook,
++ pa_hook *unlink_hook, pa_binding_target_type_get_name_cb_t get_name);
++void pa_binding_target_type_free(pa_binding_target_type *type);
++
++/* Useful when calling pa_binding_target_type_add_field(). */
++#define PA_BINDING_CALCULATE_FIELD_OFFSET(type, field) ((size_t) &(((type *) 0)->field))
++
++/* Called during the type initialization (right after
++ * pa_binding_target_type_new()). */
++void pa_binding_target_type_add_field(pa_binding_target_type *type, const char *name, size_t offset);
++
++int pa_binding_target_type_get_field_offset(pa_binding_target_type *type, const char *field, size_t *offset);
++
++struct pa_binding {
++ pa_volume_api *volume_api;
++ pa_binding_owner_info *owner_info;
++ pa_binding_target_info *target_info;
++ pa_binding_target_type *target_type;
++ void *target_object;
++ size_t target_field_offset;
++ bool target_field_offset_valid;
++ pa_hook_slot *target_type_added_slot;
++ pa_hook_slot *target_type_removed_slot;
++ pa_hook_slot *target_put_slot;
++ pa_hook_slot *target_unlink_slot;
++};
++
++pa_binding *pa_binding_new(pa_volume_api *api, const pa_binding_owner_info *owner_info,
++ const pa_binding_target_info *target_info);
++void pa_binding_free(pa_binding *binding);
++
++#endif
+diff --git a/src/modules/volume-api/bvolume.h b/src/modules/volume-api/bvolume.h
+new file mode 100644
+index 0000000..0317fb6
+--- /dev/null
++++ b/src/modules/volume-api/bvolume.h
+@@ -0,0 +1,43 @@
++#ifndef foobvolumehfoo
++#define foobvolumehfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <pulse/ext-volume-api.h>
++
++typedef pa_ext_volume_api_bvolume pa_bvolume;
++
++#define pa_balance_valid pa_ext_volume_api_balance_valid
++#define pa_bvolume_valid pa_ext_volume_api_bvolume_valid
++#define pa_bvolume_init_invalid pa_ext_volume_api_bvolume_init_invalid
++#define pa_bvolume_init_mono pa_ext_volume_api_bvolume_init_mono
++#define pa_bvolume_equal pa_ext_volume_api_bvolume_equal
++#define pa_bvolume_from_cvolume pa_ext_volume_api_bvolume_from_cvolume
++#define pa_bvolume_to_cvolume pa_ext_volume_api_bvolume_to_cvolume
++#define pa_bvolume_copy_balance pa_ext_volume_api_bvolume_copy_balance
++#define pa_bvolume_reset_balance pa_ext_volume_api_bvolume_reset_balance
++#define pa_bvolume_remap pa_ext_volume_api_bvolume_remap
++
++#define PA_BVOLUME_SNPRINT_BALANCE_MAX PA_EXT_VOLUME_API_BVOLUME_SNPRINT_BALANCE_MAX
++#define pa_bvolume_snprint_balance pa_ext_volume_api_bvolume_snprint_balance
++
++#endif
+diff --git a/src/modules/volume-api/device-creator.c b/src/modules/volume-api/device-creator.c
+new file mode 100644
+index 0000000..1d912ba
+--- /dev/null
++++ b/src/modules/volume-api/device-creator.c
+@@ -0,0 +1,1108 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "device-creator.h"
++
++#include <modules/volume-api/device.h>
++#include <modules/volume-api/mute-control.h>
++#include <modules/volume-api/volume-control.h>
++
++#include <pulsecore/core-util.h>
++#include <pulsecore/i18n.h>
++
++struct pa_device_creator {
++ pa_volume_api *volume_api;
++ pa_hashmap *devices; /* pa_device_port/pa_sink/pa_source -> struct device */
++ pa_hook_slot *card_put_slot;
++ pa_hook_slot *card_unlink_slot;
++ pa_hook_slot *sink_put_slot;
++ pa_hook_slot *sink_unlink_slot;
++ pa_hook_slot *source_put_slot;
++ pa_hook_slot *source_unlink_slot;
++};
++
++enum device_type {
++ DEVICE_TYPE_PORT,
++ DEVICE_TYPE_PORT_MONITOR,
++ DEVICE_TYPE_SINK,
++ DEVICE_TYPE_SOURCE,
++};
++
++struct device_volume_control {
++ struct device *device;
++ pa_volume_control *volume_control;
++
++ bool unlinked;
++
++ pa_hook_slot *volume_changed_slot;
++};
++
++struct device_mute_control {
++ struct device *device;
++ pa_mute_control *mute_control;
++
++ bool unlinked;
++
++ pa_hook_slot *mute_changed_slot;
++};
++
++struct device {
++ pa_device_creator *creator;
++ enum device_type type;
++ pa_device_port *port;
++ pa_sink *sink;
++ pa_source *source;
++ pa_device *device;
++ struct device_volume_control *volume_control;
++ struct device_mute_control *mute_control;
++
++ bool unlinked;
++
++ pa_hook_slot *proplist_changed_slot;
++ pa_hook_slot *port_active_changed_slot;
++ struct device *monitor;
++};
++
++static const char *device_type_from_icon_name(const char *icon_name) {
++ if (!icon_name)
++ return NULL;
++
++ if (pa_streq(icon_name, "audio-input-microphone"))
++ return "microphone";
++
++ if (pa_streq(icon_name, "audio-speakers"))
++ return "speakers";
++
++ if (pa_streq(icon_name, "audio-headphones"))
++ return "headphones";
++
++ return NULL;
++}
++
++static const char *device_type_from_port_name(pa_device_port *port) {
++ pa_assert(port);
++
++ if (strstr(port->name, "analog")) {
++ if (port->direction == PA_DIRECTION_INPUT)
++ return "analog-input";
++ else
++ return "analog-output";
++ }
++
++ if (strstr(port->name, "hdmi")) {
++ if (port->direction == PA_DIRECTION_INPUT)
++ return "hdmi-input";
++ else
++ return "hdmi-output";
++ }
++
++ if (strstr(port->name, "iec958")) {
++ if (port->direction == PA_DIRECTION_INPUT)
++ return "spdif-input";
++ else
++ return "spdif-output";
++ }
++
++ return NULL;
++}
++
++static const char *device_type_from_port(pa_device_port *port) {
++ const char *device_type;
++
++ pa_assert(port);
++
++ device_type = device_type_from_icon_name(pa_proplist_gets(port->proplist, PA_PROP_DEVICE_ICON_NAME));
++ if (device_type)
++ return device_type;
++
++ device_type = device_type_from_port_name(port);
++ if (device_type)
++ return device_type;
++
++ return NULL;
++}
++
++static const char *get_sink_description(pa_sink *sink) {
++ const char *description;
++
++ pa_assert(sink);
++
++ description = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
++ if (description)
++ return description;
++
++ return sink->name;
++}
++
++static const char *get_source_description(pa_source *source) {
++ const char *description;
++
++ pa_assert(source);
++
++ description = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION);
++ if (description)
++ return description;
++
++ return source->name;
++}
++
++static int volume_control_set_volume_cb(pa_volume_control *c, const pa_bvolume *volume, bool set_volume, bool set_balance) {
++ struct device_volume_control *control;
++ struct device *device;
++ pa_bvolume bvolume;
++ pa_cvolume cvolume;
++
++ pa_assert(c);
++ pa_assert(volume);
++
++ control = c->userdata;
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ pa_bvolume_from_cvolume(&bvolume, &device->sink->reference_volume, &device->sink->channel_map);
++ else
++ pa_bvolume_from_cvolume(&bvolume, &device->source->reference_volume, &device->source->channel_map);
++ break;
++
++ case DEVICE_TYPE_SINK:
++ pa_bvolume_from_cvolume(&bvolume, &device->sink->reference_volume, &device->sink->channel_map);
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ pa_bvolume_from_cvolume(&bvolume, &device->source->reference_volume, &device->source->channel_map);
++ break;
++ }
++
++ if (set_volume)
++ bvolume.volume = volume->volume;
++
++ if (set_balance)
++ pa_bvolume_copy_balance(&bvolume, volume);
++
++ pa_bvolume_to_cvolume(&bvolume, &cvolume);
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ pa_sink_set_volume(device->sink, &cvolume, true, true);
++ else
++ pa_source_set_volume(device->source, &cvolume, true, true);
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ pa_source_set_volume(device->source, &cvolume, true, true);
++ break;
++
++ case DEVICE_TYPE_SINK:
++ pa_sink_set_volume(device->sink, &cvolume, true, true);
++ break;
++ }
++
++ return 0;
++}
++
++static struct device_volume_control *device_volume_control_new(struct device *device) {
++ struct device_volume_control *control;
++ const char *name = NULL;
++ bool convertible_to_dB = false;
++ bool channel_map_is_writable;
++
++ pa_assert(device);
++
++ control = pa_xnew0(struct device_volume_control, 1);
++ control->device = device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ name = "port-volume-control";
++
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ convertible_to_dB = device->sink->flags & PA_SINK_DECIBEL_VOLUME;
++ else
++ convertible_to_dB = device->source->flags & PA_SOURCE_DECIBEL_VOLUME;
++
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ name = "port-monitor-volume-control";
++ convertible_to_dB = device->source->flags & PA_SOURCE_DECIBEL_VOLUME;
++ break;
++
++ case DEVICE_TYPE_SINK:
++ name = "sink-volume-control";
++ convertible_to_dB = device->sink->flags & PA_SINK_DECIBEL_VOLUME;
++ break;
++
++ case DEVICE_TYPE_SOURCE:
++ name = "source-volume-control";
++ convertible_to_dB = device->source->flags & PA_SOURCE_DECIBEL_VOLUME;
++ break;
++ }
++
++ channel_map_is_writable = false;
++ control->volume_control = pa_volume_control_new(device->creator->volume_api, name, device->device->description,
++ convertible_to_dB, channel_map_is_writable);
++ control->volume_control->set_volume = volume_control_set_volume_cb;
++ control->volume_control->userdata = control;
++
++ return control;
++}
++
++static pa_hook_result_t sink_or_source_volume_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct device_volume_control *control = userdata;
++ struct device *device;
++ pa_sink *sink = NULL;
++ pa_source *source = NULL;
++ pa_bvolume bvolume;
++
++ pa_assert(control);
++ pa_assert(call_data);
++
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ sink = call_data;
++ else
++ source = call_data;
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ source = call_data;
++ break;
++
++ case DEVICE_TYPE_SINK:
++ sink = call_data;
++ break;
++ }
++
++ if ((sink && sink != device->sink) || (source && source != device->source))
++ return PA_HOOK_OK;
++
++ if (sink)
++ pa_bvolume_from_cvolume(&bvolume, &sink->reference_volume, &sink->channel_map);
++ else
++ pa_bvolume_from_cvolume(&bvolume, &source->reference_volume, &source->channel_map);
++
++ pa_volume_control_volume_changed(control->volume_control, &bvolume, true, true);
++
++ return PA_HOOK_OK;
++}
++
++static void volume_control_set_initial_volume_cb(pa_volume_control *c) {
++ struct device_volume_control *control;
++ struct device *device;
++ pa_cvolume cvolume;
++
++ pa_assert(c);
++
++ control = c->userdata;
++ device = control->device;
++ pa_bvolume_to_cvolume(&control->volume_control->volume, &cvolume);
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ pa_sink_set_volume(device->sink, &cvolume, true, true);
++ else
++ pa_source_set_volume(device->source, &cvolume, true, true);
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ pa_source_set_volume(device->source, &cvolume, true, true);
++ break;
++
++ case DEVICE_TYPE_SINK:
++ pa_sink_set_volume(device->sink, &cvolume, true, true);
++ break;
++ }
++}
++
++static void device_volume_control_put(struct device_volume_control *control) {
++ struct device *device;
++ pa_bvolume volume;
++
++ pa_assert(control);
++
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT) {
++ control->volume_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
++ pa_bvolume_from_cvolume(&volume, &device->sink->reference_volume, &device->sink->channel_map);
++ } else {
++ control->volume_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
++ pa_bvolume_from_cvolume(&volume, &device->source->reference_volume, &device->source->channel_map);
++ }
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ control->volume_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
++ pa_bvolume_from_cvolume(&volume, &device->source->reference_volume, &device->source->channel_map);
++ break;
++
++ case DEVICE_TYPE_SINK:
++ control->volume_changed_slot = pa_hook_connect(&device->sink->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
++ pa_bvolume_from_cvolume(&volume, &device->sink->reference_volume, &device->sink->channel_map);
++ break;
++ }
++
++ pa_volume_control_put(control->volume_control, &volume, volume_control_set_initial_volume_cb);
++}
++
++static void device_volume_control_unlink(struct device_volume_control *control) {
++ pa_assert(control);
++
++ if (control->unlinked)
++ return;
++
++ control->unlinked = true;
++
++ if (control->volume_control)
++ pa_volume_control_unlink(control->volume_control);
++
++ if (control->volume_changed_slot) {
++ pa_hook_slot_free(control->volume_changed_slot);
++ control->volume_changed_slot = NULL;
++ }
++}
++
++static void device_volume_control_free(struct device_volume_control *control) {
++ pa_assert(control);
++
++ if (!control->unlinked)
++ device_volume_control_unlink(control);
++
++ if (control->volume_control)
++ pa_volume_control_free(control->volume_control);
++
++ pa_xfree(control);
++}
++
++static int mute_control_set_mute_cb(pa_mute_control *c, bool mute) {
++ struct device_mute_control *control;
++ struct device *device;
++
++ pa_assert(c);
++
++ control = c->userdata;
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ pa_sink_set_mute(device->sink, mute, true);
++ else
++ pa_source_set_mute(device->source, mute, true);
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ pa_source_set_mute(device->source, mute, true);
++ break;
++
++ case DEVICE_TYPE_SINK:
++ pa_sink_set_mute(device->sink, mute, true);
++ break;
++ }
++
++ return 0;
++}
++
++static struct device_mute_control *device_mute_control_new(struct device *device) {
++ struct device_mute_control *control;
++ const char *name = NULL;
++
++ pa_assert(device);
++
++ control = pa_xnew0(struct device_mute_control, 1);
++ control->device = device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ name = "port-mute-control";
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ name = "port-monitor-mute-control";
++ break;
++
++ case DEVICE_TYPE_SINK:
++ name = "sink-mute-control";
++ break;
++
++ case DEVICE_TYPE_SOURCE:
++ name = "source-mute-control";
++ break;
++ }
++
++ control->mute_control = pa_mute_control_new(device->creator->volume_api, name, device->device->description);
++ control->mute_control->set_mute = mute_control_set_mute_cb;
++ control->mute_control->userdata = control;
++
++ return control;
++}
++
++static pa_hook_result_t sink_or_source_mute_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct device_mute_control *control = userdata;
++ struct device *device;
++ pa_sink *sink = NULL;
++ pa_source *source = NULL;
++ bool mute;
++
++ pa_assert(control);
++ pa_assert(call_data);
++
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ sink = call_data;
++ else
++ source = call_data;
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ source = call_data;
++ break;
++
++ case DEVICE_TYPE_SINK:
++ sink = call_data;
++ break;
++ }
++
++ if ((sink && sink != device->sink) || (source && source != device->source))
++ return PA_HOOK_OK;
++
++ if (sink)
++ mute = sink->muted;
++ else
++ mute = source->muted;
++
++ pa_mute_control_mute_changed(control->mute_control, mute);
++
++ return PA_HOOK_OK;
++}
++
++static void mute_control_set_initial_mute_cb(pa_mute_control *c) {
++ struct device_volume_control *control;
++ struct device *device;
++
++ pa_assert(c);
++
++ control = c->userdata;
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ pa_sink_set_mute(device->sink, c->mute, true);
++ else
++ pa_source_set_mute(device->source, c->mute, true);
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ pa_source_set_mute(device->source, c->mute, true);
++ break;
++
++ case DEVICE_TYPE_SINK:
++ pa_sink_set_mute(device->sink, c->mute, true);
++ break;
++ }
++}
++
++static void device_mute_control_put(struct device_mute_control *control) {
++ struct device *device;
++ bool mute = false;
++
++ pa_assert(control);
++
++ device = control->device;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT) {
++ control->mute_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SINK_MUTE_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
++ mute = device->sink->muted;
++ } else {
++ control->mute_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SOURCE_MUTE_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
++ mute = device->source->muted;
++ }
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ case DEVICE_TYPE_SOURCE:
++ control->mute_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_MUTE_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
++ mute = device->source->muted;
++ break;
++
++ case DEVICE_TYPE_SINK:
++ control->mute_changed_slot = pa_hook_connect(&device->sink->core->hooks[PA_CORE_HOOK_SINK_MUTE_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
++ mute = device->sink->muted;
++ break;
++ }
++
++ pa_mute_control_put(control->mute_control, mute, true, mute_control_set_initial_mute_cb);
++}
++
++static void device_mute_control_unlink(struct device_mute_control *control) {
++ pa_assert(control);
++
++ if (control->unlinked)
++ return;
++
++ control->unlinked = true;
++
++ if (control->mute_control)
++ pa_mute_control_unlink(control->mute_control);
++
++ if (control->mute_changed_slot) {
++ pa_hook_slot_free(control->mute_changed_slot);
++ control->mute_changed_slot = NULL;
++ }
++}
++
++static void device_mute_control_free(struct device_mute_control *control) {
++ pa_assert(control);
++
++ if (!control->unlinked)
++ device_mute_control_unlink(control);
++
++ if (control->mute_control)
++ pa_mute_control_free(control->mute_control);
++
++ pa_xfree(control);
++}
++
++static void device_set_sink_and_source_from_port(struct device *device) {
++ pa_sink *sink;
++ pa_source *source;
++ uint32_t idx;
++
++ pa_assert(device);
++
++ device->sink = NULL;
++ device->source = NULL;
++
++ if (!device->port->active)
++ return;
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT) {
++ PA_IDXSET_FOREACH(sink, device->port->card->sinks, idx) {
++ if (sink->active_port == device->port) {
++ device->sink = sink;
++ break;
++ }
++ }
++
++ pa_assert(device->sink);
++ } else {
++ PA_IDXSET_FOREACH(source, device->port->card->sources, idx) {
++ if (source->active_port == device->port) {
++ device->source = source;
++ break;
++ }
++ }
++
++ pa_assert(device->source);
++ }
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR: {
++ PA_IDXSET_FOREACH(sink, device->port->card->sinks, idx) {
++ if (sink->active_port == device->port) {
++ device->sink = sink;
++ device->source = sink->monitor_source;
++ break;
++ }
++ }
++
++ pa_assert(device->sink);
++ break;
++ }
++
++ case DEVICE_TYPE_SINK:
++ case DEVICE_TYPE_SOURCE:
++ pa_assert_not_reached();
++ }
++}
++
++static pa_hook_result_t sink_or_source_proplist_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct device *device = userdata;
++ pa_sink *sink = NULL;
++ pa_source *source = NULL;
++ const char *description = NULL;
++
++ pa_assert(device);
++ pa_assert(call_data);
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ case DEVICE_TYPE_PORT_MONITOR:
++ pa_assert_not_reached();
++
++ case DEVICE_TYPE_SINK:
++ sink = call_data;
++
++ if (sink != device->sink)
++ return PA_HOOK_OK;
++
++ description = get_sink_description(sink);
++ break;
++
++ case DEVICE_TYPE_SOURCE:
++ source = call_data;
++
++ if (source != device->source)
++ return PA_HOOK_OK;
++
++ description = get_source_description(source);
++ break;
++ }
++
++ pa_device_description_changed(device->device, description);
++ pa_volume_control_description_changed(device->volume_control->volume_control, description);
++ pa_mute_control_description_changed(device->mute_control->mute_control, description);
++
++ return PA_HOOK_OK;
++}
++
++static struct device *device_new(pa_device_creator *creator, enum device_type type, void *core_device) {
++ struct device *device = NULL;
++ const char *name = NULL;
++ char *description = NULL;
++ pa_direction_t direction = PA_DIRECTION_OUTPUT;
++ const char *device_type = NULL;
++ bool create_volume_and_mute_controls = true;
++
++ pa_assert(creator);
++ pa_assert(core_device);
++
++ device = pa_xnew0(struct device, 1);
++ device->creator = creator;
++ device->type = type;
++
++ switch (type) {
++ case DEVICE_TYPE_PORT:
++ device->port = core_device;
++ device_set_sink_and_source_from_port(device);
++ name = "port-device";
++ description = pa_xstrdup(device->port->description);
++ direction = device->port->direction;
++ device_type = device_type_from_port(device->port);
++
++ if (!device->sink && !device->source)
++ create_volume_and_mute_controls = false;
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ device->port = core_device;
++ device_set_sink_and_source_from_port(device);
++ name = "port-monitor-device";
++ description = pa_sprintf_malloc(_("Monitor of %s"), device->port->description);
++ direction = PA_DIRECTION_INPUT;
++
++ if (!device->source)
++ create_volume_and_mute_controls = false;
++ break;
++
++ case DEVICE_TYPE_SINK:
++ device->sink = core_device;
++ name = "sink-device";
++ description = pa_xstrdup(get_sink_description(device->sink));
++ direction = PA_DIRECTION_OUTPUT;
++ break;
++
++ case DEVICE_TYPE_SOURCE:
++ device->source = core_device;
++ name = "source-device";
++ description = pa_xstrdup(get_source_description(device->source));
++ direction = PA_DIRECTION_INPUT;
++ break;
++ }
++
++ device->device = pa_device_new(creator->volume_api, name, description, direction, &device_type, device_type ? 1 : 0);
++ pa_xfree(description);
++
++ if (create_volume_and_mute_controls) {
++ device->volume_control = device_volume_control_new(device);
++ device->mute_control = device_mute_control_new(device);
++ }
++
++ switch (type) {
++ case DEVICE_TYPE_PORT:
++ if (device->port->direction == PA_DIRECTION_OUTPUT)
++ device->monitor = device_new(creator, DEVICE_TYPE_PORT_MONITOR, device->port);
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ break;
++
++ case DEVICE_TYPE_SINK:
++ device->proplist_changed_slot = pa_hook_connect(&device->sink->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_proplist_changed_cb, device);
++ break;
++
++ case DEVICE_TYPE_SOURCE:
++ device->proplist_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED],
++ PA_HOOK_NORMAL, sink_or_source_proplist_changed_cb, device);
++ break;
++ }
++
++ return device;
++}
++
++static pa_hook_result_t port_active_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct device *device = userdata;
++ pa_device_port *port = call_data;
++ bool should_have_volume_and_mute_controls = false;
++
++ pa_assert(device);
++ pa_assert(port);
++
++ if (port != device->port)
++ return PA_HOOK_OK;
++
++ device_set_sink_and_source_from_port(device);
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ should_have_volume_and_mute_controls = device->sink || device->source;
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ should_have_volume_and_mute_controls = !!device->source;
++ break;
++
++ case DEVICE_TYPE_SINK:
++ case DEVICE_TYPE_SOURCE:
++ pa_assert_not_reached();
++ }
++
++ if (should_have_volume_and_mute_controls && !device->volume_control) {
++ pa_assert(!device->mute_control);
++
++ device->volume_control = device_volume_control_new(device);
++ device_volume_control_put(device->volume_control);
++ pa_device_set_default_volume_control(device->device, device->volume_control->volume_control);
++
++ device->mute_control = device_mute_control_new(device);
++ device_mute_control_put(device->mute_control);
++ pa_device_set_default_mute_control(device->device, device->mute_control->mute_control);
++ }
++
++ if (!should_have_volume_and_mute_controls && device->volume_control) {
++ pa_assert(device->mute_control);
++
++ device_mute_control_free(device->mute_control);
++ device->mute_control = NULL;
++ device_volume_control_free(device->volume_control);
++ device->volume_control = NULL;
++ }
++
++ return PA_HOOK_OK;
++}
++
++static void device_put(struct device *device) {
++ pa_assert(device);
++
++ switch (device->type) {
++ case DEVICE_TYPE_PORT:
++ case DEVICE_TYPE_PORT_MONITOR:
++ device->port_active_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_PORT_ACTIVE_CHANGED],
++ PA_HOOK_NORMAL, port_active_changed_cb, device);
++
++ case DEVICE_TYPE_SINK:
++ case DEVICE_TYPE_SOURCE:
++ break;
++ }
++
++ if (device->volume_control)
++ device_volume_control_put(device->volume_control);
++
++ if (device->mute_control)
++ device_mute_control_put(device->mute_control);
++
++ pa_device_put(device->device, device->volume_control ? device->volume_control->volume_control : NULL,
++ device->mute_control ? device->mute_control->mute_control : NULL);
++
++ if (device->monitor)
++ device_put(device->monitor);
++}
++
++static void device_unlink(struct device *device) {
++ pa_assert(device);
++
++ if (device->unlinked)
++ return;
++
++ device->unlinked = true;
++
++ if (device->monitor)
++ device_unlink(device->monitor);
++
++ if (device->device)
++ pa_device_unlink(device->device);
++
++ if (device->mute_control)
++ device_mute_control_unlink(device->mute_control);
++
++ if (device->volume_control)
++ device_volume_control_unlink(device->volume_control);
++
++ if (device->port_active_changed_slot) {
++ pa_hook_slot_free(device->port_active_changed_slot);
++ device->port_active_changed_slot = NULL;
++ }
++}
++
++static void device_free(struct device *device) {
++ pa_assert(device);
++
++ if (!device->unlinked)
++ device_unlink(device);
++
++ if (device->monitor)
++ device_free(device->monitor);
++
++ if (device->proplist_changed_slot)
++ pa_hook_slot_free(device->proplist_changed_slot);
++
++ if (device->mute_control)
++ device_mute_control_free(device->mute_control);
++
++ if (device->volume_control)
++ device_volume_control_free(device->volume_control);
++
++ if (device->device)
++ pa_device_free(device->device);
++
++ pa_xfree(device);
++}
++
++static void create_device(pa_device_creator *creator, enum device_type type, void *core_device) {
++ struct device *device;
++
++ pa_assert(creator);
++ pa_assert(core_device);
++
++ switch (type) {
++ case DEVICE_TYPE_PORT:
++ break;
++
++ case DEVICE_TYPE_PORT_MONITOR:
++ pa_assert_not_reached();
++
++ case DEVICE_TYPE_SINK:
++ if (!pa_hashmap_isempty(((pa_sink *) core_device)->ports))
++ return;
++ break;
++
++ case DEVICE_TYPE_SOURCE: {
++ pa_source *source = core_device;
++
++ if (source->monitor_of && !pa_hashmap_isempty(source->monitor_of->ports))
++ return;
++
++ if (!pa_hashmap_isempty(((pa_source *) core_device)->ports))
++ return;
++ break;
++ }
++ }
++
++ device = device_new(creator, type, core_device);
++ pa_hashmap_put(creator->devices, core_device, device);
++ device_put(device);
++}
++
++static pa_hook_result_t card_put_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_device_creator *creator = userdata;
++ pa_card *card = call_data;
++ pa_device_port *port;
++ void *state;
++
++ pa_assert(creator);
++ pa_assert(card);
++
++ PA_HASHMAP_FOREACH(port, card->ports, state)
++ create_device(creator, DEVICE_TYPE_PORT, port);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t card_unlink_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_device_creator *creator = userdata;
++ pa_card *card = call_data;
++ pa_device_port *port;
++ void *state;
++
++ pa_assert(creator);
++ pa_assert(card);
++
++ PA_HASHMAP_FOREACH(port, card->ports, state)
++ pa_hashmap_remove_and_free(creator->devices, port);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_device_creator *creator = userdata;
++ pa_sink *sink = call_data;
++
++ pa_assert(creator);
++ pa_assert(sink);
++
++ create_device(creator, DEVICE_TYPE_SINK, sink);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_device_creator *creator = userdata;
++ pa_sink *sink = call_data;
++
++ pa_assert(creator);
++ pa_assert(sink);
++
++ pa_hashmap_remove_and_free(creator->devices, sink);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_device_creator *creator = userdata;
++ pa_source *source = call_data;
++
++ pa_assert(creator);
++ pa_assert(source);
++
++ create_device(creator, DEVICE_TYPE_SOURCE, source);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t source_unlink_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_device_creator *creator = userdata;
++ pa_source *source = call_data;
++
++ pa_assert(creator);
++ pa_assert(source);
++
++ pa_hashmap_remove_and_free(creator->devices, source);
++
++ return PA_HOOK_OK;
++}
++
++pa_device_creator *pa_device_creator_new(pa_volume_api *api) {
++ pa_device_creator *creator;
++ pa_card *card;
++ uint32_t idx;
++ pa_sink *sink;
++ pa_source *source;
++
++ pa_assert(api);
++
++ creator = pa_xnew0(pa_device_creator, 1);
++ creator->volume_api = api;
++ creator->devices = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) device_free);
++ creator->card_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_CARD_PUT], PA_HOOK_NORMAL, card_put_cb, creator);
++ creator->card_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_CARD_UNLINK], PA_HOOK_NORMAL, card_unlink_cb,
++ creator);
++ creator->sink_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, sink_put_cb, creator);
++ creator->sink_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL, sink_unlink_cb,
++ creator);
++ creator->source_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, source_put_cb,
++ creator);
++ creator->source_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_NORMAL,
++ source_unlink_cb, creator);
++
++ PA_IDXSET_FOREACH(card, api->core->cards, idx) {
++ pa_device_port *port;
++ void *state;
++
++ PA_HASHMAP_FOREACH(port, card->ports, state)
++ create_device(creator, DEVICE_TYPE_PORT, port);
++ }
++
++ PA_IDXSET_FOREACH(sink, api->core->sinks, idx)
++ create_device(creator, DEVICE_TYPE_SINK, sink);
++
++ PA_IDXSET_FOREACH(source, api->core->sources, idx)
++ create_device(creator, DEVICE_TYPE_SOURCE, source);
++
++ return creator;
++}
++
++void pa_device_creator_free(pa_device_creator *creator) {
++ pa_assert(creator);
++
++ if (creator->devices)
++ pa_hashmap_remove_all(creator->devices);
++
++ if (creator->source_unlink_slot)
++ pa_hook_slot_free(creator->source_unlink_slot);
++
++ if (creator->source_put_slot)
++ pa_hook_slot_free(creator->source_put_slot);
++
++ if (creator->sink_unlink_slot)
++ pa_hook_slot_free(creator->sink_unlink_slot);
++
++ if (creator->sink_put_slot)
++ pa_hook_slot_free(creator->sink_put_slot);
++
++ if (creator->card_unlink_slot)
++ pa_hook_slot_free(creator->card_unlink_slot);
++
++ if (creator->card_put_slot)
++ pa_hook_slot_free(creator->card_put_slot);
++
++ if (creator->devices)
++ pa_hashmap_free(creator->devices);
++
++ pa_xfree(creator);
++}
+diff --git a/src/modules/volume-api/device-creator.h b/src/modules/volume-api/device-creator.h
+new file mode 100644
+index 0000000..bcec8d9
+--- /dev/null
++++ b/src/modules/volume-api/device-creator.h
+@@ -0,0 +1,32 @@
++#ifndef foodevicecreatorhfoo
++#define foodevicecreatorhfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/volume-api.h>
++
++typedef struct pa_device_creator pa_device_creator;
++
++pa_device_creator *pa_device_creator_new(pa_volume_api *api);
++void pa_device_creator_free(pa_device_creator *creator);
++
++#endif
+diff --git a/src/modules/volume-api/device.c b/src/modules/volume-api/device.c
+new file mode 100644
+index 0000000..ea496ba
+--- /dev/null
++++ b/src/modules/volume-api/device.c
+@@ -0,0 +1,293 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "device.h"
++
++#include <modules/volume-api/mute-control.h>
++#include <modules/volume-api/volume-control.h>
++
++#include <pulse/direction.h>
++
++#include <pulsecore/core-util.h>
++
++pa_device *pa_device_new(pa_volume_api *api, const char *name, const char *description, pa_direction_t direction,
++ const char * const *device_types, unsigned n_device_types) {
++ pa_device *device;
++ unsigned i;
++
++ pa_assert(api);
++ pa_assert(name);
++ pa_assert(description);
++ pa_assert(device_types || n_device_types == 0);
++
++ device = pa_xnew0(pa_device, 1);
++ device->volume_api = api;
++ device->index = pa_volume_api_allocate_device_index(api);
++ pa_assert_se(pa_volume_api_register_name(api, name, false, &device->name) >= 0);
++ device->description = pa_xstrdup(description);
++ device->direction = direction;
++ device->device_types = pa_dynarray_new(pa_xfree);
++
++ for (i = 0; i < n_device_types; i++)
++ pa_dynarray_append(device->device_types, pa_xstrdup(device_types[i]));
++
++ device->proplist = pa_proplist_new();
++ device->use_default_volume_control = true;
++ device->use_default_mute_control = true;
++
++ return device;
++}
++
++void pa_device_put(pa_device *device, pa_volume_control *default_volume_control, pa_mute_control *default_mute_control) {
++ char *device_types_str;
++ const char *prop_key;
++ void *state = NULL;
++
++ pa_assert(device);
++
++ if (default_volume_control) {
++ device->default_volume_control = default_volume_control;
++ pa_volume_control_add_default_for_device(default_volume_control, device);
++
++ device->volume_control = default_volume_control;
++ pa_volume_control_add_device(default_volume_control, device);
++ }
++
++ if (default_mute_control) {
++ device->default_mute_control = default_mute_control;
++ pa_mute_control_add_default_for_device(default_mute_control, device);
++
++ device->mute_control = default_mute_control;
++ pa_mute_control_add_device(default_mute_control, device);
++ }
++
++ pa_volume_api_add_device(device->volume_api, device);
++
++ device->linked = true;
++
++ device_types_str = pa_join((const char * const *) pa_dynarray_get_raw_array(device->device_types),
++ pa_dynarray_size(device->device_types), ", ");
++
++ pa_log_debug("Created device #%u.", device->index);
++ pa_log_debug(" Name: %s", device->name);
++ pa_log_debug(" Description: %s", device->description);
++ pa_log_debug(" Direction: %s", pa_direction_to_string(device->direction));
++ pa_log_debug(" Device Types: %s", *device_types_str ? device_types_str : "(none)");
++ pa_log_debug(" Volume control: %s", device->volume_control ? device->volume_control->name : "(unset)");
++ pa_log_debug(" Mute control: %s", device->mute_control ? device->mute_control->name : "(unset)");
++ pa_log_debug(" Properties:");
++
++ while ((prop_key = pa_proplist_iterate(device->proplist, &state)))
++ pa_log_debug(" %s = %s", prop_key, pa_strnull(pa_proplist_gets(device->proplist, prop_key)));
++
++ pa_xfree(device_types_str);
++
++ pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_PUT], device);
++}
++
++void pa_device_unlink(pa_device *device) {
++ pa_assert(device);
++
++ if (device->unlinked) {
++ pa_log_debug("Unlinking device %s (already unlinked, this is a no-op).", device->name);
++ return;
++ }
++
++ device->unlinked = true;
++
++ pa_log_debug("Unlinking device %s.", device->name);
++
++ if (device->linked)
++ pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_UNLINK], device);
++
++ pa_volume_api_remove_device(device->volume_api, device);
++
++ if (device->mute_control) {
++ pa_mute_control_remove_device(device->mute_control, device);
++ device->mute_control = NULL;
++ }
++
++ if (device->default_mute_control) {
++ pa_mute_control_remove_default_for_device(device->default_mute_control, device);
++ device->default_mute_control = NULL;
++ }
++
++ if (device->volume_control) {
++ pa_volume_control_remove_device(device->volume_control, device);
++ device->volume_control = NULL;
++ }
++
++ if (device->default_volume_control) {
++ pa_volume_control_remove_default_for_device(device->default_volume_control, device);
++ device->default_volume_control = NULL;
++ }
++}
++
++void pa_device_free(pa_device *device) {
++ pa_assert(device);
++
++ if (!device->unlinked)
++ pa_device_unlink(device);
++
++ if (device->proplist)
++ pa_proplist_free(device->proplist);
++
++ if (device->device_types)
++ pa_dynarray_free(device->device_types);
++
++ pa_xfree(device->description);
++
++ if (device->name)
++ pa_volume_api_unregister_name(device->volume_api, device->name);
++
++ pa_xfree(device);
++}
++
++static void set_volume_control_internal(pa_device *device, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(device);
++
++ old_control = device->volume_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control)
++ pa_volume_control_remove_device(old_control, device);
++
++ device->volume_control = control;
++
++ if (control)
++ pa_volume_control_add_device(control, device);
++
++ if (!device->linked || device->unlinked)
++ return;
++
++ pa_log_debug("The volume control of device %s changed from %s to %s.", device->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_VOLUME_CONTROL_CHANGED], device);
++}
++
++void pa_device_set_volume_control(pa_device *device, pa_volume_control *control) {
++ pa_assert(device);
++
++ device->use_default_volume_control = false;
++ set_volume_control_internal(device, control);
++}
++
++static void set_mute_control_internal(pa_device *device, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(device);
++
++ old_control = device->mute_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control)
++ pa_mute_control_remove_device(old_control, device);
++
++ device->mute_control = control;
++
++ if (control)
++ pa_mute_control_add_device(control, device);
++
++ pa_log_debug("The mute control of device %s changed from %s to %s.", device->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_MUTE_CONTROL_CHANGED], device);
++}
++
++void pa_device_set_mute_control(pa_device *device, pa_mute_control *control) {
++ pa_assert(device);
++
++ device->use_default_mute_control = false;
++ set_mute_control_internal(device, control);
++}
++
++void pa_device_description_changed(pa_device *device, const char *new_description) {
++ char *old_description;
++
++ pa_assert(device);
++ pa_assert(new_description);
++
++ old_description = device->description;
++
++ if (pa_streq(new_description, old_description))
++ return;
++
++ device->description = pa_xstrdup(new_description);
++ pa_log_debug("The description of device %s changed from \"%s\" to \"%s\".", device->name, old_description,
++ new_description);
++ pa_xfree(old_description);
++ pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_DESCRIPTION_CHANGED], device);
++}
++
++void pa_device_set_default_volume_control(pa_device *device, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(device);
++
++ old_control = device->default_volume_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control)
++ pa_volume_control_remove_default_for_device(old_control, device);
++
++ device->default_volume_control = control;
++
++ if (control)
++ pa_volume_control_add_default_for_device(control, device);
++
++ if (device->use_default_volume_control)
++ set_volume_control_internal(device, control);
++}
++
++void pa_device_set_default_mute_control(pa_device *device, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(device);
++
++ old_control = device->default_mute_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control)
++ pa_mute_control_remove_default_for_device(old_control, device);
++
++ device->default_mute_control = control;
++
++ if (control)
++ pa_mute_control_add_default_for_device(control, device);
++
++ if (device->use_default_mute_control)
++ set_mute_control_internal(device, control);
++}
+diff --git a/src/modules/volume-api/device.h b/src/modules/volume-api/device.h
+new file mode 100644
+index 0000000..9eac7e9
+--- /dev/null
++++ b/src/modules/volume-api/device.h
+@@ -0,0 +1,76 @@
++#ifndef foodevicehfoo
++#define foodevicehfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/volume-api.h>
++
++#include <pulsecore/dynarray.h>
++
++typedef struct pa_device pa_device;
++
++struct pa_device {
++ pa_volume_api *volume_api;
++ uint32_t index;
++ const char *name;
++ char *description;
++ pa_direction_t direction;
++ pa_dynarray *device_types;
++ pa_proplist *proplist;
++ pa_volume_control *volume_control;
++ pa_mute_control *mute_control;
++
++ /* The device implementation can provide default volume and mute controls,
++ * which are used in case there's no policy module that wants to override
++ * the defaults. */
++ pa_volume_control *default_volume_control;
++ bool use_default_volume_control;
++ pa_mute_control *default_mute_control;
++ bool use_default_mute_control;
++
++ bool linked;
++ bool unlinked;
++};
++
++pa_device *pa_device_new(pa_volume_api *api, const char *name, const char *description, pa_direction_t direction,
++ const char * const *device_types, unsigned n_device_types);
++void pa_device_put(pa_device *device, pa_volume_control *default_volume_control, pa_mute_control *default_mute_control);
++void pa_device_unlink(pa_device *device);
++void pa_device_free(pa_device *device);
++
++/* Called by policy modules. */
++void pa_device_set_volume_control(pa_device *device, pa_volume_control *control);
++void pa_device_set_mute_control(pa_device *device, pa_mute_control *control);
++
++/* Called by policy modules. Note that pa_device_set_volume_control() and
++ * pa_device_set_mute_control() automatically disable the corresponding
++ * use_default flags, so these functions are mainly useful for re-enabling the
++ * flags. */
++void pa_device_set_use_default_volume_control(pa_device *device, bool use);
++void pa_device_set_use_default_mute_control(pa_device *device, bool use);
++
++/* Called by the device implementation. */
++void pa_device_description_changed(pa_device *device, const char *new_description);
++void pa_device_set_default_volume_control(pa_device *device, pa_volume_control *control);
++void pa_device_set_default_mute_control(pa_device *device, pa_mute_control *control);
++
++#endif
+diff --git a/src/modules/volume-api/mute-control.c b/src/modules/volume-api/mute-control.c
+new file mode 100644
+index 0000000..adc008e
+--- /dev/null
++++ b/src/modules/volume-api/mute-control.c
+@@ -0,0 +1,306 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "mute-control.h"
++
++#include <modules/volume-api/audio-group.h>
++#include <modules/volume-api/device.h>
++#include <modules/volume-api/sstream.h>
++
++#include <pulsecore/core-util.h>
++
++pa_mute_control *pa_mute_control_new(pa_volume_api *api, const char *name, const char *description) {
++ pa_mute_control *control;
++
++ pa_assert(api);
++ pa_assert(name);
++ pa_assert(description);
++
++ control = pa_xnew0(pa_mute_control, 1);
++ control->volume_api = api;
++ control->index = pa_volume_api_allocate_mute_control_index(api);
++ pa_assert_se(pa_volume_api_register_name(api, name, false, &control->name) >= 0);
++ control->description = pa_xstrdup(description);
++ control->proplist = pa_proplist_new();
++ control->devices = pa_hashmap_new(NULL, NULL);
++ control->default_for_devices = pa_hashmap_new(NULL, NULL);
++ control->streams = pa_hashmap_new(NULL, NULL);
++ control->audio_groups = pa_hashmap_new(NULL, NULL);
++
++ return control;
++}
++
++void pa_mute_control_put(pa_mute_control *control, bool initial_mute, bool initial_mute_is_set,
++ pa_mute_control_set_initial_mute_cb_t set_initial_mute_cb) {
++ const char *prop_key;
++ void *state = NULL;
++
++ pa_assert(control);
++ pa_assert(initial_mute_is_set || control->set_mute);
++ pa_assert(set_initial_mute_cb || !control->set_mute);
++
++ if (initial_mute_is_set)
++ control->mute = initial_mute;
++ else
++ control->mute = false;
++
++ if (set_initial_mute_cb)
++ set_initial_mute_cb(control);
++
++ pa_volume_api_add_mute_control(control->volume_api, control);
++
++ control->linked = true;
++
++ pa_log_debug("Created mute control #%u.", control->index);
++ pa_log_debug(" Name: %s", control->name);
++ pa_log_debug(" Description: %s", control->description);
++ pa_log_debug(" Mute: %s", pa_yes_no(control->mute));
++ pa_log_debug(" Properties:");
++
++ while ((prop_key = pa_proplist_iterate(control->proplist, &state)))
++ pa_log_debug(" %s = %s", prop_key, pa_strnull(pa_proplist_gets(control->proplist, prop_key)));
++
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_PUT], control);
++}
++
++void pa_mute_control_unlink(pa_mute_control *control) {
++ pa_audio_group *group;
++ pa_device *device;
++ pas_stream *stream;
++
++ pa_assert(control);
++
++ if (control->unlinked) {
++ pa_log_debug("Unlinking mute control %s (already unlinked, this is a no-op).", control->name);
++ return;
++ }
++
++ control->unlinked = true;
++
++ pa_log_debug("Unlinking mute control %s.", control->name);
++
++ if (control->linked)
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK], control);
++
++ pa_volume_api_remove_mute_control(control->volume_api, control);
++
++ while ((group = pa_hashmap_first(control->audio_groups)))
++ pa_audio_group_set_mute_control(group, NULL);
++
++ while ((stream = pa_hashmap_first(control->streams)))
++ pas_stream_set_mute_control(stream, NULL);
++
++ while ((device = pa_hashmap_first(control->default_for_devices)))
++ pa_device_set_default_mute_control(device, NULL);
++
++ while ((device = pa_hashmap_first(control->devices))) {
++ /* Why do we have this assertion here? The concern is that if we call
++ * pa_device_set_mute_control() for some device that has the
++ * use_default_mute_control flag set, then that flag will be unset as
++ * a side effect, and we don't want that side effect. This assertion
++ * should be safe, because we just called
++ * pa_device_set_default_mute_control(NULL) for each device that this
++ * control was the default for, and that should ensure that we don't
++ * any more hold any references to devices that used to use this
++ * control as the default. */
++ pa_assert(!device->use_default_mute_control);
++ pa_device_set_mute_control(device, NULL);
++ }
++}
++
++void pa_mute_control_free(pa_mute_control *control) {
++ pa_assert(control);
++
++ if (!control->unlinked)
++ pa_mute_control_unlink(control);
++
++ if (control->audio_groups) {
++ pa_assert(pa_hashmap_isempty(control->audio_groups));
++ pa_hashmap_free(control->audio_groups);
++ }
++
++ if (control->streams) {
++ pa_assert(pa_hashmap_isempty(control->streams));
++ pa_hashmap_free(control->streams);
++ }
++
++ if (control->default_for_devices) {
++ pa_assert(pa_hashmap_isempty(control->default_for_devices));
++ pa_hashmap_free(control->default_for_devices);
++ }
++
++ if (control->devices) {
++ pa_assert(pa_hashmap_isempty(control->devices));
++ pa_hashmap_free(control->devices);
++ }
++
++ if (control->proplist)
++ pa_proplist_free(control->proplist);
++
++ pa_xfree(control->description);
++
++ if (control->name)
++ pa_volume_api_unregister_name(control->volume_api, control->name);
++
++ pa_xfree(control);
++}
++
++void pa_mute_control_set_owner_audio_group(pa_mute_control *control, pa_audio_group *group) {
++ pa_assert(control);
++ pa_assert(group);
++
++ control->owner_audio_group = group;
++}
++
++static void set_mute_internal(pa_mute_control *control, bool mute) {
++ bool old_mute;
++
++ pa_assert(control);
++
++ old_mute = control->mute;
++
++ if (mute == old_mute)
++ return;
++
++ control->mute = mute;
++
++ if (!control->linked || control->unlinked)
++ return;
++
++ pa_log_debug("The mute of mute control %s changed from %s to %s.", control->name, pa_yes_no(old_mute),
++ pa_yes_no(control->mute));
++
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_MUTE_CHANGED], control);
++}
++
++int pa_mute_control_set_mute(pa_mute_control *control, bool mute) {
++ int r;
++
++ pa_assert(control);
++
++ if (!control->set_mute) {
++ pa_log_info("Tried to set the mute of mute control %s, but the mute control doesn't support the operation.",
++ control->name);
++ return -PA_ERR_NOTSUPPORTED;
++ }
++
++ if (mute == control->mute)
++ return 0;
++
++ control->set_mute_in_progress = true;
++ r = control->set_mute(control, mute);
++ control->set_mute_in_progress = false;
++
++ if (r >= 0)
++ set_mute_internal(control, mute);
++
++ return r;
++}
++
++void pa_mute_control_description_changed(pa_mute_control *control, const char *new_description) {
++ char *old_description;
++
++ pa_assert(control);
++ pa_assert(new_description);
++
++ old_description = control->description;
++
++ if (pa_streq(new_description, old_description))
++ return;
++
++ control->description = pa_xstrdup(new_description);
++ pa_log_debug("The description of mute control %s changed from \"%s\" to \"%s\".", control->name, old_description,
++ new_description);
++ pa_xfree(old_description);
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_DESCRIPTION_CHANGED], control);
++}
++
++void pa_mute_control_mute_changed(pa_mute_control *control, bool new_mute) {
++ pa_assert(control);
++
++ if (!control->linked)
++ return;
++
++ if (control->set_mute_in_progress)
++ return;
++
++ set_mute_internal(control, new_mute);
++}
++
++void pa_mute_control_add_device(pa_mute_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_put(control->devices, device, device) >= 0);
++}
++
++void pa_mute_control_remove_device(pa_mute_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_remove(control->devices, device));
++}
++
++void pa_mute_control_add_default_for_device(pa_mute_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_put(control->default_for_devices, device, device) >= 0);
++}
++
++void pa_mute_control_remove_default_for_device(pa_mute_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_remove(control->default_for_devices, device));
++}
++
++void pa_mute_control_add_stream(pa_mute_control *control, pas_stream *stream) {
++ pa_assert(control);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_put(control->streams, stream, stream) >= 0);
++}
++
++void pa_mute_control_remove_stream(pa_mute_control *control, pas_stream *stream) {
++ pa_assert(control);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_remove(control->streams, stream));
++}
++
++void pa_mute_control_add_audio_group(pa_mute_control *control, pa_audio_group *group) {
++ pa_assert(control);
++ pa_assert(group);
++
++ pa_assert_se(pa_hashmap_put(control->audio_groups, group, group) >= 0);
++}
++
++void pa_mute_control_remove_audio_group(pa_mute_control *control, pa_audio_group *group) {
++ pa_assert(control);
++ pa_assert(group);
++
++ pa_assert_se(pa_hashmap_remove(control->audio_groups, group));
++}
+diff --git a/src/modules/volume-api/mute-control.h b/src/modules/volume-api/mute-control.h
+new file mode 100644
+index 0000000..1f70a43
+--- /dev/null
++++ b/src/modules/volume-api/mute-control.h
+@@ -0,0 +1,102 @@
++#ifndef foomutecontrolhfoo
++#define foomutecontrolhfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/volume-api.h>
++
++typedef struct pa_mute_control pa_mute_control;
++
++struct pa_mute_control {
++ pa_volume_api *volume_api;
++ uint32_t index;
++ const char *name;
++ char *description;
++ pa_proplist *proplist;
++ bool mute;
++
++ /* If this mute control is the "own mute control" of an audio group, this
++ * is set to point to that group, otherwise this is NULL. */
++ pa_audio_group *owner_audio_group;
++
++ pa_hashmap *devices; /* pa_device -> pa_device (hashmap-as-a-set) */
++ pa_hashmap *default_for_devices; /* pa_device -> pa_device (hashmap-as-a-set) */
++ pa_hashmap *streams; /* pas_stream -> pas_stream (hashmap-as-a-set) */
++ pa_hashmap *audio_groups; /* pa_audio_group -> pa_audio_group (hashmap-as-a-set) */
++
++ bool linked;
++ bool unlinked;
++ bool set_mute_in_progress;
++
++ /* Called from pa_mute_control_set_mute(). The implementation is expected
++ * to return a negative error code on failure. May be NULL, if the mute
++ * control is read-only. */
++ int (*set_mute)(pa_mute_control *control, bool mute);
++
++ void *userdata;
++};
++
++pa_mute_control *pa_mute_control_new(pa_volume_api *api, const char *name, const char *description);
++
++typedef void (*pa_mute_control_set_initial_mute_cb_t)(pa_mute_control *control);
++
++/* initial_mute is the preferred initial mute of the mute control
++ * implementation. It may be unset, if the implementation doesn't care about
++ * the initial state of the mute control. Read-only mute controls, however,
++ * must always set initial_mute.
++ *
++ * The implementation's initial mute preference may be overridden by policy, if
++ * the mute control isn't read-only. When the final initial mute is known, the
++ * the implementation is notified via set_initial_mute_cb (the mute can be read
++ * from control->mute). set_initial_mute_cb may be NULL, if the mute control is
++ * read-only. */
++void pa_mute_control_put(pa_mute_control *control, bool initial_mute, bool initial_mute_is_set,
++ pa_mute_control_set_initial_mute_cb_t set_initial_mute_cb);
++
++void pa_mute_control_unlink(pa_mute_control *control);
++void pa_mute_control_free(pa_mute_control *control);
++
++/* Called by audio-group.c only. */
++void pa_mute_control_set_owner_audio_group(pa_mute_control *control, pa_audio_group *group);
++
++/* Called by clients and policy modules. */
++int pa_mute_control_set_mute(pa_mute_control *control, bool mute);
++
++/* Called by the mute control implementation. */
++void pa_mute_control_description_changed(pa_mute_control *control, const char *new_description);
++void pa_mute_control_mute_changed(pa_mute_control *control, bool new_mute);
++
++/* Called from device.c only. */
++void pa_mute_control_add_device(pa_mute_control *control, pa_device *device);
++void pa_mute_control_remove_device(pa_mute_control *control, pa_device *device);
++void pa_mute_control_add_default_for_device(pa_mute_control *control, pa_device *device);
++void pa_mute_control_remove_default_for_device(pa_mute_control *control, pa_device *device);
++
++/* Called from sstream.c only. */
++void pa_mute_control_add_stream(pa_mute_control *control, pas_stream *stream);
++void pa_mute_control_remove_stream(pa_mute_control *control, pas_stream *stream);
++
++/* Called from audio-group.c only. */
++void pa_mute_control_add_audio_group(pa_mute_control *control, pa_audio_group *group);
++void pa_mute_control_remove_audio_group(pa_mute_control *control, pa_audio_group *group);
++
++#endif
+diff --git a/src/modules/volume-api/sstream.c b/src/modules/volume-api/sstream.c
+new file mode 100644
+index 0000000..e3531a8
+--- /dev/null
++++ b/src/modules/volume-api/sstream.c
+@@ -0,0 +1,366 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "sstream.h"
++
++#include <modules/volume-api/audio-group.h>
++#include <modules/volume-api/binding.h>
++#include <modules/volume-api/mute-control.h>
++#include <modules/volume-api/volume-control.h>
++
++#include <pulse/direction.h>
++
++#include <pulsecore/core-util.h>
++
++pas_stream *pas_stream_new(pa_volume_api *api, const char *name, const char *description, pa_direction_t direction) {
++ pas_stream *stream;
++
++ pa_assert(api);
++ pa_assert(name);
++ pa_assert(description);
++
++ stream = pa_xnew0(pas_stream, 1);
++ stream->volume_api = api;
++ stream->index = pa_volume_api_allocate_stream_index(api);
++ pa_assert_se(pa_volume_api_register_name(api, name, false, &stream->name) >= 0);
++ stream->description = pa_xstrdup(description);
++ stream->direction = direction;
++ stream->proplist = pa_proplist_new();
++ stream->use_default_volume_control = true;
++ stream->use_default_mute_control = true;
++
++ return stream;
++}
++
++static void set_volume_control_internal(pas_stream *stream, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(stream);
++
++ old_control = stream->volume_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control) {
++ /* If the old control pointed to the own volume control of an audio
++ * group, then the stream's audio group for volume needs to be
++ * updated. We set it to NULL here, and if it should be non-NULL, that
++ * will be fixed very soon (a few lines down). */
++ pas_stream_set_audio_group_for_volume(stream, NULL);
++
++ pa_volume_control_remove_stream(old_control, stream);
++ }
++
++ stream->volume_control = control;
++
++ if (control) {
++ pa_volume_control_add_stream(control, stream);
++ pas_stream_set_audio_group_for_volume(stream, control->owner_audio_group);
++ }
++
++ if (!stream->linked || stream->unlinked)
++ return;
++
++ pa_log_debug("The volume control of stream %s changed from %s to %s.", stream->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_VOLUME_CONTROL_CHANGED], stream);
++}
++
++static void set_mute_control_internal(pas_stream *stream, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(stream);
++
++ old_control = stream->mute_control;
++
++ if (control == old_control)
++ return;
++
++ if (old_control) {
++ /* If the old control pointed to the own mute control of an audio
++ * group, then the stream's audio group for mute needs to be updated.
++ * We set it to NULL here, and if it should be non-NULL, that will be
++ * fixed very soon (a few lines down). */
++ pas_stream_set_audio_group_for_mute(stream, NULL);
++
++ pa_mute_control_remove_stream(old_control, stream);
++ }
++
++ stream->mute_control = control;
++
++ if (control) {
++ pa_mute_control_add_stream(control, stream);
++ pas_stream_set_audio_group_for_mute(stream, control->owner_audio_group);
++ }
++
++ if (!stream->linked || stream->unlinked)
++ return;
++
++ pa_log_debug("The mute control of stream %s changed from %s to %s.", stream->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_MUTE_CONTROL_CHANGED], stream);
++}
++
++void pas_stream_put(pas_stream *stream, pa_proplist *initial_properties) {
++ const char *prop_key;
++ void *state = NULL;
++
++ pa_assert(stream);
++ pa_assert(!stream->create_own_volume_control || stream->delete_own_volume_control);
++ pa_assert(!stream->create_own_mute_control || stream->delete_own_mute_control);
++
++ if (initial_properties)
++ pa_proplist_update(stream->proplist, PA_UPDATE_REPLACE, initial_properties);
++
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_SET_INITIAL_VOLUME_CONTROL], stream);
++
++ if (stream->use_default_volume_control)
++ set_volume_control_internal(stream, stream->own_volume_control);
++
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_SET_INITIAL_MUTE_CONTROL], stream);
++
++ if (stream->use_default_mute_control)
++ set_mute_control_internal(stream, stream->own_mute_control);
++
++ pa_volume_api_add_stream(stream->volume_api, stream);
++
++ stream->linked = true;
++
++ pa_log_debug("Created stream #%u.", stream->index);
++ pa_log_debug(" Name: %s", stream->name);
++ pa_log_debug(" Description: %s", stream->description);
++ pa_log_debug(" Direction: %s", pa_direction_to_string(stream->direction));
++ pa_log_debug(" Volume control: %s", stream->volume_control ? stream->volume_control->name : "(unset)");
++ pa_log_debug(" Mute control: %s", stream->mute_control ? stream->mute_control->name : "(unset)");
++ pa_log_debug(" Properties:");
++
++ while ((prop_key = pa_proplist_iterate(stream->proplist, &state)))
++ pa_log_debug(" %s = %s", prop_key, pa_strnull(pa_proplist_gets(stream->proplist, prop_key)));
++
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_PUT], stream);
++}
++
++void pas_stream_unlink(pas_stream *stream) {
++ pa_assert(stream);
++
++ if (stream->unlinked) {
++ pa_log_debug("Unlinking stream %s (already unlinked, this is a no-op).", stream->name);
++ return;
++ }
++
++ stream->unlinked = true;
++
++ pa_log_debug("Unlinking stream %s.", stream->name);
++
++ if (stream->linked)
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_UNLINK], stream);
++
++ pa_volume_api_remove_stream(stream->volume_api, stream);
++
++ pas_stream_set_audio_group_for_mute(stream, NULL);
++ pas_stream_set_audio_group_for_volume(stream, NULL);
++ pas_stream_set_mute_control(stream, NULL);
++ pas_stream_set_volume_control(stream, NULL);
++ pas_stream_set_have_own_mute_control(stream, false);
++ pas_stream_set_have_own_volume_control(stream, false);
++}
++
++void pas_stream_free(pas_stream *stream) {
++ pa_assert(stream);
++
++ if (!stream->unlinked)
++ pas_stream_unlink(stream);
++
++ if (stream->proplist)
++ pa_proplist_free(stream->proplist);
++
++ pa_xfree(stream->description);
++
++ if (stream->name)
++ pa_volume_api_unregister_name(stream->volume_api, stream->name);
++
++ pa_xfree(stream);
++}
++
++int pas_stream_set_have_own_volume_control(pas_stream *stream, bool have) {
++ pa_assert(stream);
++
++ if (have == stream->have_own_volume_control)
++ return 0;
++
++ if (have) {
++ pa_assert(!stream->own_volume_control);
++
++ if (!stream->create_own_volume_control) {
++ pa_log_debug("Stream %s doesn't support own volume control.", stream->name);
++ return -PA_ERR_NOTSUPPORTED;
++ }
++
++ stream->own_volume_control = stream->create_own_volume_control(stream);
++ } else {
++ stream->delete_own_volume_control(stream);
++ stream->own_volume_control = NULL;
++ }
++
++ stream->have_own_volume_control = have;
++
++ return 0;
++}
++
++int pas_stream_set_have_own_mute_control(pas_stream *stream, bool have) {
++ pa_assert(stream);
++
++ if (have == stream->have_own_mute_control)
++ return 0;
++
++ if (have) {
++ pa_assert(!stream->own_mute_control);
++
++ if (!stream->create_own_mute_control) {
++ pa_log_debug("Stream %s doesn't support own mute control.", stream->name);
++ return -PA_ERR_NOTSUPPORTED;
++ }
++
++ stream->own_mute_control = stream->create_own_mute_control(stream);
++ } else {
++ stream->delete_own_mute_control(stream);
++ stream->own_mute_control = NULL;
++ }
++
++ stream->have_own_mute_control = have;
++
++ return 0;
++}
++
++void pas_stream_set_volume_control(pas_stream *stream, pa_volume_control *control) {
++ pa_assert(stream);
++
++ stream->use_default_volume_control = false;
++
++ if (stream->volume_control_binding) {
++ pa_binding_free(stream->volume_control_binding);
++ stream->volume_control_binding = NULL;
++ }
++
++ set_volume_control_internal(stream, control);
++}
++
++void pas_stream_set_mute_control(pas_stream *stream, pa_mute_control *control) {
++ pa_assert(stream);
++
++ stream->use_default_mute_control = false;
++
++ if (stream->mute_control_binding) {
++ pa_binding_free(stream->mute_control_binding);
++ stream->mute_control_binding = NULL;
++ }
++
++ set_mute_control_internal(stream, control);
++}
++
++void pas_stream_bind_volume_control(pas_stream *stream, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = stream,
++ .set_value = (pa_binding_set_value_cb_t) set_volume_control_internal,
++ };
++
++ pa_assert(stream);
++ pa_assert(target_info);
++
++ stream->use_default_volume_control = false;
++
++ if (stream->volume_control_binding)
++ pa_binding_free(stream->volume_control_binding);
++
++ stream->volume_control_binding = pa_binding_new(stream->volume_api, &owner_info, target_info);
++}
++
++void pas_stream_bind_mute_control(pas_stream *stream, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = stream,
++ .set_value = (pa_binding_set_value_cb_t) set_mute_control_internal,
++ };
++
++ pa_assert(stream);
++ pa_assert(target_info);
++
++ stream->use_default_mute_control = false;
++
++ if (stream->mute_control_binding)
++ pa_binding_free(stream->mute_control_binding);
++
++ stream->mute_control_binding = pa_binding_new(stream->volume_api, &owner_info, target_info);
++}
++
++void pas_stream_description_changed(pas_stream *stream, const char *new_description) {
++ char *old_description;
++
++ pa_assert(stream);
++ pa_assert(new_description);
++
++ old_description = stream->description;
++
++ if (pa_streq(new_description, old_description))
++ return;
++
++ stream->description = pa_xstrdup(new_description);
++ pa_log_debug("The description of stream %s changed from \"%s\" to \"%s\".", stream->name, old_description,
++ new_description);
++ pa_xfree(old_description);
++ pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_DESCRIPTION_CHANGED], stream);
++}
++
++void pas_stream_set_audio_group_for_volume(pas_stream *stream, pa_audio_group *group) {
++ pa_assert(stream);
++
++ if (group == stream->audio_group_for_volume)
++ return;
++
++ if (stream->audio_group_for_volume)
++ pa_audio_group_remove_volume_stream(stream->audio_group_for_volume, stream);
++
++ stream->audio_group_for_volume = group;
++
++ if (group)
++ pa_audio_group_add_volume_stream(group, stream);
++}
++
++void pas_stream_set_audio_group_for_mute(pas_stream *stream, pa_audio_group *group) {
++ pa_assert(stream);
++
++ if (group == stream->audio_group_for_mute)
++ return;
++
++ if (stream->audio_group_for_mute)
++ pa_audio_group_remove_mute_stream(stream->audio_group_for_mute, stream);
++
++ stream->audio_group_for_mute = group;
++
++ if (group)
++ pa_audio_group_add_mute_stream(group, stream);
++}
+diff --git a/src/modules/volume-api/sstream.h b/src/modules/volume-api/sstream.h
+new file mode 100644
+index 0000000..a65b34c
+--- /dev/null
++++ b/src/modules/volume-api/sstream.h
+@@ -0,0 +1,108 @@
++#ifndef foosstreamhfoo
++#define foosstreamhfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/volume-api.h>
++
++/* We use the "pas_" prefix in pas_stream, because there's already pa_stream in
++ * the client API, and there's no good alternative term for streams. The 's' in
++ * "pas" means "server", i.e. the point is that this stuff is for servers,
++ * while pa_stream is for clients. */
++
++typedef struct pas_stream pas_stream;
++
++struct pas_stream {
++ pa_volume_api *volume_api;
++ uint32_t index;
++ const char *name;
++ char *description;
++ pa_direction_t direction;
++ pa_proplist *proplist;
++ pa_volume_control *volume_control;
++ pa_mute_control *mute_control;
++ bool use_default_volume_control;
++ bool use_default_mute_control;
++ bool have_own_volume_control;
++ bool have_own_mute_control;
++ pa_volume_control *own_volume_control;
++ pa_mute_control *own_mute_control;
++
++ pa_binding *volume_control_binding;
++ pa_binding *mute_control_binding;
++ pa_audio_group *audio_group_for_volume;
++ pa_audio_group *audio_group_for_mute;
++
++ bool linked;
++ bool unlinked;
++
++ /* Called when the own volume control is enabled. The callback
++ * implementation should return a new linked volume control object. The
++ * callback may be NULL, in which case the own volume control can't be
++ * enabled. */
++ pa_volume_control *(*create_own_volume_control)(pas_stream *stream);
++
++ /* Called when the own volume control is disabled. The implementation
++ * should free stream->own_volume_control. The callback may be NULL only if
++ * create_own_volume_control is NULL also. */
++ void (*delete_own_volume_control)(pas_stream *stream);
++
++ /* Called when the own mute control is enabled. The callback implementation
++ * should return a new linked mute control object. The callback may be
++ * NULL, in which case the own mute control can't be enabled. */
++ pa_mute_control *(*create_own_mute_control)(pas_stream *stream);
++
++ /* Called when the own mute control is disabled. The implementation should
++ * free stream->own_mute_control. The callback may be NULL only if
++ * create_own_mute_control is NULL also. */
++ void (*delete_own_mute_control)(pas_stream *stream);
++
++ void *userdata;
++};
++
++pas_stream *pas_stream_new(pa_volume_api *api, const char *name, const char *description, pa_direction_t direction);
++void pas_stream_put(pas_stream *stream, pa_proplist *initial_properties);
++void pas_stream_unlink(pas_stream *stream);
++void pas_stream_free(pas_stream *stream);
++
++/* Called by the stream implementation and possibly by policy modules.
++ * Enabling own controls may fail (the stream may not support own controls),
++ * disabling will never fail. */
++int pas_stream_set_have_own_volume_control(pas_stream *stream, bool have);
++int pas_stream_set_have_own_mute_control(pas_stream *stream, bool have);
++
++/* Called by policy modules. */
++void pas_stream_set_volume_control(pas_stream *stream, pa_volume_control *control);
++void pas_stream_set_mute_control(pas_stream *stream, pa_mute_control *control);
++void pas_stream_bind_volume_control(pas_stream *stream, pa_binding_target_info *target_info);
++void pas_stream_bind_mute_control(pas_stream *stream, pa_binding_target_info *target_info);
++
++/* Called by the stream implementation. */
++void pas_stream_description_changed(pas_stream *stream, const char *new_description);
++
++/* Called by audio-group.c only. Adding a stream to an audio group happens
++ * implicitly when the volume or mute control of a stream is set to point to
++ * the own control of an audio group. */
++void pas_stream_set_audio_group_for_volume(pas_stream *stream, pa_audio_group *group);
++void pas_stream_set_audio_group_for_mute(pas_stream *stream, pa_audio_group *group);
++
++#endif
+diff --git a/src/modules/volume-api/stream-creator.c b/src/modules/volume-api/stream-creator.c
+new file mode 100644
+index 0000000..2bd0053
+--- /dev/null
++++ b/src/modules/volume-api/stream-creator.c
+@@ -0,0 +1,691 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "stream-creator.h"
++
++#include <modules/volume-api/sstream.h>
++#include <modules/volume-api/mute-control.h>
++#include <modules/volume-api/volume-control.h>
++
++#include <pulsecore/core-util.h>
++#include <pulsecore/i18n.h>
++
++struct pa_stream_creator {
++ pa_volume_api *volume_api;
++ pa_hashmap *streams; /* pa_sink_input/pa_source_output -> struct stream */
++ pa_hook_slot *sink_input_put_slot;
++ pa_hook_slot *sink_input_unlink_slot;
++ pa_hook_slot *source_output_put_slot;
++ pa_hook_slot *source_output_unlink_slot;
++};
++
++enum stream_type {
++ STREAM_TYPE_SINK_INPUT,
++ STREAM_TYPE_SOURCE_OUTPUT,
++};
++
++struct stream {
++ pa_stream_creator *creator;
++ enum stream_type type;
++ pa_sink_input *sink_input;
++ pa_source_output *source_output;
++ pa_client *client;
++ pas_stream *stream;
++
++ bool unlinked;
++
++ pa_hook_slot *proplist_changed_slot;
++ pa_hook_slot *client_proplist_changed_slot;
++ pa_hook_slot *volume_changed_slot;
++ pa_hook_slot *mute_changed_slot;
++};
++
++static char *get_stream_volume_and_mute_control_description_malloc(struct stream *stream) {
++ const char *application_name = NULL;
++ char *description;
++
++ pa_assert(stream);
++
++ if (stream->client)
++ application_name = pa_proplist_gets(stream->client->proplist, PA_PROP_APPLICATION_NAME);
++
++ if (application_name)
++ description = pa_sprintf_malloc("%s: %s", application_name, stream->stream->description);
++ else
++ description = pa_xstrdup(stream->stream->description);
++
++ return description;
++}
++
++static int volume_control_set_volume_cb(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance) {
++ struct stream *stream;
++ pa_bvolume bvolume;
++ pa_cvolume cvolume;
++
++ pa_assert(control);
++ pa_assert(volume);
++
++ stream = control->userdata;
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ pa_bvolume_from_cvolume(&bvolume, &stream->sink_input->volume, &stream->sink_input->channel_map);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ pa_bvolume_from_cvolume(&bvolume, &stream->source_output->volume, &stream->source_output->channel_map);
++ break;
++ }
++
++ if (set_volume)
++ bvolume.volume = volume->volume;
++
++ if (set_balance)
++ pa_bvolume_copy_balance(&bvolume, volume);
++
++ pa_bvolume_to_cvolume(&bvolume, &cvolume);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ pa_sink_input_set_volume(stream->sink_input, &cvolume, true, true);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ pa_source_output_set_volume(stream->source_output, &cvolume, true, true);
++ break;
++ }
++
++ return 0;
++}
++
++static pa_hook_result_t sink_input_or_source_output_volume_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct stream *stream = userdata;
++ pa_sink_input *input = NULL;
++ pa_source_output *output = NULL;
++ pa_bvolume bvolume;
++
++ pa_assert(stream);
++ pa_assert(call_data);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ input = call_data;
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ output = call_data;
++ break;
++ }
++
++ if ((input && input != stream->sink_input) || (output && output != stream->source_output))
++ return PA_HOOK_OK;
++
++ if (input)
++ pa_bvolume_from_cvolume(&bvolume, &input->volume, &input->channel_map);
++ else
++ pa_bvolume_from_cvolume(&bvolume, &output->volume, &output->channel_map);
++
++ pa_volume_control_volume_changed(stream->stream->own_volume_control, &bvolume, true, true);
++
++ return PA_HOOK_OK;
++}
++
++static void volume_control_set_initial_volume_cb(pa_volume_control *control) {
++ struct stream *stream;
++ pa_cvolume cvolume;
++
++ pa_assert(control);
++
++ stream = control->userdata;
++ pa_bvolume_to_cvolume(&control->volume, &cvolume);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ pa_sink_input_set_volume(stream->sink_input, &cvolume, true, true);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ pa_source_output_set_volume(stream->source_output, &cvolume, true, true);
++ break;
++ }
++}
++
++static int mute_control_set_mute_cb(pa_mute_control *control, bool mute) {
++ struct stream *stream;
++
++ pa_assert(control);
++
++ stream = control->userdata;
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ pa_sink_input_set_mute(stream->sink_input, mute, true);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ pa_source_output_set_mute(stream->source_output, mute, true);
++ break;
++ }
++
++ return 0;
++}
++
++static pa_hook_result_t sink_input_or_source_output_mute_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct stream *stream = userdata;
++ pa_sink_input *input = NULL;
++ pa_source_output *output = NULL;
++ bool mute;
++
++ pa_assert(stream);
++ pa_assert(call_data);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ input = call_data;
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ output = call_data;
++ break;
++ }
++
++ if ((input && input != stream->sink_input) || (output && output != stream->source_output))
++ return PA_HOOK_OK;
++
++ if (input)
++ mute = input->muted;
++ else
++ mute = output->muted;
++
++ pa_mute_control_mute_changed(stream->stream->own_mute_control, mute);
++
++ return PA_HOOK_OK;
++}
++
++static void mute_control_set_initial_mute_cb(pa_mute_control *control) {
++ struct stream *stream;
++
++ pa_assert(control);
++
++ stream = control->userdata;
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ pa_sink_input_set_mute(stream->sink_input, control->mute, true);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ pa_source_output_set_mute(stream->source_output, control->mute, true);
++ break;
++ }
++}
++
++static const char *get_sink_input_description(pa_sink_input *input) {
++ const char *description;
++
++ pa_assert(input);
++
++ description = pa_proplist_gets(input->proplist, PA_PROP_MEDIA_NAME);
++ if (description)
++ return description;
++
++ return NULL;
++}
++
++static const char *get_source_output_description(pa_source_output *output) {
++ const char *description;
++
++ pa_assert(output);
++
++ description = pa_proplist_gets(output->proplist, PA_PROP_MEDIA_NAME);
++ if (description)
++ return description;
++
++ return NULL;
++}
++
++static pa_volume_control *stream_create_own_volume_control_cb(pas_stream *s) {
++ struct stream *stream;
++ const char *name = NULL;
++ char *description;
++ pa_volume_control *control;
++ pa_bvolume volume;
++
++ pa_assert(s);
++
++ stream = s->userdata;
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ name = "sink-input-volume-control";
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ name = "source-output-volume-control";
++ break;
++ }
++
++ description = get_stream_volume_and_mute_control_description_malloc(stream);
++ control = pa_volume_control_new(stream->creator->volume_api, name, description, true, false);
++ pa_xfree(description);
++ control->set_volume = volume_control_set_volume_cb;
++ control->userdata = stream;
++
++ pa_assert(!stream->volume_changed_slot);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ stream->volume_changed_slot =
++ pa_hook_connect(&stream->sink_input->core->hooks[PA_CORE_HOOK_SINK_INPUT_VOLUME_CHANGED], PA_HOOK_NORMAL,
++ sink_input_or_source_output_volume_changed_cb, stream);
++ pa_bvolume_from_cvolume(&volume, &stream->sink_input->volume, &stream->sink_input->channel_map);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ stream->volume_changed_slot =
++ pa_hook_connect(&stream->source_output->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_VOLUME_CHANGED],
++ PA_HOOK_NORMAL, sink_input_or_source_output_volume_changed_cb, stream);
++ pa_bvolume_from_cvolume(&volume, &stream->source_output->volume, &stream->source_output->channel_map);
++ break;
++ }
++
++ pa_volume_control_put(control, &volume, volume_control_set_initial_volume_cb);
++
++ return control;
++}
++
++static void stream_delete_own_volume_control_cb(pas_stream *s) {
++ struct stream *stream;
++
++ pa_assert(s);
++
++ stream = s->userdata;
++ pa_hook_slot_free(stream->volume_changed_slot);
++ stream->volume_changed_slot = NULL;
++ pa_volume_control_free(s->own_volume_control);
++}
++
++static pa_mute_control *stream_create_own_mute_control_cb(pas_stream *s) {
++ struct stream *stream;
++ const char *name = NULL;
++ char *description;
++ pa_mute_control *control;
++ bool mute = false;
++
++ pa_assert(s);
++
++ stream = s->userdata;
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ name = "sink-input-mute-control";
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ name = "source-output-mute-control";
++ break;
++ }
++
++ description = get_stream_volume_and_mute_control_description_malloc(stream);
++ control = pa_mute_control_new(stream->creator->volume_api, name, description);
++ pa_xfree(description);
++ control->set_mute = mute_control_set_mute_cb;
++ control->userdata = stream;
++
++ pa_assert(!stream->mute_changed_slot);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ stream->mute_changed_slot =
++ pa_hook_connect(&stream->sink_input->core->hooks[PA_CORE_HOOK_SINK_INPUT_MUTE_CHANGED], PA_HOOK_NORMAL,
++ sink_input_or_source_output_mute_changed_cb, stream);
++ mute = stream->sink_input->muted;
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ stream->mute_changed_slot =
++ pa_hook_connect(&stream->source_output->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MUTE_CHANGED],
++ PA_HOOK_NORMAL, sink_input_or_source_output_mute_changed_cb, stream);
++ mute = stream->source_output->muted;
++ break;
++ }
++
++ pa_mute_control_put(control, mute, true, mute_control_set_initial_mute_cb);
++
++ return control;
++}
++
++static void stream_delete_own_mute_control_cb(pas_stream *s) {
++ struct stream *stream;
++
++ pa_assert(s);
++
++ stream = s->userdata;
++ pa_hook_slot_free(stream->mute_changed_slot);
++ stream->mute_changed_slot = NULL;
++ pa_mute_control_free(s->own_mute_control);
++}
++
++static pa_hook_result_t sink_input_or_source_output_proplist_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct stream *stream = userdata;
++ pa_sink_input *input = NULL;
++ pa_source_output *output = NULL;
++ const char *new_stream_description = NULL;
++ char *new_control_description;
++
++ pa_assert(stream);
++ pa_assert(call_data);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ input = call_data;
++
++ if (input != stream->sink_input)
++ return PA_HOOK_OK;
++
++ new_stream_description = get_sink_input_description(input);
++ if (!new_stream_description)
++ new_stream_description = stream->stream->name;
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ output = call_data;
++
++ if (output != stream->source_output)
++ return PA_HOOK_OK;
++
++ new_stream_description = get_source_output_description(output);
++ if (!new_stream_description)
++ new_stream_description = stream->stream->name;
++ break;
++ }
++
++ pas_stream_description_changed(stream->stream, new_stream_description);
++
++ new_control_description = get_stream_volume_and_mute_control_description_malloc(stream);
++
++ if (stream->stream->own_volume_control)
++ pa_volume_control_description_changed(stream->stream->own_volume_control, new_control_description);
++
++ if (stream->stream->own_mute_control)
++ pa_mute_control_description_changed(stream->stream->own_mute_control, new_control_description);
++
++ pa_xfree(new_control_description);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t client_proplist_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct stream *stream = userdata;
++ pa_client *client = call_data;
++ char *description;
++
++ pa_assert(stream);
++ pa_assert(client);
++
++ if (client != stream->client)
++ return PA_HOOK_OK;
++
++ description = get_stream_volume_and_mute_control_description_malloc(stream);
++
++ if (stream->stream->own_volume_control)
++ pa_volume_control_description_changed(stream->stream->own_volume_control, description);
++
++ if (stream->stream->own_mute_control)
++ pa_mute_control_description_changed(stream->stream->own_mute_control, description);
++
++ pa_xfree(description);
++
++ return PA_HOOK_OK;
++}
++
++static struct stream *stream_new(pa_stream_creator *creator, enum stream_type type, void *core_stream) {
++ struct stream *stream;
++ const char *name = NULL;
++ const char *description = NULL;
++ pa_direction_t direction = PA_DIRECTION_OUTPUT;
++
++ pa_assert(creator);
++ pa_assert(core_stream);
++
++ stream = pa_xnew0(struct stream, 1);
++ stream->creator = creator;
++ stream->type = type;
++
++ switch (type) {
++ case STREAM_TYPE_SINK_INPUT:
++ stream->sink_input = core_stream;
++ stream->client = stream->sink_input->client;
++ name = "sink-input-stream";
++
++ description = get_sink_input_description(stream->sink_input);
++ if (!description)
++ description = name;
++
++ direction = PA_DIRECTION_OUTPUT;
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ stream->source_output = core_stream;
++ stream->client = stream->source_output->client;
++ name = "source-output-stream";
++
++ description = get_source_output_description(stream->source_output);
++ if (!description)
++ description = name;
++
++ direction = PA_DIRECTION_INPUT;
++ break;
++ }
++
++ stream->stream = pas_stream_new(creator->volume_api, name, description, direction);
++ stream->stream->create_own_volume_control = stream_create_own_volume_control_cb;
++ stream->stream->delete_own_volume_control = stream_delete_own_volume_control_cb;
++ stream->stream->create_own_mute_control = stream_create_own_mute_control_cb;
++ stream->stream->delete_own_mute_control = stream_delete_own_mute_control_cb;
++ stream->stream->userdata = stream;
++ pas_stream_set_have_own_volume_control(stream->stream, true);
++ pas_stream_set_have_own_mute_control(stream->stream, true);
++
++ switch (type) {
++ case STREAM_TYPE_SINK_INPUT:
++ stream->proplist_changed_slot =
++ pa_hook_connect(&stream->sink_input->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], PA_HOOK_NORMAL,
++ sink_input_or_source_output_proplist_changed_cb, stream);
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ stream->proplist_changed_slot =
++ pa_hook_connect(&stream->source_output->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED],
++ PA_HOOK_NORMAL, sink_input_or_source_output_proplist_changed_cb, stream);
++ break;
++ }
++
++ stream->client_proplist_changed_slot =
++ pa_hook_connect(&stream->creator->volume_api->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED],
++ PA_HOOK_NORMAL, client_proplist_changed_cb, stream);
++
++ return stream;
++}
++
++static void stream_put(struct stream *stream) {
++ pa_proplist *proplist = NULL;
++
++ pa_assert(stream);
++
++ switch (stream->type) {
++ case STREAM_TYPE_SINK_INPUT:
++ proplist = stream->sink_input->proplist;
++ break;
++
++ case STREAM_TYPE_SOURCE_OUTPUT:
++ proplist = stream->source_output->proplist;
++ break;
++ }
++
++ pas_stream_put(stream->stream, proplist);
++}
++
++static void stream_unlink(struct stream *stream) {
++ pa_assert(stream);
++
++ if (stream->unlinked)
++ return;
++
++ stream->unlinked = true;
++
++ if (stream->stream)
++ pas_stream_unlink(stream->stream);
++}
++
++static void stream_free(struct stream *stream) {
++ pa_assert(stream);
++
++ if (!stream->unlinked)
++ stream_unlink(stream);
++
++ if (stream->client_proplist_changed_slot)
++ pa_hook_slot_free(stream->client_proplist_changed_slot);
++
++ if (stream->proplist_changed_slot)
++ pa_hook_slot_free(stream->proplist_changed_slot);
++
++ if (stream->stream)
++ pas_stream_free(stream->stream);
++
++ pa_xfree(stream);
++}
++
++static void create_stream(pa_stream_creator *creator, enum stream_type type, void *core_stream) {
++ struct stream *stream;
++
++ pa_assert(creator);
++ pa_assert(core_stream);
++
++ stream = stream_new(creator, type, core_stream);
++ pa_hashmap_put(creator->streams, core_stream, stream);
++ stream_put(stream);
++}
++
++static pa_hook_result_t sink_input_put_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_stream_creator *creator = userdata;
++ pa_sink_input *input = call_data;
++
++ pa_assert(creator);
++ pa_assert(input);
++
++ create_stream(creator, STREAM_TYPE_SINK_INPUT, input);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t sink_input_unlink_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_stream_creator *creator = userdata;
++ pa_sink_input *input = call_data;
++
++ pa_assert(creator);
++ pa_assert(input);
++
++ pa_hashmap_remove_and_free(creator->streams, input);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t source_output_put_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_stream_creator *creator = userdata;
++ pa_source_output *output = call_data;
++
++ pa_assert(creator);
++ pa_assert(output);
++
++ create_stream(creator, STREAM_TYPE_SOURCE_OUTPUT, output);
++
++ return PA_HOOK_OK;
++}
++
++static pa_hook_result_t source_output_unlink_cb(void *hook_data, void *call_data, void *userdata) {
++ pa_stream_creator *creator = userdata;
++ pa_source_output *output = call_data;
++
++ pa_assert(creator);
++ pa_assert(output);
++
++ pa_hashmap_remove_and_free(creator->streams, output);
++
++ return PA_HOOK_OK;
++}
++
++pa_stream_creator *pa_stream_creator_new(pa_volume_api *api) {
++ pa_stream_creator *creator;
++ uint32_t idx;
++ pa_sink_input *input;
++ pa_source_output *output;
++
++ pa_assert(api);
++
++ creator = pa_xnew0(pa_stream_creator, 1);
++ creator->volume_api = api;
++ creator->streams = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) stream_free);
++ creator->sink_input_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_NORMAL,
++ sink_input_put_cb, creator);
++ creator->sink_input_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_NORMAL,
++ sink_input_unlink_cb, creator);
++ creator->source_output_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_NORMAL,
++ source_output_put_cb, creator);
++ creator->source_output_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_NORMAL,
++ source_output_unlink_cb, creator);
++
++ PA_IDXSET_FOREACH(input, api->core->sink_inputs, idx)
++ create_stream(creator, STREAM_TYPE_SINK_INPUT, input);
++
++ PA_IDXSET_FOREACH(output, api->core->source_outputs, idx)
++ create_stream(creator, STREAM_TYPE_SOURCE_OUTPUT, output);
++
++ return creator;
++}
++
++void pa_stream_creator_free(pa_stream_creator *creator) {
++ pa_assert(creator);
++
++ if (creator->streams)
++ pa_hashmap_remove_all(creator->streams);
++
++ if (creator->source_output_unlink_slot)
++ pa_hook_slot_free(creator->source_output_unlink_slot);
++
++ if (creator->source_output_put_slot)
++ pa_hook_slot_free(creator->source_output_put_slot);
++
++ if (creator->sink_input_unlink_slot)
++ pa_hook_slot_free(creator->sink_input_unlink_slot);
++
++ if (creator->sink_input_put_slot)
++ pa_hook_slot_free(creator->sink_input_put_slot);
++
++ if (creator->streams)
++ pa_hashmap_free(creator->streams);
++
++ pa_xfree(creator);
++}
+diff --git a/src/modules/volume-api/stream-creator.h b/src/modules/volume-api/stream-creator.h
+new file mode 100644
+index 0000000..97a03a4
+--- /dev/null
++++ b/src/modules/volume-api/stream-creator.h
+@@ -0,0 +1,32 @@
++#ifndef foostreamcreatorhfoo
++#define foostreamcreatorhfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/volume-api.h>
++
++typedef struct pa_stream_creator pa_stream_creator;
++
++pa_stream_creator *pa_stream_creator_new(pa_volume_api *api);
++void pa_stream_creator_free(pa_stream_creator *creator);
++
++#endif
+diff --git a/src/modules/volume-api/volume-api.c b/src/modules/volume-api/volume-api.c
+new file mode 100644
+index 0000000..9abea7e
+--- /dev/null
++++ b/src/modules/volume-api/volume-api.c
+@@ -0,0 +1,647 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "volume-api.h"
++
++#include <modules/volume-api/audio-group.h>
++#include <modules/volume-api/binding.h>
++#include <modules/volume-api/device.h>
++#include <modules/volume-api/device-creator.h>
++#include <modules/volume-api/sstream.h>
++#include <modules/volume-api/stream-creator.h>
++#include <modules/volume-api/volume-control.h>
++
++#include <pulsecore/core-util.h>
++#include <pulsecore/shared.h>
++
++static pa_volume_api *volume_api_new(pa_core *core);
++static void volume_api_free(pa_volume_api *api);
++
++pa_volume_api *pa_volume_api_get(pa_core *core) {
++ pa_volume_api *api;
++
++ pa_assert(core);
++
++ api = pa_shared_get(core, "volume-api");
++
++ if (api)
++ pa_volume_api_ref(api);
++ else {
++ api = volume_api_new(core);
++ pa_assert_se(pa_shared_set(core, "volume-api", api) >= 0);
++ }
++
++ return api;
++}
++
++pa_volume_api *pa_volume_api_ref(pa_volume_api *api) {
++ pa_assert(api);
++
++ api->refcnt++;
++
++ return api;
++}
++
++void pa_volume_api_unref(pa_volume_api *api) {
++ pa_assert(api);
++ pa_assert(api->refcnt > 0);
++
++ api->refcnt--;
++
++ if (api->refcnt == 0) {
++ pa_assert_se(pa_shared_remove(api->core, "volume-api") >= 0);
++ volume_api_free(api);
++ }
++}
++
++void pa_volume_api_add_binding_target_type(pa_volume_api *api, pa_binding_target_type *type) {
++ pa_assert(api);
++ pa_assert(type);
++
++ pa_assert_se(pa_hashmap_put(api->binding_target_types, type->name, type) >= 0);
++
++ pa_log_debug("Added binding target type %s.", type->name);
++
++ pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_BINDING_TARGET_TYPE_ADDED], type);
++}
++
++void pa_volume_api_remove_binding_target_type(pa_volume_api *api, pa_binding_target_type *type) {
++ pa_assert(api);
++ pa_assert(type);
++
++ pa_log_debug("Removing binding target type %s.", type->name);
++
++ pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_BINDING_TARGET_TYPE_REMOVED], type);
++
++ pa_assert_se(pa_hashmap_remove(api->binding_target_types, type->name));
++}
++
++static void create_builtin_binding_target_types(pa_volume_api *api) {
++ pa_binding_target_type *type;
++
++ pa_assert(api);
++
++ type = pa_audio_group_create_binding_target_type(api);
++ pa_volume_api_add_binding_target_type(api, type);
++}
++
++static void delete_builtin_binding_target_types(pa_volume_api *api) {
++ pa_binding_target_type *type;
++
++ pa_assert(api);
++
++ type = pa_hashmap_get(api->binding_target_types, PA_AUDIO_GROUP_BINDING_TARGET_TYPE);
++ pa_volume_api_remove_binding_target_type(api, type);
++}
++
++static void create_objects_defer_event_cb(pa_mainloop_api *mainloop_api, pa_defer_event *event, void *userdata) {
++ pa_volume_api *volume_api = userdata;
++
++ pa_assert(volume_api);
++ pa_assert(event == volume_api->create_objects_defer_event);
++
++ mainloop_api->defer_free(event);
++ volume_api->create_objects_defer_event = NULL;
++
++ volume_api->device_creator = pa_device_creator_new(volume_api);
++ volume_api->stream_creator = pa_stream_creator_new(volume_api);
++}
++
++static pa_volume_api *volume_api_new(pa_core *core) {
++ pa_volume_api *api;
++ unsigned i;
++
++ pa_assert(core);
++
++ api = pa_xnew0(pa_volume_api, 1);
++ api->core = core;
++ api->refcnt = 1;
++ api->binding_target_types = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++ api->names = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
++ api->volume_controls = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++ api->mute_controls = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++ api->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++ api->streams = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++ api->audio_groups = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++
++ for (i = 0; i < PA_VOLUME_API_HOOK_MAX; i++)
++ pa_hook_init(&api->hooks[i], api);
++
++ create_builtin_binding_target_types(api);
++
++ /* We delay the object creation to ensure that policy modules have a chance
++ * to affect the initialization of the objects. If we created the objects
++ * immediately, policy modules wouldn't have a chance of connecting to the
++ * object creation hooks before the objects are created. */
++ api->create_objects_defer_event = core->mainloop->defer_new(core->mainloop, create_objects_defer_event_cb, api);
++
++ pa_log_debug("Created a pa_volume_api object.");
++
++ return api;
++}
++
++static void volume_api_free(pa_volume_api *api) {
++ unsigned i;
++
++ pa_assert(api);
++ pa_assert(api->refcnt == 0);
++
++ pa_log_debug("Freeing the pa_volume_api object.");
++
++ if (api->stream_creator)
++ pa_stream_creator_free(api->stream_creator);
++
++ if (api->device_creator)
++ pa_device_creator_free(api->device_creator);
++
++ if (api->create_objects_defer_event)
++ api->core->mainloop->defer_free(api->create_objects_defer_event);
++
++ if (api->binding_target_types)
++ delete_builtin_binding_target_types(api);
++
++ for (i = 0; i < PA_VOLUME_API_HOOK_MAX; i++)
++ pa_hook_done(&api->hooks[i]);
++
++ if (api->audio_groups) {
++ pa_assert(pa_hashmap_isempty(api->audio_groups));
++ pa_hashmap_free(api->audio_groups);
++ }
++
++ if (api->streams) {
++ pa_assert(pa_hashmap_isempty(api->streams));
++ pa_hashmap_free(api->streams);
++ }
++
++ if (api->devices) {
++ pa_assert(pa_hashmap_isempty(api->devices));
++ pa_hashmap_free(api->devices);
++ }
++
++ if (api->mute_controls) {
++ pa_assert(pa_hashmap_isempty(api->mute_controls));
++ pa_hashmap_free(api->mute_controls);
++ }
++
++ if (api->volume_controls) {
++ pa_assert(pa_hashmap_isempty(api->volume_controls));
++ pa_hashmap_free(api->volume_controls);
++ }
++
++ if (api->names) {
++ pa_assert(pa_hashmap_isempty(api->names));
++ pa_hashmap_free(api->names);
++ }
++
++ if (api->binding_target_types) {
++ pa_assert(pa_hashmap_isempty(api->binding_target_types));
++ pa_hashmap_free(api->binding_target_types);
++ }
++
++ pa_xfree(api);
++}
++
++int pa_volume_api_register_name(pa_volume_api *api, const char *requested_name, bool fail_if_already_registered,
++ const char **registered_name) {
++ char *n;
++
++ pa_assert(api);
++ pa_assert(requested_name);
++ pa_assert(registered_name);
++
++ n = pa_xstrdup(requested_name);
++
++ if (pa_hashmap_put(api->names, n, n) < 0) {
++ unsigned i = 1;
++
++ pa_xfree(n);
++
++ if (fail_if_already_registered) {
++ pa_log("Name %s already registered.", requested_name);
++ return -PA_ERR_EXIST;
++ }
++
++ do {
++ i++;
++ n = pa_sprintf_malloc("%s.%u", requested_name, i);
++ } while (pa_hashmap_put(api->names, n, n) < 0);
++ }
++
++ *registered_name = n;
++
++ return 0;
++}
++
++void pa_volume_api_unregister_name(pa_volume_api *api, const char *name) {
++ pa_assert(api);
++ pa_assert(name);
++
++ pa_assert_se(pa_hashmap_remove_and_free(api->names, name) >= 0);
++}
++
++uint32_t pa_volume_api_allocate_volume_control_index(pa_volume_api *api) {
++ uint32_t idx;
++
++ pa_assert(api);
++
++ idx = api->next_volume_control_index++;
++
++ return idx;
++}
++
++static void set_main_output_volume_control_internal(pa_volume_api *api, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(api);
++
++ old_control = api->main_output_volume_control;
++
++ if (control == old_control)
++ return;
++
++ api->main_output_volume_control = control;
++ pa_log_debug("Main output volume control changed from %s to %s.", old_control ? old_control->name : "(unset)",
++ control ? control->name : "(unset)");
++ pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED], api);
++}
++
++static void set_main_input_volume_control_internal(pa_volume_api *api, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(api);
++
++ old_control = api->main_input_volume_control;
++
++ if (control == old_control)
++ return;
++
++ api->main_input_volume_control = control;
++ pa_log_debug("Main input volume control changed from %s to %s.", old_control ? old_control->name : "(unset)",
++ control ? control->name : "(unset)");
++ pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_INPUT_VOLUME_CONTROL_CHANGED], api);
++}
++
++void pa_volume_api_add_volume_control(pa_volume_api *api, pa_volume_control *control) {
++ pa_assert(api);
++ pa_assert(control);
++
++ pa_assert_se(pa_hashmap_put(api->volume_controls, (void *) control->name, control) >= 0);
++}
++
++int pa_volume_api_remove_volume_control(pa_volume_api *api, pa_volume_control *control) {
++ pa_assert(api);
++ pa_assert(control);
++
++ if (!pa_hashmap_remove(api->volume_controls, control->name))
++ return -1;
++
++ if (control == api->main_output_volume_control)
++ set_main_output_volume_control_internal(api, NULL);
++
++ if (control == api->main_input_volume_control)
++ set_main_input_volume_control_internal(api, NULL);
++
++ return 0;
++}
++
++pa_volume_control *pa_volume_api_get_volume_control_by_index(pa_volume_api *api, uint32_t idx) {
++ pa_volume_control *control;
++ void *state;
++
++ pa_assert(api);
++
++ PA_HASHMAP_FOREACH(control, api->volume_controls, state) {
++ if (control->index == idx)
++ return control;
++ }
++
++ return NULL;
++}
++
++uint32_t pa_volume_api_allocate_mute_control_index(pa_volume_api *api) {
++ uint32_t idx;
++
++ pa_assert(api);
++
++ idx = api->next_mute_control_index++;
++
++ return idx;
++}
++
++static void set_main_output_mute_control_internal(pa_volume_api *api, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(api);
++
++ old_control = api->main_output_mute_control;
++
++ if (control == old_control)
++ return;
++
++ api->main_output_mute_control = control;
++ pa_log_debug("Main output mute control changed from %s to %s.", old_control ? old_control->name : "(unset)",
++ control ? control->name : "(unset)");
++ pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_OUTPUT_MUTE_CONTROL_CHANGED], api);
++}
++
++static void set_main_input_mute_control_internal(pa_volume_api *api, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(api);
++
++ old_control = api->main_input_mute_control;
++
++ if (control == old_control)
++ return;
++
++ api->main_input_mute_control = control;
++ pa_log_debug("Main input mute control changed from %s to %s.", old_control ? old_control->name : "(unset)",
++ control ? control->name : "(unset)");
++ pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_INPUT_MUTE_CONTROL_CHANGED], api);
++}
++
++void pa_volume_api_add_mute_control(pa_volume_api *api, pa_mute_control *control) {
++ pa_assert(api);
++ pa_assert(control);
++
++ pa_assert_se(pa_hashmap_put(api->mute_controls, (void *) control->name, control) >= 0);
++}
++
++int pa_volume_api_remove_mute_control(pa_volume_api *api, pa_mute_control *control) {
++ pa_assert(api);
++ pa_assert(control);
++
++ if (!pa_hashmap_remove(api->mute_controls, control->name))
++ return -1;
++
++ if (control == api->main_output_mute_control)
++ set_main_output_mute_control_internal(api, NULL);
++
++ if (control == api->main_input_mute_control)
++ set_main_input_mute_control_internal(api, NULL);
++
++ return 0;
++}
++
++pa_mute_control *pa_volume_api_get_mute_control_by_index(pa_volume_api *api, uint32_t idx) {
++ pa_mute_control *control;
++ void *state;
++
++ pa_assert(api);
++
++ PA_HASHMAP_FOREACH(control, api->mute_controls, state) {
++ if (control->index == idx)
++ return control;
++ }
++
++ return NULL;
++}
++
++uint32_t pa_volume_api_allocate_device_index(pa_volume_api *api) {
++ uint32_t idx;
++
++ pa_assert(api);
++
++ idx = api->next_device_index++;
++
++ return idx;
++}
++
++void pa_volume_api_add_device(pa_volume_api *api, pa_device *device) {
++ pa_assert(api);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_put(api->devices, (void *) device->name, device) >= 0);
++}
++
++int pa_volume_api_remove_device(pa_volume_api *api, pa_device *device) {
++ pa_assert(api);
++ pa_assert(device);
++
++ if (!pa_hashmap_remove(api->devices, device->name))
++ return -1;
++
++ return 0;
++}
++
++pa_device *pa_volume_api_get_device_by_index(pa_volume_api *api, uint32_t idx) {
++ pa_device *device;
++ void *state;
++
++ pa_assert(api);
++
++ PA_HASHMAP_FOREACH(device, api->devices, state) {
++ if (device->index == idx)
++ return device;
++ }
++
++ return NULL;
++}
++
++uint32_t pa_volume_api_allocate_stream_index(pa_volume_api *api) {
++ uint32_t idx;
++
++ pa_assert(api);
++
++ idx = api->next_stream_index++;
++
++ return idx;
++}
++
++void pa_volume_api_add_stream(pa_volume_api *api, pas_stream *stream) {
++ pa_assert(api);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_put(api->streams, (void *) stream->name, stream) >= 0);
++}
++
++int pa_volume_api_remove_stream(pa_volume_api *api, pas_stream *stream) {
++ pa_assert(api);
++ pa_assert(stream);
++
++ if (!pa_hashmap_remove(api->streams, stream->name))
++ return -1;
++
++ return 0;
++}
++
++pas_stream *pa_volume_api_get_stream_by_index(pa_volume_api *api, uint32_t idx) {
++ pas_stream *stream;
++ void *state;
++
++ pa_assert(api);
++
++ PA_HASHMAP_FOREACH(stream, api->streams, state) {
++ if (stream->index == idx)
++ return stream;
++ }
++
++ return NULL;
++}
++
++uint32_t pa_volume_api_allocate_audio_group_index(pa_volume_api *api) {
++ uint32_t idx;
++
++ pa_assert(api);
++
++ idx = api->next_audio_group_index++;
++
++ return idx;
++}
++
++void pa_volume_api_add_audio_group(pa_volume_api *api, pa_audio_group *group) {
++ pa_assert(api);
++ pa_assert(group);
++
++ pa_assert_se(pa_hashmap_put(api->audio_groups, (void *) group->name, group) >= 0);
++}
++
++int pa_volume_api_remove_audio_group(pa_volume_api *api, pa_audio_group *group) {
++ pa_assert(api);
++ pa_assert(group);
++
++ if (!pa_hashmap_remove(api->audio_groups, group->name))
++ return -1;
++
++ return 0;
++}
++
++pa_audio_group *pa_volume_api_get_audio_group_by_index(pa_volume_api *api, uint32_t idx) {
++ pa_audio_group *group;
++ void *state;
++
++ pa_assert(api);
++
++ PA_HASHMAP_FOREACH(group, api->audio_groups, state) {
++ if (group->index == idx)
++ return group;
++ }
++
++ return NULL;
++}
++
++void pa_volume_api_set_main_output_volume_control(pa_volume_api *api, pa_volume_control *control) {
++ pa_assert(api);
++
++ if (api->main_output_volume_control_binding) {
++ pa_binding_free(api->main_output_volume_control_binding);
++ api->main_output_volume_control_binding = NULL;
++ }
++
++ set_main_output_volume_control_internal(api, control);
++}
++
++void pa_volume_api_set_main_input_volume_control(pa_volume_api *api, pa_volume_control *control) {
++ pa_assert(api);
++
++ if (api->main_input_volume_control_binding) {
++ pa_binding_free(api->main_input_volume_control_binding);
++ api->main_input_volume_control_binding = NULL;
++ }
++
++ set_main_input_volume_control_internal(api, control);
++}
++
++void pa_volume_api_set_main_output_mute_control(pa_volume_api *api, pa_mute_control *control) {
++ pa_assert(api);
++
++ if (api->main_output_mute_control_binding) {
++ pa_binding_free(api->main_output_mute_control_binding);
++ api->main_output_mute_control_binding = NULL;
++ }
++
++ set_main_output_mute_control_internal(api, control);
++}
++
++void pa_volume_api_set_main_input_mute_control(pa_volume_api *api, pa_mute_control *control) {
++ pa_assert(api);
++
++ if (api->main_input_mute_control_binding) {
++ pa_binding_free(api->main_input_mute_control_binding);
++ api->main_input_mute_control_binding = NULL;
++ }
++
++ set_main_input_mute_control_internal(api, control);
++}
++
++void pa_volume_api_bind_main_output_volume_control(pa_volume_api *api, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = api,
++ .set_value = (pa_binding_set_value_cb_t) set_main_output_volume_control_internal,
++ };
++
++ pa_assert(api);
++ pa_assert(target_info);
++
++ if (api->main_output_volume_control_binding)
++ pa_binding_free(api->main_output_volume_control_binding);
++
++ api->main_output_volume_control_binding = pa_binding_new(api, &owner_info, target_info);
++}
++
++void pa_volume_api_bind_main_input_volume_control(pa_volume_api *api, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = api,
++ .set_value = (pa_binding_set_value_cb_t) set_main_input_volume_control_internal,
++ };
++
++ pa_assert(api);
++ pa_assert(target_info);
++
++ if (api->main_input_volume_control_binding)
++ pa_binding_free(api->main_input_volume_control_binding);
++
++ api->main_input_volume_control_binding = pa_binding_new(api, &owner_info, target_info);
++}
++
++void pa_volume_api_bind_main_output_mute_control(pa_volume_api *api, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = api,
++ .set_value = (pa_binding_set_value_cb_t) set_main_output_mute_control_internal,
++ };
++
++ pa_assert(api);
++ pa_assert(target_info);
++
++ if (api->main_output_mute_control_binding)
++ pa_binding_free(api->main_output_mute_control_binding);
++
++ api->main_output_mute_control_binding = pa_binding_new(api, &owner_info, target_info);
++}
++
++void pa_volume_api_bind_main_input_mute_control(pa_volume_api *api, pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = api,
++ .set_value = (pa_binding_set_value_cb_t) set_main_input_mute_control_internal,
++ };
++
++ pa_assert(api);
++ pa_assert(target_info);
++
++ if (api->main_input_mute_control_binding)
++ pa_binding_free(api->main_input_mute_control_binding);
++
++ api->main_input_mute_control_binding = pa_binding_new(api, &owner_info, target_info);
++}
+diff --git a/src/modules/volume-api/volume-api.h b/src/modules/volume-api/volume-api.h
+new file mode 100644
+index 0000000..73a1410
+--- /dev/null
++++ b/src/modules/volume-api/volume-api.h
+@@ -0,0 +1,163 @@
++#ifndef foovolumeapihfoo
++#define foovolumeapihfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <pulsecore/core.h>
++
++typedef struct pa_volume_api pa_volume_api;
++
++/* Avoid circular dependencies... */
++typedef struct pa_audio_group pa_audio_group;
++typedef struct pa_binding pa_binding;
++typedef struct pa_binding_target_info pa_binding_target_info;
++typedef struct pa_binding_target_type pa_binding_target_type;
++typedef struct pa_device pa_device;
++typedef struct pa_device_creator pa_device_creator;
++typedef struct pa_mute_control pa_mute_control;
++typedef struct pas_stream pas_stream;
++typedef struct pa_stream_creator pa_stream_creator;
++typedef struct pa_volume_control pa_volume_control;
++
++enum {
++ PA_VOLUME_API_HOOK_BINDING_TARGET_TYPE_ADDED,
++ PA_VOLUME_API_HOOK_BINDING_TARGET_TYPE_REMOVED,
++ PA_VOLUME_API_HOOK_VOLUME_CONTROL_PUT,
++ PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK,
++ PA_VOLUME_API_HOOK_VOLUME_CONTROL_DESCRIPTION_CHANGED,
++ PA_VOLUME_API_HOOK_VOLUME_CONTROL_VOLUME_CHANGED,
++ PA_VOLUME_API_HOOK_MUTE_CONTROL_PUT,
++ PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK,
++ PA_VOLUME_API_HOOK_MUTE_CONTROL_DESCRIPTION_CHANGED,
++ PA_VOLUME_API_HOOK_MUTE_CONTROL_MUTE_CHANGED,
++ PA_VOLUME_API_HOOK_DEVICE_PUT,
++ PA_VOLUME_API_HOOK_DEVICE_UNLINK,
++ PA_VOLUME_API_HOOK_DEVICE_DESCRIPTION_CHANGED,
++ PA_VOLUME_API_HOOK_DEVICE_VOLUME_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_DEVICE_MUTE_CONTROL_CHANGED,
++
++ /* Policy modules can use this to set the initial volume control for a
++ * stream. The hook callback should use pas_stream_set_volume_control() to
++ * set the volume control. The hook callback should not do anything if
++ * stream->volume_control is already non-NULL. */
++ PA_VOLUME_API_HOOK_STREAM_SET_INITIAL_VOLUME_CONTROL,
++
++ /* Policy modules can use this to set the initial mute control for a
++ * stream. The hook callback should use pas_stream_set_mute_control() to
++ * set the mute control. The hook callback should not do anything if
++ * stream->mute_control is already non-NULL. */
++ PA_VOLUME_API_HOOK_STREAM_SET_INITIAL_MUTE_CONTROL,
++
++ PA_VOLUME_API_HOOK_STREAM_PUT,
++ PA_VOLUME_API_HOOK_STREAM_UNLINK,
++ PA_VOLUME_API_HOOK_STREAM_DESCRIPTION_CHANGED,
++ PA_VOLUME_API_HOOK_STREAM_VOLUME_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_STREAM_MUTE_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT,
++ PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK,
++ PA_VOLUME_API_HOOK_AUDIO_GROUP_VOLUME_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_AUDIO_GROUP_MUTE_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_MAIN_INPUT_VOLUME_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_MAIN_OUTPUT_MUTE_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_MAIN_INPUT_MUTE_CONTROL_CHANGED,
++ PA_VOLUME_API_HOOK_MAX
++};
++
++struct pa_volume_api {
++ pa_core *core;
++ unsigned refcnt;
++ pa_hashmap *binding_target_types; /* name -> pa_binding_target_type */
++ pa_hashmap *names; /* object name -> object name (hashmap-as-a-set) */
++ pa_hashmap *volume_controls; /* name -> pa_volume_control */
++ pa_hashmap *mute_controls; /* name -> pa_mute_control */
++ pa_hashmap *devices; /* name -> pa_device */
++ pa_hashmap *streams; /* name -> pas_stream */
++ pa_hashmap *audio_groups; /* name -> pa_audio_group */
++ pa_volume_control *main_output_volume_control;
++ pa_volume_control *main_input_volume_control;
++ pa_mute_control *main_output_mute_control;
++ pa_mute_control *main_input_mute_control;
++
++ uint32_t next_volume_control_index;
++ uint32_t next_mute_control_index;
++ uint32_t next_device_index;
++ uint32_t next_stream_index;
++ uint32_t next_audio_group_index;
++ pa_binding *main_output_volume_control_binding;
++ pa_binding *main_input_volume_control_binding;
++ pa_binding *main_output_mute_control_binding;
++ pa_binding *main_input_mute_control_binding;
++ pa_hook hooks[PA_VOLUME_API_HOOK_MAX];
++ pa_defer_event *create_objects_defer_event;
++ pa_device_creator *device_creator;
++ pa_stream_creator *stream_creator;
++};
++
++pa_volume_api *pa_volume_api_get(pa_core *core);
++pa_volume_api *pa_volume_api_ref(pa_volume_api *api);
++void pa_volume_api_unref(pa_volume_api *api);
++
++void pa_volume_api_add_binding_target_type(pa_volume_api *api, pa_binding_target_type *type);
++void pa_volume_api_remove_binding_target_type(pa_volume_api *api, pa_binding_target_type *type);
++
++/* If fail_if_already_registered is false, this function never fails. */
++int pa_volume_api_register_name(pa_volume_api *api, const char *requested_name, bool fail_if_already_registered,
++ const char **registered_name);
++
++void pa_volume_api_unregister_name(pa_volume_api *api, const char *name);
++
++uint32_t pa_volume_api_allocate_volume_control_index(pa_volume_api *api);
++void pa_volume_api_add_volume_control(pa_volume_api *api, pa_volume_control *control);
++int pa_volume_api_remove_volume_control(pa_volume_api *api, pa_volume_control *control);
++pa_volume_control *pa_volume_api_get_volume_control_by_index(pa_volume_api *api, uint32_t idx);
++
++uint32_t pa_volume_api_allocate_mute_control_index(pa_volume_api *api);
++void pa_volume_api_add_mute_control(pa_volume_api *api, pa_mute_control *control);
++int pa_volume_api_remove_mute_control(pa_volume_api *api, pa_mute_control *control);
++pa_mute_control *pa_volume_api_get_mute_control_by_index(pa_volume_api *api, uint32_t idx);
++
++uint32_t pa_volume_api_allocate_device_index(pa_volume_api *api);
++void pa_volume_api_add_device(pa_volume_api *api, pa_device *device);
++int pa_volume_api_remove_device(pa_volume_api *api, pa_device *device);
++pa_device *pa_volume_api_get_device_by_index(pa_volume_api *api, uint32_t idx);
++
++uint32_t pa_volume_api_allocate_stream_index(pa_volume_api *api);
++void pa_volume_api_add_stream(pa_volume_api *api, pas_stream *stream);
++int pa_volume_api_remove_stream(pa_volume_api *api, pas_stream *stream);
++pas_stream *pa_volume_api_get_stream_by_index(pa_volume_api *api, uint32_t idx);
++
++uint32_t pa_volume_api_allocate_audio_group_index(pa_volume_api *api);
++void pa_volume_api_add_audio_group(pa_volume_api *api, pa_audio_group *group);
++int pa_volume_api_remove_audio_group(pa_volume_api *api, pa_audio_group *group);
++pa_audio_group *pa_volume_api_get_audio_group_by_index(pa_volume_api *api, uint32_t idx);
++
++void pa_volume_api_set_main_output_volume_control(pa_volume_api *api, pa_volume_control *control);
++void pa_volume_api_set_main_input_volume_control(pa_volume_api *api, pa_volume_control *control);
++void pa_volume_api_set_main_output_mute_control(pa_volume_api *api, pa_mute_control *control);
++void pa_volume_api_set_main_input_mute_control(pa_volume_api *api, pa_mute_control *control);
++void pa_volume_api_bind_main_output_volume_control(pa_volume_api *api, pa_binding_target_info *target_info);
++void pa_volume_api_bind_main_input_volume_control(pa_volume_api *api, pa_binding_target_info *target_info);
++void pa_volume_api_bind_main_output_mute_control(pa_volume_api *api, pa_binding_target_info *target_info);
++void pa_volume_api_bind_main_input_mute_control(pa_volume_api *api, pa_binding_target_info *target_info);
++
++#endif
+diff --git a/src/modules/volume-api/volume-control.c b/src/modules/volume-api/volume-control.c
+new file mode 100644
+index 0000000..c7f5dbb
+--- /dev/null
++++ b/src/modules/volume-api/volume-control.c
+@@ -0,0 +1,363 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "volume-control.h"
++
++#include <modules/volume-api/audio-group.h>
++#include <modules/volume-api/device.h>
++#include <modules/volume-api/sstream.h>
++
++#include <pulsecore/core-util.h>
++
++pa_volume_control *pa_volume_control_new(pa_volume_api *api, const char *name, const char *description, bool convertible_to_dB,
++ bool channel_map_is_writable) {
++ pa_volume_control *control;
++
++ pa_assert(api);
++ pa_assert(name);
++ pa_assert(description);
++
++ control = pa_xnew0(pa_volume_control, 1);
++ control->volume_api = api;
++ control->index = pa_volume_api_allocate_volume_control_index(api);
++ pa_assert_se(pa_volume_api_register_name(api, name, false, &control->name) >= 0);
++ control->description = pa_xstrdup(description);
++ control->proplist = pa_proplist_new();
++ pa_bvolume_init_invalid(&control->volume);
++ control->convertible_to_dB = convertible_to_dB;
++ control->channel_map_is_writable = channel_map_is_writable;
++ control->devices = pa_hashmap_new(NULL, NULL);
++ control->default_for_devices = pa_hashmap_new(NULL, NULL);
++ control->streams = pa_hashmap_new(NULL, NULL);
++ control->audio_groups = pa_hashmap_new(NULL, NULL);
++
++ return control;
++}
++
++void pa_volume_control_put(pa_volume_control *control, const pa_bvolume *initial_volume,
++ pa_volume_control_set_initial_volume_cb_t set_initial_volume_cb) {
++ const char *prop_key;
++ void *state = NULL;
++ char volume_str[PA_VOLUME_SNPRINT_VERBOSE_MAX];
++ char balance_str[PA_BVOLUME_SNPRINT_BALANCE_MAX];
++
++ pa_assert(control);
++ pa_assert((initial_volume && pa_bvolume_valid(initial_volume, true, true)) || control->set_volume);
++ pa_assert((initial_volume && pa_channel_map_valid(&initial_volume->channel_map)) || control->channel_map_is_writable);
++ pa_assert(set_initial_volume_cb || !control->set_volume);
++
++ if (initial_volume && pa_bvolume_valid(initial_volume, true, false))
++ control->volume.volume = initial_volume->volume;
++ else
++ control->volume.volume = PA_VOLUME_NORM / 3;
++
++ if (initial_volume && pa_bvolume_valid(initial_volume, false, true))
++ pa_bvolume_copy_balance(&control->volume, initial_volume);
++ else if (initial_volume && pa_channel_map_valid(&initial_volume->channel_map))
++ pa_bvolume_reset_balance(&control->volume, &initial_volume->channel_map);
++ else {
++ pa_channel_map_init_mono(&control->volume.channel_map);
++ pa_bvolume_reset_balance(&control->volume, &control->volume.channel_map);
++ }
++
++ if (set_initial_volume_cb)
++ set_initial_volume_cb(control);
++
++ pa_volume_api_add_volume_control(control->volume_api, control);
++
++ control->linked = true;
++
++ pa_log_debug("Created volume control #%u.", control->index);
++ pa_log_debug(" Name: %s", control->name);
++ pa_log_debug(" Description: %s", control->description);
++ pa_log_debug(" Properties:");
++
++ while ((prop_key = pa_proplist_iterate(control->proplist, &state)))
++ pa_log_debug(" %s = %s", prop_key, pa_strnull(pa_proplist_gets(control->proplist, prop_key)));
++
++ pa_log_debug(" Volume: %s", pa_volume_snprint_verbose(volume_str, sizeof(volume_str), control->volume.volume,
++ control->convertible_to_dB));
++ pa_log_debug(" Balance: %s", pa_bvolume_snprint_balance(balance_str, sizeof(balance_str), &control->volume));
++ pa_log_debug(" Channel map is writable: %s", pa_yes_no(control->channel_map_is_writable));
++
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_PUT], control);
++}
++
++void pa_volume_control_unlink(pa_volume_control *control) {
++ pa_audio_group *group;
++ pa_device *device;
++ pas_stream *stream;
++
++ pa_assert(control);
++
++ if (control->unlinked) {
++ pa_log_debug("Unlinking volume control %s (already unlinked, this is a no-op).", control->name);
++ return;
++ }
++
++ control->unlinked = true;
++
++ pa_log_debug("Unlinking volume control %s.", control->name);
++
++ if (control->linked)
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK], control);
++
++ pa_volume_api_remove_volume_control(control->volume_api, control);
++
++ while ((group = pa_hashmap_first(control->audio_groups)))
++ pa_audio_group_set_volume_control(group, NULL);
++
++ while ((stream = pa_hashmap_first(control->streams)))
++ pas_stream_set_volume_control(stream, NULL);
++
++ while ((device = pa_hashmap_first(control->default_for_devices)))
++ pa_device_set_default_volume_control(device, NULL);
++
++ while ((device = pa_hashmap_first(control->devices))) {
++ /* Why do we have this assertion here? The concern is that if we call
++ * pa_device_set_volume_control() for some device that has the
++ * use_default_volume_control flag set, then that flag will be unset as
++ * a side effect, and we don't want that side effect. This assertion
++ * should be safe, because we just called
++ * pa_device_set_default_volume_control(NULL) for each device that this
++ * control was the default for, and that should ensure that we don't
++ * any more hold any references to devices that used to use this
++ * control as the default. */
++ pa_assert(!device->use_default_volume_control);
++ pa_device_set_volume_control(device, NULL);
++ }
++}
++
++void pa_volume_control_free(pa_volume_control *control) {
++ pa_assert(control);
++
++ if (!control->unlinked)
++ pa_volume_control_unlink(control);
++
++ if (control->audio_groups) {
++ pa_assert(pa_hashmap_isempty(control->audio_groups));
++ pa_hashmap_free(control->audio_groups);
++ }
++
++ if (control->streams) {
++ pa_assert(pa_hashmap_isempty(control->streams));
++ pa_hashmap_free(control->streams);
++ }
++
++ if (control->default_for_devices) {
++ pa_assert(pa_hashmap_isempty(control->default_for_devices));
++ pa_hashmap_free(control->default_for_devices);
++ }
++
++ if (control->devices) {
++ pa_assert(pa_hashmap_isempty(control->devices));
++ pa_hashmap_free(control->devices);
++ }
++
++ if (control->proplist)
++ pa_proplist_free(control->proplist);
++
++ pa_xfree(control->description);
++
++ if (control->name)
++ pa_volume_api_unregister_name(control->volume_api, control->name);
++
++ pa_xfree(control);
++}
++
++void pa_volume_control_set_owner_audio_group(pa_volume_control *control, pa_audio_group *group) {
++ pa_assert(control);
++ pa_assert(group);
++
++ control->owner_audio_group = group;
++}
++
++static void set_volume_internal(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance) {
++ pa_bvolume old_volume;
++ bool volume_changed;
++ bool balance_changed;
++
++ pa_assert(control);
++ pa_assert(volume);
++
++ old_volume = control->volume;
++ volume_changed = !pa_bvolume_equal(volume, &old_volume, set_volume, false);
++ balance_changed = !pa_bvolume_equal(volume, &old_volume, false, set_balance);
++
++ if (!volume_changed && !balance_changed)
++ return;
++
++ if (volume_changed)
++ control->volume.volume = volume->volume;
++
++ if (balance_changed)
++ pa_bvolume_copy_balance(&control->volume, volume);
++
++ if (!control->linked || control->unlinked)
++ return;
++
++ if (volume_changed) {
++ char old_volume_str[PA_VOLUME_SNPRINT_VERBOSE_MAX];
++ char new_volume_str[PA_VOLUME_SNPRINT_VERBOSE_MAX];
++
++ pa_log_debug("The volume of volume control %s changed from %s to %s.", control->name,
++ pa_volume_snprint_verbose(old_volume_str, sizeof(old_volume_str), old_volume.volume,
++ control->convertible_to_dB),
++ pa_volume_snprint_verbose(new_volume_str, sizeof(new_volume_str), control->volume.volume,
++ control->convertible_to_dB));
++ }
++
++ if (balance_changed) {
++ char old_balance_str[PA_BVOLUME_SNPRINT_BALANCE_MAX];
++ char new_balance_str[PA_BVOLUME_SNPRINT_BALANCE_MAX];
++
++ pa_log_debug("The balance of volume control %s changed from %s to %s.", control->name,
++ pa_bvolume_snprint_balance(old_balance_str, sizeof(old_balance_str), &control->volume),
++ pa_bvolume_snprint_balance(new_balance_str, sizeof(new_balance_str), &control->volume));
++ }
++
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_VOLUME_CHANGED], control);
++}
++
++int pa_volume_control_set_volume(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance) {
++ pa_bvolume volume_local;
++ int r;
++
++ pa_assert(control);
++ pa_assert(volume);
++
++ volume_local = *volume;
++
++ if (!control->set_volume) {
++ pa_log_info("Tried to set the volume of volume control %s, but the volume control doesn't support the operation.",
++ control->name);
++ return -PA_ERR_NOTSUPPORTED;
++ }
++
++ if (set_balance
++ && !control->channel_map_is_writable
++ && !pa_channel_map_equal(&volume_local.channel_map, &control->volume.channel_map))
++ pa_bvolume_remap(&volume_local, &control->volume.channel_map);
++
++ if (pa_bvolume_equal(&volume_local, &control->volume, set_volume, set_balance))
++ return 0;
++
++ control->set_volume_in_progress = true;
++ r = control->set_volume(control, &volume_local, set_volume, set_balance);
++ control->set_volume_in_progress = false;
++
++ if (r >= 0)
++ set_volume_internal(control, &volume_local, set_volume, set_balance);
++
++ return r;
++}
++
++void pa_volume_control_description_changed(pa_volume_control *control, const char *new_description) {
++ char *old_description;
++
++ pa_assert(control);
++ pa_assert(new_description);
++
++ old_description = control->description;
++
++ if (pa_streq(new_description, old_description))
++ return;
++
++ control->description = pa_xstrdup(new_description);
++ pa_log_debug("The description of volume control %s changed from \"%s\" to \"%s\".", control->name, old_description,
++ new_description);
++ pa_xfree(old_description);
++ pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_DESCRIPTION_CHANGED], control);
++}
++
++void pa_volume_control_volume_changed(pa_volume_control *control, const pa_bvolume *new_volume, bool volume_changed,
++ bool balance_changed) {
++ pa_assert(control);
++ pa_assert(new_volume);
++
++ if (!control->linked)
++ return;
++
++ if (control->set_volume_in_progress)
++ return;
++
++ set_volume_internal(control, new_volume, volume_changed, balance_changed);
++}
++
++void pa_volume_control_add_device(pa_volume_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_put(control->devices, device, device) >= 0);
++}
++
++void pa_volume_control_remove_device(pa_volume_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_remove(control->devices, device));
++}
++
++void pa_volume_control_add_default_for_device(pa_volume_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_put(control->default_for_devices, device, device) >= 0);
++}
++
++void pa_volume_control_remove_default_for_device(pa_volume_control *control, pa_device *device) {
++ pa_assert(control);
++ pa_assert(device);
++
++ pa_assert_se(pa_hashmap_remove(control->default_for_devices, device));
++}
++
++void pa_volume_control_add_stream(pa_volume_control *control, pas_stream *stream) {
++ pa_assert(control);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_put(control->streams, stream, stream) >= 0);
++}
++
++void pa_volume_control_remove_stream(pa_volume_control *control, pas_stream *stream) {
++ pa_assert(control);
++ pa_assert(stream);
++
++ pa_assert_se(pa_hashmap_remove(control->streams, stream));
++}
++
++void pa_volume_control_add_audio_group(pa_volume_control *control, pa_audio_group *group) {
++ pa_assert(control);
++ pa_assert(group);
++
++ pa_assert_se(pa_hashmap_put(control->audio_groups, group, group) >= 0);
++}
++
++void pa_volume_control_remove_audio_group(pa_volume_control *control, pa_audio_group *group) {
++ pa_assert(control);
++ pa_assert(group);
++
++ pa_assert_se(pa_hashmap_remove(control->audio_groups, group));
++}
+diff --git a/src/modules/volume-api/volume-control.h b/src/modules/volume-api/volume-control.h
+new file mode 100644
+index 0000000..aaba758
+--- /dev/null
++++ b/src/modules/volume-api/volume-control.h
+@@ -0,0 +1,112 @@
++#ifndef foovolumecontrolhfoo
++#define foovolumecontrolhfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/bvolume.h>
++#include <modules/volume-api/volume-api.h>
++
++typedef struct pa_volume_control pa_volume_control;
++
++struct pa_volume_control {
++ pa_volume_api *volume_api;
++ uint32_t index;
++ const char *name;
++ char *description;
++ pa_proplist *proplist;
++ pa_bvolume volume;
++ bool convertible_to_dB;
++ bool channel_map_is_writable;
++
++ /* If this volume control is the "own volume control" of an audio group,
++ * this is set to point to that group, otherwise this is NULL. */
++ pa_audio_group *owner_audio_group;
++
++ pa_hashmap *devices; /* pa_device -> pa_device (hashmap-as-a-set) */
++ pa_hashmap *default_for_devices; /* pa_device -> pa_device (hashmap-as-a-set) */
++ pa_hashmap *streams; /* pas_stream -> pas_stream (hashmap-as-a-set) */
++ pa_hashmap *audio_groups; /* pa_audio_group -> pa_audio_group (hashmap-as-a-set) */
++
++ bool linked;
++ bool unlinked;
++ bool set_volume_in_progress;
++
++ /* Called from pa_volume_control_set_volume(). The implementation is
++ * expected to return a negative error code on failure. May be NULL, if the
++ * volume control is read-only. */
++ int (*set_volume)(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance);
++
++ void *userdata;
++};
++
++pa_volume_control *pa_volume_control_new(pa_volume_api *api, const char *name, const char *description, bool convertible_to_dB,
++ bool channel_map_is_writable);
++
++typedef void (*pa_volume_control_set_initial_volume_cb_t)(pa_volume_control *control);
++
++/* initial_volume is the preferred initial volume of the volume control
++ * implementation. It may be NULL or partially invalid, if the implementation
++ * doesn't care about the initial state of the volume control, as long as these
++ * two rules are followed:
++ *
++ * 1) Read-only volume controls must always specify fully valid initial
++ * volume.
++ * 2) Volume controls with read-only channel map must always specify a valid
++ * channel map in initial_volume.
++ *
++ * The implementation's initial volume preference may be overridden by policy,
++ * if the volume control isn't read-only. When the final initial volume is
++ * known, the implementation is notified via set_initial_volume_cb (the volume
++ * can be read from control->volume). set_initial_volume_cb may be NULL, if the
++ * volume control is read-only. */
++void pa_volume_control_put(pa_volume_control *control, const pa_bvolume *initial_volume,
++ pa_volume_control_set_initial_volume_cb_t set_initial_volume_cb);
++
++void pa_volume_control_unlink(pa_volume_control *control);
++void pa_volume_control_free(pa_volume_control *control);
++
++/* Called by audio-group.c only. */
++void pa_volume_control_set_owner_audio_group(pa_volume_control *control, pa_audio_group *group);
++
++/* Called by clients and policy modules. */
++int pa_volume_control_set_volume(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance);
++
++/* Called by the volume control implementation. */
++void pa_volume_control_description_changed(pa_volume_control *control, const char *new_description);
++void pa_volume_control_volume_changed(pa_volume_control *control, const pa_bvolume *new_volume, bool volume_changed,
++ bool balance_changed);
++
++/* Called from device.c only. */
++void pa_volume_control_add_device(pa_volume_control *control, pa_device *device);
++void pa_volume_control_remove_device(pa_volume_control *control, pa_device *device);
++void pa_volume_control_add_default_for_device(pa_volume_control *control, pa_device *device);
++void pa_volume_control_remove_default_for_device(pa_volume_control *control, pa_device *device);
++
++/* Called from sstream.c only. */
++void pa_volume_control_add_stream(pa_volume_control *control, pas_stream *stream);
++void pa_volume_control_remove_stream(pa_volume_control *control, pas_stream *stream);
++
++/* Called from audio-group.c only. */
++void pa_volume_control_add_audio_group(pa_volume_control *control, pa_audio_group *group);
++void pa_volume_control_remove_audio_group(pa_volume_control *control, pa_audio_group *group);
++
++#endif
+diff --git a/src/pulse/ext-volume-api.c b/src/pulse/ext-volume-api.c
+new file mode 100644
+index 0000000..8e93bce
+--- /dev/null
++++ b/src/pulse/ext-volume-api.c
+@@ -0,0 +1,275 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "ext-volume-api.h"
++
++#include <pulsecore/core-util.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/macro.h>
++
++#include <math.h>
++
++int pa_ext_volume_api_balance_valid(double balance) {
++ return balance >= 0.0 && balance <= 1.0;
++}
++
++int pa_ext_volume_api_bvolume_valid(const pa_ext_volume_api_bvolume *volume, int check_volume, int check_balance) {
++ unsigned channel;
++
++ pa_assert(volume);
++
++ if (check_volume && !PA_VOLUME_IS_VALID(volume->volume))
++ return 0;
++
++ if (!check_balance)
++ return 1;
++
++ if (!pa_channel_map_valid(&volume->channel_map))
++ return 0;
++
++ for (channel = 0; channel < volume->channel_map.channels; channel++) {
++ if (!pa_ext_volume_api_balance_valid(volume->balance[channel]))
++ return 0;
++ }
++
++ return 1;
++}
++
++void pa_ext_volume_api_bvolume_init_invalid(pa_ext_volume_api_bvolume *volume) {
++ unsigned i;
++
++ pa_assert(volume);
++
++ volume->volume = PA_VOLUME_INVALID;
++
++ for (i = 0; i < PA_CHANNELS_MAX; i++)
++ volume->balance[i] = -1.0;
++
++ pa_channel_map_init(&volume->channel_map);
++}
++
++void pa_ext_volume_api_bvolume_init_mono(pa_ext_volume_api_bvolume *bvolume, pa_volume_t volume) {
++ pa_assert(bvolume);
++ pa_assert(PA_VOLUME_IS_VALID(volume));
++
++ bvolume->volume = volume;
++ bvolume->balance[0] = 1.0;
++ pa_channel_map_init_mono(&bvolume->channel_map);
++}
++
++int pa_ext_volume_api_bvolume_equal(const pa_ext_volume_api_bvolume *a, const pa_ext_volume_api_bvolume *b,
++ int check_volume, int check_balance) {
++ unsigned i;
++
++ pa_assert(a);
++ pa_assert(b);
++
++ if (check_volume && a->volume != b->volume)
++ return 0;
++
++ if (!check_balance)
++ return 1;
++
++ if (!pa_channel_map_equal(&a->channel_map, &b->channel_map))
++ return 0;
++
++ for (i = 0; i < a->channel_map.channels; i++) {
++ if (fabs(a->balance[i] - b->balance[i]) > 0.00001)
++ return 0;
++ }
++
++ return 1;
++}
++
++void pa_ext_volume_api_bvolume_from_cvolume(pa_ext_volume_api_bvolume *bvolume, const pa_cvolume *cvolume,
++ const pa_channel_map *map) {
++ unsigned i;
++
++ pa_assert(bvolume);
++ pa_assert(cvolume);
++ pa_assert(map);
++ pa_assert(cvolume->channels == map->channels);
++
++ bvolume->volume = pa_cvolume_max(cvolume);
++ bvolume->channel_map = *map;
++
++ for (i = 0; i < map->channels; i++) {
++ if (bvolume->volume != PA_VOLUME_MUTED)
++ bvolume->balance[i] = ((double) cvolume->values[i]) / ((double) bvolume->volume);
++ else
++ bvolume->balance[i] = 1.0;
++ }
++}
++
++void pa_ext_volume_api_bvolume_to_cvolume(const pa_ext_volume_api_bvolume *bvolume, pa_cvolume *cvolume) {
++ unsigned i;
++
++ pa_assert(bvolume);
++ pa_assert(cvolume);
++ pa_assert(pa_ext_volume_api_bvolume_valid(bvolume, true, true));
++
++ cvolume->channels = bvolume->channel_map.channels;
++
++ for (i = 0; i < bvolume->channel_map.channels; i++)
++ cvolume->values[i] = bvolume->volume * bvolume->balance[i];
++}
++
++void pa_ext_volume_api_bvolume_copy_balance(pa_ext_volume_api_bvolume *to,
++ const pa_ext_volume_api_bvolume *from) {
++ pa_assert(to);
++ pa_assert(from);
++
++ memcpy(to->balance, from->balance, sizeof(from->balance));
++ to->channel_map = from->channel_map;
++}
++
++void pa_ext_volume_api_bvolume_reset_balance(pa_ext_volume_api_bvolume *volume, const pa_channel_map *map) {
++ unsigned i;
++
++ pa_assert(volume);
++ pa_assert(map);
++ pa_assert(pa_channel_map_valid(map));
++
++ for (i = 0; i < map->channels; i++)
++ volume->balance[i] = 1.0;
++
++ volume->channel_map = *map;
++}
++
++void pa_ext_volume_api_bvolume_remap(pa_ext_volume_api_bvolume *volume, const pa_channel_map *to) {
++ unsigned i;
++ pa_cvolume cvolume;
++
++ pa_assert(volume);
++ pa_assert(to);
++ pa_assert(pa_ext_volume_api_bvolume_valid(volume, false, true));
++ pa_assert(pa_channel_map_valid(to));
++
++ cvolume.channels = volume->channel_map.channels;
++
++ for (i = 0; i < cvolume.channels; i++)
++ cvolume.values[i] = volume->balance[i] * (double) PA_VOLUME_NORM;
++
++ pa_cvolume_remap(&cvolume, &volume->channel_map, to);
++
++ for (i = 0; i < to->channels; i++)
++ volume->balance[i] = (double) cvolume.values[i] / (double) PA_VOLUME_NORM;
++
++ volume->channel_map = *to;
++}
++
++double pa_ext_volume_api_bvolume_get_left_right_balance(const pa_ext_volume_api_bvolume *volume) {
++ pa_ext_volume_api_bvolume bvolume;
++ pa_cvolume cvolume;
++ double ret;
++
++ pa_assert(volume);
++
++ bvolume.volume = PA_VOLUME_NORM;
++ pa_ext_volume_api_bvolume_copy_balance(&bvolume, volume);
++ pa_ext_volume_api_bvolume_to_cvolume(&bvolume, &cvolume);
++ ret = pa_cvolume_get_balance(&cvolume, &volume->channel_map);
++
++ return ret;
++}
++
++void pa_ext_volume_api_bvolume_set_left_right_balance(pa_ext_volume_api_bvolume *volume, double balance) {
++ pa_cvolume cvolume;
++ pa_volume_t old_volume;
++
++ pa_assert(volume);
++
++ if (!pa_channel_map_can_balance(&volume->channel_map))
++ return;
++
++ pa_cvolume_reset(&cvolume, volume->channel_map.channels);
++ pa_cvolume_set_balance(&cvolume, &volume->channel_map, balance);
++ old_volume = volume->volume;
++ pa_ext_volume_api_bvolume_from_cvolume(volume, &cvolume, &volume->channel_map);
++ volume->volume = old_volume;
++}
++
++double pa_ext_volume_api_bvolume_get_rear_front_balance(const pa_ext_volume_api_bvolume *volume) {
++ pa_ext_volume_api_bvolume bvolume;
++ pa_cvolume cvolume;
++ double ret;
++
++ pa_assert(volume);
++
++ bvolume.volume = PA_VOLUME_NORM;
++ pa_ext_volume_api_bvolume_copy_balance(&bvolume, volume);
++ pa_ext_volume_api_bvolume_to_cvolume(&bvolume, &cvolume);
++ ret = pa_cvolume_get_fade(&cvolume, &volume->channel_map);
++
++ return ret;
++}
++
++void pa_ext_volume_api_bvolume_set_rear_front_balance(pa_ext_volume_api_bvolume *volume, double balance) {
++ pa_cvolume cvolume;
++ pa_volume_t old_volume;
++
++ pa_assert(volume);
++
++ if (!pa_channel_map_can_fade(&volume->channel_map))
++ return;
++
++ pa_cvolume_reset(&cvolume, volume->channel_map.channels);
++ pa_cvolume_set_fade(&cvolume, &volume->channel_map, balance);
++ old_volume = volume->volume;
++ pa_ext_volume_api_bvolume_from_cvolume(volume, &cvolume, &volume->channel_map);
++ volume->volume = old_volume;
++}
++
++char *pa_ext_volume_api_bvolume_snprint_balance(char *buf, size_t buf_len,
++ const pa_ext_volume_api_bvolume *volume) {
++ char *e;
++ unsigned channel;
++ bool first = true;
++
++ pa_assert(buf);
++ pa_assert(buf_len > 0);
++ pa_assert(volume);
++
++ pa_init_i18n();
++
++ if (!pa_ext_volume_api_bvolume_valid(volume, true, true)) {
++ pa_snprintf(buf, buf_len, _("(invalid)"));
++ return buf;
++ }
++
++ *(e = buf) = 0;
++
++ for (channel = 0; channel < volume->channel_map.channels && buf_len > 1; channel++) {
++ buf_len -= pa_snprintf(e, buf_len, "%s%s: %u%%",
++ first ? "" : ", ",
++ pa_channel_position_to_string(volume->channel_map.map[channel]),
++ (unsigned) (volume->balance[channel] * 100 + 0.5));
++
++ e = strchr(e, 0);
++ first = false;
++ }
++
++ return buf;
++}
+diff --git a/src/pulse/ext-volume-api.h b/src/pulse/ext-volume-api.h
+new file mode 100644
+index 0000000..36b7748
+--- /dev/null
++++ b/src/pulse/ext-volume-api.h
+@@ -0,0 +1,68 @@
++#ifndef fooextvolumeapihfoo
++#define fooextvolumeapihfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <pulse/cdecl.h>
++#include <pulse/context.h>
++#include <pulse/volume.h>
++
++/* This API is temporary, and has no stability guarantees whatsoever. Think
++ * twice before making anything that relies on this API. This is undocumented
++ * for a reason. */
++
++PA_C_DECL_BEGIN
++
++typedef struct pa_ext_volume_api_bvolume pa_ext_volume_api_bvolume;
++
++struct pa_ext_volume_api_bvolume {
++ pa_volume_t volume;
++ double balance[PA_CHANNELS_MAX];
++ pa_channel_map channel_map;
++};
++
++int pa_ext_volume_api_balance_valid(double balance) PA_GCC_CONST;
++int pa_ext_volume_api_bvolume_valid(const pa_ext_volume_api_bvolume *volume, int check_volume, int check_balance)
++ PA_GCC_PURE;
++void pa_ext_volume_api_bvolume_init_invalid(pa_ext_volume_api_bvolume *volume);
++void pa_ext_volume_api_bvolume_init_mono(pa_ext_volume_api_bvolume *bvolume, pa_volume_t volume);
++int pa_ext_volume_api_bvolume_equal(const pa_ext_volume_api_bvolume *a, const pa_ext_volume_api_bvolume *b,
++ int check_volume, int check_balance) PA_GCC_PURE;
++void pa_ext_volume_api_bvolume_from_cvolume(pa_ext_volume_api_bvolume *bvolume, const pa_cvolume *cvolume,
++ const pa_channel_map *map);
++void pa_ext_volume_api_bvolume_to_cvolume(const pa_ext_volume_api_bvolume *bvolume, pa_cvolume *cvolume);
++void pa_ext_volume_api_bvolume_copy_balance(pa_ext_volume_api_bvolume *to,
++ const pa_ext_volume_api_bvolume *from);
++void pa_ext_volume_api_bvolume_reset_balance(pa_ext_volume_api_bvolume *volume, const pa_channel_map *map);
++void pa_ext_volume_api_bvolume_remap(pa_ext_volume_api_bvolume *volume, const pa_channel_map *to);
++double pa_ext_volume_api_bvolume_get_left_right_balance(const pa_ext_volume_api_bvolume *volume) PA_GCC_PURE;
++void pa_ext_volume_api_bvolume_set_left_right_balance(pa_ext_volume_api_bvolume *volume, double balance);
++double pa_ext_volume_api_bvolume_get_rear_front_balance(const pa_ext_volume_api_bvolume *volume) PA_GCC_PURE;
++void pa_ext_volume_api_bvolume_set_rear_front_balance(pa_ext_volume_api_bvolume *volume, double balance);
++
++#define PA_EXT_VOLUME_API_BVOLUME_SNPRINT_BALANCE_MAX 500
++char *pa_ext_volume_api_bvolume_snprint_balance(char *buf, size_t buf_size,
++ const pa_ext_volume_api_bvolume *volume);
++
++PA_C_DECL_END
++
++#endif
+--
+2.1.4
+
+--- a/po/POTFILES.in 2016-04-13 17:40:00.818008672 +0200
++++ b/po/POTFILES.in 2016-04-13 17:40:30.885008622 +0200
+@@ -198,3 +198,5 @@
+ src/utils/padsp.c
+ src/utils/pasuspender.c
+ src/utils/pax11publish.c
++src/modules/volume-api/device-creator.c
++src/pulse/ext-volume-api.c
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0031-Add-module-main-volume-policy.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0031-Add-module-main-volume-policy.patch
new file mode 100644
index 000000000..216ed21e9
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0031-Add-module-main-volume-policy.patch
@@ -0,0 +1,1418 @@
+From cfb39f18569679f59c9b6283c47e8d90ddd9763d Mon Sep 17 00:00:00 2001
+From: Tanu Kaskinen <tanu.kaskinen@linux.intel.com>
+Date: Wed, 21 May 2014 14:13:41 +0300
+Subject: [PATCH] Add module-main-volume-policy
+
+Change-Id: I787141b43cafb652aa752c64ae28b6b7aa052d8e
+Signed-off-by: Jaska Uimonen <jaska.uimonen@intel.com>
+---
+ Makefile.am | 3 +
+ src/Makefile.am | 15 +
+ src/daemon/default.pa.in | 4 +
+ .../main-volume-policy/main-volume-context.c | 325 ++++++++++++
+ .../main-volume-policy/main-volume-context.h | 75 +++
+ .../main-volume-policy/main-volume-policy.c | 213 ++++++++
+ .../main-volume-policy.conf.example | 20 +
+ .../main-volume-policy/main-volume-policy.h | 72 +++
+ .../main-volume-policy/module-main-volume-policy.c | 556 +++++++++++++++++++++
+ 9 files changed, 1283 insertions(+)
+ create mode 100644 src/modules/main-volume-policy/main-volume-context.c
+ create mode 100644 src/modules/main-volume-policy/main-volume-context.h
+ create mode 100644 src/modules/main-volume-policy/main-volume-policy.c
+ create mode 100644 src/modules/main-volume-policy/main-volume-policy.conf.example
+ create mode 100644 src/modules/main-volume-policy/main-volume-policy.h
+ create mode 100644 src/modules/main-volume-policy/module-main-volume-policy.c
+
+diff --git a/Makefile.am b/Makefile.am
+index cf4a648..646b7fc 100644
+--- a/Makefile.am 2016-04-13 15:14:28.942023245 +0200
++++ b/Makefile.am 2016-04-13 15:16:32.691023039 +0200
+@@ -60,6 +60,9 @@
+ moduledevvolumeapi_DATA = src/modules/volume-api/*.h
+ moduledevvolumeapidir = $(includedir)/pulsemodule/modules/volume-api
+
++moduledevmainvolumepolicy_DATA = $(top_srcdir)/src/modules/main-volume-policy/*.h
++moduledevmainvolumepolicydir = $(includedir)/pulsemodule/modules/main-volume-policy
++
+ if HAVE_GLIB20
+ pkgconfig_DATA += \
+ libpulse-mainloop-glib.pc
+ libpulse-mainloop-glib.pc
+diff --git a/src/Makefile.am b/src/Makefile.am
+index a6bb319..8fa60ec 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1050,7 +1050,8 @@
+ libprotocol-simple.la \
+ libprotocol-http.la \
+ libprotocol-native.la \
+- libvolume-api.la
++ libvolume-api.la \
++ libmain-volume-policy.la
+
+ if HAVE_WEBRTC
+ modlibexec_LTLIBRARIES += libwebrtc-util.la
+@@ -1051,6 +1052,12 @@ libcli_la_SOURCES = pulsecore/cli.c pulsecore/cli.h
+ libcli_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+ libcli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+
++libmain_volume_policy_la_SOURCES = \
++ modules/main-volume-policy/main-volume-context.c modules/main-volume-policy/main-volume-context.h \
++ modules/main-volume-policy/main-volume-policy.c modules/main-volume-policy/main-volume-policy.h
++libmain_volume_policy_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
++libmain_volume_policy_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la libvolume-api.la
++
+ libprotocol_cli_la_SOURCES = pulsecore/protocol-cli.c pulsecore/protocol-cli.h
+ libprotocol_cli_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+ libprotocol_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la libcli.la
+@@ -1136,6 +1136,7 @@ endif
+ modlibexec_LTLIBRARIES += \
+ module-cli.la \
+ module-cli-protocol-tcp.la \
++ module-main-volume-policy.la \
+ module-simple-protocol-tcp.la \
+ module-null-sink.la \
+ module-null-source.la \
+@@ -1426,6 +1434,7 @@ SYMDEF_FILES = \
+ module-cli-symdef.h \
+ module-cli-protocol-tcp-symdef.h \
+ module-cli-protocol-unix-symdef.h \
++ module-main-volume-policy-symdef.h \
+ module-pipe-sink-symdef.h \
+ module-pipe-source-symdef.h \
+ module-simple-protocol-tcp-symdef.h \
+@@ -1575,6 +1584,12 @@ module_cli_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_CLI $(AM_
+ module_cli_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
+ module_cli_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-cli.la
+
++# Main volume and mute policy
++
++module_main_volume_policy_la_SOURCES = modules/main-volume-policy/module-main-volume-policy.c
++module_main_volume_policy_la_LDFLAGS = $(MODULE_LDFLAGS)
++module_main_volume_policy_la_LIBADD = $(MODULE_LIBADD) libmain-volume-policy.la libvolume-api.la
++
+ # HTTP protocol
+
+ module_http_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
+diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
+index 7cf52a4..f70804c 100755
+--- a/src/daemon/default.pa.in
++++ b/src/daemon/default.pa.in
+@@ -188,6 +188,10 @@
+ #.endif
+ ])dnl
+
++.ifexists module-main-volume-policy
++load-module module-main-volume-policy
++.endif
++
+ ### Make some devices default
+ #set-default-sink output
+ #set-default-source input
+diff --git a/src/modules/main-volume-policy/main-volume-context.c b/src/modules/main-volume-policy/main-volume-context.c
+new file mode 100644
+index 0000000..7ac35c6
+--- /dev/null
++++ b/src/modules/main-volume-policy/main-volume-context.c
+@@ -0,0 +1,325 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "main-volume-context.h"
++
++#include <modules/volume-api/mute-control.h>
++#include <modules/volume-api/volume-control.h>
++
++int pa_main_volume_context_new(pa_main_volume_policy *policy, const char *name, const char *description,
++ pa_main_volume_context **context) {
++ pa_main_volume_context *context_local;
++ int r;
++
++ pa_assert(policy);
++ pa_assert(name);
++ pa_assert(description);
++ pa_assert(context);
++
++ context_local = pa_xnew0(struct pa_main_volume_context, 1);
++ context_local->main_volume_policy = policy;
++ context_local->index = pa_main_volume_policy_allocate_main_volume_context_index(policy);
++
++ r = pa_main_volume_policy_register_name(policy, name, true, &context_local->name);
++ if (r < 0)
++ goto fail;
++
++ context_local->description = pa_xstrdup(description);
++
++ *context = context_local;
++
++ return 0;
++
++fail:
++ pa_main_volume_context_free(context_local);
++
++ return r;
++}
++
++void pa_main_volume_context_put(pa_main_volume_context *context) {
++ pa_assert(context);
++
++ pa_main_volume_policy_add_main_volume_context(context->main_volume_policy, context);
++
++ context->linked = true;
++
++ pa_log_debug("Created main volume context #%u.", context->index);
++ pa_log_debug(" Name: %s", context->name);
++ pa_log_debug(" Description: %s", context->description);
++ pa_log_debug(" Main output volume control: %s",
++ context->main_output_volume_control ? context->main_output_volume_control->name : "(unset)");
++ pa_log_debug(" Main input volume control: %s",
++ context->main_input_volume_control ? context->main_input_volume_control->name : "(unset)");
++ pa_log_debug(" Main output mute control: %s",
++ context->main_output_mute_control ? context->main_output_mute_control->name : "(unset)");
++ pa_log_debug(" Main input mute control: %s",
++ context->main_input_mute_control ? context->main_input_mute_control->name : "(unset)");
++
++ pa_hook_fire(&context->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_PUT], context);
++}
++
++void pa_main_volume_context_unlink(pa_main_volume_context *context) {
++ pa_assert(context);
++
++ if (context->unlinked) {
++ pa_log_debug("Unlinking main volume context %s (already unlinked, this is a no-op).", context->name);
++ return;
++ }
++
++ context->unlinked = true;
++
++ pa_log_debug("Unlinking main volume context %s.", context->name);
++
++ if (context->linked)
++ pa_hook_fire(&context->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_UNLINK], context);
++
++ if (context->main_input_mute_control_binding) {
++ pa_binding_free(context->main_input_mute_control_binding);
++ context->main_input_mute_control_binding = NULL;
++ }
++
++ if (context->main_output_mute_control_binding) {
++ pa_binding_free(context->main_output_mute_control_binding);
++ context->main_output_mute_control_binding = NULL;
++ }
++
++ if (context->main_input_volume_control_binding) {
++ pa_binding_free(context->main_input_volume_control_binding);
++ context->main_input_volume_control_binding = NULL;
++ }
++
++ if (context->main_output_volume_control_binding) {
++ pa_binding_free(context->main_output_volume_control_binding);
++ context->main_output_volume_control_binding = NULL;
++ }
++
++ context->main_input_mute_control = NULL;
++ context->main_output_mute_control = NULL;
++ context->main_input_volume_control = NULL;
++ context->main_output_volume_control = NULL;
++
++ pa_main_volume_policy_remove_main_volume_context(context->main_volume_policy, context);
++}
++
++void pa_main_volume_context_free(pa_main_volume_context *context) {
++ pa_assert(context);
++
++ if (!context->unlinked)
++ pa_main_volume_context_unlink(context);
++
++ pa_xfree(context->description);
++
++ if (context->name)
++ pa_main_volume_policy_unregister_name(context->main_volume_policy, context->name);
++
++ pa_xfree(context);
++}
++
++const char *pa_main_volume_context_get_name(pa_main_volume_context *context) {
++ pa_assert(context);
++
++ return context->name;
++}
++
++static void set_main_output_volume_control_internal(pa_main_volume_context *context, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(context);
++
++ old_control = context->main_output_volume_control;
++
++ if (control == old_control)
++ return;
++
++ context->main_output_volume_control = control;
++
++ if (!context->linked || context->unlinked)
++ return;
++
++ pa_log_debug("The main output volume control of main volume context %s changed from %s to %s.", context->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&context->main_volume_policy->hooks
++ [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED],
++ context);
++}
++
++void pa_main_volume_context_bind_main_output_volume_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = context,
++ .set_value = (pa_binding_set_value_cb_t) set_main_output_volume_control_internal,
++ };
++
++ pa_assert(context);
++ pa_assert(target_info);
++
++ if (context->main_output_volume_control_binding)
++ pa_binding_free(context->main_output_volume_control_binding);
++
++ context->main_output_volume_control_binding = pa_binding_new(context->main_volume_policy->volume_api, &owner_info,
++ target_info);
++}
++
++static void set_main_input_volume_control_internal(pa_main_volume_context *context, pa_volume_control *control) {
++ pa_volume_control *old_control;
++
++ pa_assert(context);
++
++ old_control = context->main_input_volume_control;
++
++ if (control == old_control)
++ return;
++
++ context->main_input_volume_control = control;
++
++ if (!context->linked || context->unlinked)
++ return;
++
++ pa_log_debug("The main input volume control of main volume context %s changed from %s to %s.", context->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&context->main_volume_policy->hooks
++ [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_VOLUME_CONTROL_CHANGED],
++ context);
++}
++
++void pa_main_volume_context_bind_main_input_volume_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = context,
++ .set_value = (pa_binding_set_value_cb_t) set_main_input_volume_control_internal,
++ };
++
++ pa_assert(context);
++ pa_assert(target_info);
++
++ if (context->main_input_volume_control_binding)
++ pa_binding_free(context->main_input_volume_control_binding);
++
++ context->main_input_volume_control_binding = pa_binding_new(context->main_volume_policy->volume_api, &owner_info,
++ target_info);
++}
++
++static void set_main_output_mute_control_internal(pa_main_volume_context *context, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(context);
++
++ old_control = context->main_output_mute_control;
++
++ if (control == old_control)
++ return;
++
++ context->main_output_mute_control = control;
++
++ if (!context->linked || context->unlinked)
++ return;
++
++ pa_log_debug("The main output mute control of main volume context %s changed from %s to %s.", context->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&context->main_volume_policy->hooks
++ [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_MUTE_CONTROL_CHANGED],
++ context);
++}
++
++void pa_main_volume_context_bind_main_output_mute_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = context,
++ .set_value = (pa_binding_set_value_cb_t) set_main_output_mute_control_internal,
++ };
++
++ pa_assert(context);
++ pa_assert(target_info);
++
++ if (context->main_output_mute_control_binding)
++ pa_binding_free(context->main_output_mute_control_binding);
++
++ context->main_output_mute_control_binding = pa_binding_new(context->main_volume_policy->volume_api, &owner_info,
++ target_info);
++}
++
++static void set_main_input_mute_control_internal(pa_main_volume_context *context, pa_mute_control *control) {
++ pa_mute_control *old_control;
++
++ pa_assert(context);
++
++ old_control = context->main_input_mute_control;
++
++ if (control == old_control)
++ return;
++
++ context->main_input_mute_control = control;
++
++ if (!context->linked || context->unlinked)
++ return;
++
++ pa_log_debug("The main input mute control of main volume context %s changed from %s to %s.", context->name,
++ old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
++
++ pa_hook_fire(&context->main_volume_policy->hooks
++ [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_MUTE_CONTROL_CHANGED],
++ context);
++}
++
++void pa_main_volume_context_bind_main_input_mute_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info) {
++ pa_binding_owner_info owner_info = {
++ .userdata = context,
++ .set_value = (pa_binding_set_value_cb_t) set_main_input_mute_control_internal,
++ };
++
++ pa_assert(context);
++ pa_assert(target_info);
++
++ if (context->main_input_mute_control_binding)
++ pa_binding_free(context->main_input_mute_control_binding);
++
++ context->main_input_mute_control_binding = pa_binding_new(context->main_volume_policy->volume_api, &owner_info,
++ target_info);
++}
++
++pa_binding_target_type *pa_main_volume_context_create_binding_target_type(pa_main_volume_policy *policy) {
++ pa_binding_target_type *type;
++
++ pa_assert(policy);
++
++ type = pa_binding_target_type_new(PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_TYPE, policy->main_volume_contexts,
++ &policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_PUT],
++ &policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_UNLINK],
++ (pa_binding_target_type_get_name_cb_t) pa_main_volume_context_get_name);
++ pa_binding_target_type_add_field(type, PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_OUTPUT_VOLUME_CONTROL,
++ PA_BINDING_CALCULATE_FIELD_OFFSET(pa_main_volume_context, main_output_volume_control));
++ pa_binding_target_type_add_field(type, PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_INPUT_VOLUME_CONTROL,
++ PA_BINDING_CALCULATE_FIELD_OFFSET(pa_main_volume_context, main_input_volume_control));
++ pa_binding_target_type_add_field(type, PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_OUTPUT_MUTE_CONTROL,
++ PA_BINDING_CALCULATE_FIELD_OFFSET(pa_main_volume_context, main_output_mute_control));
++ pa_binding_target_type_add_field(type, PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_INPUT_MUTE_CONTROL,
++ PA_BINDING_CALCULATE_FIELD_OFFSET(pa_main_volume_context, main_input_mute_control));
++
++ return type;
++}
+diff --git a/src/modules/main-volume-policy/main-volume-context.h b/src/modules/main-volume-policy/main-volume-context.h
+new file mode 100644
+index 0000000..4a0a6f7
+--- /dev/null
++++ b/src/modules/main-volume-policy/main-volume-context.h
+@@ -0,0 +1,75 @@
++#ifndef foomainvolumecontexthfoo
++#define foomainvolumecontexthfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/main-volume-policy/main-volume-policy.h>
++
++#include <modules/volume-api/binding.h>
++
++typedef struct pa_main_volume_context pa_main_volume_context;
++
++#define PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_TYPE "MainVolumeContext"
++#define PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_OUTPUT_VOLUME_CONTROL "main_output_volume_control"
++#define PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_INPUT_VOLUME_CONTROL "main_input_volume_control"
++#define PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_OUTPUT_MUTE_CONTROL "main_output_mute_control"
++#define PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_INPUT_MUTE_CONTROL "main_input_mute_control"
++
++struct pa_main_volume_context {
++ pa_main_volume_policy *main_volume_policy;
++ uint32_t index;
++ const char *name;
++ char *description;
++ pa_volume_control *main_output_volume_control;
++ pa_volume_control *main_input_volume_control;
++ pa_mute_control *main_output_mute_control;
++ pa_mute_control *main_input_mute_control;
++
++ pa_binding *main_output_volume_control_binding;
++ pa_binding *main_input_volume_control_binding;
++ pa_binding *main_output_mute_control_binding;
++ pa_binding *main_input_mute_control_binding;
++
++ bool linked;
++ bool unlinked;
++};
++
++int pa_main_volume_context_new(pa_main_volume_policy *policy, const char *name, const char *description,
++ pa_main_volume_context **context);
++void pa_main_volume_context_put(pa_main_volume_context *context);
++void pa_main_volume_context_unlink(pa_main_volume_context *context);
++void pa_main_volume_context_free(pa_main_volume_context *context);
++
++const char *pa_main_volume_context_get_name(pa_main_volume_context *context);
++
++void pa_main_volume_context_bind_main_output_volume_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info);
++void pa_main_volume_context_bind_main_input_volume_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info);
++void pa_main_volume_context_bind_main_output_mute_control(pa_main_volume_context *context,
++ pa_binding_target_info *target_info);
++void pa_main_volume_context_bind_main_input_mute_control(pa_main_volume_context *context, pa_binding_target_info *target_info);
++
++/* Called from main-volume-policy.c only. */
++pa_binding_target_type *pa_main_volume_context_create_binding_target_type(pa_main_volume_policy *policy);
++
++#endif
+diff --git a/src/modules/main-volume-policy/main-volume-policy.c b/src/modules/main-volume-policy/main-volume-policy.c
+new file mode 100644
+index 0000000..b0b4ede
+--- /dev/null
++++ b/src/modules/main-volume-policy/main-volume-policy.c
+@@ -0,0 +1,213 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "main-volume-policy.h"
++
++#include <modules/main-volume-policy/main-volume-context.h>
++
++#include <pulsecore/core-util.h>
++#include <pulsecore/shared.h>
++
++static pa_main_volume_policy *main_volume_policy_new(pa_core *core);
++static void main_volume_policy_free(pa_main_volume_policy *policy);
++
++pa_main_volume_policy *pa_main_volume_policy_get(pa_core *core) {
++ pa_main_volume_policy *policy;
++
++ pa_assert(core);
++
++ policy = pa_shared_get(core, "main-volume-policy");
++
++ if (policy)
++ pa_main_volume_policy_ref(policy);
++ else {
++ policy = main_volume_policy_new(core);
++ pa_assert_se(pa_shared_set(core, "main-volume-policy", policy) >= 0);
++ }
++
++ return policy;
++}
++
++pa_main_volume_policy *pa_main_volume_policy_ref(pa_main_volume_policy *policy) {
++ pa_assert(policy);
++
++ policy->refcnt++;
++
++ return policy;
++}
++
++void pa_main_volume_policy_unref(pa_main_volume_policy *policy) {
++ pa_assert(policy);
++ pa_assert(policy->refcnt > 0);
++
++ policy->refcnt--;
++
++ if (policy->refcnt == 0) {
++ pa_assert_se(pa_shared_remove(policy->core, "main-volume-policy") >= 0);
++ main_volume_policy_free(policy);
++ }
++}
++
++static pa_main_volume_policy *main_volume_policy_new(pa_core *core) {
++ pa_main_volume_policy *policy;
++ unsigned i;
++
++ pa_assert(core);
++
++ policy = pa_xnew0(pa_main_volume_policy, 1);
++ policy->core = core;
++ policy->refcnt = 1;
++ policy->volume_api = pa_volume_api_get(core);
++ policy->names = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
++ policy->main_volume_contexts = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
++
++ for (i = 0; i < PA_MAIN_VOLUME_POLICY_HOOK_MAX; i++)
++ pa_hook_init(&policy->hooks[i], policy);
++
++ policy->main_volume_context_binding_target_type = pa_main_volume_context_create_binding_target_type(policy);
++ pa_volume_api_add_binding_target_type(policy->volume_api, policy->main_volume_context_binding_target_type);
++
++ pa_log_debug("Created a pa_main_volume_policy object.");
++
++ return policy;
++}
++
++static void main_volume_policy_free(pa_main_volume_policy *policy) {
++ unsigned i;
++
++ pa_assert(policy);
++ pa_assert(policy->refcnt == 0);
++
++ pa_log_debug("Freeing the pa_main_volume_policy object.");
++
++ if (policy->main_volume_context_binding_target_type) {
++ pa_volume_api_remove_binding_target_type(policy->volume_api, policy->main_volume_context_binding_target_type);
++ pa_binding_target_type_free(policy->main_volume_context_binding_target_type);
++ }
++
++ for (i = 0; i < PA_MAIN_VOLUME_POLICY_HOOK_MAX; i++)
++ pa_hook_done(&policy->hooks[i]);
++
++ if (policy->main_volume_contexts) {
++ pa_assert(pa_hashmap_isempty(policy->main_volume_contexts));
++ pa_hashmap_free(policy->main_volume_contexts);
++ }
++
++ if (policy->names) {
++ pa_assert(pa_hashmap_isempty(policy->names));
++ pa_hashmap_free(policy->names);
++ }
++
++ if (policy->volume_api)
++ pa_volume_api_unref(policy->volume_api);
++
++ pa_xfree(policy);
++}
++
++int pa_main_volume_policy_register_name(pa_main_volume_policy *policy, const char *requested_name,
++ bool fail_if_already_registered, const char **registered_name) {
++ char *n;
++
++ pa_assert(policy);
++ pa_assert(requested_name);
++ pa_assert(registered_name);
++
++ n = pa_xstrdup(requested_name);
++
++ if (pa_hashmap_put(policy->names, n, n) < 0) {
++ unsigned i = 1;
++
++ pa_xfree(n);
++
++ if (fail_if_already_registered) {
++ pa_log("Name %s already registered.", requested_name);
++ return -PA_ERR_EXIST;
++ }
++
++ do {
++ i++;
++ n = pa_sprintf_malloc("%s.%u", requested_name, i);
++ } while (pa_hashmap_put(policy->names, n, n) < 0);
++ }
++
++ *registered_name = n;
++
++ return 0;
++}
++
++void pa_main_volume_policy_unregister_name(pa_main_volume_policy *policy, const char *name) {
++ pa_assert(policy);
++ pa_assert(name);
++
++ pa_assert_se(pa_hashmap_remove_and_free(policy->names, name) >= 0);
++}
++
++uint32_t pa_main_volume_policy_allocate_main_volume_context_index(pa_main_volume_policy *policy) {
++ uint32_t idx;
++
++ pa_assert(policy);
++
++ idx = policy->next_main_volume_context_index++;
++
++ return idx;
++}
++
++void pa_main_volume_policy_add_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context) {
++ pa_assert(policy);
++ pa_assert(context);
++
++ pa_assert_se(pa_hashmap_put(policy->main_volume_contexts, (void *) context->name, context) >= 0);
++}
++
++int pa_main_volume_policy_remove_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context) {
++ pa_assert(policy);
++ pa_assert(context);
++
++ if (!pa_hashmap_remove(policy->main_volume_contexts, context->name))
++ return -1;
++
++ if (context == policy->active_main_volume_context)
++ pa_main_volume_policy_set_active_main_volume_context(policy, NULL);
++
++ return 0;
++}
++
++void pa_main_volume_policy_set_active_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context) {
++ pa_main_volume_context *old_context;
++
++ pa_assert(policy);
++
++ old_context = policy->active_main_volume_context;
++
++ if (context == old_context)
++ return;
++
++ policy->active_main_volume_context = context;
++
++ pa_log_debug("The active main volume context changed from %s to %s.", old_context ? old_context->name : "(unset)",
++ context ? context->name : "(unset)");
++
++ pa_hook_fire(&policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_ACTIVE_MAIN_VOLUME_CONTEXT_CHANGED], NULL);
++}
+diff --git a/src/modules/main-volume-policy/main-volume-policy.conf.example b/src/modules/main-volume-policy/main-volume-policy.conf.example
+new file mode 100644
+index 0000000..a4a35d3
+--- /dev/null
++++ b/src/modules/main-volume-policy/main-volume-policy.conf.example
+@@ -0,0 +1,20 @@
++[General]
++output-volume-model = by-active-main-volume-context
++input-volume-model = by-active-main-volume-context
++output-mute-model = none
++input-mute-model = none
++main-volume-contexts = x-example-call-main-volume-context x-example-default-main-volume-context
++
++[MainVolumeContext x-example-call-main-volume-context]
++description = Call main volume context
++main-output-volume-control = bind:AudioGroup:x-example-call-downlink-audio-group
++main-input-volume-control = bind:AudioGroup:x-example-call-uplink-audio-group
++main-output-mute-control = none
++main-input-mute-control = none
++
++[MainVolumeContext x-example-default-main-volume-context]
++description = Default main volume context
++main-output-volume-control = bind:AudioGroup:x-example-default-output-audio-group
++main-input-volume-control = bind:AudioGroup:x-example-default-input-audio-group
++main-output-mute-control = none
++main-input-mute-control = none
+diff --git a/src/modules/main-volume-policy/main-volume-policy.h b/src/modules/main-volume-policy/main-volume-policy.h
+new file mode 100644
+index 0000000..5cd669e
+--- /dev/null
++++ b/src/modules/main-volume-policy/main-volume-policy.h
+@@ -0,0 +1,72 @@
++#ifndef foomainvolumepolicyhfoo
++#define foomainvolumepolicyhfoo
++
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#include <modules/volume-api/binding.h>
++#include <modules/volume-api/volume-api.h>
++
++#include <pulsecore/core.h>
++
++typedef struct pa_main_volume_policy pa_main_volume_policy;
++
++/* Avoid circular dependencies... */
++typedef struct pa_main_volume_context pa_main_volume_context;
++
++enum {
++ PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_PUT,
++ PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_UNLINK,
++ PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED,
++ PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_VOLUME_CONTROL_CHANGED,
++ PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_MUTE_CONTROL_CHANGED,
++ PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_MUTE_CONTROL_CHANGED,
++ PA_MAIN_VOLUME_POLICY_HOOK_ACTIVE_MAIN_VOLUME_CONTEXT_CHANGED,
++ PA_MAIN_VOLUME_POLICY_HOOK_MAX,
++};
++
++struct pa_main_volume_policy {
++ pa_core *core;
++ unsigned refcnt;
++ pa_volume_api *volume_api;
++ pa_hashmap *names; /* object name -> object name (hashmap-as-a-set) */
++ pa_hashmap *main_volume_contexts; /* name -> pa_main_volume_context */
++ pa_main_volume_context *active_main_volume_context;
++
++ uint32_t next_main_volume_context_index;
++ pa_hook hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAX];
++ pa_binding_target_type *main_volume_context_binding_target_type;
++};
++
++pa_main_volume_policy *pa_main_volume_policy_get(pa_core *core);
++pa_main_volume_policy *pa_main_volume_policy_ref(pa_main_volume_policy *policy);
++void pa_main_volume_policy_unref(pa_main_volume_policy *policy);
++
++int pa_main_volume_policy_register_name(pa_main_volume_policy *policy, const char *requested_name,
++ bool fail_if_already_registered, const char **registered_name);
++void pa_main_volume_policy_unregister_name(pa_main_volume_policy *policy, const char *name);
++
++uint32_t pa_main_volume_policy_allocate_main_volume_context_index(pa_main_volume_policy *policy);
++void pa_main_volume_policy_add_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context);
++int pa_main_volume_policy_remove_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context);
++void pa_main_volume_policy_set_active_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context);
++
++#endif
+diff --git a/src/modules/main-volume-policy/module-main-volume-policy.c b/src/modules/main-volume-policy/module-main-volume-policy.c
+new file mode 100644
+index 0000000..a14699d
+--- /dev/null
++++ b/src/modules/main-volume-policy/module-main-volume-policy.c
+@@ -0,0 +1,556 @@
++/***
++ This file is part of PulseAudio.
++
++ Copyright 2014 Intel Corporation
++
++ PulseAudio is free software; you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as published
++ by the Free Software Foundation; either version 2.1 of the License,
++ or (at your option) any later version.
++
++ PulseAudio is distributed in the hope that 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 Lesser General Public License
++ along with PulseAudio; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++ USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "module-main-volume-policy-symdef.h"
++
++#include <modules/main-volume-policy/main-volume-context.h>
++
++#include <modules/volume-api/binding.h>
++#include <modules/volume-api/volume-api.h>
++
++#include <pulse/direction.h>
++
++#include <pulsecore/conf-parser.h>
++#include <pulsecore/core-util.h>
++#include <pulsecore/i18n.h>
++
++PA_MODULE_AUTHOR("Tanu Kaskinen");
++PA_MODULE_DESCRIPTION(_("Main volume and mute policy"));
++PA_MODULE_VERSION(PACKAGE_VERSION);
++PA_MODULE_LOAD_ONCE(true);
++
++enum control_type {
++ CONTROL_TYPE_VOLUME,
++ CONTROL_TYPE_MUTE,
++};
++
++enum model {
++ MODEL_NONE,
++ MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT,
++};
++
++struct userdata {
++ pa_main_volume_policy *main_volume_policy;
++ enum model output_volume_model;
++ enum model input_volume_model;
++ enum model output_mute_model;
++ enum model input_mute_model;
++ pa_hashmap *contexts; /* name -> struct context */
++
++ pa_hook_slot *active_main_volume_context_changed_slot;
++
++ /* The following fields are only used during initialization. */
++ pa_hashmap *context_names; /* name -> name (hashmap-as-a-set) */
++ pa_hashmap *unused_contexts; /* name -> struct context */
++};
++
++struct context {
++ struct userdata *userdata;
++ char *name;
++ char *description;
++ pa_binding_target_info *main_output_volume_control_target_info;
++ pa_binding_target_info *main_input_volume_control_target_info;
++ pa_binding_target_info *main_output_mute_control_target_info;
++ pa_binding_target_info *main_input_mute_control_target_info;
++ pa_main_volume_context *main_volume_context;
++
++ bool unlinked;
++};
++
++static void context_unlink(struct context *context);
++
++static const char *model_to_string(enum model model) {
++ switch (model) {
++ case MODEL_NONE:
++ return "none";
++
++ case MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT:
++ return "by-active-main-volume-context";
++ }
++
++ pa_assert_not_reached();
++}
++
++static int model_from_string(const char *str, enum model *model) {
++ pa_assert(str);
++ pa_assert(model);
++
++ if (pa_streq(str, "none"))
++ *model = MODEL_NONE;
++ else if (pa_streq(str, "by-active-main-volume-context"))
++ *model = MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT;
++ else
++ return -PA_ERR_INVALID;
++
++ return 0;
++}
++
++static struct context *context_new(struct userdata *u, const char *name) {
++ struct context *context;
++
++ pa_assert(u);
++ pa_assert(name);
++
++ context = pa_xnew0(struct context, 1);
++ context->userdata = u;
++ context->name = pa_xstrdup(name);
++ context->description = pa_xstrdup(name);
++
++ return context;
++}
++
++static int context_put(struct context *context) {
++ int r;
++
++ pa_assert(context);
++
++ r = pa_main_volume_context_new(context->userdata->main_volume_policy, context->name, context->description,
++ &context->main_volume_context);
++ if (r < 0)
++ goto fail;
++
++ if (context->main_output_volume_control_target_info)
++ pa_main_volume_context_bind_main_output_volume_control(context->main_volume_context,
++ context->main_output_volume_control_target_info);
++
++ if (context->main_input_volume_control_target_info)
++ pa_main_volume_context_bind_main_input_volume_control(context->main_volume_context,
++ context->main_input_volume_control_target_info);
++
++ if (context->main_output_mute_control_target_info)
++ pa_main_volume_context_bind_main_output_mute_control(context->main_volume_context,
++ context->main_output_mute_control_target_info);
++
++ if (context->main_input_mute_control_target_info)
++ pa_main_volume_context_bind_main_input_mute_control(context->main_volume_context,
++ context->main_input_mute_control_target_info);
++
++ pa_main_volume_context_put(context->main_volume_context);
++
++ return 0;
++
++fail:
++ context_unlink(context);
++
++ return r;
++}
++
++static void context_unlink(struct context *context) {
++ pa_assert(context);
++
++ if (context->unlinked)
++ return;
++
++ context->unlinked = true;
++
++ if (context->main_volume_context) {
++ pa_main_volume_context_free(context->main_volume_context);
++ context->main_volume_context = NULL;
++ }
++}
++
++static void context_free(struct context *context) {
++ pa_assert(context);
++
++ if (!context->unlinked)
++ context_unlink(context);
++
++ if (context->main_input_mute_control_target_info)
++ pa_binding_target_info_free(context->main_input_mute_control_target_info);
++
++ if (context->main_output_mute_control_target_info)
++ pa_binding_target_info_free(context->main_output_mute_control_target_info);
++
++ if (context->main_input_volume_control_target_info)
++ pa_binding_target_info_free(context->main_input_volume_control_target_info);
++
++ if (context->main_output_volume_control_target_info)
++ pa_binding_target_info_free(context->main_output_volume_control_target_info);
++
++ pa_xfree(context->description);
++ pa_xfree(context->name);
++ pa_xfree(context);
++}
++
++static void context_set_description(struct context *context, const char *description) {
++ pa_assert(context);
++ pa_assert(description);
++
++ pa_xfree(context->description);
++ context->description = pa_xstrdup(description);
++}
++
++static void context_set_main_control_target_info(struct context *context, enum control_type type, pa_direction_t direction,
++ pa_binding_target_info *info) {
++ pa_assert(context);
++
++ switch (type) {
++ case CONTROL_TYPE_VOLUME:
++ if (direction == PA_DIRECTION_OUTPUT) {
++ if (context->main_output_volume_control_target_info)
++ pa_binding_target_info_free(context->main_output_volume_control_target_info);
++
++ if (info)
++ context->main_output_volume_control_target_info = pa_binding_target_info_copy(info);
++ else
++ context->main_output_volume_control_target_info = NULL;
++ } else {
++ if (context->main_input_volume_control_target_info)
++ pa_binding_target_info_free(context->main_input_volume_control_target_info);
++
++ if (info)
++ context->main_input_volume_control_target_info = pa_binding_target_info_copy(info);
++ else
++ context->main_input_volume_control_target_info = NULL;
++ }
++ break;
++
++ case CONTROL_TYPE_MUTE:
++ if (direction == PA_DIRECTION_OUTPUT) {
++ if (context->main_output_mute_control_target_info)
++ pa_binding_target_info_free(context->main_output_mute_control_target_info);
++
++ if (info)
++ context->main_output_mute_control_target_info = pa_binding_target_info_copy(info);
++ else
++ context->main_output_mute_control_target_info = NULL;
++ } else {
++ if (context->main_input_mute_control_target_info)
++ pa_binding_target_info_free(context->main_input_mute_control_target_info);
++
++ if (info)
++ context->main_input_mute_control_target_info = pa_binding_target_info_copy(info);
++ else
++ context->main_input_mute_control_target_info = NULL;
++ }
++ break;
++ }
++}
++
++static pa_hook_result_t active_main_volume_context_changed_cb(void *hook_data, void *call_data, void *userdata) {
++ struct userdata *u = userdata;
++ pa_main_volume_context *context;
++ pa_volume_api *api;
++ pa_binding_target_info *info = NULL;
++
++ pa_assert(u);
++
++ context = u->main_volume_policy->active_main_volume_context;
++ api = u->main_volume_policy->volume_api;
++
++ if (u->output_volume_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
++ if (context) {
++ info = pa_binding_target_info_new(PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_TYPE, context->name,
++ PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_OUTPUT_VOLUME_CONTROL);
++ pa_volume_api_bind_main_output_volume_control(api, info);
++ } else
++ pa_volume_api_set_main_output_volume_control(api, NULL);
++ }
++
++ if (u->input_volume_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
++ if (context) {
++ info = pa_binding_target_info_new(PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_TYPE, context->name,
++ PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_INPUT_VOLUME_CONTROL);
++ pa_volume_api_bind_main_input_volume_control(api, info);
++ } else
++ pa_volume_api_set_main_input_volume_control(api, NULL);
++ }
++
++ if (u->output_mute_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
++ if (context) {
++ info = pa_binding_target_info_new(PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_TYPE, context->name,
++ PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_OUTPUT_MUTE_CONTROL);
++ pa_volume_api_bind_main_output_mute_control(api, info);
++ } else
++ pa_volume_api_set_main_output_mute_control(api, NULL);
++ }
++
++ if (u->input_mute_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
++ if (context) {
++ info = pa_binding_target_info_new(PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_TYPE, context->name,
++ PA_MAIN_VOLUME_CONTEXT_BINDING_TARGET_FIELD_MAIN_INPUT_MUTE_CONTROL);
++ pa_volume_api_bind_main_input_mute_control(api, info);
++ } else
++ pa_volume_api_set_main_input_mute_control(api, NULL);
++ }
++
++ if (info)
++ pa_binding_target_info_free(info);
++
++ return PA_HOOK_OK;
++}
++
++static int parse_model(pa_config_parser_state *state) {
++ int r;
++
++ pa_assert(state);
++
++ r = model_from_string(state->rvalue, state->data);
++ if (r < 0)
++ pa_log("[%s:%u] Failed to parse model: %s", state->filename, state->lineno, state->rvalue);
++
++ return r;
++}
++
++static int parse_main_volume_contexts(pa_config_parser_state *state) {
++ struct userdata *u;
++ char *name;
++ const char *split_state = NULL;
++
++ pa_assert(state);
++
++ u = state->userdata;
++
++ while ((name = pa_split_spaces(state->rvalue, &split_state)))
++ pa_hashmap_put(u->context_names, name, name);
++
++ return 0;
++}
++
++static struct context *get_context(struct userdata *u, const char *section) {
++ const char *name;
++ struct context *context;
++
++ pa_assert(u);
++
++ if (!section)
++ return NULL;
++
++ if (!pa_startswith(section, "MainVolumeContext "))
++ return NULL;
++
++ name = section + 18;
++
++ context = pa_hashmap_get(u->unused_contexts, name);
++ if (!context) {
++ context = context_new(u, name);
++ pa_hashmap_put(u->unused_contexts, context->name, context);
++ }
++
++ return context;
++}
++
++static int parse_description(pa_config_parser_state *state) {
++ struct userdata *u;
++ struct context *context;
++
++ pa_assert(state);
++
++ u = state->userdata;
++
++ context = get_context(u, state->section);
++ if (!context) {
++ pa_log("[%s:%u] Key \"%s\" not expected in section %s.", state->filename, state->lineno, state->lvalue,
++ pa_strnull(state->section));
++ return -PA_ERR_INVALID;
++ }
++
++ context_set_description(context, state->rvalue);
++
++ return 0;
++}
++
++static const char *get_target_field_name(enum control_type type) {
++ switch (type) {
++ case CONTROL_TYPE_VOLUME:
++ return "volume_control";
++
++ case CONTROL_TYPE_MUTE:
++ return "mute_control";
++ }
++
++ pa_assert_not_reached();
++}
++
++static int parse_main_control(pa_config_parser_state *state, enum control_type type, pa_direction_t direction) {
++ struct userdata *u;
++ struct context *context;
++
++ pa_assert(state);
++
++ u = state->userdata;
++
++ context = get_context(u, state->section);
++ if (!context) {
++ pa_log("[%s:%u] Key \"%s\" not expected in section %s.", state->filename, state->lineno, state->lvalue,
++ pa_strnull(state->section));
++ return -PA_ERR_INVALID;
++ }
++
++ if (pa_streq(state->rvalue, "none"))
++ context_set_main_control_target_info(context, type, direction, NULL);
++ else if (pa_startswith(state->rvalue, "bind:")) {
++ int r;
++ pa_binding_target_info *info;
++
++ r = pa_binding_target_info_new_from_string(state->rvalue, get_target_field_name(type), &info);
++ if (r < 0) {
++ pa_log("[%s:%u] Failed to parse binding target \"%s\".", state->filename, state->lineno, state->rvalue);
++ return r;
++ }
++
++ context_set_main_control_target_info(context, type, direction, info);
++ pa_binding_target_info_free(info);
++ } else {
++ pa_log("[%s:%u] Failed to parse value \"%s\".", state->filename, state->lineno, state->rvalue);
++ return -PA_ERR_INVALID;
++ }
++
++ return 0;
++}
++
++static int parse_main_output_volume_control(pa_config_parser_state *state) {
++ pa_assert(state);
++
++ return parse_main_control(state, CONTROL_TYPE_VOLUME, PA_DIRECTION_OUTPUT);
++}
++
++static int parse_main_input_volume_control(pa_config_parser_state *state) {
++ pa_assert(state);
++
++ return parse_main_control(state, CONTROL_TYPE_VOLUME, PA_DIRECTION_INPUT);
++}
++
++static int parse_main_output_mute_control(pa_config_parser_state *state) {
++ pa_assert(state);
++
++ return parse_main_control(state, CONTROL_TYPE_MUTE, PA_DIRECTION_OUTPUT);
++}
++
++static int parse_main_input_mute_control(pa_config_parser_state *state) {
++ pa_assert(state);
++
++ return parse_main_control(state, CONTROL_TYPE_MUTE, PA_DIRECTION_INPUT);
++}
++
++static void finalize_config(struct userdata *u) {
++ const char *context_name;
++ void *state;
++ struct context *context;
++
++ pa_assert(u);
++
++ PA_HASHMAP_FOREACH(context_name, u->context_names, state) {
++ int r;
++
++ context = pa_hashmap_remove(u->unused_contexts, context_name);
++ if (!context)
++ context = context_new(u, context_name);
++
++ r = context_put(context);
++ if (r < 0) {
++ pa_log_warn("Failed to create main volume context %s.", context_name);
++ context_free(context);
++ continue;
++ }
++
++ pa_assert_se(pa_hashmap_put(u->contexts, context->name, context) >= 0);
++ }
++
++ PA_HASHMAP_FOREACH(context, u->unused_contexts, state)
++ pa_log_debug("Main volume context %s is not used.", context->name);
++
++ pa_hashmap_free(u->unused_contexts);
++ u->unused_contexts = NULL;
++
++ pa_hashmap_free(u->context_names);
++ u->context_names = NULL;
++}
++
++int pa__init(pa_module *module) {
++ struct userdata *u;
++ FILE *f;
++ char *fn = NULL;
++
++ pa_assert(module);
++
++ u = module->userdata = pa_xnew0(struct userdata, 1);
++ u->main_volume_policy = pa_main_volume_policy_get(module->core);
++ u->output_volume_model = MODEL_NONE;
++ u->input_volume_model = MODEL_NONE;
++ u->output_mute_model = MODEL_NONE;
++ u->input_mute_model = MODEL_NONE;
++ u->contexts = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
++ (pa_free_cb_t) context_free);
++ u->active_main_volume_context_changed_slot =
++ pa_hook_connect(&u->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_ACTIVE_MAIN_VOLUME_CONTEXT_CHANGED],
++ PA_HOOK_NORMAL, active_main_volume_context_changed_cb, u);
++ u->context_names = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
++ u->unused_contexts = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
++ (pa_free_cb_t) context_free);
++
++ f = pa_open_config_file(PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "main-volume-policy.conf", "main-volume-policy.conf", NULL, &fn);
++ if (f) {
++ pa_config_item config_items[] = {
++ { "output-volume-model", parse_model, &u->output_volume_model, "General" },
++ { "input-volume-model", parse_model, &u->input_volume_model, "General" },
++ { "output-mute-model", parse_model, &u->output_mute_model, "General" },
++ { "input-mute-model", parse_model, &u->input_mute_model, "General" },
++ { "main-volume-contexts", parse_main_volume_contexts, NULL, "General" },
++ { "description", parse_description, NULL, NULL },
++ { "main-output-volume-control", parse_main_output_volume_control, NULL, NULL },
++ { "main-input-volume-control", parse_main_input_volume_control, NULL, NULL },
++ { "main-output-mute-control", parse_main_output_mute_control, NULL, NULL },
++ { "main-input-mute-control", parse_main_input_mute_control, NULL, NULL },
++ { NULL },
++ };
++
++ pa_config_parse(fn, f, config_items, NULL, u);
++ pa_xfree(fn);
++ fn = NULL;
++ fclose(f);
++ f = NULL;
++ }
++
++ finalize_config(u);
++
++ pa_log_debug("Output volume model: %s", model_to_string(u->output_volume_model));
++ pa_log_debug("Input volume model: %s", model_to_string(u->input_volume_model));
++ pa_log_debug("Output mute model: %s", model_to_string(u->output_mute_model));
++ pa_log_debug("Input mute model: %s", model_to_string(u->input_mute_model));
++
++ return 0;
++}
++
++void pa__done(pa_module *module) {
++ struct userdata *u;
++
++ pa_assert(module);
++
++ u = module->userdata;
++ if (!u)
++ return;
++
++ if (u->active_main_volume_context_changed_slot)
++ pa_hook_slot_free(u->active_main_volume_context_changed_slot);
++
++ if (u->contexts)
++ pa_hashmap_free(u->contexts);
++
++ if (u->main_volume_policy)
++ pa_main_volume_policy_unref(u->main_volume_policy);
++
++ pa_xfree(u);
++}
+--
+2.1.4
+
+--- a/po/POTFILES.in 2016-04-14 13:03:50.715006116 +0200
++++ b/po/POTFILES.in 2016-04-14 13:04:23.097006062 +0200
+@@ -200,3 +200,4 @@
+ src/utils/pax11publish.c
+ src/modules/volume-api/device-creator.c
+ src/pulse/ext-volume-api.c
++src/modules/main-volume-policy/module-main-volume-policy.c
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0039-main-volume-policy-adapt-to-pa6rev.patch b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0039-main-volume-policy-adapt-to-pa6rev.patch
new file mode 100644
index 000000000..4f2777112
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio/0039-main-volume-policy-adapt-to-pa6rev.patch
@@ -0,0 +1,11 @@
+--- a/src/modules/main-volume-policy/module-main-volume-policy.c 2016-04-18 10:59:46.124086205 +0200
++++ b/src/modules/main-volume-policy/module-main-volume-policy.c 2016-04-18 11:01:31.497089360 +0200
+@@ -517,7 +517,7 @@
+ { NULL },
+ };
+
+- pa_config_parse(fn, f, config_items, NULL, u);
++ pa_config_parse(fn, f, config_items, NULL, false, u);
+ pa_xfree(fn);
+ fn = NULL;
+ fclose(f);
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend
new file mode 100644
index 000000000..a54ec60f1
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend
@@ -0,0 +1,28 @@
+FILESEXTRAPATHS_append := ":${THISDIR}/${PN}"
+
+inherit systemd
+
+do_install_append() {
+ # Install pulseaudio systemd service
+ if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
+ install -m 644 -p -D ${WORKDIR}/build/src/pulseaudio.service ${D}${systemd_user_unitdir}/pulseaudio.service
+ install -m 644 -p -D ${WORKDIR}/pulseaudio-${PV}/src/daemon/systemd/user/pulseaudio.socket ${D}${systemd_user_unitdir}/pulseaudio.socket
+
+ # Execute these manually on behalf of systemctl script (from systemd-systemctl-native.bb)
+ # because it does not support systemd's user mode.
+ install -d ${D}${systemd_user_unitdir}/sockets.target.wants/
+ ln -sf ${systemd_user_unitdir}/pulseaudio.socket ${D}${systemd_user_unitdir}/sockets.target.wants/
+
+ install -d ${D}${systemd_user_unitdir}/default.target.wants/
+ ln -sf ${systemd_user_unitdir}/pulseaudio.service ${D}${systemd_user_unitdir}/default.target.wants/
+ fi
+ mkdir -p ${D}/${bindir}
+ install -m 755 -p -D ${WORKDIR}/build/src/.libs/pacat ${D}/${bindir}/
+}
+
+FILES_${PN}-server += " \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/pulseaudio.socket', '', d)} \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/sockets.target.wants/pulseaudio.socket', '', d)} \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/pulseaudio.service', '', d)} \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_user_unitdir}/default.target.wants/pulseaudio.service', '', d)} \
+"
diff --git a/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_10.0.bbappend b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_10.0.bbappend
new file mode 100644
index 000000000..f59ee89d5
--- /dev/null
+++ b/meta-agl-profile-core/recipes-multimedia/pulseaudio/pulseaudio_10.0.bbappend
@@ -0,0 +1,15 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/pulseaudio-10.0:"
+
+SRC_URI += " \
+ file://0001-install-files-for-a-module-development.patch \
+ file://0002-volume-ramp-additions-to-the-low-level-infra.patch \
+ file://0003-volume-ramp-adding-volume-ramping-to-sink-input.patch \
+ file://0004-sink-input-Code-cleanup-regarding-volume-ramping.patch \
+ file://0005-sink-input-volume-Add-support-for-volume-ramp-factor.patch \
+ file://0006-sink-input-Remove-pa_sink_input_set_volume_ramp.patch;apply=no \
+ file://enable-ofono-hfp-backend.patch \
+"
+
+PACKAGES =+ " pulseaudio-module-dev"
+
+FILES_pulseaudio-module-dev = "${includedir}/pulsemodule/* ${libdir}/pkgconfig/pulseaudio-module-devel.pc"
diff --git a/meta-agl-profile-core/recipes-navigation/geoclue/files/org.freedesktop.GeoClue2.Client.conf b/meta-agl-profile-core/recipes-navigation/geoclue/files/org.freedesktop.GeoClue2.Client.conf
new file mode 100644
index 000000000..a7486d055
--- /dev/null
+++ b/meta-agl-profile-core/recipes-navigation/geoclue/files/org.freedesktop.GeoClue2.Client.conf
@@ -0,0 +1,8 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow receive_type="signal" receive_interface="org.freedesktop.GeoClue2.Client" />
+ </policy>
+</busconfig>
diff --git a/meta-agl-profile-core/recipes-navigation/geoclue/geoclue_%.bbappend b/meta-agl-profile-core/recipes-navigation/geoclue/geoclue_%.bbappend
new file mode 100644
index 000000000..9d61a9f61
--- /dev/null
+++ b/meta-agl-profile-core/recipes-navigation/geoclue/geoclue_%.bbappend
@@ -0,0 +1,9 @@
+inherit gobject-introspection
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI_append = "file://org.freedesktop.GeoClue2.Client.conf"
+
+do_install_append() {
+ install -d ${D}/etc/dbus-1/system.d
+ install -m 0644 ${WORKDIR}/org.freedesktop.GeoClue2.Client.conf ${D}/etc/dbus-1/system.d/org.freedesktop.GeoClue2.Client.conf
+}
diff --git a/meta-agl-profile-core/recipes-navigation/gpsd/gpsd_%.bbappend b/meta-agl-profile-core/recipes-navigation/gpsd/gpsd_%.bbappend
new file mode 100644
index 000000000..af72aece9
--- /dev/null
+++ b/meta-agl-profile-core/recipes-navigation/gpsd/gpsd_%.bbappend
@@ -0,0 +1,14 @@
+SYSTEMD_SERVICE_${PN} += " gpsdctl@.service"
+
+do_install_append() {
+ # use the systemd compatible gpsd.rules
+ install -d ${D}/${sysconfdir}/udev/rules.d
+ install -m 0644 ${S}/gpsd.rules ${D}/${sysconfdir}/udev/rules.d/60-gpsd.rules
+
+ #support for systemd
+ install -d ${D}${systemd_unitdir}/system/
+ install -m 0644 ${S}/systemd/gpsdctl@.service ${D}${systemd_unitdir}/system
+
+ #autoprobe usb gps devices
+ echo 'USBAUTO="true"' >> ${D}${sysconfdir}/default/gpsd.default
+}
diff --git a/meta-agl-profile-core/recipes-support/libsoup/libsoup-2.4_%.bbappend b/meta-agl-profile-core/recipes-support/libsoup/libsoup-2.4_%.bbappend
new file mode 100644
index 000000000..06651fc11
--- /dev/null
+++ b/meta-agl-profile-core/recipes-support/libsoup/libsoup-2.4_%.bbappend
@@ -0,0 +1 @@
+EXTRA_OECONF_append_class-native = " --disable-tls-check"
diff --git a/meta-agl-profile-core/recipes-test/aiostress/aiostress_0.22.bb b/meta-agl-profile-core/recipes-test/aiostress/aiostress_0.22.bb
new file mode 100644
index 000000000..7803d74ed
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/aiostress/aiostress_0.22.bb
@@ -0,0 +1,24 @@
+SUMMARY = "Async IO testing utility"
+DESCRIPTION = "aio-stress will open or create each file on the command line, and start a series of aio to it.\
+aio is done in a rotating loop. first file1 gets 8 requests, then file2, then file3 etc.\
+As each file finishes writing, it is switched to reads io buffers are aligned in case you want to do raw io"
+HOMEPAGE = "https://oss.oracle.com/~mason/aio-stress/"
+LICENSE = "GPLv2"
+
+S="${WORKDIR}"
+
+LIC_FILES_CHKSUM = "file://${S}/aio-stress.c;md5=ccb5d196a3736bbd835d582a4e2329c3"
+
+SRC_URI = "https://oss.oracle.com/~mason/aio-stress/aio-stress.c"
+SRC_URI[md5sum] = "ccb5d196a3736bbd835d582a4e2329c3"
+SRC_URI[sha256sum] = "3f4cffcc946fb717fff9d8fe932c7c2ee606efff198408d9fbe16955151445f7"
+
+do_compile () {
+ ${CC} -Wall -Wshadow -o aio-stress -lpthread -laio aio-stress.c
+}
+
+do_install () {
+ install -d ${D}${bindir}
+ install -m 0755 aio-stress ${D}${bindir}
+}
+
diff --git a/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0001-Makefile.patch b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0001-Makefile.patch
new file mode 100644
index 000000000..0ae56cee1
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0001-Makefile.patch
@@ -0,0 +1,53 @@
+--- a/Makefile.orig 2016-04-01 15:50:20.636358716 +0200
++++ b/Makefile 2016-04-01 15:51:58.916361191 +0200
+@@ -1,3 +1,9 @@
++INCDIR = $(SDKROOT)/usr/include
++LIBDIR = $(SDKROOT)/usr/lib
++
++EXTRA_CFLAGS=-I$(INCDIR)
++EXTRA_LDFLAGS=-Wl,-rpath-link=$(LIBDIR) -L$(LIBDIR)
++
+ OBJECTS = bs_main.o \
+ bs_vector.o \
+ bs_pointmass.o \
+@@ -15,21 +21,21 @@
+ bs_profiler.o \
+ bs_rubberband.o
+
+-CC = gcc
++#CC = gcc
+
+ DISTDIR = blobsallad-src
+
+-CFLAGS = `pkg-config --cflags cairo; sdl-config --cflags`
+-LIBS = `pkg-config --libs cairo; sdl-config --libs` -lm -lGL -lGLU
++EXTRA_CFLAGS += -I$(INCDIR)/cairo -I$(INCDIR)/SDL -D_GNU_SOURCE=1 -D_REENTRANT
++EXTRA_LDFLAGS += -lcairo -lSDL -lpthread -lm
+
+ all: $(OBJECTS)
+- $(CC) -g -o blobsallad $(OBJECTS) $(LIBS)
++ $(CC) -g -o blobsallad $(OBJECTS) $(EXTRA_LDFLAGS)
+
+ map:
+- gcc -o createmap create_testdata.c -Wall -g -lm
++ $(CC) -o createmap create_testdata.c -Wall -g -lm
+
+ octree:
+- gcc -o test_octree test_octree.c bs_octree.c bs_list.c bs_vector.c bs_vector_util.c bs_timer.c bs_array.c -Wall -O2 $(LIBS) $(CFLAGS)
++ $(CC) -o test_octree test_octree.c bs_octree.c bs_list.c bs_vector.c bs_vector_util.c bs_timer.c bs_array.c -Wall -O2 $(EXTRA_LDFLAGS) $(EXTRA_CFLAGS)
+
+ GFX_OBJECTS = gfx_main.o \
+ bs_gfx.o \
+@@ -41,10 +47,10 @@
+ bs_list.o
+
+ gfx: $(GFX_OBJECTS)
+- gcc -o gfx_main -Wall -g $(GFX_OBJECTS) $(LIBS)
++ $(CC) -o gfx_main -Wall -g $(GFX_OBJECTS) $(EXTRA_LDFLAGS)
+
+ .c.o:
+- $(CC) -g -Wall $(CFLAGS) $ -c $<
++ $(CC) -g -Wall $(EXTRA_CFLAGS) $ -c $<
+
+ clean:
+ rm -f *.o; rm -f blobsallad;
diff --git a/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0002-auto.patch b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0002-auto.patch
new file mode 100644
index 000000000..b61da2c1f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0002-auto.patch
@@ -0,0 +1,95 @@
+--- a/bs_main.c
++++ b/bs_main.c
+@@ -11,6 +11,9 @@
+ #include "bs_profiler.h"
+ #include "bs_rubberband.h"
+
++static struct timeval beginTime; /* Time of the benchmark start */
++static int cur_step; /* Current benchmark phase. Used to subsequently increase number of objects each 10 seconds */
++
+ typedef struct bs_main_data_st
+ {
+ bs_cairo_sdl_t *pCairoSdl;
+@@ -113,7 +116,9 @@
+ SDL_Event event;
+ SDL_UserEvent userevent;
+ bs_main_data_t *pMainData;
+-
++ struct timeval curTime;
++ int hunsec;
++
+ pMainData = (bs_main_data_t*) pUserData;
+
+ userevent.type = SDL_USEREVENT;
+@@ -121,6 +126,20 @@
+ userevent.data1 = NULL;
+ userevent.data2 = NULL;
+
++ gettimeofday(&curTime, NULL);
++ hunsec = curTime.tv_sec - beginTime.tv_sec;
++
++ /* increase cur_step each 10 seconds */
++ if (cur_step < hunsec / 10) {
++ printf("%d objects = %.2f fps\n", 1 << (cur_step + 1), pMainData->fps);
++ userevent.code = 2; /* add more objects */
++ cur_step++;
++ }
++
++ /* exit if requested number of objects is reached */
++ if (cur_step == 4)
++ userevent.code = 3;
++
+ event.type = SDL_USEREVENT;
+ event.user = userevent;
+
+@@ -152,14 +171,19 @@
+ pMainData->newTimerInterval = 50;
+ pMainData->fps = 20.0;
+ pMainData->running = TRUE;
+-
++
++ cur_step = 0;
++
+ bs_profiler_init();
+
++ gettimeofday(&beginTime, NULL);
+ gettimeofday(&startTime, NULL);
+ pMainData->lastFrameTimeStamp = startTime.tv_sec * 1000 + startTime.tv_usec / 1000;
+
+ SDL_AddTimer(50, bs_main_sdl_timer_callback, pMainData);
+
++ bs_blob_collective_split(pMainData->pCollective);
++
+ for(;;)
+ {
+ SDL_WaitEvent(&event);
+@@ -253,8 +277,7 @@
+ break;
+
+ case SDL_USEREVENT:
+- if(event.user.code == 1)
+- {
++ if (event.user.code == 1) {
+ gettimeofday(&startTime, NULL);
+ bs_main_update_simulation(pMainData);
+ bs_main_redraw(pMainData);
+@@ -268,10 +291,15 @@
+ usedTime = 50;
+ }
+
+- pMainData->newTimerInterval = usedTime;
+- }
+- break;
+-
++ pMainData->newTimerInterval = usedTime;
++ } else if (event.user.code == 2) {
++ int i;
++ for (i = 0; i < (1 << cur_step); i++)
++ bs_blob_collective_split(pMainData->pCollective);
++ } else if (event.user.code == 3) {
++ exit(0);
++ }
++ break;
+ case SDL_QUIT:
+ exit(0);
+ break;
diff --git a/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0003-printcleanup.patch b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0003-printcleanup.patch
new file mode 100644
index 000000000..630871dfd
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0003-printcleanup.patch
@@ -0,0 +1,11 @@
+--- a/bs_blob_collective.c
++++ b/bs_blob_collective.c
+@@ -152,7 +152,7 @@
+
+ bs_list_unlink_p_cont(pCollective->pBlobs, bs_blob_collective_remove_blob_cb, findData.pMotherBlob);
+
+- printf("number of blobs: %d\n", bs_list_get_length(pCollective->pBlobs));
++/* printf("number of blobs: %d\n", bs_list_get_length(pCollective->pBlobs)); */
+ }
+
+ typedef struct bs_blob_collective_join_find_smallest_st
diff --git a/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0004-bs_main.c.patch b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0004-bs_main.c.patch
new file mode 100644
index 000000000..ae15408de
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad/0004-bs_main.c.patch
@@ -0,0 +1,15 @@
+--- a/bs_main.c
++++ b/bs_main.c
+@@ -165,9 +165,9 @@
+ //pMainData->pRubberband = bs_rubberband_create(2.5f, 3.0f);
+ pMainData->pEnv = bs_env_create(0.0f, 0.0f, 6.0f, 4.0f);
+ pMainData->pGravity = bs_vector_create(0.0f, 10.0f);
+- pMainData->pCairoSdl = bs_cairo_sdl_create(600, 400);
+- pMainData->width = 600.0;
+- pMainData->height = 400.0;
++ pMainData->pCairoSdl = bs_cairo_sdl_create(1600, 1024);
++ pMainData->width = 1600.0;
++ pMainData->height = 1024.0;
+ pMainData->newTimerInterval = 50;
+ pMainData->fps = 20.0;
+ pMainData->running = TRUE;
diff --git a/meta-agl-profile-core/recipes-test/blobsallad/blobsallad_2006-11-14-23-57.bb b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad_2006-11-14-23-57.bb
new file mode 100644
index 000000000..373d4ddc6
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/blobsallad/blobsallad_2006-11-14-23-57.bb
@@ -0,0 +1,36 @@
+DESCRIPTION = ""
+HOMEPAGE = "http://blobsallad.se/"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = ""
+
+SRC_URI = " \
+ http://blobsallad.se/src/blobsallad-src-${PV}.tar.gz \
+ file://0001-Makefile.patch \
+ file://0002-auto.patch \
+ file://0003-printcleanup.patch \
+ file://0004-bs_main.c.patch"
+
+SRC_URI[md5sum] = "a2e3342cbf0f3a4a9b110af2663bed36"
+SRC_URI[sha256sum] = "cd6309df1929d3e6b7bce1dbecc751849aeaafe17c01e05fd2567dc4267faaa2"
+
+DEPENDS = "cairo virtual/libsdl"
+
+INSANE_SKIP_${PN} = "ldflags"
+
+S = "${WORKDIR}/blobsallad-src"
+
+do_configure () {
+ # Specify any needed configure commands here
+ :
+}
+
+do_compile () {
+ # You will almost certainly need to add additional arguments here
+ oe_runmake SDKROOT=${STAGING_DIR_HOST}
+}
+
+do_install () {
+ install -d ${D}${bindir}
+ install -m 0755 blobsallad ${D}${bindir}
+}
+
diff --git a/meta-agl-profile-core/recipes-test/dung/dung_3.4.25-m2.bb b/meta-agl-profile-core/recipes-test/dung/dung_3.4.25-m2.bb
new file mode 100644
index 000000000..28bf858a0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/dung/dung_3.4.25-m2.bb
@@ -0,0 +1,18 @@
+SUMMARY = "Kernel test scripts"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"
+
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qa-test-misc;protocol=https;branch=${AGL_BRANCH}"
+SRCREV = "e2472c7b1d061aef8bb05a4d7940fd8159c4a329"
+
+inherit allarch
+
+S = "${WORKDIR}/git/${PN}-${PV}"
+
+do_install () {
+ for subdir in arch_timer cmt common scifab sdhi.0; do
+ install -d -m 0755 ${D}/${datadir}/${PN}/$subdir
+ install -m 0755 -t ${D}/${datadir}/${PN}/$subdir ${S}/$subdir/*
+ done
+}
+
diff --git a/meta-agl-profile-core/recipes-test/ebizzy/ebizzy_0.3.bb b/meta-agl-profile-core/recipes-test/ebizzy/ebizzy_0.3.bb
new file mode 100644
index 000000000..08b0425c0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/ebizzy/ebizzy_0.3.bb
@@ -0,0 +1,20 @@
+DESCRIPTION = "Benchmark tool that generates a workload resembling common web application server workloads"
+HOMEPAGE = "http://ebizzy.sourceforge.net/"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=eb723b61539feef013de476e68b5c50a"
+
+SRC_URI = "http://downloads.sourceforge.net/project/ebizzy/ebizzy/${PV}/ebizzy-${PV}.tar.gz"
+SRC_URI[md5sum] = "af038bc506066bb3d28db08aba62bc38"
+SRC_URI[sha256sum] = "77286029d6348f3d9b3f04eae1feadb5ad1ad07b9f688f4d9f002960862467f2"
+
+INSANE_SKIP_${PN} = "ldflags"
+
+do_compile () {
+ ${CC} -Wall -Wshadow -lpthread -o ebizzy ebizzy.c
+}
+
+do_install () {
+ install -d ${D}${bindir}
+ install -m 0755 ebizzy ${D}${bindir}
+}
+
diff --git a/meta-agl-profile-core/recipes-test/ffsb/ffsb_6.0-rc2.bb b/meta-agl-profile-core/recipes-test/ffsb/ffsb_6.0-rc2.bb
new file mode 100644
index 000000000..66db133e3
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/ffsb/ffsb_6.0-rc2.bb
@@ -0,0 +1,14 @@
+DESCRIPTION = "Flexible File System Benchmark"
+HOMEPAGE = "https://sourceforge.net/projects/ffsb/"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=fd5d9bcabd8ed5a54a01ce8d183d592a"
+
+SRC_URI = "http://downloads.sourceforge.net/project/ffsb/ffsb/ffsb-${PV}/ffsb-${PV}.tar.bz2"
+SRC_URI[md5sum] = "cabfc1021c2ec6c6b168fefc84210891"
+SRC_URI[sha256sum] = "e5867692aae8c9bfbcdc774599022289c4d89c1d90f4dd7101fb9865ac773c71"
+
+inherit autotools
+
+# extra args to configure
+EXTRA_OECONF = ""
+
diff --git a/meta-agl-profile-core/recipes-test/fontconfig/fontconfig_%.bbappend b/meta-agl-profile-core/recipes-test/fontconfig/fontconfig_%.bbappend
new file mode 100644
index 000000000..c4bebdc1f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/fontconfig/fontconfig_%.bbappend
@@ -0,0 +1,17 @@
+PACKAGES =+ "fontconfig-test"
+
+do_install_append() {
+ install -m 755 -d ${D}/${datadir}/fontconfig-test
+ install -m 755 ${S}/test/run-test.sh ${D}/${datadir}/fontconfig-test/
+
+ sed -i -e "s/FCLIST=\.\.\/fc\-list\/fc\-list/FCLIST=\/usr\/bin\/fc\-list/g" -e "s/FCCACHE=\.\.\/fc\-cache\/fc\-cache/FCCACHE=\/usr\/bin\/fc\-cache/g" ${D}/${datadir}/fontconfig-test/run-test.sh
+
+ for x in 4x6.pcf 8x16.pcf out.expected fonts.conf.in; do
+ install -m 644 ${S}/test/$x ${D}/${datadir}/fontconfig-test/
+ done
+}
+
+DEBIAN_NOAUTONAME_fontconfig-test = "1"
+FILES_fontconfig-test = "${datadir}/fontconfig-test/*"
+
+
diff --git a/meta-agl-profile-core/recipes-test/freetype/files/0001-Makefile-dont-build-gfx-demos.patch b/meta-agl-profile-core/recipes-test/freetype/files/0001-Makefile-dont-build-gfx-demos.patch
new file mode 100644
index 000000000..1f3acf28e
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/freetype/files/0001-Makefile-dont-build-gfx-demos.patch
@@ -0,0 +1,32 @@
+diff -urN /tmp/ft2demos-2.6.orig/Makefile /tmp/ft2demos-2.6/Makefile
+--- ft2demos-2.6.orig/Makefile 2015-06-07 07:34:19.000000000 +0000
++++ ft2demos-2.6/Makefile 2016-06-17 14:25:37.640456725 +0000
+@@ -153,7 +153,8 @@
+
+ ifeq ($(PLATFORM),unix)
+ CC = $(CCraw)
+- LINK_CMD = $(subst /,$(SEP),$(OBJ_BUILD)/libtool) \
++ LIBTOOL = $(OBJ_BUILD)/libtool
++ LINK_CMD = $(subst /,$(SEP),$(LIBTOOL)) \
+ --mode=link $(CC) \
+ $(subst /,$(COMPILER_SEP),$(LDFLAGS))
+ LINK_LIBS = $(subst /,$(COMPILER_SEP),$(FTLIB) $(EFENCE))
+@@ -279,12 +280,12 @@
+ ttdebug
+
+ # Comment out the next line if you don't have a graphics subsystem.
+- EXES += ftdiff \
+- ftgamma \
+- ftgrid \
+- ftmulti \
+- ftstring \
+- ftview
++ # EXES += ftdiff \
++ # ftgamma \
++ # ftgrid \
++ # ftmulti \
++ # ftstring \
++ # ftview
+
+ # ftvalid requires ftgxval.c and ftotval.c
+ #
diff --git a/meta-agl-profile-core/recipes-test/freetype/files/0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch b/meta-agl-profile-core/recipes-test/freetype/files/0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch
new file mode 100644
index 000000000..7803ad7e0
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/freetype/files/0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch
@@ -0,0 +1,30 @@
+From 8c4f135619de929f9348b830a07a46a0c2c38e51 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jan-Simon=20M=C3=B6ller?= <jsmoeller@linuxfoundation.org>
+Date: Fri, 7 Oct 2016 15:26:20 +0200
+Subject: [PATCH] Do not hardcode libtool path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It is already known and imported through config.mk.
+
+Signed-off-by: Jan-Simon Möller <jsmoeller@linuxfoundation.org>
+---
+ Makefile | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index a5d34bd..254aad4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -153,7 +153,6 @@ else
+
+ ifeq ($(PLATFORM),unix)
+ CC = $(CCraw)
+- LIBTOOL = $(OBJ_BUILD)/libtool
+ LINK_CMD = $(subst /,$(SEP),$(LIBTOOL)) \
+ --mode=link $(CC) \
+ $(subst /,$(COMPILER_SEP),$(LDFLAGS))
+--
+2.1.4
+
diff --git a/meta-agl-profile-core/recipes-test/freetype/freetype_2.8.bbappend b/meta-agl-profile-core/recipes-test/freetype/freetype_2.8.bbappend
new file mode 100644
index 000000000..282ce784a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/freetype/freetype_2.8.bbappend
@@ -0,0 +1,32 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI =+ "${SOURCEFORGE_MIRROR}/freetype/ft2demos-${PV}.tar.bz2;name=ft2demos \
+ file://0001-Makefile-dont-build-gfx-demos.patch;patchdir=../ft2demos-${PV} \
+ file://0001-ft2demos-Makefile-Do-not-hardcode-libtool-path.patch;patchdir=../ft2demos-${PV} \
+ "
+SRC_URI[ft2demos.md5sum] = "61db5831e213acb843f0fc6d10186054"
+SRC_URI[ft2demos.sha256sum] = "2b6ce0d36bcb43fcc8aac07a0287982d855571ee271c3803c768e501f9c1a233"
+
+PACKAGES =+ "${PN}-demos"
+
+B = "${S}"
+
+do_compile_append () {
+
+ oe_runmake -C ${WORKDIR}/ft2demos-${PV} TOP_DIR=${WORKDIR}/${BPN}-${PV}/
+}
+
+do_install_append () {
+ install -d -m 0755 ${D}/${bindir}
+ for x in ftbench ftdump ftlint ftvalid ttdebug; do
+ install -m 0755 ${WORKDIR}/ft2demos-${PV}/bin/.libs/$x ${D}/${bindir}
+ done
+}
+
+FILES_${PN}-demos = "\
+ ${bindir}/ftbench \
+ ${bindir}/ftdump \
+ ${bindir}/ftlint \
+ ${bindir}/ftvalid \
+ ${bindir}/ttdebug \
+"
diff --git a/meta-agl-profile-core/recipes-test/fsfuzzer/files/0001-fix_missing_header_sys_stat.patch b/meta-agl-profile-core/recipes-test/fsfuzzer/files/0001-fix_missing_header_sys_stat.patch
new file mode 100644
index 000000000..e834becf3
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/fsfuzzer/files/0001-fix_missing_header_sys_stat.patch
@@ -0,0 +1,11 @@
+diff -urN fsfuzzer-0.7.orig/fstest.c fsfuzzer-0.7/fstest.c
+--- fsfuzzer-0.7.orig/fstest.c 2009-01-25 14:50:06.000000000 +0000
++++ fsfuzzer-0.7/fstest.c 2016-06-16 17:49:27.264565819 +0000
+@@ -35,6 +35,7 @@
+ #include <signal.h>
+ #include <sys/file.h>
+ #include <sys/mman.h>
++#include <sys/stat.h>
+
+ #define LOGGIT 1
+ #define CHECK_XATTR 1
diff --git a/meta-agl-profile-core/recipes-test/fsfuzzer/fsfuzzer_0.7.bb b/meta-agl-profile-core/recipes-test/fsfuzzer/fsfuzzer_0.7.bb
new file mode 100644
index 000000000..d2ddb59b1
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/fsfuzzer/fsfuzzer_0.7.bb
@@ -0,0 +1,18 @@
+SUMMARY = "The fsfuzzer is a filesystem fuzzer tool that does stress tests of various filesystems in a reproducible and logged way."
+DESCRIPTION = "This tool creates initial (valid) filesystem images and then manipulates their binary format and structure for detecting flaws/bugs/design problems in the parsing/handling code for that particular filesystem. The program expects that you have a /media directory. It uses that one for mounting test images in."
+HOMEPAGE = "https://www.ee.oulu.fi/research/ouspg/fsfuzzer"
+
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f"
+
+SRC_URI = "http://people.redhat.com/sgrubb/files/fsfuzzer-${PV}.tar.gz \
+ file://0001-fix_missing_header_sys_stat.patch \
+ "
+SRC_URI[md5sum] = "d69ac4b67aaba52a889c9188eb456c15"
+SRC_URI[sha256sum] = "094aa17c4f66c525a04e5db5ad444b4a561b6f8e310d0bd70b9ca421cdf0a434"
+
+inherit autotools
+
+# Specify any options you want to pass to the configure script using EXTRA_OECONF:
+EXTRA_OECONF = ""
+
diff --git a/meta-agl-profile-core/recipes-test/glmark2/glmark2_%.bbappend b/meta-agl-profile-core/recipes-test/glmark2/glmark2_%.bbappend
new file mode 100644
index 000000000..a64e0506c
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/glmark2/glmark2_%.bbappend
@@ -0,0 +1,2 @@
+PACKAGECONFIG = "wayland-gles2"
+PACKAGECONFIG[wayland-gles2] = ",,virtual/egl virtual/libgles2 wayland"
diff --git a/meta-agl-profile-core/recipes-test/himeno/himeno_2.0.bb b/meta-agl-profile-core/recipes-test/himeno/himeno_2.0.bb
new file mode 100644
index 000000000..f890e23a4
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/himeno/himeno_2.0.bb
@@ -0,0 +1,27 @@
+DESCRIPTION = "Himeno Benchmark"
+LICENSE = "LGPL-2.0"
+URL = "http://accc.riken.jp/en/supercom/himenobmt/"
+
+SRC_URI = "http://accc.riken.jp/en/wp-content/uploads/sites/2/2015/07/himenobmt.c.zip"
+SRC_URI[md5sum] = "8d8e837dfc3e00a3b322eb4ae3edd551"
+SRC_URI[sha256sum] = "8780bfbdacb0d4dcab2931e65cadd69411731e3f2afcc1231d0743a036298077"
+
+LIC_FILES_CHKSUM = "file://himenoBMT.c;md5=8e8771ddc01c6d1a795e088e2d6dee78"
+
+# Upstream ZIP file contains an LZH archive, thus a 2 steps "unpack" is required.
+# The LZH archive is unpacked after native tools dependency resolution,
+# thus. after "configure" task in our case:
+
+DEPENDS = "p7zip-native"
+
+do_configure_append() {
+ 7z x -y -o${S} ${WORKDIR}/himenobmt.c.lzh
+ cd ${S}
+ sed -i -e 's/CC= gcc/#CC= gcc/' Makefile
+ sed -i -e 's/CFLAGS = /#CFLAGS = /' Makefile
+}
+
+do_install () {
+ install -d ${D}${bindir}
+ install -m 0755 bmt ${D}${bindir}
+}
diff --git a/meta-agl-profile-core/recipes-test/interbench/files/interbench.c.patch b/meta-agl-profile-core/recipes-test/interbench/files/interbench.c.patch
new file mode 100644
index 000000000..c882739ba
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/interbench/files/interbench.c.patch
@@ -0,0 +1,68 @@
+--- interbench.c.orig 2009-10-30 23:14:59.000000000 -0500
++++ interbench.c 2012-07-10 19:06:00.000000000 -0500
+@@ -71,6 +71,7 @@ struct user_data {
+ char datestamp[13];
+ FILE *logfile;
+ } ud = {
++ .ram = 0,
+ .duration = 30,
+ .cpu_load = 4,
+ .log = 1,
+@@ -652,6 +653,8 @@ void emulate_write(struct thread *th)
+ terminal_error("fopen");
+ if (stat(name, &statbuf) == -1)
+ terminal_fileopen_error(fp, "stat");
++ if (statbuf.st_blksize < MIN_BLK_SIZE)
++ statbuf.st_blksize = MIN_BLK_SIZE;
+ for (i = 0 ; i < mem; i++) {
+ if (fwrite(buf, statbuf.st_blksize, 1, fp) != 1)
+ terminal_fileopen_error(fp, "fwrite");
+@@ -1136,14 +1139,17 @@ void get_ram(void)
+ if(!(meminfo = fopen("/proc/meminfo", "r")))
+ terminal_error("fopen");
+
+- ud.ram = ud.swap = 0;
+- while( !feof(meminfo) && !fscanf(meminfo, "MemTotal: %lu kB", &ud.ram) )
+- fgets(aux,sizeof(aux),meminfo);
++ if (!ud.ram)
++ {
++ while( !feof(meminfo) && !fscanf(meminfo, "MemTotal: %lu kB", &ud.ram) )
++ fgets(aux,sizeof(aux),meminfo);
++ }
++ ud.swap = 0;
+ while( !feof(meminfo) && !fscanf(meminfo, "SwapTotal: %lu kB", &ud.swap) )
+ fgets(aux,sizeof(aux),meminfo);
+ if (fclose(meminfo) == -1)
+ terminal_error("fclose");
+-
++
+ if( !ud.ram || !ud.swap ) {
+ unsigned long i;
+ fprintf(stderr, "\nCould not get memory or swap size. ");
+@@ -1399,6 +1405,7 @@ void usage(void)
+ fprintf(stderr, "\t[-h]\n\n");
+ fprintf(stderr, " -l\tUse <int> loops per sec (default: use saved benchmark)\n");
+ fprintf(stderr, " -L\tUse cpu load of <int> with burn load (default: 4)\n");
++ fprintf(stderr, " -M\tForce RAM size to <int>. Useful when disk is smaller than RAM.\n");
+ fprintf(stderr, " -t\tSeconds to run each benchmark (default: 30)\n");
+ fprintf(stderr, " -B\tNice the benchmarked thread to <int> (default: 0)\n");
+ fprintf(stderr, " -N\tNice the load thread to <int> (default: 0)\n");
+@@ -1482,7 +1489,7 @@ int main(int argc, char **argv)
+ terminal_error("signal");
+ #endif
+
+- while ((q = getopt(argc, argv, "hl:L:B:N:ut:bcnrC:I:m:w:x:W:X:")) != -1) {
++ while ((q = getopt(argc, argv, "hl:L:M:B:N:ut:bcnrC:I:m:w:x:W:X:")) != -1) {
+ switch (q) {
+ case 'h':
+ usage();
+@@ -1496,6 +1503,9 @@ int main(int argc, char **argv)
+ case 'L':
+ ud.cpu_load = atoi(optarg);
+ break;
++ case 'M':
++ ud.ram = atoi(optarg);
++ break;
+ case 'B':
+ ud.bench_nice = atoi(optarg);
+ break;
diff --git a/meta-agl-profile-core/recipes-test/interbench/interbench_0.31.bb b/meta-agl-profile-core/recipes-test/interbench/interbench_0.31.bb
new file mode 100644
index 000000000..3e6490374
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/interbench/interbench_0.31.bb
@@ -0,0 +1,31 @@
+DESCRIPTION = "The Linux interactivity benchmark"
+HOMEPAGE = "http://users.tpg.com.au/ckolivas/interbench/"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833"
+SRC_URI = "http://ck.kolivas.org/apps/interbench/interbench-${PV}.tar.bz2"
+
+SRC_URI += "file://interbench.c.patch;striplevel=0"
+
+inherit autotools
+
+INSANE_SKIP_${PN} = "ldflags"
+
+B = "${S}"
+EXTRA_OEMAKE = "CC='${CC}'"
+
+# upstream tarball contains x86_64 binaries, we need a clean source tree
+do_compile() {
+ oe_runmake clean
+ oe_runmake
+}
+
+do_install() {
+ install -d ${D}${bindir} ${D}${datadir}/doc/${PN}/ ${D}${mandir}/man8/
+ install -m 0755 ${B}/interbench ${D}${bindir}
+ install -m 0644 ${S}/readme* ${D}${datadir}/doc/${PN}/
+ install -m 0644 ${S}/interbench.8 ${D}${mandir}/man8/
+}
+
+SRC_URI[md5sum] = "832254d7fd1255c548ebea7b97f01015"
+SRC_URI[sha256sum] = "89d438b28aef22d26e79812762a57a9f9344a8dd8826edebfe60dad48ee1c784"
+
diff --git a/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0001-fix-out-of-tree-config.patch b/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0001-fix-out-of-tree-config.patch
new file mode 100644
index 000000000..e8a029790
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0001-fix-out-of-tree-config.patch
@@ -0,0 +1,52 @@
+iperf: fix out of tree configuration
+
+The configure step uses a package header to check for support of types/declares,
+this package header encapsulates all the required system header for providing
+the needed resources. When configured from an out of tree directory the package
+header is not found due to the hard path.
+We now make the path for package header relative to our 'srcdir' so it is
+found appropriately.
+
+Signed-off-by: Awais Belal <awais_belal@mentor.com>
+---
+diff --git a/configure.ac b/configure.ac
+index 2b3fd20..d420f9e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -176,8 +176,8 @@ dnl Check for system services
+
+ dnl check for multicast
+ if test "$ac_cv_multicast" != no; then
+- AC_CHECK_TYPES(struct ip_mreq,,,[#include "compat/headers_slim.h"])
+- AC_CHECK_DECLS(IP_ADD_MEMBERSHIP,,,[#include "compat/headers_slim.h"])
++ AC_CHECK_TYPES(struct ip_mreq,,,[#include "${srcdir}/compat/headers_slim.h"])
++ AC_CHECK_DECLS(IP_ADD_MEMBERSHIP,,,[#include "${srcdir}/compat/headers_slim.h"])
+ AC_MSG_CHECKING(for multicast support)
+ ac_cv_multicast=no
+ if test "$ac_cv_have_decl_IP_ADD_MEMBERSHIP" = yes; then
+@@ -193,9 +193,9 @@ fi
+
+ dnl check for IPv6
+ if test "$ac_cv_have_ipv6" != no; then
+- AC_CHECK_TYPES(struct sockaddr_storage,,,[#include "compat/headers_slim.h"])
+- AC_CHECK_TYPES(struct sockaddr_in6,,,[#include "compat/headers_slim.h"])
+- AC_CHECK_DECLS(AF_INET6,,,[#include "compat/headers_slim.h"])
++ AC_CHECK_TYPES(struct sockaddr_storage,,,[#include "${srcdir}/compat/headers_slim.h"])
++ AC_CHECK_TYPES(struct sockaddr_in6,,,[#include "${srcdir}/compat/headers_slim.h"])
++ AC_CHECK_DECLS(AF_INET6,,,[#include "${srcdir}/compat/headers_slim.h"])
+ AC_MSG_CHECKING(for IPv6 headers and structures)
+ ac_cv_have_ipv6=no
+ if test "$ac_cv_type_struct_sockaddr_storage" = yes; then
+@@ -211,9 +211,9 @@ fi
+
+ if test "$ac_cv_have_ipv6" = yes; then
+ if test "$ac_cv_multicast" = yes; then
+- AC_CHECK_TYPES(struct ipv6_mreq,,,[#include "compat/headers_slim.h"])
+- AC_CHECK_DECLS(IPV6_ADD_MEMBERSHIP,,,[#include "compat/headers_slim.h"])
+- AC_CHECK_DECLS(IPV6_MULTICAST_HOPS,,,[#include "compat/headers_slim.h"])
++ AC_CHECK_TYPES(struct ipv6_mreq,,,[#include "${srcdir}/compat/headers_slim.h"])
++ AC_CHECK_DECLS(IPV6_ADD_MEMBERSHIP,,,[#include "${srcdir}/compat/headers_slim.h"])
++ AC_CHECK_DECLS(IPV6_MULTICAST_HOPS,,,[#include "${srcdir}/compat/headers_slim.h"])
+ AC_MSG_CHECKING(for IPv6 multicast support)
+ ac_cv_have_ipv6_multicast=no
+ if test "$ac_cv_type_struct_ipv6_mreq" = yes; then
diff --git a/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0002-fix-bool-size-m4.patch b/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0002-fix-bool-size-m4.patch
new file mode 100644
index 000000000..348e316ce
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/0002-fix-bool-size-m4.patch
@@ -0,0 +1,16 @@
+--- iperf-2.0.5/m4/dast.m4.orig 2016-06-15 11:42:03.945581785 -0400
++++ iperf-2.0.5/m4/dast.m4 2016-06-15 11:42:11.053581641 -0400
+@@ -11,7 +11,12 @@
+
+ AC_DEFUN(DAST_CHECK_BOOL, [
+
+-AC_CHECK_SIZEOF(bool)
++if test "$ac_cv_header_stdbool_h" = yes; then
++ AC_CHECK_SIZEOF(bool,,[#include <stdbool.h>])
++else
++ AC_CHECK_SIZEOF(bool)
++fi
++
+ if test "$ac_cv_sizeof_bool" = 0 ; then
+ AC_DEFINE(bool, int)
+ fi
diff --git a/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/iperf-2.0.5_ManPage.patch b/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/iperf-2.0.5_ManPage.patch
new file mode 100644
index 000000000..12e8f4631
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/iperf/iperf-2.0.9/iperf-2.0.5_ManPage.patch
@@ -0,0 +1,8 @@
+diff --git iperf-2.0.5/man/Makefile.am iperf-2.0.5/man/Makefile.am
+ index ed97bc6..728873f 100644
+--- iperf-2.0.5/man/Makefile.am
++++ iperf-2.0.5/man/Makefile.am
+@@ -1,2 +1 @@
+-man_MANS = iperf.1
+-dist_man_MANS = $(man_MANS)
++dist_man_MANS = iperf.1
diff --git a/meta-agl-profile-core/recipes-test/iperf/iperf_2.0.9.bb b/meta-agl-profile-core/recipes-test/iperf/iperf_2.0.9.bb
new file mode 100644
index 000000000..f297f7f7f
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/iperf/iperf_2.0.9.bb
@@ -0,0 +1,20 @@
+DESCRIPTION = "Iperf is a tool to measure maximum TCP bandwidth, allowing the tuning of various parameters and UDP characteristics"
+HOMEPAGE = "http://dast.nlanr.net/Projects/Iperf/"
+SECTION = "console/network"
+LICENSE = "BSD-2-Clause"
+LIC_FILES_CHKSUM = "file://COPYING;md5=e8478eae9f479e39bc34975193360298"
+
+SRC_URI = " https://iperf.fr/download/source/${BP}-source.tar.gz \
+ "
+
+SRC_URI[md5sum] = "1bb3a1d98b1973aee6e8f171933c0f61"
+SRC_URI[sha256sum] = "a5350777b191e910334d3a107b5e5219b72ffa393da4186da1e0a4552aeeded6"
+
+S = "${WORKDIR}/${BP}"
+
+inherit autotools pkgconfig
+
+EXTRA_OECONF = "--exec-prefix=${STAGING_DIR_HOST}${layout_exec_prefix}"
+
+PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'ipv6', 'ipv6', '', d)}"
+PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
diff --git a/meta-agl-profile-core/recipes-test/ipv6connect/ipv6connect.bb b/meta-agl-profile-core/recipes-test/ipv6connect/ipv6connect.bb
new file mode 100644
index 000000000..a8b93716a
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/ipv6connect/ipv6connect.bb
@@ -0,0 +1,24 @@
+SUMMARY = "ipv6connect test"
+HOMEPAGE = "https://chromium.googlesource.com/chromiumos/third_party/autotest/+/0.12.369.B/client/tests/ipv6connect"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://${S}/${PN}/LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qa-test-misc;protocol=https;branch=${AGL_BRANCH}"
+SRCREV = "b355b7e1f43a19938895964f314484ffd8a39542"
+
+inherit autotools
+
+INSANE_SKIP_${PN} = "ldflags"
+
+B = "${WORKDIR}/git/ipv6connect"
+S = "${WORKDIR}/git"
+
+# configure script is not delivered, only a makefile.
+do_configure() {
+ :
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 0755 ${B}/ipv6connect ${D}${bindir}
+}
diff --git a/meta-agl-profile-core/recipes-test/linpack/linpack.bb b/meta-agl-profile-core/recipes-test/linpack/linpack.bb
new file mode 100644
index 000000000..84bed0ff6
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/linpack/linpack.bb
@@ -0,0 +1,23 @@
+SUMMARY = "Linpack benchmark"
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://${S}/${PN}/linpack.c;md5=076f1fd8d313056103f98d4253862eae"
+
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qa-test-misc;protocol=https;branch=${AGL_BRANCH}"
+SRCREV = "920cae73a918d1f516113b0ae967be3ecaba86ef"
+
+DEPENDS += "rsync-native"
+
+inherit autotools
+
+S = "${WORKDIR}/git"
+
+# configure script is not delivered, only a makefile.
+do_configure() {
+ mkdir -p ${B}
+ rsync -a ${S}/${PN}/* ${B}
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 0755 ${B}/linpack ${D}${bindir}
+}
diff --git a/meta-agl-profile-core/recipes-test/linus-stress/linus-stress.bb b/meta-agl-profile-core/recipes-test/linus-stress/linus-stress.bb
new file mode 100644
index 000000000..01b3cfce5
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/linus-stress/linus-stress.bb
@@ -0,0 +1,23 @@
+SUMMARY = "linus_stress test"
+HOMEPAGE = "https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/client/tests/linus_stress"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://${S}/linus_stress/LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/src/qa-test-misc;protocol=https;branch=${AGL_BRANCH}"
+SRCREV = "87cdfd4626c0cb47fc22f328867e49d6268df85c"
+
+inherit autotools
+INSANE_SKIP_${PN} = "ldflags"
+
+B = "${WORKDIR}/git/linus_stress"
+S = "${WORKDIR}/git"
+
+# configure script is not delivered, only a makefile.
+do_configure() {
+ :
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 0755 ${B}/linus_stress ${D}${bindir}
+}
diff --git a/meta-agl-profile-core/recipes-test/packagegroups/packagegroup-agl-test.bb b/meta-agl-profile-core/recipes-test/packagegroups/packagegroup-agl-test.bb
new file mode 100644
index 000000000..1c3412e84
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/packagegroups/packagegroup-agl-test.bb
@@ -0,0 +1,57 @@
+SUMMARY = "Utilities for testing of AGL"
+DESCRIPTION = "A set of common packages required by testing AGL for Quality Assurance"
+
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-test \
+ packagegroup-agl-test-ltp \
+ packagegroup-ivi-common-test \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ bc \
+ blobsallad \
+ dbench \
+ ebizzy \
+ ffsb \
+ interbench \
+ iozone3 \
+ iperf \
+ ipv6connect \
+ linpack \
+ linus-stress \
+ lmbench \
+ nbench-byte \
+ rt-tests \
+ stress \
+ "
+# to be added, but needs LICENSE_FLAGS_WHITELIST="non-commercial"
+# netperf
+
+# FTBS, SPEC-316
+# himeno
+# FTBS, SPEC-1384
+# trinity
+
+# packagegroup-agl-test-ltp \
+# ltp \
+#
+
+# Packages for shell commands which are required by LTP
+# readelf, logrotate, vsftpd, crontab, sar, arp, ftp,
+# host, rcp, rlogin, rsh, tcpdump, expect, iptables, dnsmasq,
+# pgrep
+RDEPENDS_packagegroup-agl-test-ltp += " \
+ initscripts-functions bind-utils binutils \
+ cronie dnsmasq expect inetutils-ftp inetutils-rsh \
+ iptables logrotate net-tools sysstat tcpdump vsftpd \
+ "
+
+RDEPENDS_packagegroup-ivi-common-test = " \
+ packagegroup-agl-test \
+ "
diff --git a/meta-agl-profile-core/recipes-test/trinity/trinity_git.bb b/meta-agl-profile-core/recipes-test/trinity/trinity_git.bb
new file mode 100644
index 000000000..f0f09a855
--- /dev/null
+++ b/meta-agl-profile-core/recipes-test/trinity/trinity_git.bb
@@ -0,0 +1,42 @@
+SUMMARY = "a Linux System call fuzz teste."
+DESCRIPTION = "Trinity, a Linux System call fuzz tester."
+HOMEPAGE = "http://codemonkey.org.uk/projects/trinity/"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://${S}/COPYING;md5=96094d47cfbd2cc45eb46ce0fc423c04"
+
+COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux"
+
+PV = "1.5"
+SRCREV = "edc2e693e298e0372010a361354c4a79a3cd93f3"
+SRC_URI = "git://github.com/kernelslacker/trinity.git;protocol=https;nobranch=1 \
+ "
+
+S = "${WORKDIR}/git"
+
+inherit useradd
+
+USERADD_PACKAGES = "${PN}"
+USERADD_PARAM_${PN} = "--system --create-home --shell /bin/sh ${PN} "
+
+do_configure () {
+ ./configure.sh
+}
+
+# workaround random build failures
+do_compile () {
+ ${MAKE}
+}
+
+do_install () {
+ oe_runmake install DESTDIR=${D}/usr
+ install -o ${PN} -d -m 0755 ${D}/${datadir}/${PN}
+ install -o ${PN} -m 0755 ${S}/scripts/test-all-syscalls-parallel.sh ${D}/${datadir}/${PN}
+ install -o ${PN} -m 0755 ${S}/scripts/test-all-syscalls-sequentially.sh ${D}/${datadir}/${PN}
+ install -o ${PN} -m 0755 ${S}/scripts/test-multi.sh ${D}/${datadir}/${PN}
+ install -o ${PN} -m 0755 ${S}/scripts/test-vm.sh ${D}/${datadir}/${PN}
+}
+
+PACKAGES =+ "${PN}-example"
+
+FILES_${PN} = "${bindir}/trinity"
+FILES_${PN}-example = "${datadir}/${PN}"