diff --git a/.gitignore b/.gitignore index 343ec10..930b071 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/libinput-1.13.2.tar.xz +SOURCES/libinput-1.14.3.tar.xz diff --git a/.libinput.metadata b/.libinput.metadata index 3ab964c..62784ed 100644 --- a/.libinput.metadata +++ b/.libinput.metadata @@ -1 +1 @@ -7e9d1bb3f5d4f8809c829753791141416a67ab1f SOURCES/libinput-1.13.2.tar.xz +af23a4359202c24b592033f54347719a8f44d872 SOURCES/libinput-1.14.3.tar.xz diff --git a/SOURCES/0001-Revert-tools-switch-measure-touchpad-tap-to-python-l.patch b/SOURCES/0001-Revert-tools-switch-measure-touchpad-tap-to-python-l.patch new file mode 100644 index 0000000..2c4423c --- /dev/null +++ b/SOURCES/0001-Revert-tools-switch-measure-touchpad-tap-to-python-l.patch @@ -0,0 +1,102 @@ +From 158391eeecbcfa05f0dc9373ed5efd7d08e365e1 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Thu, 24 Oct 2019 13:04:19 +1000 +Subject: [PATCH libinput 1/4] Revert "tools: switch measure-touchpad-tap to + python-libevdev" + +RHEL8 revert - we don't ship python-libevdev. + +This reverts commit 274b80d06cd0fb51911fae9252c7a800c5f6af94. +--- + tools/libinput-measure-touchpad-tap.py | 39 ++++++++++++++++---------- + 1 file changed, 24 insertions(+), 15 deletions(-) + +diff --git a/tools/libinput-measure-touchpad-tap.py b/tools/libinput-measure-touchpad-tap.py +index 8d8a8d8d..6f4f3999 100755 +--- a/tools/libinput-measure-touchpad-tap.py ++++ b/tools/libinput-measure-touchpad-tap.py +@@ -27,7 +27,8 @@ + import sys + import argparse + try: +- import libevdev ++ import evdev ++ import evdev.ecodes + import textwrap + import pyudev + except ModuleNotFoundError as e: +@@ -82,18 +83,27 @@ class InvalidDeviceError(Exception): + pass + + +-class Device(libevdev.Device): ++class Device(object): + def __init__(self, path): + if path is None: + self.path = self._find_touch_device() + else: + self.path = path +- fd = open(self.path, 'rb') +- super().__init__(fd) + +- print("Using {}: {}\n".format(self.name, self.path)) ++ self.device = evdev.InputDevice(self.path) + +- if not self.has(libevdev.EV_KEY.BTN_TOUCH): ++ print("Using {}: {}\n".format(self.device.name, self.path)) ++ ++ # capabilities returns a dict with the EV_* codes as key, ++ # each of which is a list of tuples of (code, AbsInfo) ++ # ++ # Get the abs list first (or empty list if missing), ++ # then extract the pressure absinfo from that ++ codes = self.device.capabilities(absinfo=True).get( ++ evdev.ecodes.EV_KEY, [] ++ ) ++ ++ if evdev.ecodes.BTN_TOUCH not in codes: + raise InvalidDeviceError("device does not have BTN_TOUCH") + + self.touches = [] +@@ -131,16 +141,16 @@ class Device(libevdev.Device): + end='') + + def handle_key(self, event): +- tapcodes = [libevdev.EV_KEY.BTN_TOOL_DOUBLETAP, +- libevdev.EV_KEY.BTN_TOOL_TRIPLETAP, +- libevdev.EV_KEY.BTN_TOOL_QUADTAP, +- libevdev.EV_KEY.BTN_TOOL_QUINTTAP] ++ tapcodes = [evdev.ecodes.BTN_TOOL_DOUBLETAP, ++ evdev.ecodes.BTN_TOOL_TRIPLETAP, ++ evdev.ecodes.BTN_TOOL_QUADTAP, ++ evdev.ecodes.BTN_TOOL_QUINTTAP] + if event.code in tapcodes and event.value > 0: + error("\rThis tool cannot handle multiple fingers, " + "output will be invalid") + return + +- if event.matches(libevdev.EV_KEY.BTN_TOUCH): ++ if event.code == evdev.ecodes.BTN_TOUCH: + self.handle_btn_touch(event) + + def handle_syn(self, event): +@@ -151,13 +161,12 @@ class Device(libevdev.Device): + orientation=self.touch.orientation) + + def handle_event(self, event): +- if event.matches(libevdev.EV_KEY): ++ if event.type == evdev.ecodes.EV_KEY: + self.handle_key(event) + + def read_events(self): +- while True: +- for event in self.events(): +- self.handle_event(event) ++ for event in self.device.read_loop(): ++ self.handle_event(event) + + def print_summary(self): + deltas = sorted(t.tdelta for t in self.touches) +-- +2.23.0 + diff --git a/SOURCES/0002-Revert-tools-switch-measure-touchpad-pressure-to-pyt.patch b/SOURCES/0002-Revert-tools-switch-measure-touchpad-pressure-to-pyt.patch new file mode 100644 index 0000000..679c376 --- /dev/null +++ b/SOURCES/0002-Revert-tools-switch-measure-touchpad-pressure-to-pyt.patch @@ -0,0 +1,147 @@ +From 85bf2c8a8595dfcc783d8b6abd460fe1bcf6d63c Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Thu, 24 Oct 2019 13:05:44 +1000 +Subject: [PATCH libinput 2/4] Revert "tools: switch measure-touchpad-pressure + to python-libevdev" + +RHEL8 revert - we don't ship python-libevdev. + +This reverts commit 33afe9f8756196e5a4df5fff33cb1344d5b6bc53. +--- + tools/libinput-measure-touchpad-pressure.py | 66 ++++++++++++--------- + 1 file changed, 37 insertions(+), 29 deletions(-) + +diff --git a/tools/libinput-measure-touchpad-pressure.py b/tools/libinput-measure-touchpad-pressure.py +index bba834c4..4973275e 100755 +--- a/tools/libinput-measure-touchpad-pressure.py ++++ b/tools/libinput-measure-touchpad-pressure.py +@@ -28,7 +28,8 @@ import sys + import subprocess + import argparse + try: +- import libevdev ++ import evdev ++ import evdev.ecodes + import pyudev + except ModuleNotFoundError as e: + print('Error: {}'.format(str(e)), file=sys.stderr) +@@ -149,33 +150,41 @@ class InvalidDeviceError(Exception): + pass + + +-class Device(libevdev.Device): ++class Device(object): + def __init__(self, path): + if path is None: + self.path = self.find_touchpad_device() + else: + self.path = path + +- fd = open(self.path, 'rb') +- super().__init__(fd) +- +- print("Using {}: {}\n".format(self.name, self.path)) +- +- self.has_mt_pressure = True +- absinfo = self.absinfo[libevdev.EV_ABS.ABS_MT_PRESSURE] +- if absinfo is None: +- absinfo = self.absinfo[libevdev.EV_ABS.ABS_PRESSURE] +- self.has_mt_pressure = False +- if absinfo is None: ++ self.device = evdev.InputDevice(self.path) ++ ++ print("Using {}: {}\n".format(self.device.name, self.path)) ++ ++ # capabilities rturns a dict with the EV_* codes as key, ++ # each of which is a list of tuples of (code, AbsInfo) ++ # ++ # Get the abs list first (or empty list if missing), ++ # then extract the pressure absinfo from that ++ all_caps = self.device.capabilities(absinfo=True) ++ caps = all_caps.get(evdev.ecodes.EV_ABS, []) ++ p = [cap[1] for cap in caps if cap[0] == evdev.ecodes.ABS_MT_PRESSURE] ++ if not p: ++ p = [cap[1] for cap in caps if cap[0] == evdev.ecodes.ABS_PRESSURE] ++ if not p: + raise InvalidDeviceError("Device does not have ABS_PRESSURE or ABS_MT_PRESSURE") ++ self.has_mt_pressure = False ++ else: ++ self.has_mt_pressure = True + +- prange = absinfo.maximum - absinfo.minimum ++ p = p[0] ++ prange = p.max - p.min + + # libinput defaults +- self.down = int(absinfo.minimum + 0.12 * prange) +- self.up = int(absinfo.minimum + 0.10 * prange) ++ self.down = int(p.min + 0.12 * prange) ++ self.up = int(p.min + 0.10 * prange) + self.palm = 130 # the libinput default +- self.thumb = absinfo.maximum ++ self.thumb = p.max + + self._init_thresholds_from_quirks() + self.sequences = [] +@@ -221,10 +230,10 @@ class Device(libevdev.Device): + + def handle_key(device, event): + tapcodes = [ +- libevdev.EV_KEY.BTN_TOOL_DOUBLETAP, +- libevdev.EV_KEY.BTN_TOOL_TRIPLETAP, +- libevdev.EV_KEY.BTN_TOOL_QUADTAP, +- libevdev.EV_KEY.BTN_TOOL_QUINTTAP ++ evdev.ecodes.BTN_TOOL_DOUBLETAP, ++ evdev.ecodes.BTN_TOOL_TRIPLETAP, ++ evdev.ecodes.BTN_TOOL_QUADTAP, ++ evdev.ecodes.BTN_TOOL_QUINTTAP + ] + if event.code in tapcodes and event.value > 0: + print("\rThis tool cannot handle multiple fingers, " +@@ -232,7 +241,7 @@ def handle_key(device, event): + + + def handle_abs(device, event): +- if event.matches(libevdev.EV_ABS.ABS_MT_TRACKING_ID): ++ if event.code == evdev.ecodes.ABS_MT_TRACKING_ID: + if event.value > -1: + device.start_new_sequence(event.value) + else: +@@ -243,8 +252,8 @@ def handle_abs(device, event): + except IndexError: + # If the finger was down at startup + pass +- elif (event.matches(libevdev.EV_ABS.ABS_MT_PRESSURE) or +- (event.matches(libevdev.EV_ABS.ABS_PRESSURE) and not device.has_mt_pressure)): ++ elif ((event.code == evdev.ecodes.ABS_MT_PRESSURE) or ++ (event.code == evdev.ecodes.ABS_PRESSURE and not device.has_mt_pressure)): + try: + s = device.current_sequence() + s.append(Touch(pressure=event.value)) +@@ -255,9 +264,9 @@ def handle_abs(device, event): + + + def handle_event(device, event): +- if event.matches(libevdev.EV_ABS): ++ if event.type == evdev.ecodes.EV_ABS: + handle_abs(device, event) +- elif event.matches(libevdev.EV_KEY): ++ elif event.type == evdev.ecodes.EV_KEY: + handle_key(device, event) + + +@@ -269,9 +278,8 @@ def loop(device): + print("Place a single finger on the touchpad to measure pressure values.\n" + "Ctrl+C to exit\n") + +- while True: +- for event in device.events(): +- handle_event(device, event) ++ for event in device.device.read_loop(): ++ handle_event(device, event) + + + def colon_tuple(string): +-- +2.23.0 + diff --git a/SOURCES/0003-Revert-tools-switch-measure-touch-size-to-python-lib.patch b/SOURCES/0003-Revert-tools-switch-measure-touch-size-to-python-lib.patch new file mode 100644 index 0000000..79bad28 --- /dev/null +++ b/SOURCES/0003-Revert-tools-switch-measure-touch-size-to-python-lib.patch @@ -0,0 +1,132 @@ +From 7e2ea0b918e8587db4975f585210e28cfaa5b2e1 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Thu, 24 Oct 2019 13:06:48 +1000 +Subject: [PATCH libinput 3/4] Revert "tools: switch measure-touch-size to + python-libevdev" + +This reverts commit deb759a0699a0ad18a9fa3dda8f1b397e34ae537. +--- + tools/libinput-measure-touch-size.py | 53 ++++++++++++++++------------ + 1 file changed, 31 insertions(+), 22 deletions(-) + +diff --git a/tools/libinput-measure-touch-size.py b/tools/libinput-measure-touch-size.py +index 4b2201e2..6f16b7e1 100755 +--- a/tools/libinput-measure-touch-size.py ++++ b/tools/libinput-measure-touch-size.py +@@ -28,7 +28,8 @@ import sys + import subprocess + import argparse + try: +- import libevdev ++ import evdev ++ import evdev.ecodes + import pyudev + except ModuleNotFoundError as e: + print('Error: {}'.format(str(e)), file=sys.stderr) +@@ -177,23 +178,32 @@ class InvalidDeviceError(Exception): + pass + + +-class Device(libevdev.Device): ++class Device(object): + def __init__(self, path): + if path is None: + self.path = self.find_touch_device() + else: + self.path = path + +- fd = open(self.path, 'rb') +- super().__init__(fd) ++ self.device = evdev.InputDevice(self.path) + +- print("Using {}: {}\n".format(self.name, self.path)) ++ print("Using {}: {}\n".format(self.device.name, self.path)) + +- if not self.has(libevdev.EV_ABS.ABS_MT_TOUCH_MAJOR): ++ # capabilities returns a dict with the EV_* codes as key, ++ # each of which is a list of tuples of (code, AbsInfo) ++ # ++ # Get the abs list first (or empty list if missing), ++ # then extract the touch major absinfo from that ++ caps = self.device.capabilities(absinfo=True).get( ++ evdev.ecodes.EV_ABS, [] ++ ) ++ codes = [cap[0] for cap in caps] ++ ++ if evdev.ecodes.ABS_MT_TOUCH_MAJOR not in codes: + raise InvalidDeviceError("Device does not have ABS_MT_TOUCH_MAJOR") + +- self.has_minor = self.has(libevdev.EV_ABS.ABS_MT_TOUCH_MINOR) +- self.has_orientation = self.has(libevdev.EV_ABS.ABS_MT_ORIENTATION) ++ self.has_minor = evdev.ecodes.ABS_MT_TOUCH_MINOR in codes ++ self.has_orientation = evdev.ecodes.ABS_MT_ORIENTATION in codes + + self.up = 0 + self.down = 0 +@@ -245,16 +255,16 @@ class Device(libevdev.Device): + return self.sequences[-1] + + def handle_key(self, event): +- tapcodes = [libevdev.EV_KEY.BTN_TOOL_DOUBLETAP, +- libevdev.EV_KEY.BTN_TOOL_TRIPLETAP, +- libevdev.EV_KEY.BTN_TOOL_QUADTAP, +- libevdev.EV_KEY.BTN_TOOL_QUINTTAP] ++ tapcodes = [evdev.ecodes.BTN_TOOL_DOUBLETAP, ++ evdev.ecodes.BTN_TOOL_TRIPLETAP, ++ evdev.ecodes.BTN_TOOL_QUADTAP, ++ evdev.ecodes.BTN_TOOL_QUINTTAP] + if event.code in tapcodes and event.value > 0: + print("\rThis tool cannot handle multiple fingers, " + "output will be invalid", file=sys.stderr) + + def handle_abs(self, event): +- if event.matches(libevdev.EV_ABS.ABS_MT_TRACKING_ID): ++ if event.code == evdev.ecodes.ABS_MT_TRACKING_ID: + if event.value > -1: + self.start_new_sequence(event.value) + else: +@@ -265,11 +275,11 @@ class Device(libevdev.Device): + except IndexError: + # If the finger was down during start + pass +- elif event.matches(libevdev.EV_ABS.ABS_MT_TOUCH_MAJOR): ++ elif event.code == evdev.ecodes.ABS_MT_TOUCH_MAJOR: + self.touch.major = event.value +- elif event.matches(libevdev.EV_ABS.ABS_MT_TOUCH_MINOR): ++ elif event.code == evdev.ecodes.ABS_MT_TOUCH_MINOR: + self.touch.minor = event.value +- elif event.matches(libevdev.EV_ABS.ABS_MT_ORIENTATION): ++ elif event.code == evdev.ecodes.ABS_MT_ORIENTATION: + self.touch.orientation = event.value + + def handle_syn(self, event): +@@ -284,11 +294,11 @@ class Device(libevdev.Device): + pass + + def handle_event(self, event): +- if event.matches(libevdev.EV_ABS): ++ if event.type == evdev.ecodes.EV_ABS: + self.handle_abs(event) +- elif event.matches(libevdev.EV_KEY): ++ elif event.type == evdev.ecodes.EV_KEY: + self.handle_key(event) +- elif event.matches(libevdev.EV_SYN): ++ elif event.type == evdev.ecodes.EV_SYN: + self.handle_syn(event) + + def read_events(self): +@@ -299,9 +309,8 @@ class Device(libevdev.Device): + print("Place a single finger on the device to measure touch size.\n" + "Ctrl+C to exit\n") + +- while True: +- for event in self.events(): +- self.handle_event(event) ++ for event in self.device.read_loop(): ++ self.handle_event(event) + + + def colon_tuple(string): +-- +2.23.0 + diff --git a/SOURCES/0004-Revert-tools-switch-measure-fuzz-to-use-python-libev.patch b/SOURCES/0004-Revert-tools-switch-measure-fuzz-to-use-python-libev.patch new file mode 100644 index 0000000..06dcae6 --- /dev/null +++ b/SOURCES/0004-Revert-tools-switch-measure-fuzz-to-use-python-libev.patch @@ -0,0 +1,94 @@ +From b79b1513b33d42b861572ad4e0bac135e58b5d12 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Thu, 24 Oct 2019 13:09:25 +1000 +Subject: [PATCH libinput 4/4] Revert "tools: switch measure-fuzz to use + python-libevdev" + +RHEL8 revert - we don't ship python-libevdev. + +This reverts commit 795c08eb44fca078fa9935fdc5b8482bb7b43413. +--- + tools/libinput-measure-fuzz.py | 42 +++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 11 deletions(-) + +diff --git a/tools/libinput-measure-fuzz.py b/tools/libinput-measure-fuzz.py +index 41e2825c..bb574882 100755 +--- a/tools/libinput-measure-fuzz.py ++++ b/tools/libinput-measure-fuzz.py +@@ -29,7 +29,8 @@ import sys + import argparse + import subprocess + try: +- import libevdev ++ import evdev ++ import evdev.ecodes + import pyudev + except ModuleNotFoundError as e: + print('Error: {}'.format(str(e)), file=sys.stderr) +@@ -69,15 +70,15 @@ class InvalidDeviceError(Exception): + pass + + +-class Device(libevdev.Device): ++class Device(object): + def __init__(self, path): + if path is None: + self.path = self.find_touch_device() + else: + self.path = path + +- fd = open(self.path, 'rb') +- super().__init__(fd) ++ self.device = evdev.InputDevice(self.path) ++ self.name = self.device.name + context = pyudev.Context() + self.udev_device = pyudev.Devices.from_device_file(context, self.path) + +@@ -132,18 +133,37 @@ class Device(libevdev.Device): + Returns a tuple of (xfuzz, yfuzz) with the fuzz as set on the device + axis. Returns None if no fuzz is set. + ''' +- if not self.has(libevdev.EV_ABS.ABS_X) or not self.has(libevdev.EV_ABS.ABS_Y): ++ # capabilities returns a dict with the EV_* codes as key, ++ # each of which is a list of tuples of (code, AbsInfo) ++ # ++ # Get the abs list first (or empty list if missing), ++ # then extract the touch major absinfo from that ++ caps = self.device.capabilities(absinfo=True).get( ++ evdev.ecodes.EV_ABS, [] ++ ) ++ codes = [cap[0] for cap in caps] ++ ++ if evdev.ecodes.ABS_X not in codes or evdev.ecodes.ABS_Y not in codes: + raise InvalidDeviceError('device does not have x/y axes') + +- if self.has(libevdev.EV_ABS.ABS_MT_POSITION_X) != self.has(libevdev.EV_ABS.ABS_MT_POSITION_Y): ++ if (evdev.ecodes.ABS_MT_POSITION_X in codes) != (evdev.ecodes.ABS_MT_POSITION_Y in codes): + raise InvalidDeviceError('device does not have both multitouch axes') + +- xfuzz = self.absinfo[libevdev.EV_ABS.ABS_X].fuzz or \ +- self.absinfo[libevdev.EV_ABS.ABS_MT_POSITION_X].fuzz +- yfuzz = self.absinfo[libevdev.EV_ABS.ABS_Y].fuzz or \ +- self.absinfo[libevdev.EV_ABS.ABS_MT_POSITION_Y].fuzz ++ axes = { ++ 0x00: None, ++ 0x01: None, ++ 0x35: None, ++ 0x36: None, ++ } + +- if xfuzz is 0 and yfuzz is 0: ++ for c in caps: ++ if c[0] in axes.keys(): ++ axes[c[0]] = c[1].fuzz ++ ++ xfuzz = axes[0x35] or axes[0x00] ++ yfuzz = axes[0x36] or axes[0x01] ++ ++ if xfuzz is None and yfuzz is None: + return None + + return (xfuzz, yfuzz) +-- +2.23.0 + diff --git a/SPECS/libinput.spec b/SPECS/libinput.spec index 7b31550..5aa6fcd 100644 --- a/SPECS/libinput.spec +++ b/SPECS/libinput.spec @@ -4,7 +4,7 @@ %global gitversion 58abea394 Name: libinput -Version: 1.13.2 +Version: 1.14.3 Release: 1%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} Summary: Input device library @@ -18,6 +18,11 @@ Source2: commitid Source0: http://www.freedesktop.org/software/libinput/libinput-%{version}.tar.xz %endif +Patch001: 0001-Revert-tools-switch-measure-touchpad-tap-to-python-l.patch +Patch002: 0002-Revert-tools-switch-measure-touchpad-pressure-to-pyt.patch +Patch003: 0003-Revert-tools-switch-measure-touch-size-to-python-lib.patch +Patch004: 0004-Revert-tools-switch-measure-fuzz-to-use-python-libev.patch + BuildRequires: git-core BuildRequires: gcc gcc-c++ BuildRequires: meson @@ -26,6 +31,7 @@ BuildRequires: pkgconfig(mtdev) >= 1.1.0 BuildRequires: pkgconfig(libevdev) >= 0.4 BuildRequires: pkgconfig(libwacom) >= 0.20 BuildRequires: python3-devel +BuildRequires: check-devel %description libinput is a library that handles input devices for display servers and other @@ -53,6 +59,14 @@ Requires: python3-evdev python3-pyudev The %{name}-utils package contains tools to debug hardware and analyze %{name}. +%package test +Summary: libinput integration test suite +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description test +The %{name}-test package contains the libinput test suite. It is not +intended to be run by users. + %prep %autosetup -S git # Replace whatever the source uses with the approved call @@ -61,7 +75,8 @@ pathfix.py -i %{__python3} -p -n $(git grep -l '#!/usr/bin/.*python3') %build %meson -Ddebug-gui=false \ -Ddocumentation=false \ - -Dtests=false \ + -Dtests=true \ + -Dinstall-tests=true \ -Dudev-dir=%{udevdir} %meson_build @@ -82,16 +97,18 @@ rm $RPM_BUILD_ROOT/%{_mandir}/man1/libinput-record.1* %doc COPYING %{_libdir}/libinput.so.* %{udevdir}/libinput-device-group -%{udevdir}/libinput-model-quirks +%{udevdir}/libinput-fuzz-override %{udevdir}/rules.d/80-libinput-device-groups.rules -%{udevdir}/rules.d/90-libinput-model-quirks.rules +%{udevdir}/rules.d/90-libinput-fuzz-override.rules %{_bindir}/libinput %dir %{_libexecdir}/libinput/ %{_libexecdir}/libinput/libinput-debug-events %{_libexecdir}/libinput/libinput-list-devices %{_mandir}/man1/libinput.1* %{_datadir}/libinput/*.quirks - +%dir %{_datadir}/zsh +%dir %{_datadir}/zsh/site-functions +%{_datadir}/zsh/site-functions/* %{_mandir}/man1/libinput-list-devices.1* %{_mandir}/man1/libinput-debug-events.1* @@ -118,7 +135,14 @@ rm $RPM_BUILD_ROOT/%{_mandir}/man1/libinput-record.1* %{_mandir}/man1/libinput-quirks-validate.1* %{_mandir}/man1/libinput-replay.1* +%files test +%{_libexecdir}/libinput/libinput-test-suite +%{_mandir}/man1/libinput-test-suite.1* + %changelog +* Mon Oct 28 2019 Peter Hutterer 1.14.3-1 +- libinput 1.14.3 (#1728821) + * Thu May 09 2019 Peter Hutterer 1.13.2-1 - libinput 1.13.3 (#1690212)