Add progressive backoff to XactLockTableWait functions

Started by Xuneng Zhou7 months ago32 messages
#1Xuneng Zhou
xunengzhou@gmail.com
1 attachment(s)

Hi hackers,

This patch implements progressive backoff in XactLockTableWait() and
ConditionalXactLockTableWait().

As Kevin reported in this thread [1]/messages/by-id/CAM45KeELdjhS-rGuvN=ZLJ_asvZACucZ9LZWVzH7bGcD12DDwg@mail.gmail.com, XactLockTableWait() can enter a
tight polling loop during logical replication slot creation on standby
servers, sleeping for fixed 1ms intervals that can continue for a long
time. This creates significant CPU overhead.

The patch implements a time-based threshold approach based on Fujii’s
idea [1]/messages/by-id/CAM45KeELdjhS-rGuvN=ZLJ_asvZACucZ9LZWVzH7bGcD12DDwg@mail.gmail.com: keep sleeping for 1ms until the total sleep time reaches 10
seconds, then start exponential backoff (doubling the sleep duration
each cycle) up to a maximum of 10 seconds per sleep. This balances
responsiveness for normal operations (which typically complete within
seconds) against CPU efficiency for the long waits in some logical
replication scenarios.

[1]: /messages/by-id/CAM45KeELdjhS-rGuvN=ZLJ_asvZACucZ9LZWVzH7bGcD12DDwg@mail.gmail.com

Best regards,
Xuneng

Attachments:

0001-Add-progressive-backoff-to-XactLockTableWait.patchapplication/octet-stream; name=0001-Add-progressive-backoff-to-XactLockTableWait.patchDownload
From cd90ff97b12d3c2e74da6cfa4b0b8939c6f6dbb6 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Sun, 8 Jun 2025 20:28:17 +0800
Subject: [PATCH] Add progressive backoff to XactLockTableWait functions

XactLockTableWait() and ConditionalXactLockTableWait() currently use
a fixed 1ms sleep when waiting for transaction completion. In logical
replication scenarios, particularly during CREATE REPLICATION SLOT,
these functions may wait for very long periods (minutes to hours) for
old transactions to complete, leading to excessive CPU usage due to
frequent polling.

This patch implements progressive backoff: keep sleeping for 1ms until
total sleep time reaches 10 seconds, then start doubling the sleep duration
each cycle, up to a maximum of 10 seconds per sleep. This balances
responsiveness for normal operations (which typically complete within seconds)
against CPU efficiency for long waits common in logical replication scenarios.
---
 src/backend/storage/lmgr/lmgr.c | 48 ++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..495fa607932 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -667,6 +667,13 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 	XactLockTableWaitInfo info;
 	ErrorContextCallback callback;
 	bool		first = true;
+	long		total_sleep_us = 0;
+	long		sleep_us = 1000;		/* Start with 1ms */
+	bool		do_backoff = false;
+
+	/* Progressive backoff threshold */
+	const long	backoff_threshold_us = 10 * USECS_PER_SEC;	/* 10 seconds */
+	const long	max_sleep_us = 10 * USECS_PER_SEC;			/* 10 seconds */
 
 	/*
 	 * If an operation is specified, set up our verbose error context
@@ -713,13 +720,25 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 * as when building snapshots for logical decoding.  It is possible to
 		 * see a transaction in ProcArray before it registers itself in the
 		 * locktable.  The topmost transaction in that case is the same xid,
-		 * so we try again after a short sleep.  (Don't sleep the first time
-		 * through, to avoid slowing down the normal case.)
+		 * so we try again after a progressive sleep.  (Don't sleep the first
+		 * time through, to avoid slowing down the normal case.)
 		 */
 		if (!first)
 		{
 			CHECK_FOR_INTERRUPTS();
-			pg_usleep(1000L);
+			pg_usleep(sleep_us);
+
+			/* Track total only until we start doing backoff */
+			if (!do_backoff)
+			{
+				total_sleep_us += sleep_us;
+				if (total_sleep_us >= backoff_threshold_us)
+					do_backoff = true;
+			}
+
+			/* Exponential backoff once threshold is reached */
+			if (do_backoff && sleep_us < max_sleep_us)
+				sleep_us = Min(sleep_us * 2, max_sleep_us);
 		}
 		first = false;
 		xid = SubTransGetTopmostTransaction(xid);
@@ -734,12 +753,21 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
  *
  * As above, but only lock if we can get the lock without blocking.
  * Returns true if the lock was acquired.
+ *
+ * Uses the same progressive backoff as XactLockTableWait.
  */
 bool
 ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 {
 	LOCKTAG		tag;
 	bool		first = true;
+	long		total_sleep_us = 0;
+	long		sleep_us = 1000;		/* Start with 1ms */
+	bool		do_backoff = false;
+
+	/* Progressive backoff threshold */
+	const long	backoff_threshold_us = 10 * USECS_PER_SEC;	/* 10 seconds */
+	const long	max_sleep_us = 10 * USECS_PER_SEC;			/* 10 seconds */
 
 	for (;;)
 	{
@@ -762,7 +790,19 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		if (!first)
 		{
 			CHECK_FOR_INTERRUPTS();
-			pg_usleep(1000L);
+			pg_usleep(sleep_us);
+
+			/* Track total only until we start doing backoff */
+			if (!do_backoff)
+			{
+				total_sleep_us += sleep_us;
+				if (total_sleep_us >= backoff_threshold_us)
+					do_backoff = true;
+			}
+
+			/* Exponential backoff once threshold is reached */
+			if (do_backoff && sleep_us < max_sleep_us)
+				sleep_us = Min(sleep_us * 2, max_sleep_us);
 		}
 		first = false;
 		xid = SubTransGetTopmostTransaction(xid);
-- 
2.48.1

#2Fujii Masao
masao.fujii@oss.nttdata.com
In reply to: Xuneng Zhou (#1)
Re: Add progressive backoff to XactLockTableWait functions

On 2025/06/08 23:33, Xuneng Zhou wrote:

Hi hackers,

This patch implements progressive backoff in XactLockTableWait() and
ConditionalXactLockTableWait().

As Kevin reported in this thread [1], XactLockTableWait() can enter a
tight polling loop during logical replication slot creation on standby
servers, sleeping for fixed 1ms intervals that can continue for a long
time. This creates significant CPU overhead.

The patch implements a time-based threshold approach based on Fujii’s
idea [1]: keep sleeping for 1ms until the total sleep time reaches 10
seconds, then start exponential backoff (doubling the sleep duration
each cycle) up to a maximum of 10 seconds per sleep. This balances
responsiveness for normal operations (which typically complete within
seconds) against CPU efficiency for the long waits in some logical
replication scenarios.

Thanks for the patch!

When I first suggested this idea, I used 10s as an example for
the maximum sleep time. But thinking more about it now, 10s might
be too long. Even if the target transaction has already finished,
XactLockTableWait() could still wait up to 10 seconds,
which seems excessive.

What about using 1s instead? That value is already used as a max
sleep time in other places, like WaitExceedsMaxStandbyDelay().

If we agree on 1s as the max, then using exponential backoff from
1ms to 1s after the threshold might not be necessary. It might
be simpler and sufficient to just sleep for 1s once we hit
the threshold.

Based on that, I think a change like the following could work well.
Thought?

----------------------------------------
         XactLockTableWaitInfo info;
         ErrorContextCallback callback;
         bool            first = true;
+       int             left_till_hibernate = 5000;

<snip>

                 if (!first)
                 {
                         CHECK_FOR_INTERRUPTS();
-                       pg_usleep(1000L);
+
+                       if (left_till_hibernate > 0)
+                       {
+                               pg_usleep(1000L);
+                               left_till_hibernate--;
+                       }
+                       else
+                               pg_usleep(1000000L);
----------------------------------------

Regards,

--
Fujii Masao
NTT DATA Japan Corporation

#3Xuneng Zhou
xunengzhou@gmail.com
In reply to: Fujii Masao (#2)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

Thanks for the feedback!

On Thu, Jun 12, 2025 at 10:02 PM Fujii Masao <masao.fujii@oss.nttdata.com>
wrote:

When I first suggested this idea, I used 10s as an example for
the maximum sleep time. But thinking more about it now, 10s might
be too long. Even if the target transaction has already finished,
XactLockTableWait() could still wait up to 10 seconds,
which seems excessive.

+1, this could be a problem

What about using 1s instead? That value is already used as a max
sleep time in other places, like WaitExceedsMaxStandbyDelay().

1s should be generally good

If we agree on 1s as the max, then using exponential backoff from
1ms to 1s after the threshold might not be necessary. It might
be simpler and sufficient to just sleep for 1s once we hit
the threshold.

That makes sense to me.

Based on that, I think a change like the following could work well.

Thought?

I'll update the patch accordingly.

Best regards,
Xuneng

#4Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#3)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

Attached is v2 of the patch to add threshold-based sleep to
XactLockTableWait functions.

Changes from v1:
- Simplified approach based on Fujii's feedback [1]/messages/by-id/7c72c5d1-4d2f-46f7-8b68-dd96905f8c42@oss.nttdata.com: instead of exponential
backoff,
we now sleep 1ms for the first 5 seconds, then switch directly to 1s
sleeps
- Reduced the threshold from 10 seconds to 5 seconds to avoid excessive
delays

[1]: /messages/by-id/7c72c5d1-4d2f-46f7-8b68-dd96905f8c42@oss.nttdata.com
/messages/by-id/7c72c5d1-4d2f-46f7-8b68-dd96905f8c42@oss.nttdata.com

Best regards,
Xuneng

Attachments:

v2-0001-Add-threshold-based-sleep-to-XactLockTableWait-functions.patchapplication/octet-stream; name=v2-0001-Add-threshold-based-sleep-to-XactLockTableWait-functions.patchDownload
From 3dfcb99c8208d6c121d9e32231d1b111a498cbd2 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Sun, 15 Jun 2025 15:47:30 +0800
Subject: [PATCH v2] Add threshold-based sleep to XactLockTableWait functions

XactLockTableWait() and ConditionalXactLockTableWait() currently use
a fixed 1ms sleep when waiting for transaction completion. In logical
replication scenarios, particularly during CREATE REPLICATION SLOT,
these functions may wait for very long periods (minutes to hours) for
old transactions to complete, leading to excessive CPU usage due to
frequent polling.

This patch implements a threshold-based approach: sleep for 1ms for
the first 5 seconds (5000 iterations), then switch to 1s sleeps for
the remainder of the wait. This balances responsiveness for normal
operations (which typically complete within seconds) against CPU
efficiency for long waits common in logical replication scenarios.
---
 src/backend/storage/lmgr/lmgr.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..c81b2fbe849 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -667,6 +667,7 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 	XactLockTableWaitInfo info;
 	ErrorContextCallback callback;
 	bool		first = true;
+	int			left_till_hibernate = 5000;
 
 	/*
 	 * If an operation is specified, set up our verbose error context
@@ -713,13 +714,22 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 * as when building snapshots for logical decoding.  It is possible to
 		 * see a transaction in ProcArray before it registers itself in the
 		 * locktable.  The topmost transaction in that case is the same xid,
-		 * so we try again after a short sleep.  (Don't sleep the first time
-		 * through, to avoid slowing down the normal case.)
+		 * so we try again after a sleep.  We sleep 1ms for the first 5 seconds
+		 * to keep normal operations responsive, then 1s to reduce CPU overhead
+		 * during long waits.  (Don't sleep the first time through, to avoid
+		 * slowing down the normal case.)
 		 */
 		if (!first)
 		{
 			CHECK_FOR_INTERRUPTS();
-			pg_usleep(1000L);
+
+			if (left_till_hibernate > 0)
+			{
+				pg_usleep(1000L);
+				left_till_hibernate--;
+			}
+			else
+				pg_usleep(1000000L); /* 1s */
 		}
 		first = false;
 		xid = SubTransGetTopmostTransaction(xid);
@@ -740,6 +750,7 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 {
 	LOCKTAG		tag;
 	bool		first = true;
+	int			left_till_hibernate = 5000;
 
 	for (;;)
 	{
@@ -762,7 +773,14 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		if (!first)
 		{
 			CHECK_FOR_INTERRUPTS();
-			pg_usleep(1000L);
+
+			if (left_till_hibernate > 0)
+			{
+				pg_usleep(1000L); 
+				left_till_hibernate--;
+			}
+			else
+				pg_usleep(1000000L); 
 		}
 		first = false;
 		xid = SubTransGetTopmostTransaction(xid);
-- 
2.48.1

#5Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#4)
4 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

Although it’s clear that replacing tight 1 ms polling loops will reduce CPU
usage, I'm curious about the hard numbers. To that end, I ran a 60 s
logical-replication slot–creation workload on a standby using three
different XactLockTableWait() variants—on an 8-core, 16 GB AMD system—and
collected both profiling traces and hardware-counter metrics.

1. Hardware‐counter results

[image: image.png]

- CPU cycles drop by 58% moving from 1 ms to exp. backoff, and another
25% to the 1 s threshold variant.
- Cache‐misses and context‐switches see similarly large reductions.
- IPC remains around 0.45, dipping slightly under longer sleeps.

2. Flame‐graph
See attached files

Best regards,
Xuneng

Attachments:

image.pngimage/png; name=image.pngDownload
�PNG


IHDR�l�sRGB����eXIfMM*>F(�iN��������ASCIIScreenshots��	pHYs%%IR$��iTXtXML:com.adobe.xmp<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <exif:PixelYDimension>512</exif:PixelYDimension>
         <exif:PixelXDimension>2060</exif:PixelXDimension>
         <exif:UserComment>Screenshot</exif:UserComment>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
�0Y�iDOT(�j�&@IDATx���$E���"(9*$*�H%HO�dDr�J��D�@���$	� (9G��������kjzv'������<w3���]���U��o�E�(�P@P@P@P@P@P@P@P`D	�g�����n�
(��
(��
(��
(��
(��
(��
(����
(��
(��
(��
(��
(��
(��
(��
�@F�Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@F��#p���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��#P������dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�@F�Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@F��#p���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��#P������dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�@F�Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@F��#p���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��#P������dP@P@P@P@P@P@P@���m�Y5jT]�y�������M��
(0���s���2��e���k8������AP@P@P@P@P@�B���*{�����;����uk��������^{����e�^z���RK�}�������G�3\��{��^{�����_�
k��V�4?(���I��?�i����\��[n�%l���u����
(��
(��
(��
(��
(��
T!`�@�=\�7�����~�5���w�uW��|BY�:�D��������e�e����}f�E�i��6�1�us���[������qG�����qg��%
(��
(��
(��
(��
(��
��C����
(G2`�������N;�6�t���z��wZ�����a-�j�������f^P@P@P@P@P@��0`�ovEyF(w1`��������;�6�d���bH�/}�Ku��0��0��1��s�DP@P@P@P@P@��0``(�[X��H��8u��Rx����l��(9�
(��
(��
(��
(��
(��
T%`�@U�=Z�PL:��a�9�M4Qx���������V�?��a����L2Ix���\��?��0�3���?<������>��8��x���|�g,�_~����s����D~��f���r�)�o�^y����/���V�6�TS���SO^���8��J��V����&�p�0��3����������}PE�@���v����mg�Uo�L3�f�u���|�����~�N�+�wl��6W�BP@P@P@P@P@P�#:b{?�T�����a�Ws�=wQ�n)��=�P������g��|������	'�f�}������o�o����.��UW]5�;�n����1L<��a���
���n�m�������~;�w�}���q�a����|y:����������.�h8������a���O?�t�t�N~�D�����>�����~p$�c�u�	_������O^�[|���^.�����{���={���>8�WYe�0�d�5����^
�^{m8��������	T��5*�������D���;f��p�����.�(<��#
��c������Cf:������_�0?T�����m���v�4;��:����V[���[/����g����p�W������������	���L�>�l�#?�vX�s|��1�l�Z�[���_�Xn���D��[l8>��g�����x����9��S����k/����86������*��
(��
(��
(��
(��
(���!`�@����0@%,���/�xK"������{�������}��j��;��b�r�-�N.����N���n*�S�Ke��?�����	��~z�b�)��k��N�����`Z�_u�U���4�=:�r�)����w�-������:(��w���^�@�_���j���#�{��g�`�	j�j����w��V��l�N�S���v���6��a�-��pZ��U�3?�$����*�������'����3������x��_~��EE:���-�X��/~�Om�Q���qO@�w��������L'0�, �M���[n	�n�m:���h�M�}��\���C�����f�r�!
�QYv��{���sY�zq,
0���Q�6���{P@P@P@P@P@���>Tr�{������IQ@��_|���������M+xc����9����������.������;o�"�����r<�HE0�hy���K=�������g�IEP��~p�gZ���h�������z;�h^zo���v�[o�U�=O�{;h��n�7�#�<���^T����@k�VA��n+��:������b#����V�m+��R��X�{�Y\pA��8O/��^T��q�}U@P@P@P@P@P@�qC���>��c#`��c�)m1�
�g�Q�����U���^c��w����%z�<�NK�`��7��)�
T��Dw�tA?�D�I�W�#Xc�5j�����s�5M���o�K��v|��7�����v%(�s�m������*�����G?�QG�c_�sC��B-T�Q�=++�7�n��������y��x��b��w0���Vv��M�o9���s���j�8�.���0�,��YD5�t���1�AR��A�������*���	
(��
(��
(��
(��
(��
(0�����,`�����������>�P����Zj�@7�Tx��Oj���3�:c���'���.[t��0�����*�|��p���^��;�����>Z�_������z*�y�����?���4��>
���~�����-*cc�TB�v�i
��	TX3��1�����<\e�U�+�������_C���k�-��g_���@0����U]�m������]|����g��a	�<�L��������>�`����$����_�*�7�|�,���e�u�]a������Zi�������}��J����x ��o+*�	�'�����+��N;mXz���Y����.�0;71q��q����^0���c`�mb�e�l�`���V�m�]tQC69���5�TSC�0�F��;����_�����ci���N��*�9���
(��
(��
(��
(��
(��
o�|�5�6�1``�)�(����Telo*��TVaG�\*�cjV��{��}�����f�iZr�%�����I������1���a���|�4�H+�[~�v��nxM{X{����{�]7������iC���B���w�1|�����SaM���i���+�1����e�����.�����J�����
CbP�{�a��T\x��q��+/�n�iH+�g�m�bh�I&��6_|��������mv�SQ���}��SA1��~z�g�yb�j�l��w�]����w�9l��&u��}����/}�n�>�m�@�
�*���r��6�}'�pBC���b�����n:=�����+�(�����@i��96���4�W@P@P@P@P@P@��/`�@���^������nQ����_�B������*{��[o�Z|�B{��6k��@�TVy�<i��O:���������N9��Zp���_k�]�!y+��D��t���}���'?�	o�J�p��<��=���~��F��O���,�Lm��?������>������?�V1���r�-~������������~�����Wz���=O��^�=���T���x�k6i��C=4�T�'����c��v*��>����
��\��&:Yn��6����s�9�!w��sO8�����*������o�p	�r��Y8]P@P@P@P@P@���}���"`�J0���7-�'�|���z����*��������%*������������7�x�x��y�@YE��7�\�*����]w]�l��j�������+�\�����7��M1$B����l�����������ei�%�3�8c�W_��W����^L�����Yg��y�M ��Jr]���h���_�jx����O8��
�����l�F�f!Osp��W���n���s��0@kuZ����58����� �����N�@3�N���������2��C'��r�r��8��%�O�x ���Px�����l��K��a��]U�\
�DP@P@P@P@P@����k0@��7�xc����(�'I��h���x^�����m5
0@�t��,�R<����>�]oVQw�gZ��)(���1a�V(��bb:��,7M���;E��n1�����/_|��:T�e��i�Z}O����>Z��M�@Y�
y���l��_z����ZH��P��T�2E/Z��U�_p���?�a���}���n��V���x�m�`�-,�����f��u��V�m��8i%����E
����R���r�-a�m�MW��p���m���P@P@P@P@P@P`�0����Y���w�u����{��]��)
��j���s�9��Z�<X��y���:����j��?�1����4�T�_s�5a�)�Lg+�����v�M���^{����������SO�����o������t�k�\�.��|�d�Mj���������v�V����{.|��_o��s�=7|�3������$�E%oY�z��~���.������C�U�lS�-}�d�Uo�L?����J+
����^���~.�����^K�
�j�k�P@P@P@P@P@'������Z�RF��NS�?����a
�����.���%~��'�E]4�I���@zHA�#O�@L�G/c��������O��w�=N*^O<��@bj��^b��y]w�u�#�<R���������r�-�Nv�y����{��/��M{����+C����	�hV�Ko�
���_<�t�I����F�������N%x���2���x��M-,�6K'��z�������K���DK}zD ��X�U���b�Y�IP@P@P@P@P@��|_�:`���
6��A����_}�+lZ�3����.�� O����:�Xc���>_�� �9�,`���<�u�YE%!�1�J�
7������z��@�{3�k{���i�<��b�b~x}��g�t�`��! �(_b�%�I�=CH�
<����
���z�o���W^i�>���mc~*z�y����26=�n�����"��Y%/�+yO,�J�C9$_\��9ustR���T2���V�my�����X 0��<���4� G,��R/���t��e�^P@P@P@P@P@���}�{0p�i���Z�N�1����w�h�O�z��
�e�]��o�/����7O����8�\���l��.����y_}���8�1���lz3�{����
��_=��o��V�;A�g��v�f�m�H _X�1��v�m����6�6m��~Ip���;�#X��C
����.���t1�{��?��#�����Gyd���?����4TS�}�4��YOC����~X�����uym���1�I�~]��|�d�Uo[���&�2�,�s���n�$Mc����Z��c����f�F��f�[��f�w�
(��
(��
(��
(��
(��
O�|��:`���.
��>{���������W��U�n�����C�_����q���\*�w�y�p�M7��#�����"�SY�SVA������C������k�TSM��R�>ma�jGZE�y��1;�W�N�o���vXl�������'�|���O!jj���/\�Z���^+�NJ�i��&+*��!�q�l������]�����N�5O;��C���������o����Z72k��Vx��j�?��Oz����>V��U���G��45s��(��a����&u��*��}���&�9��|���R>����!T�>��	`����Q�FU�����P@P@P@P@P@P`x0�������^q���;����n�w��t�y������
��.C��w������^T
3��O:���l��f���Q\���N���/3I��TJ���7c�������^.�����
�����;���O�<P:<E:O��	D����KLXy���{�|�������EY�a���x�����JY�x��G�m���{�������o����E��_�j�6�l1��7�8��b���g���&�����`����s�������O�!UytR�����s���j��
���_�2�t�I��U�m�������n3���8��>�Z
h���z������
(��
(��
(��
(��
(���_���>���X{��zh�����G�(`��f���J�l�T2S	�.����5�����q�V������_�R>n�~����?�!~����������`�UW
���f���,�9���� �8�[l��v������0�pe�o�f���-U�V��y+{��r��6���/K��<���a�	&�.�k�,H{D��Xj5`��c��m�M���
(��
(��
(��
(��
(���W���>�w�*]7�l��u�`�gh*��DK}*�����e]���i�����I&��h)>��36[����L3�4����j�������i�s�9�����{�._m�����k�8p�a�5�����7�^zi8��[�����*?�1�|���P���ZI�����������Z�����������06����/0�i�Y����b��!BZ���m��z��%,�|�����`�������>���f�}���96������FP@P@P@P@P@���}�{0��/���E+�f]�3����[T\����|�KU�@*�G�]��� �p������OS���9��sJ���[�}��7]L���+�,*��/�D���,������v�i�����e�ac�����������@w����OX}��[Z��1c�^{�����7�Oko�Rhu�X���&�������%�X"���TC�{�����0�JB��C�oY�+��:�1`��mc�����r��kn}����C9$��q�*��VXw;�F����WP@P@P@P@P@�����[��;�!����^x�����v�e��
���{/,��2u��%��������SNY[]�_s�5EE>-i����e���a������7��~z���~V7��������/�"L>��u�����E�`��/����lP���a��w�l�I�X{������9�y����e�]�O�}�G*0Za�e�
N8a-�
���v[�_����8�g�_��W��Q�=[P��'*���������_<���:a���+���������^"n��������f�i���n���b(��'�8�u�Yu�hA{��bz;�=���W_���=��3P)]��Yk����0��~�b�@� �}�
���1��6�����*������q,m��Va����{����o�Gy$��w�+=O��Wu,q��!8�D��n���N��o���r�k���
(��
(��
(��
(��
(��
[����M�im;���Z�������
��Dkr*q��b�b�g�y&���+c;��_	��u�Y���Ozx��'���>�X��JY*8�Ag��C���~���P�>�l��b��<g��Z�7[8��;o`8���G}4������c�u���o�@��UnC���(d�w�N��c��c��mn��yP@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@��7�xa�%��-�\���;���������7���
(��
(��^��}�?P����g�;�%����t�I�<��>�����C�����tK��
(��p�r�)�L3�x}�����/�X���/���a�m��e����|p��oP@����������{�2|����<���7
(��	'�0�0�a�������K/�T�Z�o�����������O��n���<����=��S����	xm����H`8���]~�\������������7
�#`�@;ZC<�����Yf�0�����f�-�?��E�xP����W^ye����8��^P`\�c�9�z����`��'�|����{��}<�?�<���a����7��
(0�6�t���RK�����og�yf��o�W��������k���������f�|��O~����g>��f�b�}���B?�x������?�����[n����O�/{���<���*a�u�-�"b9D�����n�)\r�%�ED_�W�?@���k�TSMU��}���u�]W�<���C|�A����:�8����o}�[a��V*f������������Q�W���b��9�L�������=.\o���)0�����c�X�k����Q���G}N?��0z������7������.O=����[3�{�����Q@�Z���w�1l��&-e�������kx��GZ�l�d���w}
�����������2J��{��G�s?�)��������+�\��9���<�p�	u�/��rXm������y���� 0��j�y�
��sN[���������� h�����;{��a��gn6K��3�8#��I���
�k�l��P���������a���������������.�������g�I^�k�Q�&0.�k��7��gl���z����������W��q�z��W�R�����oa�D"������0��f��}�]vi���M4Qm�����.��������
��U@���>�8�����V2���o�}��7�p�
��>V�1``�r�2��@^��#��V�;��S���B�V�y����<��0����;</������*0��������z�����>�@���K�K7��$������@�����>.T`������5�X�����i�7'*���xm���<����b�_��3N��[u=Pj]��V����J�i\�����{�J�����oq����h���f�Zqr�@��s�9g�<G}t���4��u��V��{�Z��S@����[n��f��M����17)�g�y�������v�-�������)�+W�/�p�~7�0@N'�d�@��t���+�}���=�|�,`����*rEk5�(K��T�wD���^X� �sw�<
���t��w��6�,��I�V����{\����?q�|����O�����#Hg���k{*���.0����:��z�����R�^����k�t����m�=�W`�*��;�x��4���1c���:(\��uKXs�5��{�Y�\�/x�_g�u���ul���V���~�_���l
(����k���.m��_������g��mAQa��'�x���`�/���~��C����
�}�N�����(0�;_�p���C��la����-�\Je�~����SO=�6��C	_���j�yC���~��p�W�� ��[z)`i����e�]�N������;.T`����	Z}��k��8=}�f�i���_^XT0����
�d�q������V�����(�������g\�����g�B����Poq�3�0C��@��n�m�b�-jK�����.[�@��o|����o~��=o��������K����b�����EL����Z��������&����K�EY$ps���D�=��c��,�u�5��uO����_\�SN9eXk���qLg�q����#��"�<������O��_�.>��O�O|���_,zp��o~S���Z:,�p��7=;l���u���������~�n������E�K��NS@�B�.dG�U��+����Z�l<Z���?��������1-)D��9���S\��NR��s��{��7�w�}��[n	�y��v[l���Mz�a>���]tQx�����}��|�UV)�����7�|3<��������o��;����P`���y�@��0e�,�LX|������9��������f�^��O�E.��a�|���������N������p�{x��X`�Z������9*O�������KM[vr��q��{x��g��8�2�1����G�.ZA��_+��b�-�u�]����m�s�f�)�_�����f���nP��5*>���D�=��:��\�X�K,�Da��x����[�e����v���;_�|5X�@*��g�yf�[a�������_|�n���g�4��������i*�&}��W���0Mw�yg��w��N���U>0<g�xVXm����)�/��:kx���j�S�������'
��[������!#$�nx��9���n*=��U`�@�������+�
������zC�	�>���j�}~�I�0Bl{���-f�R0�����ki��g[��U����i��@/��(��������1��U���E���~h��q�,��z�4#�������a���K�L{V�K�~��!M���������-��
���z�w�y����N&&�-T��������u�Q�,���.����5;gw�;y�$��x��l��pr�00`��w���X�D�������A(������>�(�kv��.��u����+���z��������a����M��i��V������/�j,�U���KQH��� �������������a��'���5@IDAT�^�������
�1��&,�H!%]�q�����'�_�������+����@A�)��R�7��l����7a1��W�
�sL���
(0���?~�����(�"�j��+��\��y���*��\�8����t}�=�>Z�����V���:K0�@����?���BH�1���7]�^\�����>���|~����������a
�hM[�(L����^}�
6;��s]]����_a���.
`���{��<s������=1���q�t%L�21q���+����N��c���V[`�{*���H���7�X�f��[\[6�?��O���Z`����Pw����J�A����c _��G��`��vP<��C�J�(J��P$�8�����E8����I
�)|O����!��h���~��<&�VX�����6���J���|8��=�Gyd]��]��s�a	�)�����+
�K�'0�
�8�H�]�*��Z}�����}<�5K�5��<`��k{���n_�>�6���>�����1LYFz�_&�pE�mS1��*��;y�!����A�i��$�)�������jm�6����v�Uji�MU�@�2�'�1�~��W����4Mp���L0A��5�Ac�g�}�r�f��N�/���Y�������A��i8
0��{�($��5&
)9!?���q���������f+���Dr���N+�B4�h��I�X.R�$�"i�JO	i��+�z��0@�9G3�<sm2d���V��x���h�|^?+��C!PV�O�6�(�%*�hI-M���Y�0����`G+P��1
0@e�:������J� Av�+&"�)�"@��Do5y�|+�s�F /,`���RA������65Ppj�L�Y���������{�*�9O�"`�����}/'n��������@����/~���A�����x��w~�����
(����Bf�u:�+B��Ak����v�0L
4�����?�i�*z�!`������	48��sj=
������n����5�a����w�4����I�w��Y%_O����O�;�{��!o��<e�6�m���O�uv��*�A�y�����-P���M�L</N>��E��l��� ��l�M]��U�wR���
Nh����'X�|��#�U�sR�.��������g�t9������Q/A�sL���{r����4LB1����R�AO=Ut�,I~��zk�`<�|���^����4��]�R�@��o��F�u�{��]�p�O'x��$�u�;�VcK�7�#�h�����:�m�]�����N���
��{ �.aYc4��!
h-�z�KXn������H�y����>�@H�<1q��+������*������w���U
���\�&Z�P��i��ID7�]���Ds\&�h�����>�����j1}�����*mh��u�s��\C�`�$�~:&���&Mt�M7D/��R��7�{R1���8�W;yx;�+�j�!	����SHt]LaSzOI�-Sq�+b����/�����o'�����W0��y��N(�
�\�]��<<�����0@�<i�5���������'
�_��
DY�n�2������q��n��<~�����]������r���J��9~9?�2�,���2����]
����{w*<r2M��C�/���D�� �
������a�sB�p$~�����4P���)�Q������Y%������r����r5�9���i�t%S;�^K��=y�vT��h���-���"by�tT|����^M�s&�3���E���?�����?�s�8���:��o���/�9��&����3CP��I~�r�}���u���;\��(N�wGAo91���:u�	j���6����gI��O�[����p0`���'�&m�x������G1n3��@��i�
�fl�<��{"���;*���SD=8����`C�B�� 2�.��BU�v�}�������)N�x��>��u9DP=!�x�Io������>�La��yJ(���q>n�(h��V.�SO=u�b�Em�oP@�!�����4��U�w����I�y��������n���"��i�s����#("��c<��7��6��������X��`1/`g<��>���o���zB`�&�yx+T(�b����*����o�[�A�Jc���$�~T43���1�[	�
�D��M[�z���=|UU�����:�ZF^�P�y�
D���?c��AK#�C����/�9�7+��7������t�2��>cUu�m�ud
v�*+n0�qK7���9�M��%*
���4)�����:�}��l����8��3}$�g���e���!4Ie�0��;�;���6�i#*cx.����
���:���?7j��b��?��������U=��e�����;��x�C�Y�� (k��X�A@$��1�0������W���Ct�u���y�@���E�����N��$����=E���QU��q��<�T����x����&z#��$-��{���[�Z�o��v>WUD���tHzR�G5A_eCM�����X��e^1QvEi��1�i���g�~��Z6��7
W���+�.�Y���

"|��
l�D]V�x��G7��qv�L��n�c��8�������`�%~�Z��p�K#���_�����}�`CKOP���{��!� ����4��Y�������o>�)/p.������(��WP`(�(���/5���c7�H
�	���M���5�|��KS��A����@<4��1QH�a��.�y�%M�q��$�9�4������t�o��A�kPL\��e��W��@~��������1w{��Gq���97q�$8 o�A�DZ�Q1��|�����s����[���V����,���W0P�y�����P�A�.��1��C�������J<�����@��(@d��D/�����|����Tu���:2;_�0@/Tp���%��'*�HSZ8�N��U����������x��q�����k��6Ba�k���V�\_�4�<��d!��p��rK�1�� (�g��zD�xi�=$�B�T��J�����?T:��Z��]IS��i��e�x��E�J\��N�@���n_�>�6���q_��E����?�z�d�F�=���H<Vu�b+�8U���>�Y(�I{Q�n��wZ�S6�X;���v�ZU=�����s�Nq�.K�����_�P'����[o���������%��zk�`�����"`��0�SD�QyAV�$
�h@�G�Z�3^�X��)]�@�)<�����tLC���o��4��?���f�(���W����o�)�M��<����^
��D%�
7�P�mQ0�������+�*��)��,���8�WP`�8GS�"_���*F�w��vs�,��O[n�� zz�E�M�%l���B0z����B����`�Hk��MS�f�N�A5)�@�������5�-�\8��c�6l�e�-��X`�����Kz)� �J9�Q�G�t��}+�����{�*�:O��*�*N��z���yok�k������.�.���X��c��c ]��G��`������bki*P)�eLU��D �j��@�Ll�x�������G�|R1��7�Q��F�����������=8ib\�)"�����������6���8�t�����
�li%`���=�T������]F�g)�k�|�)���gJZ���O���V^���*����v�����}�m�����@/���1<�pC���O��4�	p"�T��q������3N��N�������w���G=���V���:=��uVQ��jB��p�t����r�x-���p�1q0�@l�3�9;�����%��zk�`<|������~��
�
������!�7�k�D�2����2?]~�{�~�r�W
$(p Z�,u0����o��;�4Z��?���K������{���`�<`���� �*�{;Z!������x�$b���
���"��D���u��9G��3�7iZw�u�#�<�N��@��)��$�r�)���|���I��7�\�)�7)���	��O��M7#yb����.P1w�e�c����3��T��n�
��E{u_E�@U�i<��@����cq�Deh:t����iV�TV ��&����e{��a�e��MJ+��:j����|U0�
��<��^���g�4����|��V��<
�"����Me�(���e:T��=M�y��$LK+��L�	+���C��)oQ�T���sH�mO�C��xS~�!`�F5�[���)G���w^�y��C�<y�v���v��*�A�y���f���y1?�
4�PY�F|����8��V�q��������p>�q��Yc��}+�e�N��q=���z z��C��<�������3��1��lP�2�p����g��n��������z����m��Pt����T���&`�@���6�Ce<]�S(FW`\��D�8��cj�����
��4K<t�=�k��N�J�b�i"��`x`�"��(��/��!���;nV��H�	F�)��P�"���a��I�������
�M<<���AU�~���N���/������/���[�C~�N=��(����N�aGuT��yk����1c���i��l?*�@��������~�������������%�G��^P��{�*�:OcSE�@Y~��?����q1Q�����@�Y�Z~,�,��c ����)�c������v�}��2/U%xi����M"H�c��@/z����BC��C�
��4` �kEZq2����ys�]w]���Jo���T���iV~��"�
%�~c����^����<�M����Z�������!:�:��������r�T��w�5�O=�T������g�����6����<��������J~�}������I=�d�;1�3i������D}�
+�~ �����cUe�n��������Z���d�`����R������p�SL1E8��C���t���<Nk���n����@�D[���u0@W�Gyd������������+���Z��%��ib<��a
���SY�@���3�<!�,�(.�WP��Ze�t�I�s�`��j�����/�X�Y��HT�
y��n��4P����Eo��]W����jZ��������cZ�����zzt��?���gyx^����`l
3�8�9��n]ZIg��=|�!S�@���:O��*��3PObyj7������c�e�F��`��V�������/������|P4R�u���>�������;��3~�U�R�^<,��"E�^l=����!���g�I�^"/����F'�r�>WQ�Q��
=�63I���k��b��E�{�|���j�h���/���j��G����ki���jT�
�����)���b~N�o�!��RY.=��]����<�T����6������7�8p.k�Z�/���|�l���V��8_o�����3���3�\<s1�����o�Ii��8�1LAPELU�=�uR��O��hd�`��u8	0��{k��g@�D���w�?6��]�O<��p��'��m���j)���n
��<�c�U=���o��];
 R��i�0�/��������f�b�����g�Z����-�2&Zb)��^LvP8cR@�M��^zH�cO<�D���S�����4����.����sd�9��o'
0��~��+�������I���D�>���X1�O��
�^ /�e�@�5��ya��+��R��3�G�a/��R��R�fn������.� P��'
�(p�)
��<���(��.��R�r=n�\����L��e�V��0�r���1����#O`��UY��=�P�@�sqFZ�m����c����t���1����t~�+�@/�?��2�� ]��9��H����*��
&
rI�����Z�{UT`�y��Y�a����f�����ex������
&�sb�'*�bJ{f�"` .��n������}����m����qC����f�.��*K;��C��#��uy�����z�<������hu?��3���{�����s�Z�Z�/���|��z�<�;���������qXi�7�|�������{�4U0P���I�_?]oS'�[6�����������C$V<���|�0�����L��-v����6�
�42��G��0P�?"���5
Ph�#��iJ�JL���Z�=4��g�f���e|�7Q�11�5���)=�����g�U�+
�h�&
��^Y��y��~���IE�Ai��Yv����:��'/����������w�����	I���Cbm�6��3�<�p6�5�n~�Dtv*���V�@�	�o��VE��t:���p0���g}�9��[o-��L��{z�����������,;`=�;��Gq���@Te�!X���<�q�G�M��U���$���1����#P`��UY��>y�@+te�
<�3������&�,������
��w�*�
��"����#�����g:s�M�������r8��~��4�EY+\{x���n�i�I��#�K��U�6,��������_>�}�4j�������H����t����}0X�����/P�y1?����hXG�OZ^N��I@�����g�<����e�IAL�Yj%�e�keZ/��&�x�b�������0^���c�"P����GS�u-��)z��k������2��t��l0!������W�/Oy����g��w�}�.�SO=u8�������*��'&Zdr���q���Bqz;e��[�S�0z��0�4��U�I�j��a m�I��4���[l�E���������,����t�H�	�����;q��5VN�y��f��<�W@�R �@&/T�s�1�q��Jt2���EY|�`~z����.o���9�.�i���|�Oz���T�hi~�_�|��������'j=Mec�%��3�$���z���]z�I�N�;�H�z���	R�+0v��^P���r_��`2�L3=s�[��z���=<��[s�'���{��e������`,�H�\�y���nz�J�i�]�V@�?+���@�����{��u�
*zj!vUM�S�:�a��c ���G��`��*���%`�<C��B1�����������L
�U?p=O{>����11��B/i�0��K-�T8���O�Wz 89��2�t�g��h@�f����g��
i�C~�I&�`�p����U,��3�Zj�M�@���n_�>�6����!P�y��.;��+W�K������h��,������.�hQ)�>�x��E�y�������t����+N�������m�����y��@,���_|q��%�W�s������� h M�=�1o�^U<K�������(��p0`�����<d���1�Tf3���`��`�#�GE
�i��,�.nb��w�qGT_�������	�6b<P
����
Z�����V���\��D�Z5��A������>��`���������Y����~@GY�g�}����s�
(�/y�v��c�=V����=�s�i���Mny����Zk���\������O}��b,�4��L��W0@�!�Og�u����������!��3=��O�`��f�����u�@����ri%K�E:��
&�yx/����0�~���T���1|I��yLo���{x���2i��J���K��i���U��Y����Z7�
�8�^w�u�X����Jz���g�x�����`z�a��4�_��w�bRU�Ui>}?�;_�=�s��I�������!��NE)e,��{����K6ts��c���������U>����1Q&���&9������r(��P~�%�c=��ye�f�Io��fQ�r�7���HU<���u���������;�I��	������	��Z�������!:�:r�</6;�9�1d/����S9���s��~��G-���?�{��g�fy���V�k��� ��b������F��<��v[�8�z�4���t�v����������|��G���@Y��i��1�m���g�~���7b�`z��~�	0��{��Z/v���o�"�7�-��+K7�|s`�"R;���H\u�Uu��-?�V0�j�X��D}����b�7���"%��]�<*R���b���H������~1�������{-�(<1)���,@o0��f�e������t��9�,ur��:CTtz.[v:�@Z�4P��0�8Ad<������|�D��z�&>�~�5�
�}����G�ph��B�Aij���{x�?�t��j����Tq�f�TR����n��(�k���.��*��-���u�Y�P`��
D�:����#C`��U������Z����*NM
�*P��-C�����~��K=e��g-�{{�������f����U��R�T�o��O0@e}i"��
���+���E)�����w{-������}PE���#C���"b��,���c�Ej�����='p�N{U+�9����
��������M������X����h@��SO=���M�W�fX�&�J���i�sv��U�*�%��zk�`<|������T�L2�$-��.eo����j���h)��n�3u0���^z�b��I'�4.��������,`����pnR�������^��s�x��;*���p�$���
!Z�+���v�nP�D7m��P@�� ��)�CiW���.8�@O�-���9�!x��Aq�D���)��i����e+]��Rq�w�A:�����5{��DO9����C#���"`�-�^������������;�j������\X���]�S0��n��q��3�YYj'`�g,i�<X�G�������,�����ud
v��E������p�v0}��o�TL
�+P��=N�27�n�y�1Z�R�S0�t��)�++C�����6���@����`��>���j�}~��XV:�5�����	`��^K��=y�vT��a9U���0��t���]�J�|zlI{.����������������g�Q��Cy�!��b�D}�Oi���$C0q�[R;���n���DU�@����������L��@]M��*�����y[	h���g�~��Z6�)�n�=6��+����\��:�[o�����L73v���=��'��#6<���.�������k�
�kZ����O�O<1��V�S0GW�yj%�7T�s�f���n���S�R���V�������57c�B@~�MQ>*7�|��������!MD+Z1���^�]��1
��&�F�Y"�^_ZmI��9�.������tx�E���
?���5�\�����@����V�+��RC� �d,�t��������H��)�d�<x���I�N��C-���9������Z��o��cD�+����U]Lr����6�#2N&-7�
3��7�#��r��j��2�+Cy��H�_�|��;��q~���zT��<����s0��$F@��,��������r���6�������M�������������-�	�}�����x�@w�l{��c��SN)Z���Uq���������|�}C���7�
�����C�l�����$�*M9GPMA�`������G�@U����&r=I�-�\~�e���������<�)O����:���h&���!��yb]3�0Cm�v�mW	Z��o��CPa��*�U�e�9?�l�����[n��\���=E���<��g*��b�
xf����^K��=y�vT��h��������'��F�������`���,+�����u����|�N���s
�G������=zt��>M��7�];���b��~xq��s*
#i,�&�W�k=���4O����M;^�<K����������p0``8��$�<�0�2H����"�������������=�[�G!�<�W�����F����
�v��CCpsCA��O>�p�/2������u�����I��.���4P��J��~>k����w��$�����:Q�c
�f�m��<K�<7������5Y���s$�{����y�!X�J���W
	��2��+�D��@��z��\(D�����
(��
(��
(��
(��
(�@�0�/{�|�u�<��Hs��&h��!��4�g�41�#�dybX����O�q����Y	�#G�^vP@P@P@P@P@����io��J��yd�u#�gi]�u�+�k����:~,^n��giI�'Z��}6c��P@��(�9r$�u�YP@P@P@P@P`800��y���>��S�i��
n�������7��xF�,�H�b���q����������
���#eO��
(��
(��
(��
(��
(���M�������o��.�l p����%�(`X��N;�/;���2���������]w����gP`D	x�Q���U@P@P@P@P@F��eV{'0�D����+�9����	&�����=�Px��'���r��F�g�����g�	�=�X�����[o���'NW@F�������PP@P@P@P@P@�a&`��0�afWP@P@P@P@P@P@P@�*�B�e(��
(��
(��
(��
(��
(��
(��
(0�f;��*��
(��
(��
(��
(��
(��
(��
(P��U(�P@P@P@P@P@P@P@����l��]P@P@P@P@P@P@P@�0`�
E���
(��
(��
(��
(��
(��
(��
(��00``��0���
(��
(��
(��
(��
(��
(��
(�@T��2P@P@P@P@P@P@P@f�fvP@P@P@P@P@P@P@�B���*]�
(��
(��
(��
(��
(��
(��
(���L���a����
(��
(��
(��
(��
(��
(��
(��U0P���P@P@P@P@P@P@P@P`�	00�v��U@P@P@P@P@P@P@P�
�Pt
(��
(��
(��
(��
(��
(��
(��
3��3�
(��
(��
(��
(��
(��
(��
(��
T!`�@�.CP@P@P@P@P@P@P@�a&`��0�afWP@P@P@P@P@P@P@�*�B�e(��
(��
(��
(��
(��
(��
(��������(8�H�9 9$�D��#�  Ir�99����HA���$���$9�������m���v����nw�����f�g���oP������*��
(��
(��
(��
(��
(��
(��
(P��E(�P@P@P@P@P@P@P@�L���.�a��
(��
(��
(��
(��
(��
(��
(��E0P���P@P@P@P@P@P@P@P������*��
(��
(��
(��
(��
(��
(��
(P��E(�P@P@P@P@P@P@P@�L����aC����s�P@P@P@P@P@P@P@��x����#�������0��~�
(��
(��
(��
(��
(��
(��
�������vP@P@P@P@P@P@P@zP�=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;0h�{����}/|��W���_i;�\r���f��9��#�~����.o��f��>Q@P@P@P@P@P@P@zA���^��=��l��Fa��
��>{2dH0�����C=4����N8a�����LPR�����Pz�mON8��������H><�(M��
(��c�1F�t�I����>�]����M6Y���������~�x����>����?��e��2u,���<�8��i��6L1�Y��[o�U�';�'0������.�������One���[�K�s�0�4����k���^n�����U�V���w���\�N9����"��@���*�Z��8�8���6�����o�)n��%�?���s�"��s�n�e'�S��)��i��&
������������?����:]���b���SM5U�����{���Y�����n�.r�
(�@I���Ew<Ys�5�*���ge������n�u|�Z��.�	����e�|�QG����*�;�����C�K,��~�_~y�-!�����g��O?M'�\hJ`����l�Mk����_z����{�mjY��?�AXi���<���h�a��������]w�{����O���������;��������U������
Y��#`�F���{.���
��w_��_�Ru�����^;����2�,Y��|���������\\��t�M���/^�����i��_6�X�~f9�����52�Bf�'�x"�p�
u�����q]|�n�"4����_�"�9��%:�����|0�z��U��&�|�p��G��[����;.��g�r�d]:�l�e��8��>�/��B�	�z�������f����>�������XD]��_���y>.�w�i���r�~��p>�q��s�	~�a�\�#�2�����,��s��x�6uY���E�]W38d�
6���~�!h�y���c�y�����xL����s��g�9�\�k��������_�Uh�q�=�#cy����a�_�}l�:���v�!8[u�U��[o���������8����a��|T�S��#Xw��m��6,��"�6�����Y�u���'�|�I-������n��%���
t���s�U����e�Y&�\z��b��|�SZX>�p�
�{�Qq�c�',tv����^�.&�i�����n�[���#����[n�0�3:�/������Gq���6n��H��O>9�5*��>�g�u��Sm���*M�!��a���Zk�����������??�u�YM�1
��X���d������W��+jY'�xbXz����O��g�y&����L'��������g��4+P~%��x�����Tz���ri�>�z��~|�:������W5�����?�x�������1�H'�����L���@��d�1bD8Vm������. H����?�!����{����s�e�]�������������b�pl<���������N������l7{\C���,��K�����������C���z��f�f�XS���O�1�|���{����c�B@4�{�&���]� �9v���u���i�M���d�\j���j�}dm��]��:�m�y��k^������#G6�TT{@���:6
�P@�.0`�v'�t��j�R���Fb
6���<�@���^y����t�0�B���n����u7�g�@7�5�Y�� �;�T��%_�
�j���l����8F�����i�)W�K���������v�u�lDL�>��>4��?��{��:��U���<��,}~�Y�����4zia�o~����#�����E.����kF������~:l������_���(p�1�����Q[�MG"�V|W��Lo�w��Z�@�
�:�V^y�>0��R�pk��P�l�����|!��t�Fs��h����tz��DF71-(T����r��H�FK�������X��6;wp��.�������7�x#�Q����\$���w�iy�v�q�,�4��j�Y������%PT]�9��^���so�z��	�!�)|�5�l8O���_���~�-�@�z
jtls}��j�^�t=:���u���}�Y/��rH�u��c!(��gQ�[��#�V�
�92-������ena����>;�J������>����f�1pP����������?���k�e�0��{�����J�����i��@L?��0�	{�uP`�������L2I��j&`����o����O�K�i�i\�xGp�n��*
=�� ���3�Y�B��J�r#cAl,�����w�ygv_q~��g��96�����6PF�u�~=�P6��5���q.���P,�S����=-E.+m��a�j�_���FG]���@q�M7�+Q��4p�
~I��(n��1���F2���v|������!P�o��i�������>����������������,.���kd�e����Z6&�FJ6r_���K	�����t��E��K.�:v���.��jt��B���-cxo�cY\&��9�p�%?����?�Eq[|\����H�N���rm�^{�h���{�o3�6�Q-`�?���>v�@Qu5�$e�IDAT#���Y,����9��L=����c:
���N�F
�"n��w�����k��	$�k����K.g	�k����B����_~�Y��{������&��w
p
Gv
i�	�g�S�/	. ���@7
4SGp�����t�L������55���]�2���'���V[-{�&��_Q�|T���8�A�,
(�@�0���p��7�FP���E�PG�Y����N8av��|'G����qdh��E�e��t���DI�Q��z�e��hHN�j�6��4*��
(PI`�e�
�|�?s�M:nh0�40�6����z�e�B}>��?��O���q����'�<��}�I�I�S���0����n����c�����#��8B���o���UzM�(_��F��	�N�|! p��6*M�31f�ab��by���JF��j)j?s�&�@,��2_�?-��������]���Y>�V���+�y(
p�`�/�7�w6�K�A�O8����,�t]��f��I�_)�#&�2dHF�=��7�>�O�:��c�T�uq������� K#{c��0����N:������1���=������yD|]-`�?��h�coT���Y��[�p-����g"���z�h���p�
���n�9k�<~;�d��,�����c����x�J�h�:����N;o"+M(�G�^{���u��kY�'b��5�\�8���g��f�6�6����o��/�V�dZ�q�����Uz]T{�o�o�Y�J��tP`0	0��{s�M6����H4o�{�60��=:a��2�'2
���nXt�E�F)pQ����SN9����'��3Ov�N��xa4(|����*��3�����������^z)����.R��S��i�~������t��4�)��A���MO<�D6��u"-t�q�(������TZ�pb�c! �u�>���16$�I::.����q|�h�,�Q��W�
�R�S��Qf��hlNP@�&�o���9����?�)�h���~�-�����b�������3�22��)�yh��X��,�Rg8�G������RI#�M�O��K����7�Nc,���E.�\)C��oG)j?��j�'�X�pL$`06hp�;S��].�N�^�"~.�`��o��*��1C)W��D��U�3jM������.�b�\n�����K�z5���#��t�L5�T���;��X�����X����%@���/��,���56�c��(��1���ip�:�J�:*^W�����Mq�.�UWsl  ��wu�
7����m6)��\E!#�>�����.7o~Z��{i��f�y7�t��mh(�S<�����9'�� ��'X���.#F��f�0��u��;���66�	��W8�(W>���5���~��.c]���>�i
%�lA�m��V���|�����Z�K���������������n��"�P@���C��:n���d���W����|'��$��J�(���D�rb����tH����i!

�d�V��")�I�Z����V�?v���B�`Zt�^Nt<\}����
��?��SY�H��O���6��w����n�Yf�^W����4�����`��r���N��9����,���� �
(��@�d��N���B�y�hl&``��*���������E9��(H�a����E*k"�I�K!`�V�@��^��..��4`��3R|�[8��6?�j[�c1�����"��1��4�Ji��:��X�~&�k�<� ��"]G�/\�SU9r���y������o���`�_��L�K�;�A�����+��r������o4��+7m����Vb��������y�%�
��)���[\�p+�b)�.��cQ\w�@�����FP�t$SO���f~o��,f!�I=�Q�5�M�����j:�c�	����;�-����J{�-��R�s��B��/7�'}3i��Yg�l�@�����V�@;�)]?�w�yS~�0�dV�+�[i�&��}��r�:M��h���Z#�;���s�J��V7����v���ul���+���"`�@��xQ�E>HqJiG�@=���0R�V+�4:sH�Z)� �,:���J;N����������7�RJ�XI����id (��H$"�i`������d��N3k`U����(��
4"0�\se��F��3�����z�!���=��O;n868������zb�q|un�@����>����v(�Vgd^#%�����-	��c�l�����{���&-E-�wF�PH�O #
���T%3
�4�����S�k��z?�X������|0{9����N>v�@�
F4���p�:���Xc�!�c!��=��_f�R&����	r����H�-	6}���YLo�t]J=N�%�I��6����=�\�\n�F���BP�!�R������<5j���-@`��w�]����,E��O�gN�&������@�\���������uY�����)P���r�)����Z���j��1����N���g�)���'���Q(���Z�5������?���s���)j��
��S��v�y�P��Rh/%�J�B�v1Ah\�=NW�SZ�#��B���S�~��9�p;,���jh�o��v��|P�S��=Qf=H�L�7#�2P�:T{�O-J'i�C��%q�F
�8j(�S����������-p��a .����[�(����w�>Q����/��23�N�4�j\&�Dr��\ 
�����sH��������J9�
�#�����(fh���w�}a��w��z��@F�:�
u1�����04(�&��,uQ�s�)D���!�=�r���ND�������������X��VXa���U���4�rl&���ux��k����\���_����Q;l����5j�w��z:�s��m�C}��%��R�^�|n,Gyd����� �VV�vQ_�3I�7|XVQ����.�dd���K`U�2�SdiT��ku���y$x,�rN����o�������<��N�j�9>����I�J�;���!YN�K����z�.������UW���],�2_n���,a�6g�o<��C�|������0p^��d���B�q�
ma8��~����-�
ht���'�:�����$��Y���-�'+�E�Nh��H��i #�./��h�N�Yyi��gm�&&�����v��Ml�oQ@�R����na��@IDAT��	�S��'�T>k�B�/BY�,�-E�6K(KY*�Bi�&k��F%�$�C������?��������w���]�{�����sg���s�3��9�y�s��k��PF��/~��b�9�hK�:��S���h;�i���~v��o}k���z�8��#�����x�K^R��5��������/��������u�{]���pB�M6��x����?��O���������w����w�ygyl��/N>����O}j+�_���b�
7,�����U<�	O(����<|��gN����o������/?���,����������//��������o|������1~v�a��_����2�v����dq�I'��VYe�����o;��G>�����O/����>�8��c��K���������Y|��_-���������w^q��s�=w��[+��Bz��{�
6(}����?$ 	C�:�����>U[����^��b��7./Yx����VZ��N�;�������^�>���/>�������=��E]�8������N��?�i���x�����^\����:���=��f�m�}���-O|���s�	�_x���{�������������?���|�{�+=���������9W��s�]�r��'GuT5�������x`��(�-�\q��������|����?��O<�)O)���G!�:����/��g��4uZ�=��}��G�6�
7����T�����'�v>	����\���PM|�u����v������~�����N+�8���Kr��D>U����xpd	�����W�����~��iy�$}���������IyX`���g�uV�~���q���j������8��3�T�v����D�3�����}0&��]d�l��6��w����k���+������?����X~��^/����K,�j����<������o,��s���?���b�w,n���r�~���[����X�u�'��HS�U�V�������>E�v}@�;��s�-���wU�����H�!��v�	�D��������g�]��t�_���i�.�0��A�&�l�q^+	H`�<N��Qz\����2�u�]�+�������.�_��>?��l���-e4��O�������o-;j(G.���6E};��Cq�����Yz����Z��O�_�����^?�	�bpPM;��(�z	���w���#�����J��F��D�A��.����p�0(B�C:�U�`�J�}	H`��JU�5H��|�;����k1hC�K=�D�A�^�$�M���t���
#�n�i��}�k�����b~�����]K��{�-I�����j�,�Lkp�p�����~���%}�������V�I�'r�}��F����~�{���3�@����o~�Xj��Z����?\p,�W	B��x'C� ?��0�!�

����1\E�����������o�Cm��.�0c�#����C�v��6+��UCi�����-�;oz��
�+
�����g�?l]I��oQ���h�@?5�[o��j

#��1Vy�k_[45,B�F�~�n����f�����"�ng�&u51�V��'�������{��Z�0��������
����?���8���@�I���g���'?��e�/~���g?��V�A�MS��5?fZ�����+�X���N(��&�mh[ ?��O�}���[p�I`�	��#0�I��#SX��W�*���?�8(K�&�����n�w�u�l�]�sp�'����$0�4��7u��(���{�6B0�>��QP�BG��K/-�r�)��uz��9�3(z�5����o{HH����
�^@�����Wl���i�����1��e :}�VM��O�S�3���b�-V�1!k���K�N�q��*k00�$ �!�V����(��$��������;io��B��L~�z	u-u+���
3���~n"��Nw�}�����:��������?�l������20����>W�?���p���u��9�s��)^x�L�`��`o�9"\�m�w��}<>r�
A?����dQR�@����J���W^���Xg�IY������
������05��
�W�W����Tv���.��A~Le]�2�<��������Ge�`�y�-�Zk�rT�X�2���k�4����O�{��Z7�\u1i��oQ��{n�T��{�00�����^{m�v�RW���rW�A����t�e3���#����{x����c�}�M2�x����
`(�;	�,�����c9\��������4� ���S^8>��M�Xcj��)�e��e/+Oc�Q��t��%0]r���r���C�y���U|�_h3��`��s�� }o�]�sp�;�^ 	H`D	h00�n2P����m4P.�!Hkg��T;
�K�o��������%~�)���~V6D`�E\?Rm
�a�{����ec)����������fz]��?�p9��R�jM�g����X��� u��A��$��@n%+����aP��x��}h��|��h���D��R���p������������*n���b�E)g����>��}�{_���u���Q2��@$�l������::U�aT��t�|�������3I��D�Iu�>.1�Tr>g�@|�AR(���Y�����r��x|4�,�f�WI�L�[����G?Z|��_/��d�n��c,�o U��������B�>T��.����h�\�<`\��K�T�5����V���nep�u'�29����5�`��!P5�+^Q.#�)�c�>;��w��)xy�w�<��B�uM�������t�ee��7+4��)�ky&v��&5�K���~���
ohd������]J�2�w�I'(�S/�u����@��1.�� \?h��{��N�
����n��0���s��u��$"��V�]�9	L�\ue�����0>�[n�%����7������%S��~����,��8��o�J@e��������pL%�����z!H���F�Bg���]6~O��qs�1.��N)���\s�U��1Xt^�x��F���>���8���1M�.m�yK@���T)Y�\s��57�O��a���4Qr�'0�b���oU�]v��`+��H�u���>Z
Z�����K��_]^�Ef���t�A��q��0���W3��/}�K�����o�W��U� C������\L��3��,�~d���~�d��%��lPn1�	��j�p��;\�N������H���+��X:$�����T��.e0��vZ���SwR�q��2���m��6
���y����.�Y:���+�0g]<U��4���0��"r����e���4�[n�e��$�a�I���0�����R<AU��q������.����������`7��{f�c[�~�]N��i�A?�IO*�-�}�Xv����
��7��WeP��j<��JS�5u��lwk�p]�>�����}�c-#B�ob	�n�~�����\�H`&�YG��3�K�~u�.���16P
7�~���\e;'�a�����F������?��f0@�1��A�������*�3X�D&�`7���vZ����&�nof�.��m����8�q�5�6�|����q��
��X��*(�.���	�TI�/	C`*���1��F5F[������b/�zBP�3X�IXV�}�t�5�OeU����u�3_g�u� ��M
r��-
�s�[��|S
�c����	�<+������W��]�7m�����
�������18���������\�#������
����?0�~k*�Y�b0K��	�|<%�t�M%/�ka�`xShbH��A���0����{:^��.��oQ��xbd	�\F�!����q<�x�`v6B��g�~5��0Bg& B_��n�����-cu����)�<�@�%=����z��#A���z�5�h3 ����;��5��;��)�i��8�Q��%����7�����d��dx��%�f��|���P��tKS�k=>�&��bI�^}/��0��:������$��@�:��}m��N���0`�0�����!:���x���\e;'�^���$ ��B@��|��h0�b^|����V[�4`��:��Gg��L��@�n�.
���KWs����,�1�G���T����r\�Ue�%�,���5�q_���J���_��i��5��nRu�� �g:I/%��p	�c�l��Y3i����"2;)�ig�q����=S�2�aY�XG0g\�)f<�5�[�?�����d<g������!�fG�����r]�]SU6RBi��`n2c�7�1��O�S�ri\��#]� 
���L�K�4S|��(p���S'����+J�Xz��p�&�����s���u���F�@��K������YZ`�]v��<^5H���I�i� �Y�uH��G�@�u5�f���@�f|�#��c�1~.���X���Xj?��n������5��T���N�0tc�	�+M����i��t9
�7���%���/���;C�eT��[	�9�������y��[Y���ep���I�0��w��<��x:�6~���k< W���1���% 	�f���%�:c1(�Mg�b�`�|��A�-.��}���Nn�X�1��Un������K�M6��u���Izb��nc��tn�x�k@X>�5U�
�{4����@�����0�Q�2�n>�Pg��n���f]��^�r�Rr1��.���
C�pQ�K_*]�Gz�m(�(am���2�k��St��]w���@����E]�2 M����J�&3�"��z��N>\x����F���a��j\��6�\e��.�A��8��3;�X�p���Iu�<�tq��p�
�K�N��2G�b�o�k�������VB����rfs��m��v�22q~�x��Y��G����Mr��S�-����.<$��"\���n�v���V?������5��
��.��QO��A��SO=���C{�_Qh1�#��Ci�F�����}���ua9��J&y ,?�2DH�}[��_j0�+M�n?�M��R�q��y�` �������d-�}������@�:�w/&!��Gydi|Cx&������6��;���l���)���$0�h00�Ot��=S��f���c%��n�
�r�Au@L��4`�:�1�)���W,3c�fO����/�M������l|k�����g�}�]f<�Ve*l�E�g�u�L�:�`����$ �A	�d�����cF�_�uF�4U
��hG�������K��28���-5 ���Mg�s������-K��^�:w~��#X���1���F3g\���gJN��j������^��Y�w��~x��������qs��3�[� �����0�r�?g	�e���(�Q��3��h����8
����!������b�m{����wq�A9��G���KSe"�y�v��>C=I��AI�i�i~��R!��M�.�UO���)������m10���4'�o'M,{B���
+��h� ������\F0�u��-�5��o��4n�7�W�������od	ZWc@�Q
�7��$��Ua��qf����f����^)?�����O��~W
�6�kpd��6*��i��c�UW]�u6���R����M���i�&��G	�0�.�UC�0.�qb�9��S$0S	��#0��C^6�k���4P�����>�����_Se�{< G�����_�% 	�V���%�f+0��>(?��O�uY?	����h�ur�i0P���1l�=�����"�L�zf���H�O�
�I|o�����<]?*��k�2`CGgP�``Pr^'	�V�Z������������\s�U*�7�x��1f��<L7���b`���[��\P<��#�ct�8�uB9�`J�nK�"x�a}l]�\�1��:��W,��X��'�pBq��G��Y�b=�T�O��;K��0 �@&j!ox�����:v{ns>gf3�,����+gc
c,@\�������@��Qm�����;���U�1cg�m����Fh[����K/mg0��A1S���Z��1�u)�933�%r�m���;]��A}�������W�m�N4��Z��-������w_�+s��S�-��)�$��0xF����TD?5Ow��%,B���9E�QGU8��L����kcK{e��W.w;y���t�e�N��I`���wC\��F��,�kXcR���G�_��W�n��Azn�n�&
���]~��m�b@�Q`�b�����w]f�-���Yo��Z��`4��[L6�i������?<�9������j���ia"�"�Q'��� �>6��z���+�	q���v1���9���DS�90�e�)��'	H`�	h00�Oo��K���c�
}W�����a�kj��r��4�Pt�
���Xe��Lt�
���F���T���� ��� ��F�D`X%+��O<�5K���9e����_v�e[�o�gP�N3�	��Rr� K��K�0�x�-����������~<!0c��0X��O�5�?����{a���"�,I�
��q����3.�]M����c7�x������-�\K��y�y/��K%�s^��K�F�e�5U������]w���8�a������ ��l��f}q�Bp�O������!��p@��r�m�n(���h'2s�����r���D�������K�%YH7�����1(���3�����]��������w��x��E�<�?{`x��|��?���e���g�8p���~�������F�g��``���4��-�����I1�?r�q�1�'�{���a�~?�%��t��7-��T�?��R�k���k��4�M|��&��J+���&������L��.���6���E���hZG��/|�m�3�^y���x�*��R,��Rm�����cm{���6SY������% 	�<
F������������0��`Fj�����|��_,��LW��p
�z��K+��gK'�?�-�t,U�*��5�P�Ci�
Zf��)�$�(�o�a��@'b��!�C�J�<��^���������gz}%��/�'��Y�|�.���^A'��c����w�y�������j�7/g\)�Mi����
Dr<����i:���z��$���-~���\e�v�	�A�N4����5x���u@7���6�]w��-X�sS]�2;������%(a0�`F� B}��6����Y��M���r��S�-����}h_�L^7�oJ_OM���������c���F��D6uY�LhF��&S���:et���N;�Tz����������N;�SR��G�5Ui���&<�b����G�vSu���������#0d�[�����3G����'=W��(��l��1��V��l%���>Y��O��|a5�t=O\ �.q��Aa���T��8w��G'�|r���M��r����s(���g�f�DD4�Y~��SN�0�a�m12���	���M7�t�%.�`q�Yg������O��h���B�`���{[��F:�-�J�u�2�,S��bG��V�tj���i�k�1@����y�X�9p=��t];�DY�)��i��$ �A0��/xAy)�^��D����:fQ�1�>�ok�2�e5uY����a�>k�v��p����Yz��~{�,u�?��z�����T�,U�����x0�m�x`��s�=�NX2�v�9��e��_��1X�Mr�������#��l��d����Z���D�f��K.�$u�b�����b6qFx�e���������P���K1���@�M 2B[�:��.�\��g�9?m��%k?q�����[�O�;:6�l�b�=�l��F��S�g��g����P(�h�������X^�6E�(!�������nG�@���e��r��8|?Y��F���k�]z�\a�&��?��O���\A?�����xX���LE���Ll7�I�z���������,E?L��l!�oA��c��u��3e< }>SQ���������f
f�����'�8�(�q�@���(t�X;{��*�E2��
�#�
.n����:���WS&���F�T����o����F9r�kj�������*1V���&(�n1Q��;8��7G\(QB� d���	i
������=��y��{�x�U6���I���)_�c(����1�������v3JOg���Ki���>�_,G�2�z�l69�b����d���g���
��6�v����r)��`�?���Oy�����wh��e��sc�.(�B�O{��{����'c=�E�k�~q����H�Ll7���8
O��3v��F�$��~6�_�M�6�������m�	m��9�x�e{�'�u���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���q�y����3i��$ 	H@��$ 	H@��$ 	H@��F��C=4��0n*.�``*({	H@��$ 	H@��$ 	H@��$ 	H`�	h00�O��K@��$ 	H@��$ 	H@��$ 	H@���������e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����_�b��w.�Yf�����+���/w�}�,��Y�A�)OyJ����������b�9�(������{��$ 	H@��$ 	H@��$ 	H@���``��I�����g�}v�R8�?�Aq���n����o_����mqv�a�����cu;(�O;��b���j����[��w���?�?�a2��]a�
���RKK/�t��p�;����z���n���q��5�X���g<�4����]~����������H`\�=���"�,R��/)z����G�Y��.�����.X�y������?)�z��X,�������_�����>3��@���� �;���?��s�9��o��4����I�$�,�@A=����O{���%�X��
r�����_LU����w����.����4�`�C=��O.�`|w	4!���5��a$0������3O���b9��������9ON.�U3�@�r7Um��Z����Y�����f
f�����7�������>�x�(�8��^�<?l����>����0;|����:������m�����Q�	��F�/~���`(���j��c��3����f�mVr�!���<���&�l�:L��c�������>T|�[�J�{L���N�����8��]w]��O}�qx�����QK\�����x�����v��V+�����k���"M�*���^��W�n�m�����nE|w�uWq�%��sL���������I���\u�UKk��f���?���{�)��	'����[��������al�A�����\y���w�����K/��������o1�BP�x������!�;��&��_|�V����������e��i��e����G���h�6C�e��=����x����0��8����?��O�mj�~�-�(���7�-�X+��M7�T|�3�).�����a~P���%/)V^y��>A	Ezo����������o��7_����}�cF�uB]�;��*�+��R���K������;��3�?���u�{l�	�*� ��k���.���P\q�m�b'wy�x��~���n�iY/������R��7�)��\pA��.�3Y�d��'����������A��AT<����$5�2�'NE�F W���6���o�z�6�����W�NL'����g?[����
B�A���W����{#E�AX��0����>v[[:Z��rJk���{��_�vl��a��4L5�	������?��������U��v���o��j�rP���hf��#�<�x��^�8��\sM�����q�:C'��(�R�;�� ����k�m|)��z��^�������������;�4��k��������\�N:����������GuT��������H��3���*�ss|���]*��[n���P����:�}H`��N�H�&�'��&J��g�2����q��R��+>��O�
�q��,������j������D����u�����I��T���wuM3��K_*>��������{�	��~��	��!�1��n���w�����]���I W����$�M�����'F-u��������I������#��Ei��|��qh�v2��d�O)k��o�9�K�<������HW��O��b���n�p�r���ls��s�k��g��l"$ �"���X��4������Jw�q�awR�1��/E���Z���?�K�l5��q&c�������������n����Ys:���l���K_���>?������L0���V?�VgfS�����7��
���aC����T�^�����Y���~Pr3����T(>���A)*���7J4�~������
��"����O�z!�e���W�(���|�m���\�t�E8n�RA�W5V��o�x�;�'=�I�����mH���5R����b����:����.��R�m��Z�k�*�iZo�]��� e������+��(���?��������{���m�R(]*����[o-���;<����fD��g���J������e	��R��O~R*�IO*x��0����|�5�x,��
�0�Jr��x�}�-.���4����@����=�������t3�U^��t���!��T�����o����Ci�Ve���d�O)k��o�9�K�>g�(��+�K���M g���6w��7W�f�{��b�/	�"
f�S�``�?�IL^?$���N��w��e�8�{=�~"��R����o}�['~�3�S���?����xpd	�1���{�����W����|��-^��OZg0@'9]`�E��W��U-����
�p��D��<�w�}��n�1�Zh���e
�-���M��|G�t������H1 ���;�B����P�k� �e[n�e��xzm����2�F�3�
�|Ey�?</����m��uN�����Aa�8l���ez���0P%���^��������eGx������?��6*���{l\�q;H��Y����0e�������R�O������f�VVN?��	Kgq7��|+��y�{J��d�<?<��O/�?�&�#�rfj`�����D}�A�Zk�Uz��BZ�������s��`4��[�� ����J�7��<c�41R@��X�-CN��U��x�=�	�*����x��m��q}7��\�%��vvx�S�R�o�H��%���c4��o4��X����
F~�Lv9�����em2�m�5W{)�sF���b��-����:���4~K`�	�*wS���G��7W�f�{��R���f#
f�S�3`���7��5��5���	�����Z�e
��g�����'=��?O�_��`0���sB�4��$fyu�g&���� e��d����8��S�C��,_���f�2.�s�����c$	0�A�����6��T���(��:���kKZ1�A����j<�)�=���[e�<��WU���9��[��j�t�|S~�6�:�oCUV]u�r�o(�X���M�r�w��u2�*�y�k
�PI���#F��m��~���{s�������?x�	��a UmC�v2
��6��v����
k�2_i��"�A��g��R7�N=��O~���@'E?3������q��;��#�.��m$�F���?���w�z������*�,�H����5���FR�pm�����W����t�����b��P��I���`|��m��V�Oc�9�_S|�����
�%������` Gyi�N��>����~8��,V��d�,���o[&k:�I�����2LY��~[��\��\�9M[��i�������������@�r7Um���o�z�6�T���K�M4��O��`��S��n"����*�,fvd*�10�
i	�uHg,��[LfY������)�(k���6����|��+}:���=42��P����o~��4Y��Nib�����v
Q�p�8���~4!��3:^w�u����%�Se�)��Uv\�#=�����{\�q����)���f�49y��W�YS��E���Jp!�K.�di��A��7�\�t�M)uk����������X�3��9fu�1`�I�`����+��g�����"�������^���3�x/������y3p�K�T�0��9���Z3��z����>��rv��[��K�<��mh�x�_&O����;�l�:�i+����0����\�����9�/�g�EIB�3u�1��D��0 �l��A��|�����B*�r�!�r�_����Ji�84�|S�=����X~��v'���s����4ux?��T���������<�a��G�R����M�7��J+�T`�h0P�t<�/��x��m7��~��W����-������u���Ov\i���1��Gh�m����hh����1����6�lG]�R,9P'�>��V|�}��b��<�t�[T��N��������C�R;���������0�!��U���������u��9���@���)�w�5�)w��(1f����Q^�I�aG�@��bf)ul��]������\�t���tr�����em��mi�r��r=�4}u��T���|�Xp��������1	L5�\�n*�����\��m��~k��$0[h00������v�i�">��UW]Uv��X��qG�y�Yg�+����87��;��2s�*�/�x���}�ma5L�c��r5�}�)M�/��q}��4;�AKf��^t`������A������9����hE����0 `P��P*s��Tp����V[-=<�7JqfsaT�*��(�'D��h��0��YU���������l��v��.	���F���
�|�z��:\��C��&L;��	e�7����,`��aMa��2�{�D�nBi������C�u�����)�������`c��X�������d���R(��-eP][t�M6i�/���t�=H�����FUL���������w#�NB�E'a�I'�T���e���������%j�e"@��m
�h+��]���?�n�;I��.g\iz-c�g�^����b"�u��^�?:�o(&S(�*@6�t����B���`��20H����M~����KH?,�Sg�q���r�����c2�1\��z���&�L�@IDAT9�K��n�	�������#�e0�S'��i��{�Q^�B����}��~�'����������^�������N]��kL^��$0�r���ls��s�k������~��l!������=��Z������CX��(�:exy����7fA3�4u��+��k�a�T7��a�N;��+����J���H�d`���o�4f�c�D9a��:��`3����>�P���zLQ�5<(�������!�8�rM�j�z1aN����l�a��)Y� �@�=ePf0�}�W,���g���YC��PgV�f��"?��({B�L�` �����u]��^J�#B�D���^�~+P2���N����������x��RaPq�e�)U�i����:�t&[���8����HN�������~�*�i0����)&�-F;H��6M�0e>���9���=H�P��/l������f�W�A[;�-<l��� ���#,���N�r�>I|?RC�N����.��T�m�3����.Zz�z�S�Z�b�<#��1��k�Y����o�K,Q��|�}����8�MR��$H=[�}{��_<�2k�����O g�k��tb��y��,��` Wyi�^��������&&LG9�D����0em2�m����x��R���=�^�2�#��H�	C����F�@�r7Um���o�z�6�����S�I4�IO�&-9��A���q�X�w�����n%mt��Q��u��@�-~��Z���&M��f���B�b02��e ��F�,xf��Ar��6�M����&����(�P�1[��z��������Ni�n�SW�,��p/�^�{�5�0S#�������G���,��o|���	�����S�if4"9��ou�gy��JE�M�eJ��!�\g��&��g�K(�1NIc<��Z����2K��u���	&�`������o�����Q�$�['�N��Q���U6��w���L~��u�N������d	������������>X�O�������&�2#������p[��|��+����^e���i]�k�4,��`�c�0���J7�����|����G�-x�9����^F0@���_�(����Z��"���,��rd��k����-�WU��
�uReC[��#)�����S/n1��.>��~9�_Zx��C@H�u���@��ip;���n���e[8�.X��oQ�T���ou�O�d�����V�K?�M�K��l���]��t�A���}���.��F�@�r7Um���o�z�6�H��&Z�fL��u�:�������^{�����>.�Qr�`'���c��_*��;���W\qE��2�q����ziT�����3����/O�����;���C���Y>���o.����&'(Z����j\�3+6�?��O�,�8�Zu�1�zGy�������5T�0��A��0@^�9���M�%_��!�H���5Ty�c�h8�`�]b����:�4��l��u������)��k�~w3���N!��a�zM���o[�j�X���P��|xV��G���r�����%�o�(������2��(�c(�q�����9aR���0��Q@�x�2�rH����-NHoj�}�l�u�fQN	��y��m�`�vy�ce`��
�4\87�������Izmu��|���`��p=���r�-�fL�@8��:a�r�L�����Ue�|�[a��hQ�m������{��o	�����:��K�K���,�/ef�s+��h���C�	<1��*���4��q��v����U�,�9R/ ����8��M
��=���]�zW���}�
����u�E�u6�|s�B;85������?���M�����v:��j�*
�w+�������o�Q�#<��}��:�[xv�`Ce<	�,�����X���	S�����K��z~vx��^T�}����VZ����ON ����t���������u�W�s����xy�����|S1&�1�A���q�/��J�I���6w��7g�f�{����K��4��O���u2���tF�M;.q�n����>�QB'e85�1���1���]Y?~�m�-o�2����n)����;���!Gx�E��)Mh0����Xc9���s�`��~���
�=����;��f�Lc���W^9��T�2`�+=�e�]��&�J����`��S13��x��6������G�m8�;)�Y���t2��6^RW�������#��$^w�u�T�e��T���B����+�`cV�"�,���F��Z�Cx��J��&�Y��n���c���w9�����8-W��B����
={u��q����_�.����@�F:��,K��P������8&L'W�k1�,�g0���2���\�eC�A$���i��1E��u{�8��XV!���7uQj�q�-�[�'��|�������k����g(�P����}H%7�4�T���E�M�vAj�������G^r�q6��*c��S#!�e���zf<�~������ByN����s������k���U��/�K/�t�K����
mB�`I�}�	�6����v���[�I��	^z}�`w���/����Ex�4��o��v-oBkb00��{+�C�I�	m~�E���Le9I���������������w��R5�A�s5�t�MozS9y�c������^�o	�*�&�n���9�����ls��[n�% �� ���tP���9
���L�p]�f����N�1wR�3��������g:[%)�H��2s�UVI/)���U������P���	�.O��ju�f��pA�P7����0�+8�J_4����4�8�-����S����N%u�_�?����a��{���[Sa�	% J�TP�wp%y ?��X�=��e�
7,wy����q����[�/�����[n���[�:&m����//�~��J%WY�85n�!@��uc',���Q/�T������Y>���Y�[}��w��i9�`����Qc�!�������7��?�qA=�rC1����
l���J�|W
z��Y�.����P��L@�c�T�R�����#�����&�>k���H�!�����rH����{��G��e>��3�����W�|�K>�������\���������/_��3��kb�G���D���c?� !3�i+��Q��(ES�]�$c�'<���
����XH��*���eWx�����x��{�.�;���s��n�h��?���������3�h����@���vsw�����$����W_}u+�T���
k~4���*k9�m5�it���R5�A�s5��g�q���cLq���L%���MU�;g���^��=S�`�%	�d����X�5`P	��UY}��K�B:;&
�i�O�2���?��_�a�
��]w]�����������6tU����������`d�2�sa0���Cs�=���(.�s�'���`��X2���X�5�W���'>�rg_��`�����9zq���b��������:�?��6����9kq�R]� =��w���x$���3d�,�=5n�!������MFS��Iu�9��rR�4�hcvf*�`�F����l�+�0�r(�� y���f�B)�c�����!�������J�jQD�-7���|���A�?������a���^�8F|�����pn%��^�����[o-���k��*��;g\�r�U�Pn��QuF��=�sP�`��q&B<�,��������b���,��=�t�����X>�'�y�UW��~{Y�bL��q�&���e�o��is�}�*��h���#�B�5�u
0�b�-�X�c����R	�q��]"���@�����&�x/B0v����75�Q^:�����m�����o��?��,��x���LE9)o��_��I������!K=��^��l��\����
��z�D���L��r7Um���o�z�6�(���]�NL'���3`���/�������j�c�9�t�^=�>�S�>���Su��k���x��_?!,��]um�G����k������P���
oxC[�X7�.MIpMU�FR��`:������HGN�9������G��d0�N��N�\�1�^X�#�P��Q=��=�A,��Ni�~�>�=�Ur���W�� �vX1W$���u�TL,7��'=�T*3���X�2���p<� 9��.�$�R5�,�kl���VGRc����m�e�m%��o}k9��u��#u��W���]%x�]���y�.�����"�c]����u�xL�`�"cdB0��e�]j�s���q
��^e#��8�Y�xP�$��i{��F����C0�X����)G��\�T�ki{����*���{�>|[x�~Q|�����/,��.G�����s�=��O��p���o]���f�����r��N�^��W��8�X��1T�J���Q^��v_k��f�^	�_���-�cSQN�=�����*k��K��S��[�������-��s��s]�y���4&��Yc���xL�M��r7Um���o�!���lsO����% �Q%���ruo��{t��������������u�p�����t��8���I]'s>]�4����"�X(,��4��@�a#�������!=�q�\����4@N����4` ��o��J���sc��gff�+��kqV�������`�8�3�8��,����q���H���e~:�������'_����	�.�Y�>�`GE�|��W������k>���d�����[��b�'�KP�
r0��+]��e�Dr���,a����2�c�Ft�YJ���`\W�ew��3��:�_��0���K�Yw��$�/�3�u,���Qd��vk�����������&���K����p3]r ��n���.�>�:�eSh#���Gq��?�Ca���^�'����������dJ��N��|�-��Q"����p���+��a�����kV��r��:Jx��{�}��P'���k�8�a	'���<PwI�c��K�
0�h{3���}aL��d��n���O���u��u�W�s���:���x��\w
c�a`G	/?��sO]P�I`d	R����=]�o�z�6����&\�fL��u��(IQ�v��������R��<�4Q����JfJ�����`�t
�8����cl����>P�~����U������C9������ q�\�YN������\�����(�0�`m�TP��z����:���Kt2A���&x�`��:c�3`���T���.�/����
7����{�(ilV�$�X����cR�>�q!�������c��B��6���}x������T=��]���M�:#f��5 <u�N�9\4����cZw]�c�l��������d:������?�I(�s��5�Y�;���z��P��(��xo���:��7�z�5�C&c�N7�q�t�K�����!���<�4J
c$�����Ir���quJo��M�X�����Z�I�������r�������j�%�(��q����^\z����u��3dV��������[���
Ce�V�5��L�ri��4]��W��k��N7��n�}�-���������U���U����:���;��*/�����C`���/���s���I��5h,��Lf9�������e-G��[���
�^�xr=���-L1`�e����wW��l"0h���67�s����5�����	H`*	h00���WN���V[�t��}:%�n��:e8��� 'n���E������d�M"x�E���5u7Dg������l��4
������;�,
'B	������n9`��������g��D�U�TaX��uju�.b���u�X�:����]RS�L��w
k�T����2��{�r(��E��
�S(�9��RK�^�0���0JH�40���[��p�_�:�;A����:����\yW����h�7WY�����8��@�p��38/�����J����'/MB��;��cv�_x�a@(��uM]���H���g�yf�)R��%\V�nP�;g�1�� f���t{��G�����3X�0M~W���?�z���.����o�����chB�v�KE�CJ�Qu������%=��wj�3�&���iR�����X����I����1��=��{l+H��J_��i�` @�	A�D��z���&�axF��7�oU'!��3�{��/}�l���
}��n(���;5��L�$H�o���_����k�DSJgM�z�u��`��Y~<W����[�������c��@Zg���f�m�;���cFa����~����d���_u�O�$gY��o�������%�����4��Y�c5iK`�	S����
��o�z�6�(���]�NL'���3`�
�n��f���tg�8J�Tp��,��M��3�����V8�vAqK|(Ra&~J�:����a@���t�p�L�(���b��.M�*��=Y��p%	��X*3��9f���:gz���K.�`,k��d�{H����`�A�`��Y����[�3�b�4�O���C#�w�5��5���������r�W_|������<W����@&������c�c`��e?�U��o`0�������z������+�m~�*��h0��?�]���3 ��1����nDP��z�,��O/Yr�%�UW]�,��P����
np����b����>��
G����z[�8���+1 ��o�c�M��E����RYU7w�5�(�q�-���Hk�6U�q���\��^��c5n��(3����z�m=u�� ,C�b8����Y�s��-���5)cxKg�a4�*�#�j]�QV� 3�&E���!J��k�N���ou�l,��C�P�������9�+�Xv�%txOB02��N�%��+`�������G����L'�,,�
�,aPF��YI W��{��
+�e�w����y�P�$}�0���
�Y��;Wy����f����|��:-AHX�a<�0vD��A�����5��O�$wY��ok�����^�9�s�����?F(�1y��V3��0��H�T���W��7W�f�;�����#��@��<t��@�D�JM�W����{��G��P���n��B��������U�l0�X�q_�Gg�����aQ���'R��N�(iq]�
��b���0K�W��Ui4���\�'���9gz�G�>)�';��"�7�tS9�5�l.5X}���Ysq.���c0|��+�����0Pw��c(��e+�%k��V[0�y�1�@q��IUR��5.�~U����8��I�����p�	���.�vo%��7WY�h0$�C`�-�l)���3Jc��	A�OYH��X6$�4���h���^�>�$xw�.����w�Y��/I.��
�������4��i�M�\q���Wj4�q�a!(;{F��2��:!��w^�1���@\3��(3#n%���y�{�p���9�i�or��q��kR�h�3�H����x�`!cl���h8���.@���&�b1���]����s�9��4m��.��4H�T�@k���j3��m��?��E{;<��g��,]e������'�!���}����g�W,�3�X���+�>�������Q�(Oxc��������*f���W^�<�.CP
���T�t�����grK|�9�
0N�%�8�$���QN"�&����4)kS�o��^�����x���������e��"��@ W���67�s����5�����	H`:h00���g����Ng�`
n9Q2�!K?$1��S�o�
�@(U����0��TXC�5�c&D]�5�a�G�tP�W�P,���N*�3=����X������b����A/|l=����j|u�3�`�n�����=���.�]�U
(t��[n����'�u�qI,C��`�������P0F\�0���r���W�� �v|0XJ��0�B���flRn�7C0K�M��^�~_����B���^ZO���<�4��'5���?�����?�Wk���o�
��&�~��W�o�����8�a]��k��B�M&���D�e��Y�.�drl���K��$������Ri�><�5x<j*���^q��+�W�2�����/�SP���/A}K<]�!�*|C���J+�NQ�bE��}��	m����uQ���+B,�@pf�����I;�:>m��'f�2c:�!�����/gU�7�|e]�C�,�
!�?�;H�Yd�E��@#�p��9e|	[��K�
2���'��������3�q��'���u4-L��<uux��<u,c�^Z�-'��T&����MU�-W{)�s�[�8f�sv�L��yN3�@�r7Umn���s�k��g��lZ$ �Q"���Z�0����{v\���n�z���g������(&����^dvB:��^�of.���s�����N_�����7����x]�5 >�D�z"�\UhD�r�)��N�N3���q�45�Zm tc��'��R��%	P��v�m-���}�7F&<wfg���c�:	�����R]���0&��/�|��%����O9`�z������:�8������-�
���a	0[�:��A
m<"M_�U��P� �����A�]����z2UPU��~���#L�m�|�a���[L/�{_��C���������[o���n��b��N�������#�XC�S;���(�9��nA���S��.���W}?e�������x�w��6��[fN���Y����7(��K�a���[F{EE/�s��N!|b4� d7A�E�i?V�k�h�&����M��4��0���0�/]_:(#��SSZM��W��q���������?�.� F�u2L9�����d�O�������l/�z�|��X��	�e#c�I����F�@�r7Umn��s�k��G��7���L ���Lx
]�p��G���.AjOa���03�Sa��������:�GL�}z�x��g�%3�P��33Q�s-.�����>�c�e�)X�����?�9X
�|��-�q�K�v����*��Lg<1#h��6����u���o_*@�Zj�j4eh���J�T&#=t�pk�r��uI7��0��3��\p��s����.*��i����.�D:�
�
&�Kp��J�f�nf?�|\���F��g�r
4$�t����:q1�g�>`,R��`k�i���:���!�������nk���V[��3�N<��t0���e�T�0�+������@�0e!�Tu������-3�S~�t�j�^���O����;��{�	�}a6;�9f�cp�P����NR��x�;
�]���)�NY�$�S�z'��/���84��i�#r�B=�L������>�a�q6�b�7�*��q�UW-�7��[�HT$0,���>���J��hO���?m��y���ka��G�8	�o��Qp���{����&u%����4�z���7�����K`lK>�h�I����o/
�i?F����6�`�R�O;3<-DX���]vY�-�����p����?i�W���/m`�7T=�F���"0h��H�k�y�1����W���Zs�5�����^5\��*/���M���j��j]�7��o,X~��:<Ov"2h9�_��d�O�)k��o��^�9�^`�o�y�)�d�W����j���T�������Y��������I@�L@��Q~zS��N��Ah��0g���<��]�J*��/��1{sx`�m:$��@ 
U�cPq��8�a[M+�/����3�Y�b|������1���W�`e8��M\	��I��s�}j�5n���}l&���y4��"@Y�����>�Z����4K-���M(q��7
��:�f1�	E����
+�P�Q�,X?C��&3��L�dz$0���X�a�%�,���&���\sM��e�dQf����*3��~�8����b�R�pI3
�A�`�J���`XG����#Z�4chE�H��~��M�c��C`��G[�A�����,/��)��nx�1��=��A&�2��7h9��3*���o���G���N	�S���U����ls����4H@3��3������2�AI5)��$ 	H@��$ 	H@��$ 	H@��$���
 �(g�~�[�jC�����t��v�	H@��$ 	H@��$ 	H@��$ 	H@	��c��D�a`���)��$ 	H@��$ 	H@��$ 	H@��$���9i���4����I@��$ 	H@��$ 	H@��$ 	H@cI@���|��g���|��Fs�1G��;�������Z����$ 	H@��$ 	H@��$ 	H@��$ ��!����<+S*	H@��$ 	H@��$ 	H@��$ 	H@�F@��l(�H��$ 	H@��$ 	H@��$ 	H@��$0:4�geJ% 	H@��$ 	H@��$ 	H@��$ 	H@�h0�
�I@��$ 	H@��$ 	H@��$ 	H@��F�����L�$ 	H@��$ 	H@��$ 	H@��$ 	H 
��4"	H@��$ 	H@��$ 	H@��$ 	H@����``t��)��$ 	H@��$ 	H@��$ 	H@��$ 	d#��@6�F$	H@��$ 	H@��$ 	H@��$ 	H@���2���$ 	H@��$ 	H@��$ 	H@��$ �l4����$ 	H@��$ 	H@��$ 	H@��$ 	H@�C@���yV�T��$ 	H@��$ 	H@��$ 	H@��$����P�$ 	H@��$ 	H@��$ 	H@��$ 	H`th00:���J@��$ 	H@��$ 	H@��$ 	H@����` J#��$ 	H@��$ 	H@��$ 	H@��$ 	�
F�Y�R	H@��$ 	H@��$ 	H@��$ 	H@�@6dCiD��$ 	H@��$ 	H@��$ 	H@��$ ��!����<+S*	H@��$ 	H@��$ 	H@��$ 	H@�F@��l(�H��$ 	H@��$ 	H@��$ 	H@��$0:4�geJ% 	H@��$ 	H@��$ 	H@��$ 	H@�h0�
�I@��$ 	H@��$ 	H@��$ 	H@��F�����L�$ 	H@��$ 	H@��$ 	H@��$ 	H 
��4"	H@��$ 	H@��$ 	H@��$ 	H@����``t��)��$ 	H@��$ 	H@��$ 	H@��$ 	d#��@6�F$	H@��$ 	H@��$ 	H@��$ 	H@��g5�<�����4	H@��$ 	H@��$ 	H@��$ 	H@�O����L�
7�i00���$ 	H@��$ 	H@��$ 	H@��$0�4��o�% 	H@��$ 	H@��$ 	H@��$ 	H@cH@c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``L�s�Q�v�i�\s����-��R��������c&2�~���]w��
�a�V���?o;�dg�5�(�8����'�tR��"	H`T	<��O,^x�b���/���������d%�}�����3O��C���N/��E]�Xp��;�������������;o��������f�9�,Zh��-w�q��qM�����"0��s�,����w���Ue^���1�� ��(���J�b%"�Jj��`��LQ����
��R�Hy/��2$.�\�(�d$����w�y�������}�y�1�Y{��\��k�9����[}�����u��z�R�oQ�����E���]
���~��nw�[]?��4O�ckP�A=�g�&�6���q�{�u����������������w��{��V����[�p�
���7�;��y����&��e�{���;�P_/|�?����u$ 	H@��& �``��������U46���.��:���*�	��O��fWt>������y��e��o�fu��G���;��;��>��5��|9����N;m����^�q�k�m�/8
�?����0-�G>�����D:�����	��o�vu���ov������^�����7}���3o��-�*tL��%/iZ�z��T����Tw���f�!���K���;�����g��~��8�����w���m��*�]8�����TW]uUu���W�\rI�b����������a{X�#?�#�mn�����_�r��w���������(�/��/T~������'��W_]���.�������������~��~lV���k����O��b_����^�y�������nQ�����|u	����s����}��������g'��W����}�3���up�lY~�c������~�z���\������������^}�_��<�����n�-����_��5��}�������"/��<�Z��:����/�h�Q�
�N�������[n�%fO2{R�y���Tq���v�����~D��/��/��o�}�r���M��uJ~3;����d�{�����}����~���'T���Qw>��x_]{���[���5��X>f:U}z�$m<����|�;WO{����;�J�q��\/��x�;z�F��9�XN%����)Q�g>��������9�=��7��s�����mc��s�����e��6K|�qPRq��������������m���F�����N��~���;����������b����sWlc_N% �n��������kV���\����.u�>����p=����}O?<������7��OY������#�J��y�(/������=�������V�G��)7O�'�|rk�)�;����mo{[c��oy�[�wA[���/��>��}�{��~�W~��������!p&_y��C6q]	4����g?�#�u�0�;��j�������;��l~�c��0�~}���z���^��WV_���Z��"C��
�XA��������}j��|.���'���'@���o~s���G�����Ix��?�����en3��'�pBI�m=��6~g���1��?��M�����~z��G?�m7�_��_U�����O/c������6�DND)k3#��(6��6g�~�/�e"���ef��c����9���+:�M;Z�����gLu��r9_��f$�``�����i/�e�����{����=�q�E��w�Ss�1�v� D�A�#��p����m���% ���c�Q��u	���G�G���"%����`�#����D#�h:�����i�Mu���,O��K81a��'5�J�KFTF7����T�&L�
������������3[y�e����]G6��������'��N4���NB��F$�����������z��^�n�������\��)O�� �Sn�`�o��o�{1_��{������1�r�	t�G�/���\D�@�����p@�5���6r#���"��c�E���������ztu������o|�����~����n�����g+B��,�� �#�|��ud)B�k���{:�~��~n��S�'�E�;�w�;�wPn�x�P�;�k_�Z�����C��t�MU�^�6I�)�m���w��N?�$u�C:���"�-��r����������vJ��h�������_^y��}W��7�l���c�}�p���*	H@-�����L{L��������������ID���p�T@�L�@�I`Z�;�����I0@g9�L���u�0�a���d�n���mX���q����/��g��$e��qT<�3�:��������!(����Z���!N?�����8-9��Z���N�������B$s��������N�����{��WCr���(�,��������|�3�~v�f$1�Ya/{���O~������_��QQ�9������"�0!�	?�{"RI�N���:��S���Y$r��!�0A��<����'�'�������Mw�3��ra�(�m���,�H�:���o�bBC��fT i
�F��� ��S�K<;���|�``*��~.������$�H/[���N���3�Q����?�.2T,�;{���s�3;������Bo:�)�L�f������(kl���N��!	<���^����Nz�I0�3����t����(W�!f�G�P�:,Q,0�}��D�C�{�hD7Cl���2�I�8Lyo���na���k�H\w���4Z�+D�ac����S	,3����8�T���B�X�O���"w�Z-M6�IDAT��}l�J�S�����29O��f&�``�������u#9).j�����]n�!���>Uw4�]���!���~��G'HW�m�1j5
s\Z��``^l����.����6�8��D�f��]����vLa��o��@� �%��?����.N�N�HC�$��;���7�Y��J<#S�7���Gt�0Bx3277r\��9�h$�����S'��p�NmF����>�Tg�u�l�)���.�NP8��~�����:��	��4:���J�����?�����dTAn����>0���O|�v��z�����k������������<��oN�5�����P��'�Q��<���"�6��+,�3{�K�QtF��>����}~�}�����?�� f"
�0��W�<���#��eK���~��u:����j���x���1���<��90Z�Q�a�)�Q7��?��Ymlgh�o��I9�;����AaZ�K���HY�T�����.������\�?���^#���C=t
Rv�����<|L�9����}�:�����H�C�PE��!6U}z�$m���s���zD���ENv����8��Y:��$�L�z"e��N����z�D��2�9�S���c�S?/��% 	H��l�_Ab�S`t ��&k�,��_��Z���B��-���K���4�����>sB0��t~0����;��h <"
4����E�@�7��|����r8.QC����u�a���\:����#���������
�D�nJi�8oT����c����_��"�-��h�������#�������po���z�t��pft�i������Oh�E#OQvG�>�1�h ���H6:�h��66����Pzl?K`�@�S:F���y���7����Ms}3��N��w����+5`S����R�p3">:����7�q�w]����:%�F�����g?;���?%�Q[�|�|��'7��^���g~�g�������P��+g�G~o��hMWOG���
9�
���g�}|������t"��Lq�2j�����%aF���$��@�����~����AN�_c�u�(����^�d��e����g��{�]w�V�!<����#<��g����He��u�E
�/��<�Z�K��J"F�)��.�/i�����
�#������37�+���$�"E��1�Q��a�l�V�(�m������(H���o�6G����A}�d��B���v�m��wDD"f��>�lm��t���6��������J��)��������u�6��is��&�e&0��B�F{9�sS������0��1��Ker�$ ��N@���L)����z��<�pF�p�A���uh��c"���n:�Yo��w���)��8D.���u�	!G2F�[��3=�,��@�JQ�0�04D�I�����r� ��"^,�+ D|������s�uL�t����~F4@H�]v�e���
���(�iL��b9���<��5'�	l��|�S�R�-�i�Cr�G�6��O��O��	�����M0@����M�zFw6
a�������4��n�T�!�y�����/���u�c98)oD3�II��0���[1���!���b�)�i�CWg^*�z0�+��;��C���C!�O��c�o=�����z����^k���-�s�&"�&������
���c.����}�M��wB�`��i����[�N��3�<���J�g�h�@�E>��^����7�tm�{�:�#��B�4"P_j����G�'��iJ���id���zJ�\3�_�&RN"z�.I#��Ny5��y���	����+����������&�:�)�m��G���~�*K,G00���:����N����?lHz�!��-?��z�T����w	H@�
6�/a*��NN�Pr7���N>�$�e�4D`D*��>����:�������j�:M�m����
P)������������gDD_�������F�1�h�e��P��yMm����U4�T}�*��7�u*��B�Q�����:wpBw	x�"�!�JX�` ������atP12ij��8i�eD����g�B�?���F���Z�@D���d4�X�vl���$������:%A��!2����8��<bB��NS��W_]G�I�7}NG�Z��������3��R:�p��t�@�N���9f����<�l���:3����M-���C������y&r,FNo
�@�E=���%���H^p���y��lk�4�8��y�c�Vm��5�O�����40m����ME��Z��+��0�7��0�������;�8C��S�������Zm���c�w���������G������hK^q�����"����	l%c�)h �
F�F���K���[�&(|
�JQ��������[����yy�.	H@�O@���%L)�s�T$p������c?L�D��$$ 7*a`Tz���F��T���c����$�u��9B%�I
��m�e�_}�I��%����\��������|#zN��|�ox�f!|�lcEt�! �y���yCQ��x�"���#���7	�G0Pb4�`���|e��c��Ej�<
M��C��{�;���x�c�����c�=vMQ���F�%�M��MW����{�|t�5xt2 F�x#�B@: u��8���$�+@�va��	��N8��X�nJ4�,�u9qc=��t��0���`u����b�X�yt\�2���}��e�x������<�~FD���G��eL�SNN�0�Y����&�����7��}/��<����}� �QzQ��>�dt����`�@_��'�[�{��W],����Fj( ,�>��:77�i������H ������8R�
��LU�.��4ok�IJ�:����x��V� Ho���wtnDE��
��u��S�9�}�Y�@���B��8�_!�<�R��N���mB�t���]eK�_D=c�����Y���P0�����6�`U?�
�@�|��e�tN���~u��t��S���i(���u�]+���BS���@E%F2����;���������0���'?������z��;�X�K��(%��q�6��P�1����s���������#�<r]��%|��.�@������8�	M�>�,�����X����/Br�1�0�C�N���������}�3�``��P����V�@���}������G>��y��ys�9�������9�c����EYx����k�k�.p�����x����a�7�����������H�:�����e�5�\SG�I#�����O���|Fh���)�8�?�}a�+��eT"
�����c�\9���&��\�����L����Y�(��at�3"�d8���	�y����'�����tn.Z0���"���^�`�t��;��J�Fp����e,�#����q"���B��?"
��u9�,�6rZ?K��������.�1��K}4UO>��XT����t�Iq���)�������5�$��1c�������"R��R��h?���/�.������e�3�o��s�� �% �>�Ju����Ud�}��#]"��y��l��E�3�w��G9�J@�@����2���;�`���o��g��(@*�K4v�a�u�]W-	�x�I'����&�i~��W������3��U�i4�H�@��������^� ������=�k�:�Bne#�0�e��y;�!8ctn*�B��K0@
�|$*�cR!��������
����"��[�/��yS������$��l���u���W��*a�J0@xJ�'!�I������6�8'�xb-�*��Q�DbA������-��@c��J0M#���g��Q0�S.��1�iS��t�� &y�s��.�����3q��EH �2���~��$�hc�Mi=�b����M�0��~�g9�h��,m���3!y�S+���9��C��?�)OY��X�`�/����S]����7��S��w�}��cS:���q�����"�O�;���!"F����0��4a���R#Bue,O�����rC=#u)
�������m�6IWy��c�mDLtR�F�%m
D��U�Y�6�"�h�}|W0$����vJ��(��(�m�����)?B��:cS���c�U�Xo�����Q���$P&�`��e��N) �s����Sev���q���_K�FE���&��*�c�=�k=���Q������S�����������Y�����f�HE$P�&��P(���U�Wf?�*3�J�i��.��,t��Vj����P���C�#*�1��m4Z�����������6�o��q\O���wK����u[�g�g��}��I��(�MS1��8���)�d��N9�����/_�
#�bTr, Z
�i�sa;��S��'u�!Hs���mS����G\�q�y��O�E�g�c9�Im���4�6 ZB.�����>������{��j��v���&���8�)Cs�Sc.S���z�#�%�s���w��#-���12�N��&��T������{�����l������~.Ou-�����!���DwT���^�(�]����NU:d��z���1L��M�;s���F?��c�E�J�����,��������'�0�w�q��NQ�n;��h�����l����$�����������/��k!�3����<��0`����q�F&��N��x�RO-0`��-���R��:�*�[T=�}�9>�i��$�N@�@;��\�W(di�OZ�RgyS����H+%�!�X��:�u�y��_�5M�H{F������u�	��4��TJjh58 s�s�fj�1B1w	K(���>��bnG���!�!�:p�2�uJ�DD���Z���;
Xo�``��PS��/�U"�;�q�!�Jmke��,
�hs:���y������}�"�@�3)}�H?��<:�G?��������Tp�����n`�]v���tPb�������|��A�<���/�����n����,r�G�	vG�T�K�sDd�H�.CD�1�!A��������
��u��%0���������F��w?���)ZH���"j
9��9�QG�uMF� �.J00�������E����O ����-���{�]����$R�����O�p�=8�Z� 5r�S6���$�$Hy��5�(��w�O�[:��g8u�6�>���S��m��)���c�������c�$��t�so�K�u�<D*���K��{��^VG#����rv,c�` ���U"��NI��6i������v���-���u�1��6��6#��O%`�(�Rs+��K0@G>�%�����i�GGF4��t�;U8c�k�61�1]���r�=�1��F���y��W!���N���W:�Px���������^xaE>��P����
G��6D0�����������^S��z�Tj\?*�CG�����S��
EY�J`U	���NxF�ai
�����`����i�k|g�}vZ��?/�8{���QN�0R��{���_������z�����}5[x��4�*�{�p��x_�g+ND�Q��O?}�.��!�������p��3�\s}�x�q�H�)v�������d pcc;_���|	t�l":�\Q_+p��w��g9#1����(gI
�O����KShQG$"Kq��%�x��������C�~o8k���(����\G4�yK������?�?��{�G�R0-��7����5`���7�g?��3�NN���N�	R	������:1�|��k��S����n�6IZ�y>w��<��\��.�����q�k�s���4��J��Sb�B.��9�z��3?���__=��O�W���l��gt����$ �ML@������1�t���a�M0@gq>�}������������cqE�/�8,c��la�#/X��T������ZS��{��^���X����a�%��G>R��������:�B:��4�H�6F0�n��3�A�Q�� 5�N�������?O!�����F�
%�A�I��V���\n�����t���o������:�I�QY(�I	�<�m����H4?��*�3��� ���k���'��#���<s���tl�!t���d�bdB�l��S2�}8���QH��k����I�o��H�s�D�����������G�v~��T�:���E����o���A���w��g9�F��$#�]w�u������~g�p_��D,a'�1��iN�z��!Be?�D�s�7�|��6�x���"��0���	68mS�����i�����HG;��A�����-�O���E����1������m�7���u��3f��k��MF��U��o|c�n��>�!�!�=����D�(m�Y���m�8�)�m��������Z?W����:�pAr�
ms6���X6C�)m�OS� |B�3���mk�3��?�y��$ ��F@����M0������'��<���;V{��W-���q���}*�@V�c�p=��C�>m����n��"�+�%@u�W���v��~Q�} �Ea����L��r�(K[��1�����J���V�@�hs~t��"�|�3���T���3��#�sm���|���y���=�N5�3��6��	��$F�T��������&cT�	'�P/�yK�������I��-DM���.�`����9����O:�m?D�!�6�����I`���N<:�"}#���5����/�Y�v~�s�{�z3����mM�^���T��{n����CO�\�����7�����D�i�4�?�����'�"���[n����UJ����'����W�C��(uU�g_��W[O<
sO����w����6���}����eiD�����{�U��O/C����g����#���.�0�}�3��"%[W��!m����A�@W;�xD#j@�� t�����lS�3J�i;~i}�I@�@����2�������M?F�����@�:�<�|��|���|G����D��������c��tx�y��I�<4d�����]�F��8N�P���M�4��q����)��(_:�R[�X���+��7����%����1�y���N"��]���^���ICcR&Dcm��> �
c�%���9�!��1/��q���y����1�0A]|��w��]+F����w���uz�#��
0"1
����<1�8_'$��D��������w	�!0��t��'�F�Q/�����[��>�
)���/�OD�����"(P7��iO�:��p6���S=���M����A��@D�����RG��O~����3�����-����?�0�}r����v�y���S�Qn=Y.5����~�_�t?�^������'��'������V�<�9���S��Q.K�����O����}�>S�I���>Oyo��}���q������4�&�is�6N%���S����6/z��*��6Y*.������o+������������S	H@�&�`�������(�	Y��1:������l���#�q�F���h	�����c�Z�N���^��W�S	�7�\i�����F'��8��i����!rPv	8��b.��.��nH��|O:��
�En�������HC@���m^��������I`��$�#�T>��{���lq8��D"�g��u��N<�ExkC%�x������8���s;F���Jsq��g]����xV>�Q����h��^a�v��W�"�TV/���8��2q��Y�
b~L��hKC ��d����^���������w%!��ww��0�O{����c;_c_N%0�@_g�gy���8V�������rF��w����F��������Bd�������������It��W��Q�������a<�sy�k�t~��<��5L�rx�u�<u ���-[�+��b��h��3���q!�K�wm����#@��wp��!�
�2Hy���~����^!/��\����"�=��H�����O�1��vH�g�6I��i:���s!��������'�_�Fj�y��o�3������)o}�[g`I����L���$�Bd�!>��S�Un+����R���_Z�y��$P&�`��e��n4�?�����8.����k_�ZE�S��9��a�5"��|=�*�����|��������)���X�R0@����h��	�h�����Z=�IO�������w�;�������E
>��OU4��)�i�T���oz���k�t��P�\(�MD`�}������	OxB�����a�;�v� !��Z,0�qr��:�[��~{��J�X#�W���+�2p�%���
R�ixx������G��e����>��j�v�-:���+�����(�q�` g+�"���5e!�
���	a�������U������}7��5��Tc	�u6��%/����:-������A��������c�9fMHs�����F���Od����~�x�$����w��z��\����k�|�[����{-b}���m�4�u�c�=�"�G�AT�b]���/����!:$� ��D��J������I���[������!�DX��=��Y��8���'@[�wK�g9cRi0Hd����":��9�W���aC�3e}�2,[�$���S��<�����T��0�I�%�n���z���/}�K��G_��>m��������j�|��k:�������7;3����S��GY]~���u�|�*[�}��g��5��K�v�$ ��D@����M0b*���D����>@C w4�vJ�1��#i���*�Qf�cn%�8[p�`��
��{��o����"|��^i���k�H��V8y�E�8����1�o�}h�@U����r����~�#;}W�<N;�J�y���7�n�����s�����t��|'��w�u�����,�[J_p��g�q`�	y������c�=�E�y���U���of���kG��4��p��Rv��9:��1b
"$Dt�8�\�:��x���"���^g}��BFac;_�}�]c�q6�����.!dm�0�V�m����,G�C���'�9Q��#1������&�����XGa�X�2��e���Z���y���:;���������8����!�!��0��u-l�8�����l�x<�@�NB���
����y� #�S�#8�wF��0�4�k��w�Y��
!.�T������.X#T�m��a�����I�N�{�ACyD�\/�}�Cg�d�D;
�u�6�js�m�2	,3��v
�	-�?��o����9��>��i�r����(�m�v��m�tY�zF�
��:~�_�K@�ll�+^��fD���l��r��*|9f��TB����/_�	QZ�yt\��B�&l��������(�>�c�H�����G1]F���g�Y+��uKb�\T�3����s'��q1b�<��-R0@G#@~�'~����	�������yC]et�6��]��#�8�:��c$RM��k�����YHg:
�.�i���),/�s��}�h�x�;Z�?����Rf��e��%Dh���m9Hg#���|�']�����a�0r����u�,�E��l��8��C��0b��C�,��~����.#�����k��7�i�t�XGa�>O�xk=��\��<���<�Y��#��5�����h���i����Ju�
�?���g�Qh��me��M����u�j`�G��rF�C�|�~�']�\���������>OQ�^�6I�y�l�{����H�tl��\����M���w�9g+�A�@�v
���&��?�0�mo{�$�������3��Mu�t�~��$�	(��W����bK�Ct�7��/�p���k��v�+8�.W�����������>���������:�����
jbw�%.�@d=��4�v�i�u)
h��~����A2%�(/���	���bST����gk�@)�\��R\_BD���AD�/5�K�

�\:O�Rz�e�����LTl��������q}	�*�x���hr��}l�=����r�-�xS�����F�W}m��0Z�(4���]����9�y�3���m������$b2�y#$+e���eF�v�
7�9c)s�c�T;DH�	D��Dd���J�����B������$0%�R�x�#�]��E���G	q����e��}��*�+����L
>t��;�_�B�5e�a�*#}K^�����o����k�����&��=�qu�����>��3��!��I�D{����������?���g�}�G[�lY'8������i�t�q����]����{��w\��2_�}�g!B%�����3�������w�E�?�[�^�6I�)�mB�
2��GE�OD���XW���>\G�H���e&�uh��0�+��|
�~��-���yh=#�1��cN% 	lV
6�����M������=��t(�� �b_#w
%OF�
�ma�@��)���PiC��������'���
]��|=�e�
�/�s$ ��F�N~�q�����8�K$P:G�CG>v����x����IPW�O�y�O8�3��"p3���\���[�nFB�����
�)��H@�I���������	��W����,�D��������nV��GB��|G{��M��+����>W�,�������ZX��Y�c)/��7�x�b��7=��e�4���gRd������OOU���$}�3����#�E�KxF Fd`�&	'�a�]v�	���B�i�G���$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@���_a�O��$ 	H@��$ 	H@��$ 	H@��$P �`��Y��$ 	H@��$ 	H@��$ 	H@��$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@���_a�O��$ 	H@��$ 	H@��$ 	H@��$P �`��Y��$ 	H@��$ 	H@��$ 	H@��$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@���_a�O��$ 	H@��$ 	H@��$ 	H@��$P �`��Y��$ 	H@��$ 	H@��$ 	H@��$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N��n��POY'�IEND�B`�
1s-threshold.svgimage/svg+xml; name=1s-threshold.svgDownload
exp_backoff.svgimage/svg+xml; name=exp_backoff.svgDownload
head.svgimage/svg+xml; name=head.svgDownload
#6Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#4)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Sun, Jun 15, 2025 at 4:01 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

Attached is v2 of the patch to add threshold-based sleep to
XactLockTableWait functions.

Changes from v1:
- Simplified approach based on Fujii's feedback [1]: instead of
exponential backoff,
we now sleep 1ms for the first 5 seconds, then switch directly to 1s
sleeps
- Reduced the threshold from 10 seconds to 5 seconds to avoid excessive
delays

When applying the v2 patch for benchmarking, warnings about trailing
whitespaces are emitted. I’ve removed them—please find the updated v3 patch
attached.

Best regards,

Xuneng

Attachments:

v3-0001-Add-threshold-based-sleep-to-XactLockTableWait-functions.patchapplication/octet-stream; name=v3-0001-Add-threshold-based-sleep-to-XactLockTableWait-functions.patchDownload
From 3dfcb99c8208d6c121d9e32231d1b111a498cbd2 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Sun, 15 Jun 2025 15:47:30 +0800
Subject: [PATCH v3] Add threshold-based sleep to XactLockTableWait functions

XactLockTableWait() and ConditionalXactLockTableWait() currently use
a fixed 1ms sleep when waiting for transaction completion. In logical
replication scenarios, particularly during CREATE REPLICATION SLOT,
these functions may wait for very long periods (minutes to hours) for
old transactions to complete, leading to excessive CPU usage due to
frequent polling.

This patch implements a threshold-based approach: sleep for 1ms for
the first 5 seconds (5000 iterations), then switch to 1s sleeps for
the remainder of the wait. This balances responsiveness for normal
operations (which typically complete within seconds) against CPU
efficiency for long waits common in logical replication scenarios.
---
 src/backend/storage/lmgr/lmgr.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..c81b2fbe849 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -667,6 +667,7 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 	XactLockTableWaitInfo info;
 	ErrorContextCallback callback;
 	bool		first = true;
+	int			left_till_hibernate = 5000;
 
 	/*
 	 * If an operation is specified, set up our verbose error context
@@ -713,13 +714,22 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 * as when building snapshots for logical decoding.  It is possible to
 		 * see a transaction in ProcArray before it registers itself in the
 		 * locktable.  The topmost transaction in that case is the same xid,
-		 * so we try again after a short sleep.  (Don't sleep the first time
-		 * through, to avoid slowing down the normal case.)
+		 * so we try again after a sleep.  We sleep 1ms for the first 5 seconds
+		 * to keep normal operations responsive, then 1s to reduce CPU overhead
+		 * during long waits.  (Don't sleep the first time through, to avoid
+		 * slowing down the normal case.)
 		 */
 		if (!first)
 		{
 			CHECK_FOR_INTERRUPTS();
-			pg_usleep(1000L);
+
+			if (left_till_hibernate > 0)
+			{
+				pg_usleep(1000L);
+				left_till_hibernate--;
+			}
+			else
+				pg_usleep(1000000L); /* 1s */
 		}
 		first = false;
 		xid = SubTransGetTopmostTransaction(xid);
@@ -740,6 +750,7 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 {
 	LOCKTAG		tag;
 	bool		first = true;
+	int			left_till_hibernate = 5000;
 
 	for (;;)
 	{
@@ -762,7 +773,14 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		if (!first)
 		{
 			CHECK_FOR_INTERRUPTS();
-			pg_usleep(1000L);
+
+			if (left_till_hibernate > 0)
+			{
+				pg_usleep(1000L);
+				left_till_hibernate--;
+			}
+			else
+				pg_usleep(1000000L);
 		}
 		first = false;
 		xid = SubTransGetTopmostTransaction(xid);
-- 
2.48.1
#7Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#5)
2 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Tue, Jun 17, 2025 at 9:38 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

Although it’s clear that replacing tight 1 ms polling loops will reduce
CPU usage, I'm curious about the hard numbers. To that end, I ran a 60 s
logical-replication slot–creation workload on a standby using three
different XactLockTableWait() variants—on an 8-core, 16 GB AMD system—and
collected both profiling traces and hardware-counter metrics.

1. Hardware‐counter results

[image: image.png]

- CPU cycles drop by 58% moving from 1 ms to exp. backoff, and another
25% to the 1 s threshold variant.
- Cache‐misses and context‐switches see similarly large reductions.
- IPC remains around 0.45, dipping slightly under longer sleeps.

Gmail does not seem to support embedded images, so I’ve included it as an
attachment.

Best regards,

Xuneng

Attachments:

image.pngimage/png; name=image.pngDownload
�PNG


IHDR�l�sRGB����eXIfMM*>F(�iN��������ASCIIScreenshots��	pHYs%%IR$��iTXtXML:com.adobe.xmp<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <exif:PixelYDimension>512</exif:PixelYDimension>
         <exif:PixelXDimension>2060</exif:PixelXDimension>
         <exif:UserComment>Screenshot</exif:UserComment>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
�0Y�iDOT(�j�&@IDATx���$E���"(9*$*�H%HO�dDr�J��D�@���$	� (9G��������kjzv'������<w3���]���U��o�E�(�P@P@P@P@P@P@P@P`D	�g�����n�
(��
(��
(��
(��
(��
(��
(����
(��
(��
(��
(��
(��
(��
(��
�@F�Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@F��#p���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��#P������dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�@F�Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@F��#p���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��#P������dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�@F�Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@F��#p���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��#P������dP@P@P@P@P@P@P@���m�Y5jT]�y�������M��
(0���s���2��e���k8������AP@P@P@P@P@�B���*{�����;����uk��������^{����e�^z���RK�}�������G�3\��{��^{�����_�
k��V�4?(���I��?�i����\��[n�%l���u����
(��
(��
(��
(��
(��
T!`�@�=\�7�����~�5���w�uW��|BY�:�D��������e�e����}f�E�i��6�1�us���[������qG�����qg��%
(��
(��
(��
(��
(��
��C����
(G2`�������N;�6�t���z��wZ�����a-�j�������f^P@P@P@P@P@��0`�ovEyF(w1`��������;�6�d���bH�/}�Ku��0��0��1��s�DP@P@P@P@P@��0``(�[X��H��8u��Rx����l��(9�
(��
(��
(��
(��
(��
T%`�@U�=Z�PL:��a�9�M4Qx���������V�?��a����L2Ix���\��?��0�3���?<������>��8��x���|�g,�_~����s����D~��f���r�)�o�^y����/���V�6�TS���SO^���8��J��V����&�p�0��3����������}PE�@���v����mg�Uo�L3�f�u���|�����~�N�+�wl��6W�BP@P@P@P@P@P�#:b{?�T�����a�Ws�=wQ�n)��=�P������g��|������	'�f�}������o�o����.��UW]5�;�n����1L<��a���
���n�m�������~;�w�}���q�a����|y:����������.�h8������a���O?�t�t�N~�D�����>�����~p$�c�u�	_������O^�[|���^.�����{���={���>8�WYe�0�d�5����^
�^{m8��������	T��5*�������D���;f��p�����.�(<��#
��c������Cf:������_�0?T�����m���v�4;��:����V[���[/����g����p�W������������	���L�>�l�#?�vX�s|��1�l�Z�[���_�Xn���D��[l8>��g�����x����9��S����k/����86������*��
(��
(��
(��
(��
(���!`�@����0@%,���/�xK"������{�������}��j��;��b�r�-�N.����N���n*�S�Ke��?�����	��~z�b�)��k��N�����`Z�_u�U���4�=:�r�)����w�-������:(��w���^�@�_���j���#�{��g�`�	j�j����w��V��l�N�S���v���6��a�-��pZ��U�3?�$����*�������'����3������x��_~��EE:���-�X��/~�Om�Q���qO@�w��������L'0�, �M���[n	�n�m:���h�M�}��\���C�����f�r�!
�QYv��{���sY�zq,
0���Q�6���{P@P@P@P@P@���>Tr�{������IQ@��_|���������M+xc����9����������.������;o�"�����r<�HE0�hy���K=�������g�IEP��~p�gZ���h�������z;�h^zo���v�[o�U�=O�{;h��n�7�#�<���^T����@k�VA��n+��:������b#����V�m+��R��X�{�Y\pA��8O/��^T��q�}U@P@P@P@P@P@�qC���>��c#`��c�)m1�
�g�Q�����U���^c��w����%z�<�NK�`��7��)�
T��Dw�tA?�D�I�W�#Xc�5j�����s�5M���o�K��v|��7�����v%(�s�m������*�����G?�QG�c_�sC��B-T�Q�=++�7�n��������y��x��b��w0���Vv��M�o9���s���j�8�.���0�,��YD5�t���1�AR��A�������*���	
(��
(��
(��
(��
(��
(0�����,`�����������>�P����Zj�@7�Tx��Oj���3�:c���'���.[t��0�����*�|��p���^��;�����>Z�_������z*�y�����?���4��>
���~�����-*cc�TB�v�i
��	TX3��1�����<\e�U�+�������_C���k�-��g_���@0����U]�m������]|����g��a	�<�L��������>�`����$����_�*�7�|�,���e�u�]a������Zi�������}��J����x ��o+*�	�'�����+��N;mXz���Y����.�0;71q��q����^0���c`�mb�e�l�`���V�m�]tQC69���5�TSC�0�F��;����_�����ci���N��*�9���
(��
(��
(��
(��
(��
o�|�5�6�1``�)�(����Telo*��TVaG�\*�cjV��{��}�����f�iZr�%�����I������1���a���|�4�H+�[~�v��nxM{X{����{�]7������iC���B���w�1|�����SaM���i���+�1����e�����.�����J�����
CbP�{�a��T\x��q��+/�n�iH+�g�m�bh�I&��6_|��������mv�SQ���}��SA1��~z�g�yb�j�l��w�]����w�9l��&u��}����/}�n�>�m�@�
�*���r��6�}'�pBC���b�����n:=�����+�(�����@i��96���4�W@P@P@P@P@P@��/`�@���^������nQ����_�B������*{��[o�Z|�B{��6k��@�TVy�<i��O:���������N9��Zp���_k�]�!y+��D��t���}���'?�	o�J�p��<��=���~��F��O���,�Lm��?������>������?�V1���r�-~������������~�����Wz���=O��^�=���T���x�k6i��C=4�T�'����c��v*��>����
��\��&:Yn��6����s�9�!w��sO8�����*������o�p	�r��Y8]P@P@P@P@P@���}���"`�J0���7-�'�|���z����*��������%*������������7�x�x��y�@YE��7�\�*����]w]�l��j�������+�\�����7��M1$B����l�����������ei�%�3�8c�W_��W����^L�����Yg��y�M ��Jr]���h���_�jx����O8��
�����l�F�f!Osp��W���n���s��0@kuZ����58����� �����N�@3�N���������2��C'��r�r��8��%�O�x ���Px�����l��K��a��]U�\
�DP@P@P@P@P@����k0@��7�xc����(�'I��h���x^�����m5
0@�t��,�R<����>�]oVQw�gZ��)(���1a�V(��bb:��,7M���;E��n1�����/_|��:T�e��i�Z}O����>Z��M�@Y�
y���l��_z����ZH��P��T�2E/Z��U�_p���?�a���}���n��V���x�m�`�-,�����f��u��V�m��8i%����E
����R���r�-a�m�MW��p���m���P@P@P@P@P@P`�0����Y���w�u����{��]��)
��j���s�9��Z�<X��y���:����j��?�1����4�T�_s�5a�)�Lg+�����v�M���^{����������SO�����o������t�k�\�.��|�d�Mj���������v�V����{.|��_o��s�=7|�3������$�E%oY�z��~���.������C�U�lS�-}�d�Uo�L?����J+
����^���~.�����^K�
�j�k�P@P@P@P@P@'������Z�RF��NS�?����a
�����.���%~��'�E]4�I���@zHA�#O�@L�G/c��������O��w�=N*^O<��@bj��^b��y]w�u�#�<R���������r�-�Nv�y����{��/��M{����+C����	�hV�Ko�
���_<�t�I����F�������N%x���2���x��M-,�6K'��z�������K���DK}zD ��X�U���b�Y�IP@P@P@P@P@��|_�:`���
6��A����_}�+lZ�3����.�� O����:�Xc���>_�� �9�,`���<�u�YE%!�1�J�
7������z��@�{3�k{���i�<��b�b~x}��g�t�`��! �(_b�%�I�=CH�
<����
���z�o���W^i�>���mc~*z�y����26=�n�����"��Y%/�+yO,�J�C9$_\��9ustR���T2���V�my�����X 0��<���4� G,��R/���t��e�^P@P@P@P@P@���}�{0p�i���Z�N�1����w�h�O�z��
�e�]��o�/����7O����8�\���l��.����y_}���8�1���lz3�{����
��_=��o��V�;A�g��v�f�m�H _X�1��v�m����6�6m��~Ip���;�#X��C
����.���t1�{��?��#�����Gyd���?����4TS�}�4��YOC����~X�����uym���1�I�~]��|�d�Uo[���&�2�,�s���n�$Mc����Z��c����f�F��f�[��f�w�
(��
(��
(��
(��
(��
O�|��:`���.
��>{���������W��U�n�����C�_����q���\*�w�y�p�M7��#�����"�SY�SVA������C������k�TSM��R�>ma�jGZE�y��1;�W�N�o���vXl�������'�|���O!jj���/\�Z���^+�NJ�i��&+*��!�q�l������]�����N�5O;��C���������o����Z72k��Vx��j�?��Oz����>V��U���G��45s��(��a����&u��*��}���&�9��|���R>����!T�>��	`����Q�FU�����P@P@P@P@P@P`x0�������^q���;����n�w��t�y������
��.C��w������^T
3��O:���l��f���Q\���N���/3I��TJ���7c�������^.�����
�����;���O�<P:<E:O��	D����KLXy���{�|�������EY�a���x�����JY�x��G�m���{�������o����E��_�j�6�l1��7�8��b���g���&�����`����s�������O�!UytR�����s���j��
���_�2�t�I��U�m�������n3���8��>�Z
h���z������
(��
(��
(��
(��
(���_���>���X{��zh�����G�(`��f���J�l�T2S	�.����5�����q�V������_�R>n�~����?�!~����������`�UW
���f���,�9���� �8�[l��v������0�pe�o�f���-U�V��y+{��r��6���/K��<���a�	&�.�k�,H{D��Xj5`��c��m�M���
(��
(��
(��
(��
(���W���>�w�*]7�l��u�`�gh*��DK}*�����e]���i�����I&��h)>��36[����L3�4����j�������i�s�9�����{�._m�����k�8p�a�5�����7�^zi8��[�����*?�1�|���P���ZI�����������Z�����������06����/0�i�Y����b��!BZ���m��z��%,�|�����`�������>���f�}���96������FP@P@P@P@P@���}�{0��/���E+�f]�3����[T\����|�KU�@*�G�]��� �p������OS���9��sJ���[�}��7]L���+�,*��/�D���,������v�i�����e�ac�����������@w����OX}��[Z��1c�^{�����7�Oko�Rhu�X���&�������%�X"���TC�{�����0�JB��C�oY�+��:�1`��mc�����r��kn}����C9$��q�*��VXw;�F����WP@P@P@P@P@�����[��;�!����^x�����v�e��
���{/,��2u��%��������SNY[]�_s�5EE>-i����e���a������7��~z���~V7��������/�"L>��u�����E�`��/����lP���a��w�l�I�X{������9�y����e�]�O�}�G*0Za�e�
N8a-�
���v[�_����8�g�_��W��Q�=[P��'*���������_<���:a���+���������^"n��������f�i���n���b(��'�8�u�Yu�hA{��bz;�=���W_���=��3P)]��Yk����0��~�b�@� �}�
���1��6�����*������q,m��Va����{����o�Gy$��w�+=O��Wu,q��!8�D��n���N��o���r�k���
(��
(��
(��
(��
(��
[����M�im;���Z�������
��Dkr*q��b�b�g�y&���+c;��_	��u�Y���Ozx��'���>�X��JY*8�Ag��C���~���P�>�l��b��<g��Z�7[8��;o`8���G}4������c�u���o�@��UnC���(d�w�N��c��c��mn��yP@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@P@P@P@P@���='v
(��
(��
(��
(��
(��
(��
(��
�����O��
(��
(��
(��
(��
(��
(��
(��=0`����@P@P@P@P@P@P@P@��0`����9R@P@P@P@P@P@P@P�����(��
(��
(��
(��
(��
(��
(��
(���>1G
(��
(��
(��
(��
(��
(��
(��
�\�����P@P@P@P@P@P@P@�O�����'�HP@P@P@P@P@P@P@��0�sbW��
(��
(��
(��
(��
(��
(��
(�@�	0���)��
(��
(��
(��
(��
(��
(��
(�szN�
P@P@P@P@P@P@P@�?�o��#P@P@P@P@P@P@P@z.`�@��]�
(��
(��
(��
(��
(��
(��
(���'`�@��s��
(��
(��
(��
(��
(��
(��
(�@��9�+P@P@P@P@P@P@P@P����}b�P@P@P@��7�xa�%��-�\���;���������7���
(��
(��^��}�?P����g�;�%����t�I�<��>�����C�����tK��
(��p�r�)�L3�x}�����/�X���/���a�m��e����|p��oP@����������{�2|����<���7
(��	'�0�0�a�������K/�T�Z�o�����������O��n���<����=��S����	xm����H`8���]~�\������������7
�#`�@;ZC<�����Yf�0�����f�-�?��E�xP����W^ye����8��^P`\�c�9�z����`��'�|����{��}<�?�<���a����7��
(0�6�t���RK�����og�yf��o�W��������k���������f�|��O~����g>��f�b�}���B?�x������?�����[n����O�/{���<���*a�u�-�"b9D�����n�)\r�%�ED_�W�?@���k�TSMU��}���u�]W�<���C|�A����:�8����o}�[a��V*f������������Q�W���b��9�L�������=.\o���)0�����c�X�k����Q���G}N?��0z������7������.O=����[3�{�����Q@�Z���w�1l��&-e�������kx��GZ�l�d���w}
�����������2J��{��G�s?�)��������+�\��9���<�p�	u�/��rXm������y���� 0��j�y�
��sN[���������� h�����;{��a��gn6K��3�8#��I���
�k�l��P���������a���������������.�������g�I^�k�Q�&0.�k��7��gl���z����������W��q�z��W�R�����oa�D"������0��f��}�]vi���M4Qm�����.��������
��U@���>�8�����V2���o�}��7�p�
��>V�1``�r�2��@^��#��V�;��S���B�V�y����<��0����;</������*0��������z�����>�@���K�K7��$������@�����>.T`������5�X�����i�7'*���xm���<����b�_��3N��[u=Pj]��V����J�i\�����{�J�����oq����h���f�Zqr�@��s�9g�<G}t���4��u��V��{�Z��S@����[n��f��M����17)�g�y�������v�-�������)�+W�/�p�~7�0@N'�d�@��t���+�}���=�|�,`����*rEk5�(K��T�wD���^X� �sw�<
���t��w��6�,��I�V����{\����?q�|����O�����#Hg���k{*���.0����:��z�����R�^����k�t����m�=�W`�*��;�x��4���1c���:(\��uKXs�5��{�Y�\�/x�_g�u���ul���V���~�_���l
(����k���.m��_������g��mAQa��'�x���`�/���~��C����
�}�N�����(0�;_�p���C��la����-�\Je�~����SO=�6��C	_���j�yC���~��p�W�� ��[z)`i����e�]�N������;.T`����	Z}��k��8=}�f�i���_^XT0����
�d�q������V�����(�������g\�����g�B����Poq�3�0C��@��n�m�b�-jK�����.[�@��o|����o~��=o��������K����b�����EL����Z��������&����K�EY$ps���D�=��c��,�u�5��uO����_\�SN9eXk���qLg�q����#��"�<������O��_�.>��O�O|���_,zp��o~S���Z:,�p��7=;l���u���������~�n������E�K��NS@�B�.dG�U��+����Z�l<Z���?��������1-)D��9���S\��NR��s��{��7�w�}��[n	�y��v[l���Mz�a>���]tQx�����}��|�UV)�����7�|3<��������o��;����P`���y�@��0e�,�LX|������9��������f�^��O�E.��a�|���������N������p�{x��X`�Z������9*O�������KM[vr��q��{x��g��8�2�1����G�.ZA��_+��b�-�u�]����m�s�f�)�_�����f���nP��5*>���D�=��:��\�X�K,�Da��x����[�e����v���;_�|5X�@*��g�yf�[a�������_|�n���g�4��������i*�&}��W���0Mw�yg��w��N���U>0<g�xVXm����)�/��:kx���j�S�������'
��[������!#$�nx��9���n*=��U`�@�������+�
������zC�	�>���j�}~�I�0Bl{���-f�R0�����ki��g[��U����i��@/��(��������1��U���E���~h��q�,��z�4#�������a���K�L{V�K�~��!M���������-��
���z�w�y����N&&�-T��������u�Q�,���.����5;gw�;y�$��x��l��pr�00`��w���X�D�������A(������>�(�kv��.��u����+���z��������a����M��i��V������/�j,�U���KQH��� �������������a��'���5@IDAT�^�������
�1��&,�H!%]�q�����'�_�������+����@A�)��R�7��l����7a1��W�
�sL���
(0���?~�����(�"�j��+��\��y���*��\�8����t}�=�>Z�����V���:K0�@����?���BH�1���7]�^\�����>���|~����������a
�hM[�(L����^}�
6;��s]]����_a���.
`���{��<s������=1���q�t%L�21q���+����N��c���V[`�{*���H���7�X�f��[\[6�?��O���Z`����Pw����J�A����c _��G��`��vP<��C�J�(J��P$�8�����E8����I
�)|O����!��h���~��<&�VX�����6���J���|8��=�Gyd]��]��s�a	�)�����+
�K�'0�
�8�H�]�*��Z}�����}<�5K�5��<`��k{���n_�>�6���>�����1LYFz�_&�pE�mS1��*��;y�!����A�i��$�)�������jm�6����v�Uji�MU�@�2�'�1�~��W����4Mp���L0A��5�Ac�g�}�r�f��N�/���Y�������A��i8
0��{�($��5&
)9!?���q���������f+���Dr���N+�B4�h��I�X.R�$�"i�JO	i��+�z��0@�9G3�<sm2d���V��x���h�|^?+��C!PV�O�6�(�%*�hI-M���Y�0����`G+P��1
0@e�:������J� Av�+&"�)�"@��Do5y�|+�s�F /,`���RA������65Ppj�L�Y���������{�*�9O�"`�����}/'n��������@����/~���A�����x��w~�����
(����Bf�u:�+B��Ak����v�0L
4�����?�i�*z�!`������	48��sj=
������n����5�a����w�4����I�w��Y%_O����O�;�{��!o��<e�6�m���O�uv��*�A�y�����-P���M�L</N>��E��l��� ��l�M]��U�wR���
Nh����'X�|��#�U�sR�.��������g�t9������Q/A�sL���{r����4LB1����R�AO=Ut�,I~��zk�`<�|���^����4��]�R�@��o��F�u�{��]�p�O'x��$�u�;�VcK�7�#�h�����:�m�]�����N���
��{ �.aYc4��!
h-�z�KXn������H�y����>�@H�<1q��+������*������w���U
���\�&Z�P��i��ID7�]���Ds\&�h�����>�����j1}�����*mh��u�s��\C�`�$�~:&���&Mt�M7D/��R��7�{R1���8�W;yx;�+�j�!	����SHt]LaSzOI�-Sq�+b����/�����o'�����W0��y��N(�
�\�]��<<�����0@�<i�5���������'
�_��
DY�n�2������q��n��<~�����]������r���J��9~9?�2�,���2����]
����{w*<r2M��C�/���D�� �
������a�sB�p$~�����4P���)�Q������Y%������r����r5�9���i�t%S;�^K��=y�vT��h���-���"by�tT|����^M�s&�3���E���?�����?�s�8���:��o���/�9��&����3CP��I~�r�}���u���;\��(N�wGAo91���:u�	j���6����gI��O�[����p0`���'�&m�x������G1n3��@��i�
�fl�<��{"���;*���SD=8����`C�B�� 2�.��BU�v�}�������)N�x��>��u9DP=!�x�Io������>�La��yJ(���q>n�(h��V.�SO=u�b�Em�oP@�!�����4��U�w����I�y��������n���"��i�s����#("��c<��7��6��������X��`1/`g<��>���o���zB`�&�yx+T(�b����*����o�[�A�Jc���$�~T43���1�[	�
�D��M[�z���=|UU�����:�ZF^�P�y�
D���?c��AK#�C����/�9�7+��7������t�2��>cUu�m�ud
v�*+n0�qK7���9�M��%*
���4)�����:�}��l����8��3}$�g���e���!4Ie�0��;�;���6�i#*cx.����
���:���?7j��b��?��������U=��e�����;��x�C�Y�� (k��X�A@$��1�0������W���Ct�u���y�@���E�����N��$����=E���QU��q��<�T����x����&z#��$-��{���[�Z�o��v>WUD���tHzR�G5A_eCM�����X��e^1QvEi��1�i���g�~��Z6��7
W���+�.�Y���

"|��
l�D]V�x��G7��qv�L��n�c��8�������`�%~�Z��p�K#���_�����}�`CKOP���{��!� ����4��Y�������o>�)/p.������(��WP`(�(���/5���c7�H
�	���M���5�|��KS��A����@<4��1QH�a��.�y�%M�q��$�9�4������t�o��A�kPL\��e��W��@~��������1w{��Gq���97q�$8 o�A�DZ�Q1��|�����s����[���V����,���W0P�y�����P�A�.��1��C�������J<�����@��(@d��D/�����|����Tu���:2;_�0@/Tp���%��'*�HSZ8�N��U����������x��q�����k��6Ba�k���V�\_�4�<��d!��p��rK�1�� (�g��zD�xi�=$�B�T��J�����?T:��Z��]IS��i��e�x��E�J\��N�@���n_�>�6���q_��E����?�z�d�F�=���H<Vu�b+�8U���>�Y(�I{Q�n��wZ�S6�X;���v�ZU=�����s�Nq�.K�����_�P'����[o���������%��zk�`�����"`��0�SD�QyAV�$
�h@�G�Z�3^�X��)]�@�)<�����tLC���o��4��?���f�(���W����o�)�M��<����^
��D%�
7�P�mQ0�������+�*��)��,���8�WP`�8GS�"_���*F�w��vs�,��O[n�� zz�E�M�%l���B0z����B����`�Hk��MS�f�N�A5)�@�������5�-�\8��c�6l�e�-��X`�����Kz)� �J9�Q�G�t��}+�����{�*�:O��*�*N��z���yok�k������.�.���X��c��c ]��G��`������bki*P)�eLU��D �j��@�Ll�x�������G�|R1��7�Q��F�����������=8ib\�)"�����������6���8�t�����
�li%`���=�T������]F�g)�k�|�)���gJZ���O���V^���*����v�����}�m�����@/���1<�pC���O��4�	p"�T��q������3N��N�������w���G=���V���:=��uVQ��jB��p�t����r�x-���p�1q0�@l�3�9;�����%��zk�`<|������~��
�
������!�7�k�D�2����2?]~�{�~�r�W
$(p Z�,u0����o��;�4Z��?���K������{���`�<`���� �*�{;Z!������x�$b���
���"��D���u��9G��3�7iZw�u�#�<�N��@��)��$�r�)���|���I��7�\�)�7)���	��O��M7#yb����.P1w�e�c����3��T��n�
��E{u_E�@U�i<��@����cq�Deh:t����iV�TV ��&����e{��a�e��MJ+��:j����|U0�
��<��^���g�4����|��V��<
�"����Me�(���e:T��=M�y��$LK+��L�	+���C��)oQ�T���sH�mO�C��xS~�!`�F5�[���)G���w^�y��C�<y�v���v��*�A�y���f���y1?�
4�PY�F|����8��V�q��������p>�q��Yc��}+�e�N��q=���z z��C��<�������3��1��lP�2�p����g��n��������z����m��Pt����T���&`�@���6�Ce<]�S(FW`\��D�8��cj�����
��4K<t�=�k��N�J�b�i"��`x`�"��(��/��!���;nV��H�	F�)��P�"���a��I�������
�M<<���AU�~���N���/������/���[�C~�N=��(����N�aGuT��yk����1c���i��l?*�@��������~�������������%�G��^P��{�*�:OcSE�@Y~��?����q1Q�����@�Y�Z~,�,��c ����)�c������v�}��2/U%xi����M"H�c��@/z����BC��C�
��4` �kEZq2����ys�]w]���Jo���T���iV~��"�
%�~c����^����<�M����Z�������!:�:��������r�T��w�5�O=�T������g�����6����<��������J~�}������I=�d�;1�3i������D}�
+�~ �����cUe�n��������Z���d�`����R������p�SL1E8��C���t���<Nk���n����@�D[���u0@W�Gyd������������+���Z��%��ib<��a
���SY�@���3�<!�,�(.�WP��Ze�t�I�s�`��j�����/�X�Y��HT�
y��n��4P����Eo��]W����jZ��������cZ�����zzt��?���gyx^����`l
3�8�9��n]ZIg��=|�!S�@���:O��*��3PObyj7������c�e�F��`��V�������/������|P4R�u���>�������;��3~�U�R�^<,��"E�^l=����!���g�I�^"/����F'�r�>WQ�Q��
=�63I���k��b��E�{�|���j�h���/���j��G����ki���jT�
�����)���b~N�o�!��RY.=��]����<�T����6������7�8p.k�Z�/���|�l���V��8_o�����3���3�\<s1�����o�Ii��8�1LAPELU�=�uR��O��hd�`��u8	0��{k��g@�D���w�?6��]�O<��p��'��m���j)���n
��<�c�U=���o��];
 R��i�0�/��������f�b�����g�Z����-�2&Zb)��^LvP8cR@�M��^zH�cO<�D���S�����4����.����sd�9��o'
0��~��+�������I���D�>���X1�O��
�^ /�e�@�5��ya��+��R��3�G�a/��R��R�fn������.� P��'
�(p�)
��<���(��.��R�r=n�\����L��e�V��0�r���1����#O`��UY��=�P�@�sqFZ�m����c����t���1����t~�+�@/�?��2�� ]��9��H����*��
&
rI�����Z�{UT`�y��Y�a����f�����ex������
&�sb�'*�bJ{f�"` .��n������}����m����qC����f�.��*K;��C��#��uy�����z�<������hu?��3���{�����s�Z�Z�/���|��z�<�;���������qXi�7�|�������{�4U0P���I�_?]oS'�[6�����������C$V<���|�0�����L��-v����6�
�42��G��0P�?"���5
Ph�#��iJ�JL���Z�=4��g�f���e|�7Q�11�5���)=�����g�U�+
�h�&
��^Y��y��~���IE�Ai��Yv����:��'/����������w�����	I���Cbm�6��3�<�p6�5�n~�Dtv*���V�@�	�o��VE��t:���p0���g}�9��[o-��L��{z�����������,;`=�;��Gq���@Te�!X���<�q�G�M��U���$���1����#P`��UY��>y�@+te�
<�3������&�,������
��w�*�
��"����#�����g:s�M�������r8��~��4�EY+\{x���n�i�I��#�K��U�6,��������_>�}�4j�������H����t����}0X�����/P�y1?����hXG�OZ^N��I@�����g�<����e�IAL�Yj%�e�keZ/��&�x�b�������0^���c�"P����GS�u-��)z��k������2��t��l0!������W�/Oy����g��w�}�.�SO=u8�������*��'&Zdr���q���Bqz;e��[�S�0z��0�4��U�I�j��a m�I��4���[l�E���������,����t�H�	�����;q��5VN�y��f��<�W@�R �@&/T�s�1�q��Jt2���EY|�`~z����.o���9�.�i���|�Oz���T�hi~�_�|��������'j=Mec�%��3�$���z���]z�I�N�;�H�z���	R�+0v��^P���r_��`2�L3=s�[��z���=<��[s�'���{��e������`,�H�\�y���nz�J�i�]�V@�?+���@�����{��u�
*zj!vUM�S�:�a��c ���G��`��*���%`�<C��B1�����������L
�U?p=O{>����11��B/i�0��K-�T8���O�Wz 89��2�t�g��h@�f����g��
i�C~�I&�`�p����U,��3�Zj�M�@���n_�>�6����!P�y��.;��+W�K������h��,������.�hQ)�>�x��E�y�������t����+N�������m�����y��@,���_|q��%�W�s������� h M�=�1o�^U<K�������(��p0`�����<d���1�Tf3���`��`�#�GE
�i��,�.nb��w�qGT_�������	�6b<P
����
Z�����V���\��D�Z5��A������>��`���������Y����~@GY�g�}����s�
(�/y�v��c�=V����=�s�i���Mny����Zk���\������O}��b,�4��L��W0@�!�Og�u����������!��3=��O�`��f�����u�@����ri%K�E:��
&�yx/����0�~���T���1|I��yLo���{x���2i��J���K��i���U��Y����Z7�
�8�^w�u�X����Jz���g�x�����`z�a��4�_��w�bRU�Ui>}?�;_�=�s��I�������!��NE)e,��{����K6ts��c���������U>����1Q&���&9������r(��P~�%�c=��ye�f�Io��fQ�r�7���HU<���u���������;�I��	������	��Z�������!:�:r�</6;�9�1d/����S9���s��~��G-���?�{��g�fy���V�k��� ��b������F��<��v[�8�z�4���t�v����������|��G���@Y��i��1�m���g�~���7b�`z��~�	0��{��Z/v���o�"�7�-��+K7�|s`�"R;���H\u�Uu��-?�V0�j�X��D}����b�7���"%��]�<*R���b���H������~1�������{-�(<1)���,@o0��f�e������t��9�,ur��:CTtz.[v:�@Z�4P��0�8Ad<������|�D��z�&>�~�5�
�}����G�ph��B�Aij���{x�?�t��j����Tq�f�TR����n��(�k���.��*��-���u�Y�P`��
D�:����#C`��U������Z����*NM
�*P��-C�����~��K=e��g-�{{�������f����U��R�T�o��O0@e}i"��
���+���E)�����w{-������}PE���#C���"b��,���c�Ej�����='p�N{U+�9����
��������M������X����h@��SO=���M�W�fX�&�J���i�sv��U�*�%��zk�`<|������T�L2�$-��.eo����j���h)��n�3u0���^z�b��I'�4.��������,`����pnR�������^��s�x��;*���p�$���
!Z�+���v�nP�D7m��P@�� ��)�CiW���.8�@O�-���9�!x��Aq�D���)��i����e+]��Rq�w�A:�����5{��DO9����C#���"`�-�^������������;�j������\X���]�S0��n��q��3�YYj'`�g,i�<X�G�������,�����ud
v��E������p�v0}��o�TL
�+P��=N�27�n�y�1Z�R�S0�t��)�++C�����6���@����`��>���j�}~��XV:�5�����	`��^K��=y�vT��a9U���0��t���]�J�|zlI{.����������������g�Q��Cy�!��b�D}�Oi���$C0q�[R;���n���DU�@����������L��@]M��*�����y[	h���g�~��Z6�)�n�=6��+����\��:�[o�����L73v���=��'��#6<���.�������k�
�kZ����O�O<1��V�S0GW�yj%�7T�s�f���n���S�R���V�������57c�B@~�MQ>*7�|��������!MD+Z1���^�]��1
��&�F�Y"�^_ZmI��9�.������tx�E���
?���5�\�����@����V�+��RC� �d,�t��������H��)�d�<x���I�N��C-���9������Z��o��cD�+����U]Lr����6�#2N&-7�
3��7�#��r��j��2�+Cy��H�_�|��;��q~���zT��<����s0��$F@��,��������r���6�������M�������������-�	�}�����x�@w�l{��c��SN)Z���Uq���������|�}C���7�
�����C�l�����$�*M9GPMA�`������G�@U����&r=I�-�\~�e���������<�)O����:���h&���!��yb]3�0Cm�v�mW	Z��o��CPa��*�U�e�9?�l�����[n��\���=E���<��g*��b�
xf����^K��=y�vT��h��������'��F�������`���,+�����u����|�N���s
�G������=zt��>M��7�];���b��~xq��s*
#i,�&�W�k=���4O����M;^�<K����������p0``8��$�<�0�2H����"�������������=�[�G!�<�W�����F����
�v��CCpsCA��O>�p�/2������u�����I��.���4P��J��~>k����w��$�����:Q�c
�f�m��<K�<7������5Y���s$�{����y�!X�J���W
	��2��+�D��@��z��\(D�����
(��
(��
(��
(��
(�@�0�/{�|�u�<��Hs��&h��!��4�g�41�#�dybX����O�q����Y	�#G�^vP@P@P@P@P@����io��J��yd�u#�gi]�u�+�k����:~,^n��giI�'Z��}6c��P@��(�9r$�u�YP@P@P@P@P`800��y���>��S�i��
n�������7��xF�,�H�b���q����������
���#eO��
(��
(��
(��
(��
(���M�������o��.�l p����%�(`X��N;�/;���2���������]w����gP`D	x�Q���U@P@P@P@P@F��eV{'0�D����+�9����	&�����=�Px��'���r��F�g�����g�	�=�X�����[o���'NW@F�������PP@P@P@P@P@�a&`��0�afWP@P@P@P@P@P@P@�*�B�e(��
(��
(��
(��
(��
(��
(��
(0�f;��*��
(��
(��
(��
(��
(��
(��
(P��U(�P@P@P@P@P@P@P@����l��]P@P@P@P@P@P@P@�0`�
E���
(��
(��
(��
(��
(��
(��
(��00``��0���
(��
(��
(��
(��
(��
(��
(�@T��2P@P@P@P@P@P@P@f�fvP@P@P@P@P@P@P@�B���*]�
(��
(��
(��
(��
(��
(��
(���L���a����
(��
(��
(��
(��
(��
(��
(��U0P���P@P@P@P@P@P@P@P`�	00�v��U@P@P@P@P@P@P@P�
�Pt
(��
(��
(��
(��
(��
(��
(��
3��3�
(��
(��
(��
(��
(��
(��
(��
T!`�@�.CP@P@P@P@P@P@P@�a&`��0�afWP@P@P@P@P@P@P@�*�B�e(��
(��
(��
(��
(��
(��
(��������(8�H�9 9$�D��#�  Ir�99����HA���$���$9�������m���v����nw�����f�g���oP������*��
(��
(��
(��
(��
(��
(��
(P��E(�P@P@P@P@P@P@P@�L���.�a��
(��
(��
(��
(��
(��
(��
(��E0P���P@P@P@P@P@P@P@P������*��
(��
(��
(��
(��
(��
(��
(P��E(�P@P@P@P@P@P@P@�L����aC����s�P@P@P@P@P@P@P@��x����#�������0��~�
(��
(��
(��
(��
(��
(��
�������vP@P@P@P@P@P@P@zP�=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;��
(��
(��
(��
(��
(��
(��
(�@
0��;�MV@P@P@P@P@P@P@P���
(��
(��
(��
(��
(��
(��
(��
���=���dP@P@P@P@P@P@P@�;0h�{����}/|��W���_i;�\r���f��9��#�~����.o��f��>Q@P@P@P@P@P@P@zA���^��=��l��Fa��
��>{2dH0�����C=4����N8a�����LPR�����Pz�mON8��������H><�(M��
(��c�1F�t�I����>�]����M6Y���������~�x����>����?��e��2u,���<�8��i��6L1�Y��[o�U�';�'0������.�������One���[�K�s�0�4����k���^n�����U�V���w���\�N9����"��@���*�Z��8�8���6�����o�)n��%�?���s�"��s�n�e'�S��)��i��&
������������?����:]���b���SM5U�����{���Y�����n�.r�
(�@I���Ew<Ys�5�*���ge������n�u|�Z��.�	����e�|�QG����*�;�����C�K,��~�_~y�-!�����g��O?M'�\hJ`����l�Mk����_z����{�mjY��?�AXi���<���h�a��������]w�{����O���������;��������U������
Y��#`�F���{.���
��w_��_�Ru�����^;����2�,Y��|���������\\��t�M���/^�����i��_6�X�~f9�����52�Bf�'�x"�p�
u�����q]|�n�"4����_�"�9��%:�����|0�z��U��&�|�p��G��[����;.��g�r�d]:�l�e��8��>�/��B�	�z�������f����>�������XD]��_���y>.�w�i���r�~��p>�q��s�	~�a�\�#�2�����,��s��x�6uY���E�]W38d�
6���~�!h�y���c�y�����xL����s��g�9�\�k��������_�Uh�q�=�#cy����a�_�}l�:���v�!8[u�U��[o���������8����a��|T�S��#Xw��m��6,��"�6�����Y�u���'�|�I-������n��%���
t���s�U����e�Y&�\z��b��|�SZX>�p�
�{�Qq�c�',tv����^�.&�i�����n�[���#����[n�0�3:�/������Gq���6n��H��O>9�5*��>�g�u��Sm���*M�!��a���Zk�����������??�u�YM�1
��X���d������W��+jY'�xbXz����O��g�y&����L'��������g��4+P~%��x�����Tz���ri�>�z��~|�:������W5�����?�x�������1�H'�����L���@��d�1bD8Vm������. H����?�!����{����s�e�]�������������b�pl<���������N������l7{\C���,��K�����������C���z��f�f�XS���O�1�|���{����c�B@4�{�&���]� �9v���u���i�M���d�\j���j�}dm��]��:�m�y��k^������#G6�TT{@���:6
�P@�.0`�v'�t��j�R���Fb
6���<�@���^y����t�0�B���n����u7�g�@7�5�Y�� �;�T��%_�
�j���l����8F�����i�)W�K���������v�u�lDL�>��>4��?��{��:��U���<��,}~�Y�����4zia�o~����#�����E.����kF������~:l������_���(p�1�����Q[�MG"�V|W��Lo�w��Z�@�
�:�V^y�>0��R�pk��P�l�����|!��t�Fs��h����tz��DF71-(T����r��H�FK�������X��6;wp��.�������7�x#�Q����\$���w�iy�v�q�,�4��j�Y������%PT]�9��^���so�z��	�!�)|�5�l8O���_���~�-�@�z
jtls}��j�^�t=:���u���}�Y/��rH�u��c!(��gQ�[��#�V�
�92-������ena����>;�J������>����f�1pP����������?���k�e�0��{�����J�����i��@L?��0�	{�uP`�������L2I��j&`����o����O�K�i�i\�xGp�n��*
=�� ���3�Y�B��J�r#cAl,�����w�ygv_q~��g��96�����6PF�u�~=�P6��5���q.���P,�S����=-E.+m��a�j�_���FG]���@q�M7�+Q��4p�
~I��(n��1���F2���v|������!P�o��i�������>����������������,.���kd�e����Z6&�FJ6r_���K	�����t��E��K.�:v���.��jt��B���-cxo�cY\&��9�p�%?����?�Eq[|\����H�N���rm�^{�h���{�o3�6�Q-`�?���>v�@Qu5�$e�IDAT#���Y,����9��L=����c:
���N�F
�"n��w�����k��	$�k����K.g	�k����B����_~�Y��{������&��w
p
Gv
i�	�g�S�/	. ���@7
4SGp�����t�L������55���]�2���'���V[-{�&��_Q�|T���8�A�,
(�@�0���p��7�FP���E�PG�Y����N8av��|'G����qdh��E�e��t���DI�Q��z�e��hHN�j�6��4*��
(PI`�e�
�|�?s�M:nh0�40�6����z�e�B}>��?��O���q����'�<��}�I�I�S���0����n����c�����#��8B���o���UzM�(_��F��	�N�|! p��6*M�31f�ab��by���JF��j)j?s�&�@,��2_�?-��������]���Y>�V���+�y(
p�`�/�7�w6�K�A�O8����,�t]��f��I�_)�#&�2dHF�=��7�>�O�:��c�T�uq������� K#{c��0����N:������1���=������yD|]-`�?��h�coT���Y��[�p-����g"���z�h���p�
���n�9k�<~;�d��,�����c����x�J�h�:����N;o"+M(�G�^{���u��kY�'b��5�\�8���g��f�6�6����o��/�V�dZ�q�����Uz]T{�o�o�Y�J��tP`0	0��{s�M6����H4o�{�60��=:a��2�'2
���nXt�E�F)pQ����SN9����'��3Ov�N��xa4(|����*��3�����������^z)����.R��S��i�~������t��4�)��A���MO<�D6��u"-t�q�(������TZ�pb�c! �u�>���16$�I::.����q|�h�,�Q��W�
�R�S��Qf��hlNP@�&�o���9����?�)�h���~�-�����b�������3�22��)�yh��X��,�Rg8�G������RI#�M�O��K����7�Nc,���E.�\)C��oG)j?��j�'�X�pL$`06hp�;S��].�N�^�"~.�`��o��*��1C)W��D��U�3jM������.�b�\n�����K�z5���#��t�L5�T���;��X�����X����%@���/��,���56�c��(��1���ip�:�J�:*^W�����Mq�.�UWsl  ��wu�
7����m6)��\E!#�>�����.7o~Z��{i��f�y7�t��mh(�S<�����9'�� ��'X���.#F��f�0��u��;���66�	��W8�(W>���5���~��.c]���>�i
%�lA�m��V���|�����Z�K���������������n��"�P@���C��:n���d���W����|'��$��J�(���D�rb����tH����i!

�d�V��")�I�Z����V�?v���B�`Zt�^Nt<\}����
��?��SY�H��O���6��w����n�Yf�^W����4�����`��r���N��9����,���� �
(��@�d��N���B�y�hl&``��*���������E9��(H�a����E*k"�I�K!`�V�@��^��..��4`��3R|�[8��6?�j[�c1�����"��1��4�Ji��:��X�~&�k�<� ��"]G�/\�SU9r���y������o���`�_��L�K�;�A�����+��r������o4��+7m����Vb��������y�%�
��)���[\�p+�b)�.��cQ\w�@�����FP�t$SO���f~o��,f!�I=�Q�5�M�����j:�c�	����;�-����J{�-��R�s��B��/7�'}3i��Yg�l�@�����V�@;�)]?�w�yS~�0�dV�+�[i�&��}��r�:M��h���Z#�;���s�J��V7����v���ul���+���"`�@��xQ�E>HqJiG�@=���0R�V+�4:sH�Z)� �,:���J;N����������7�RJ�XI����id (��H$"�i`������d��N3k`U����(��
4"0�\se��F��3�����z�!���=��O;n868������zb�q|un�@����>����v(�Vgd^#%�����-	��c�l�����{���&-E-�wF�PH�O #
���T%3
�4�����S�k��z?�X������|0{9����N>v�@�
F4���p�:���Xc�!�c!��=��_f�R&����	r����H�-	6}���YLo�t]J=N�%�I��6����=�\�\n�F���BP�!�R������<5j���-@`��w�]����,E��O�gN�&������@�\���������uY�����)P���r�)����Z���j��1����N���g�)���'���Q(���Z�5������?���s���)j��
��S��v�y�P��Rh/%�J�B�v1Ah\�=NW�SZ�#��B���S�~��9�p;,���jh�o��v��|P�S��=Qf=H�L�7#�2P�:T{�O-J'i�C��%q�F
�8j(�S����������-p��a .����[�(����w�>Q����/��23�N�4�j\&�Dr��\ 
�����sH��������J9�
�#�����(fh���w�}a��w��z��@F�:�
u1�����04(�&��,uQ�s�)D���!�=�r���ND�������������X��VXa���U���4�rl&���ux��k����\���_����Q;l����5j�w��z:�s��m�C}��%��R�^�|n,Gyd����� �VV�vQ_�3I�7|XVQ����.�dd���K`U�2�SdiT��ku���y$x,�rN����o�������<��N�j�9>����I�J�;���!YN�K����z�.������UW���],�2_n���,a�6g�o<��C�|������0p^��d���B�q�
ma8��~����-�
ht���'�:�����$��Y���-�'+�E�Nh��H��i #�./��h�N�Yyi��gm�&&�����v��Ml�oQ@�R����na��@IDAT��	�S��'�T>k�B�/BY�,�-E�6K(KY*�Bi�&k��F%�$�C������?��������w���]�{�����sg���s�3��9�y�s��k��PF��/~��b�9�hK�:��S���h;�i���~v��o}k���z�8��#�����x�K^R��5��������/��������u�{]���pB�M6��x����?��O���������w����w�ygyl��/N>����O}j+�_���b�
7,�����U<�	O(����<|��gN����o������/?���,����������//��������o|������1~v�a��_����2�v����dq�I'��VYe�����o;��G>�����O/����>�8��c��K���������Y|��_-���������w^q��s�=w��[+��Bz��{�
6(}����?$ 	C�:�����>U[����^��b��7./Yx����VZ��N�;�������^�>���/>�������=��E]�8������N��?�i���x�����^\����:���=��f�m�}���-O|���s�	�_x���{�������������?���|�{�+=���������9W��s�]�r��'GuT5�������x`��(�-�\q��������|����?��O<�)O)���G!�:����/��g��4uZ�=��}��G�6�
7����T�����'�v>	����\���PM|�u����v������~�����N+�8���Kr��D>U����xpd	�����W�����~��iy�$}���������IyX`���g�uV�~���q���j������8��3�T�v����D�3�����}0&��]d�l��6��w����k���+������?����X~��^/����K,�j����<������o,��s���?���b�w,n���r�~���[����X�u�'��HS�U�V�������>E�v}@�;��s�-���wU�����H�!��v�	�D��������g�]��t�_���i�.�0��A�&�l�q^+	H`�<N��Qz\����2�u�]�+�������.�_��>?��l���-e4��O�������o-;j(G.���6E};��Cq�����Yz����Z��O�_�����^?�	�bpPM;��(�z	���w���#�����J��F��D�A��.����p�0(B�C:�U�`�J�}	H`��JU�5H��|�;����k1hC�K=�D�A�^�$�M���t���
#�n�i��}�k�����b~�����]K��{�-I�����j�,�Lkp�p�����~���%}�������V�I�'r�}��F����~�{���3�@����o~�Xj��Z����?\p,�W	B��x'C� ?��0�!�

����1\E�����������o�Cm��.�0c�#����C�v��6+��UCi�����-�;oz��
�+
�����g�?l]I��oQ���h�@?5�[o��j

#��1Vy�k_[45,B�F�~�n����f�����"�ng�&u51�V��'�������{��Z�0��������
����?���8���@�I���g���'?��e�/~���g?��V�A�MS��5?fZ�����+�X���N(��&�mh[ ?��O�}���[p�I`�	��#0�I��#SX��W�*���?�8(K�&�����n�w�u�l�]�sp�'����$0�4��7u��(���{�6B0�>��QP�BG��K/-�r�)��uz��9�3(z�5����o{HH����
�^@�����Wl���i�����1��e :}�VM��O�S�3���b�-V�1!k���K�N�q��*k00�$ �!�V����(��$��������;io��B��L~�z	u-u+���
3���~n"��Nw�}�����:��������?�l������20����>W�?���p���u��9�s��)^x�L�`��`o�9"\�m�w��}<>r�
A?����dQR�@����J���W^���Xg�IY������
������05��
�W�W����Tv���.��A~Le]�2�<��������Ge�`�y�-�Zk�rT�X�2���k�4����O�{��Z7�\u1i��oQ��{n�T��{�00�����^{m�v�RW���rW�A����t�e3���#����{x����c�}�M2�x����
`(�;	�,�����c9\��������4� ���S^8>��M�Xcj��)�e��e/+Oc�Q��t��%0]r���r���C�y���U|�_h3��`��s�� }o�]�sp�;�^ 	H`D	h00�n2P����m4P.�!Hkg��T;
�K�o��������%~�)���~V6D`�E\?Rm
�a�{����ec)����������fz]��?�p9��R�jM�g����X��� u��A��$��@n%+����aP��x��}h��|��h���D��R���p������������*n���b�E)g����>��}�{_���u���Q2��@$�l������::U�aT��t�|�������3I��D�Iu�>.1�Tr>g�@|�AR(���Y�����r��x|4�,�f�WI�L�[����G?Z|��_/��d�n��c,�o U��������B�>T��.����h�\�<`\��K�T�5����V���nep�u'�29����5�`��!P5�+^Q.#�)�c�>;��w��)xy�w�<��B�uM�������t�ee��7+4��)�ky&v��&5�K���~���
ohd������]J�2�w�I'(�S/�u����@��1.�� \?h��{��N�
����n��0���s��u��$"��V�]�9	L�\ue�����0>�[n�%����7������%S��~����,��8��o�J@e��������pL%�����z!H���F�Bg���]6~O��qs�1.��N)���\s�U��1Xt^�x��F���>���8���1M�.m�yK@���T)Y�\s��57�O��a���4Qr�'0�b���oU�]v��`+��H�u���>Z
Z�����K��_]^�Ef���t�A��q��0���W3��/}�K�����o�W��U� C������\L��3��,�~d���~�d��%��lPn1�	��j�p��;\�N������H���+��X:$�����T��.e0��vZ���SwR�q��2���m��6
���y����.�Y:���+�0g]<U��4���0��"r����e���4�[n�e��$�a�I���0�����R<AU��q������.����������`7��{f�c[�~�]N��i�A?�IO*�-�}�Xv����
��7��WeP��j<��JS�5u��lwk�p]�>�����}�c-#B�ob	�n�~�����\�H`&�YG��3�K�~u�.���16P
7�~���\e;'�a�����F������?��f0@�1��A�������*�3X�D&�`7���vZ����&�nof�.��m����8�q�5�6�|����q��
��X��*(�.���	�TI�/	C`*���1��F5F[������b/�zBP�3X�IXV�}�t�5�OeU����u�3_g�u� ��M
r��-
�s�[��|S
�c����	�<+������W��]�7m�����
�������18���������\�#������
����?0�~k*�Y�b0K��	�|<%�t�M%/�ka�`xShbH��A���0����{:^��.��oQ��xbd	�\F�!����q<�x�`v6B��g�~5��0Bg& B_��n�����-cu����)�<�@�%=����z��#A���z�5�h3 ����;��5��;��)�i��8�Q��%����7�����d��dx��%�f��|���P��tKS�k=>�&��bI�^}/��0��:������$��@�:��}m��N���0`�0�����!:���x���\e;'�^���$ ��B@��|��h0�b^|����V[�4`��:��Gg��L��@�n�.
���KWs����,�1�G���T����r\�Ue�%�,���5�q_���J���_��i��5��nRu�� �g:I/%��p	�c�l��Y3i����"2;)�ig�q����=S�2�aY�XG0g\�)f<�5�[�?�����d<g������!�fG�����r]�]SU6RBi��`n2c�7�1��O�S�ri\��#]� 
���L�K�4S|��(p���S'����+J�Xz��p�&�����s���u���F�@��K������YZ`�]v��<^5H���I�i� �Y�uH��G�@�u5�f���@�f|�#��c�1~.���X���Xj?��n������5��T���N�0tc�	�+M����i��t9
�7���%���/���;C�eT��[	�9�������y��[Y���ep���I�0��w��<��x:�6~���k< W���1���% 	�f���%�:c1(�Mg�b�`�|��A�-.��}���Nn�X�1��Un������K�M6��u���Izb��nc��tn�x�k@X>�5U�
�{4����@�����0�Q�2�n>�Pg��n���f]��^�r�Rr1��.���
C�pQ�K_*]�Gz�m(�(am���2�k��St��]w���@����E]�2 M����J�&3�"��z��N>\x����F���a��j\��6�\e��.�A��8��3;�X�p���Iu�<�tq��p�
�K�N��2G�b�o�k�������VB����rfs��m��v�22q~�x��Y��G����Mr��S�-����.<$��"\���n�v���V?������5��
��.��QO��A��SO=���C{�_Qh1�#��Ci�F�����}���ua9��J&y ,?�2DH�}[��_j0�+M�n?�M��R�q��y�` �������d-�}������@�:�w/&!��Gydi|Cx&������6��;���l���)���$0�h00�Ot��=S��f���c%��n�
�r�Au@L��4`�:�1�)���W,3c�fO����/�M������l|k�����g�}�]f<�Ve*l�E�g�u�L�:�`����$ �A	�d�����cF�_�uF�4U
��hG�������K��28���-5 ���Mg�s������-K��^�:w~��#X���1���F3g\���gJN��j������^��Y�w��~x��������qs��3�[� �����0�r�?g	�e���(�Q��3��h����8
����!������b�m{����wq�A9��G���KSe"�y�v��>C=I��AI�i�i~��R!��M�.�UO���)������m10���4'�o'M,{B���
+��h� ������\F0�u��-�5��o��4n�7�W�������od	ZWc@�Q
�7��$��Ua��qf����f����^)?�����O��~W
�6�kpd��6*��i��c�UW]�u6���R����M���i�&��G	�0�.�UC�0.�qb�9��S$0S	��#0��C^6�k���4P�����>�����_Se�{< G�����_�% 	�V���%�f+0��>(?��O�uY?	����h�ur�i0P���1l�=�����"�L�zf���H�O�
�I|o�����<]?*��k�2`CGgP�``Pr^'	�V�Z������������\s�U*�7�x��1f��<L7���b`���[��\P<��#�ct�8�uB9�`J�nK�"x�a}l]�\�1��:��W,��X��'�pBq��G��Y�b=�T�O��;K��0 �@&j!ox�����:v{ns>gf3�,����+gc
c,@\�������@��Qm�����;���U�1cg�m����Fh[����K/mg0��A1S���Z��1�u)�933�%r�m���;]��A}�������W�m�N4��Z��-������w_�+s��S�-��)�$��0xF����TD?5Ow��%,B���9E�QGU8��L����kcK{e��W.w;y���t�e�N��I`���wC\��F��,�kXcR���G�_��W�n��Azn�n�&
���]~��m�b@�Q`�b�����w]f�-���Yo��Z��`4��[L6�i������?<�9������j���ia"�"�Q'��� �>6��z���+�	q���v1���9���DS�90�e�)��'	H`�	h00�Oo��K���c�
}W�����a�kj��r��4�Pt�
���Xe��Lt�
���F���T���� ��� ��F�D`X%+��O<�5K���9e����_v�e[�o�gP�N3�	��Rr� K��K�0�x�-����������~<!0c��0X��O�5�?����{a���"�,I�
��q����3.�]M����c7�x������-�\K��y�y/��K%�s^��K�F�e�5U������]w���8�a������ ��l��f}q�Bp�O������!��p@��r�m�n(���h'2s�����r���D�������K�%YH7�����1(���3�����]��������w��x��E�<�?{`x��|��?���e���g�8p���~�������F�g��``���4��-�����I1�?r�q�1�'�{���a�~?�%��t��7-��T�?��R�k���k��4�M|��&��J+���&������L��.���6���E���hZG��/|�m�3�^y���x�*��R,��Rm�����cm{���6SY������% 	�<
F������������0��`Fj�����|��_,��LW��p
�z��K+��gK'�?�-�t,U�*��5�P�Ci�
Zf��)�$�(�o�a��@'b��!�C�J�<��^���������gz}%��/�'��Y�|�.���^A'��c����w�y�������j�7/g\)�Mi����
Dr<����i:���z��$���-~���\e�v�	�A�N4����5x���u@7���6�]w��-X�sS]�2;������%(a0�`F� B}��6����Y��M���r��S�-����}h_�L^7�oJ_OM���������c���F��D6uY�LhF��&S���:et���N;�Tz����������N;�SR��G�5Ui���&<�b����G�vSu���������#0d�[�����3G����'=W��(��l��1��V��l%���>Y��O��|a5�t=O\ �.q��Aa���T��8w��G'�|r���M��r����s(���g�f�DD4�Y~��SN�0�a�m12���	���M7�t�%.�`q�Yg������O��h���B�`���{[��F:�-�J�u�2�,S��bG��V�tj���i�k�1@����y�X�9p=��t];�DY�)��i��$ �A0��/xAy)�^��D����:fQ�1�>�ok�2�e5uY����a�>k�v��p����Yz��~{�,u�?��z�����T�,U�����x0�m�x`��s�=�NX2�v�9��e��_��1X�Mr�������#��l��d����Z���D�f��K.�$u�b�����b6qFx�e���������P���K1���@�M 2B[�:��.�\��g�9?m��%k?q�����[�O�;:6�l�b�=�l��F��S�g��g����P(�h�������X^�6E�(!�������nG�@���e��r��8|?Y��F���k�]z�\a�&��?��O���\A?�����xX���LE���Ll7�I�z���������,E?L��l!�oA��c��u��3e< }>SQ���������f
f�����'�8�(�q�@���(t�X;{��*�E2��
�#�
.n����:���WS&���F�T����o����F9r�kj�������*1V���&(�n1Q��;8��7G\(QB� d���	i
������=��y��{�x�U6���I���)_�c(����1�������v3JOg���Ki���>�_,G�2�z�l69�b����d���g���
��6�v����r)��`�?���Oy�����wh��e��sc�.(�B�O{��{����'c=�E�k�~q����H�Ll7���8
O��3v��F�$��~6�_�M�6�������m�	m��9�x�e{�'�u���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���LH@��$ 	H@��$ 	H@��$ 	H@���#��@�-	H@��$ 	H@��$ 	H@��$ 	H@�4���q�y����3i��$ 	H@��$ 	H@��$ 	H@��F��C=4��0n*.�``*({	H@��$ 	H@��$ 	H@��$ 	H`�	h00�O��K@��$ 	H@��$ 	H@��$ 	H@���������e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����_�b��w.�Yf�����+���/w�}�,��Y�A�)OyJ����������b�9�(������{��$ 	H@��$ 	H@��$ 	H@���``��I�����g�}v�R8�?�Aq���n����o_����mqv�a�����cu;(�O;��b���j����[��w���?�?�a2��]a�
���RKK/�t��p�;����z���n���q��5�X���g<�4����]~����������H`\�=���"�,R��/)z����G�Y��.�����.X�y������?)�z��X,�������_�����>3��@���� �;���?��s�9��o��4����I�$�,�@A=����O{���%�X��
r�����_LU����w����.����4�`�C=��O.�`|w	4!���5��a$0������3O���b9��������9ON.�U3�@�r7Um��Z����Y�����f
f�����7�������>�x�(�8��^�<?l����>����0;|����:������m�����Q�	��F�/~���`(���j��c��3����f�mVr�!���<���&�l�:L��c�������>T|�[�J�{L���N�����8��]w]��O}�qx�����QK\�����x�����v��V+�����k���"M�*���^��W�n�m�����nE|w�uWq�%��sL���������I���\u�UKk��f���?���{�)��	'����[��������al�A�����\y���w�����K/��������o1�BP�x������!�;��&��_|�V����������e��i��e����G���h�6C�e��=����x����0��8����?��O�mj�~�-�(���7�-�X+��M7�T|�3�).�����a~P���%/)V^y��>A	Ezo����������o��7_����}�cF�uB]�;��*�+��R���K������;��3�?���u�{l�	�*� ��k���.���P\q�m�b'wy�x��~���n�iY/������R��7�)��\pA��.�3Y�d��'����������A��AT<����$5�2�'NE�F W���6���o�z�6�����W�NL'����g?[����
B�A���W����{#E�AX��0����>v[[:Z��rJk���{��_�vl��a��4L5�	������?��������U��v���o��j�rP���hf��#�<�x��^�8��\sM�����q�:C'��(�R�;�� ����k�m|)��z��^�������������;�4��k��������\�N:����������GuT��������H��3���*�ss|���]*��[n���P����:�}H`��N�H�&�'��&J��g�2����q��R��+>��O�
�q��,������j������D����u�����I��T���wuM3��K_*>��������{�	��~��	��!�1��n���w�����]���I W����$�M�����'F-u��������I������#��Ei��|��qh�v2��d�O)k��o�9�K�<������HW��O��b���n�p�r���ls��s�k��g��l"$ �"���X��4������Jw�q�awR�1��/E���Z���?�K�l5��q&c�������������n����Ys:���l���K_���>?������L0���V?�VgfS�����7��
���aC����T�^�����Y���~Pr3����T(>���A)*���7J4�~������
��"����O�z!�e���W�(���|�m���\�t�E8n�RA�W5V��o�x�;�'=�I�����mH���5R����b����:����.��R�m��Z�k�*�iZo�]��� e������+��(���?��������{���m�R(]*����[o-���;<����fD��g���J������e	��R��O~R*�IO*x��0����|�5�x,��
�0�Jr��x�}�-.���4����@����=�������t3�U^��t���!��T�����o����Ci�Ve���d�O)k��o�9�K�>g�(��+�K���M g���6w��7W�f�{��b�/	�"
f�S�``�?�IL^?$���N��w��e�8�{=�~"��R����o}�['~�3�S���?����xpd	�1���{�����W����|��-^��OZg0@'9]`�E��W��U-����
�p��D��<�w�}��n�1�Zh���e
�-���M��|G�t������H1 ���;�B����P�k� �e[n�e��xzm����2�F�3�
�|Ey�?</����m��uN�����Aa�8l���ez���0P%���^��������eGx������?��6*���{l\�q;H��Y����0e�������R�O������f�VVN?��	Kgq7��|+��y�{J��d�<?<��O/�?�&�#�rfj`�����D}�A�Zk�Uz��BZ�������s��`4��[�� ����J�7��<c�41R@��X�-CN��U��x�=�	�*����x��m��q}7��\�%��vvx�S�R�o�H��%���c4��o4��X����
F~�Lv9�����em2�m�5W{)�sF���b��-����:���4~K`�	�*wS���G��7W�f�{��R���f#
f�S�3`���7��5��5���	�����Z�e
��g�����'=��?O�_��`0���sB�4��$fyu�g&���� e��d����8��S�C��,_���f�2.�s�����c$	0�A�����6��T���(��:���kKZ1�A����j<�)�=���[e�<��WU���9��[��j�t�|S~�6�:�oCUV]u�r�o(�X���M�r�w��u2�*�y�k
�PI���#F��m��~���{s�������?x�	��a UmC�v2
��6��v����
k�2_i��"�A��g��R7�N=��O~���@'E?3������q��;��#�.��m$�F���?���w�z������*�,�H����5���FR�pm�����W����t�����b��P��I���`|��m��V�Oc�9�_S|�����
�%������` Gyi�N��>����~8��,V��d�,���o[&k:�I�����2LY��~[��\��\�9M[��i�������������@�r7Um���o�z�6�T���K�M4��O��`��S��n"����*�,fvd*�10�
i	�uHg,��[LfY������)�(k���6����|��+}:���=42��P����o~��4Y��Nib�����v
Q�p�8���~4!��3:^w�u����%�Se�)��Uv\�#=�����{\�q����)���f�49y��W�YS��E���Jp!�K.�di��A��7�\�t�M)uk����������X�3��9fu�1`�I�`����+��g�����"�������^���3�x/������y3p�K�T�0��9���Z3��z����>��rv��[��K�<��mh�x�_&O����;�l�:�i+����0����\�����9�/�g�EIB�3u�1��D��0 �l��A��|�����B*�r�!�r�_����Ji�84�|S�=����X~��v'���s����4ux?��T���������<�a��G�R����M�7��J+�T`�h0P�t<�/��x��m7��~��W����-������u���Ov\i���1��Gh�m����hh����1����6�lG]�R,9P'�>��V|�}��b��<�t�[T��N��������C�R;���������0�!��U���������u��9���@���)�w�5�)w��(1f����Q^�I�aG�@��bf)ul��]������\�t���tr�����em��mi�r��r=�4}u��T���|�Xp��������1	L5�\�n*�����\��m��~k��$0[h00������v�i�">��UW]Uv��X��qG�y�Yg�+����87��;��2s�*�/�x���}�ma5L�c��r5�}�)M�/��q}��4;�AKf��^t`������A������9����hE����0 `P��P*s��Tp����V[-=<�7JqfsaT�*��(�'D��h��0��YU���������l��v��.	���F���
�|�z��:\��C��&L;��	e�7����,`��aMa��2�{�D�nBi������C�u�����)�������`c��X�������d���R(��-eP][t�M6i�/���t�=H�����FUL���������w#�NB�E'a�I'�T���e���������%j�e"@��m
�h+��]���?�n�;I��.g\iz-c�g�^����b"�u��^�?:�o(&S(�*@6�t����B���`��20H����M~����KH?,�Sg�q���r�����c2�1\��z���&�L�@IDAT9�K��n�	�������#�e0�S'��i��{�Q^�B����}��~�'����������^�������N]��kL^��$0�r���ls��s�k������~��l!������=��Z������CX��(�:exy����7fA3�4u��+��k�a�T7��a�N;��+����J���H�d`���o�4f�c�D9a��:��`3����>�P���zLQ�5<(�������!�8�rM�j�z1aN����l�a��)Y� �@�=ePf0�}�W,���g���YC��PgV�f��"?��({B�L�` �����u]��^J�#B�D���^�~+P2���N����������x��RaPq�e�)U�i����:�t&[���8����HN�������~�*�i0����)&�-F;H��6M�0e>���9���=H�P��/l������f�W�A[;�-<l��� ���#,���N�r�>I|?RC�N����.��T�m�3����.Zz�z�S�Z�b�<#��1��k�Y����o�K,Q��|�}����8�MR��$H=[�}{��_<�2k�����O g�k��tb��y��,��` Wyi�^��������&&LG9�D����0em2�m����x��R���=�^�2�#��H�	C����F�@�r7Um���o�z�6�����S�I4�IO�&-9��A���q�X�w�����n%mt��Q��u��@�-~��Z���&M��f���B�b02��e ��F�,xf��Ar��6�M����&����(�P�1[��z��������Ni�n�SW�,��p/�^�{�5�0S#�������G���,��o|���	�����S�if4"9��ou�gy��JE�M�eJ��!�\g��&��g�K(�1NIc<��Z����2K��u���	&�`������o�����Q�$�['�N��Q���U6��w���L~��u�N������d	������������>X�O�������&�2#������p[��|��+����^e���i]�k�4,��`�c�0���J7�����|����G�-x�9����^F0@���_�(����Z��"���,��rd��k����-�WU��
�uReC[��#)�����S/n1��.>��~9�_Zx��C@H�u���@��ip;���n���e[8�.X��oQ�T���ou�O�d�����V�K?�M�K��l���]��t�A���}���.��F�@�r7Um���o�z�6�H��&Z�fL��u�:�������^{�����>.�Qr�`'���c��_*��;���W\qE��2�q����ziT�����3����/O�����;���C���Y>���o.����&'(Z����j\�3+6�?��O�,�8�Zu�1�zGy�������5T�0��A��0@^�9���M�%_��!�H���5Ty�c�h8�`�]b����:�4��l��u������)��k�~w3���N!��a�zM���o[�j�X���P��|xV��G���r�����%�o�(������2��(�c(�q�����9aR���0��Q@�x�2�rH����-NHoj�}�l�u�fQN	��y��m�`�vy�ce`��
�4\87�������Izmu��|���`��p=���r�-�fL�@8��:a�r�L�����Ue�|�[a��hQ�m������{��o	�����:��K�K���,�/ef�s+��h���C�	<1��*���4��q��v����U�,�9R/ ����8��M
��=���]�zW���}�
����u�E�u6�|s�B;85������?���M�����v:��j�*
�w+�������o�Q�#<��}��:�[xv�`Ce<	�,�����X���	S�����K��z~vx��^T�}����VZ����ON ����t���������u�W�s����xy�����|S1&�1�A���q�/��J�I���6w��7g�f�{����K��4��O���u2���tF�M;.q�n����>�QB'e85�1���1���]Y?~�m�-o�2����n)����;���!Gx�E��)Mh0����Xc9���s�`��~���
�=����;��f�Lc���W^9��T�2`�+=�e�]��&�J����`��S13��x��6������G�m8�;)�Y���t2��6^RW�������#��$^w�u�T�e��T���B����+�`cV�"�,���F��Z�Cx��J��&�Y��n���c���w9�����8-W��B����
={u��q����_�.����@�F:��,K��P������8&L'W�k1�,�g0���2���\�eC�A$���i��1E��u{�8��XV!���7uQj�q�-�[�'��|�������k����g(�P����}H%7�4�T���E�M�vAj�������G^r�q6��*c��S#!�e���zf<�~������ByN����s������k���U��/�K/�t�K����
mB�`I�}�	�6����v���[�I��	^z}�`w���/����Ex�4��o��v-oBkb00��{+�C�I�	m~�E���Le9I���������������w��R5�A�s5�t�MozS9y�c������^�o	�*�&�n���9�����ls��[n�% �� ���tP���9
���L�p]�f����N�1wR�3��������g:[%)�H��2s�UVI/)���U������P���	�.O��ju�f��pA�P7����0�+8�J_4����4�8�-����S����N%u�_�?����a��{���[Sa�	% J�TP�wp%y ?��X�=��e�
7,wy����q����[�/�����[n���[�:&m����//�~��J%WY�85n�!@��uc',���Q/�T������Y>���Y�[}��w��i9�`����Qc�!�������7��?�qA=�rC1����
l���J�|W
z��Y�.����P��L@�c�T�R�����#�����&�>k���H�!�����rH����{��G��e>��3�����W�|�K>�������\���������/_��3��kb�G���D���c?� !3�i+��Q��(ES�]�$c�'<���
����XH��*���eWx�����x��{�.�;���s��n�h��?���������3�h����@���vsw�����$����W_}u+�T���
k~4���*k9�m5�it���R5�A�s5��g�q���cLq���L%���MU�;g���^��=S�`�%	�d����X�5`P	��UY}��K�B:;&
�i�O�2���?��_�a�
��]w]�����������6tU����������`d�2�sa0���Cs�=���(.�s�'���`��X2���X�5�W���'>�rg_��`�����9zq���b��������:�?��6����9kq�R]� =��w���x$���3d�,�=5n�!������MFS��Iu�9��rR�4�hcvf*�`�F����l�+�0�r(�� y���f�B)�c�����!�������J�jQD�-7���|���A�?������a���^�8F|�����pn%��^�����[o-���k��*��;g\�r�U�Pn��QuF��=�sP�`��q&B<�,��������b���,��=�t�����X>�'�y�UW��~{Y�bL��q�&���e�o��is�}�*��h���#�B�5�u
0�b�-�X�c����R	�q��]"���@�����&�x/B0v����75�Q^:�����m�����o��?��,��x���LE9)o��_��I������!K=��^��l��\����
��z�D���L��r7Um���o�z�6�(���]�NL'���3`���/�������j�c�9�t�^=�>�S�>���Su��k���x��_?!,��]um�G����k������P���
oxC[�X7�.MIpMU�FR��`:������HGN�9������G��d0�N��N�\�1�^X�#�P��Q=��=�A,��Ni�~�>�=�Ur���W�� �vX1W$���u�TL,7��'=�T*3���X�2���p<� 9��.�$�R5�,�kl���VGRc����m�e�m%��o}k9��u��#u��W���]%x�]���y�.�����"�c]����u�xL�`�"cdB0��e�]j�s���q
��^e#��8�Y�xP�$��i{��F����C0�X����)G��\�T�ki{����*���{�>|[x�~Q|�����/,��.G�����s�=��O��p���o]���f�����r��N�^��W��8�X��1T�J���Q^��v_k��f�^	�_���-�cSQN�=�����*k��K��S��[�������-��s��s]�y���4&��Yc���xL�M��r7Um���o�!���lsO����% �Q%���ruo��{t��������������u�p�����t��8���I]'s>]�4����"�X(,��4��@�a#�������!=�q�\����4@N����4` ��o��J���sc��gff�+��kqV�������`�8�3�8��,����q���H���e~:�������'_����	�.�Y�>�`GE�|��W������k>���d�����[��b�'�KP�
r0��+]��e�Dr���,a����2�c�Ft�YJ���`\W�ew��3��:�_��0���K�Yw��$�/�3�u,���Qd��vk�����������&���K����p3]r ��n���.�>�:�eSh#���Gq��?�Ca���^�'����������dJ��N��|�-��Q"����p���+��a�����kV��r��:Jx��{�}��P'���k�8�a	'���<PwI�c��K�
0�h{3���}aL��d��n���O���u��u�W�s���:���x��\w
c�a`G	/?��sO]P�I`d	R����=]�o�z�6����&\�fL��u��(IQ�v��������R��<�4Q����JfJ�����`�t
�8����cl����>P�~����U������C9������ q�\�YN������\�����(�0�`m�TP��z����:���Kt2A���&x�`��:c�3`���T���.�/����
7����{�(ilV�$�X����cR�>�q!�������c��B��6���}x������T=��]���M�:#f��5 <u�N�9\4����cZw]�c�l��������d:������?�I(�s��5�Y�;���z��P��(��xo���:��7�z�5�C&c�N7�q�t�K�����!���<�4J
c$�����Ir���quJo��M�X�����Z�I�������r�������j�%�(��q����^\z����u��3dV��������[���
Ce�V�5��L�ri��4]��W��k��N7��n�}�-���������U���U����:���;��*/�����C`���/���s���I��5h,��Lf9�������e-G��[���
�^�xr=���-L1`�e����wW��l"0h���67�s����5�����	H`*	h00���WN���V[�t��}:%�n��:e8��� 'n���E������d�M"x�E���5u7Dg������l��4
������;�,
'B	������n9`��������g��D�U�TaX��uju�.b���u�X�:����]RS�L��w
k�T����2��{�r(��E��
�S(�9��RK�^�0���0JH�40���[��p�_�:�;A����:����\yW����h�7WY�����8��@�p��38/�����J����'/MB��;��cv�_x�a@(��uM]���H���g�yf�)R��%\V�nP�;g�1�� f���t{��G�����3X�0M~W���?�z���.����o�����chB�v�KE�CJ�Qu������%=��wj�3�&���iR�����X����I����1��=��{l+H��J_��i�` @�	A�D��z���&�axF��7�oU'!��3�{��/}�l���
}��n(���;5��L�$H�o���_����k�DSJgM�z�u��`��Y~<W����[�������c��@Zg���f�m�;���cFa����~����d���_u�O�$gY��o�������%�����4��Y�c5iK`�	S����
��o�z�6�(���]�NL'���3`�
�n��f���tg�8J�Tp��,��M��3�����V8�vAqK|(Ra&~J�:����a@���t�p�L�(���b��.M�*��=Y��p%	��X*3��9f���:gz���K.�`,k��d�{H����`�A�`��Y����[�3�b�4�O���C#�w�5��5���������r�W_|������<W����@&������c�c`��e?�U��o`0�������z������+�m~�*��h0��?�]���3 ��1����nDP��z�,��O/Yr�%�UW]�,��P����
np����b����>��
G����z[�8���+1 ��o�c�M��E����RYU7w�5�(�q�-���Hk�6U�q���\��^��c5n��(3����z�m=u�� ,C�b8����Y�s��-���5)cxKg�a4�*�#�j]�QV� 3�&E���!J��k�N���ou�l,��C�P�������9�+�Xv�%txOB02��N�%��+`�������G����L'�,,�
�,aPF��YI W��{��
+�e�w����y�P�$}�0���
�Y��;Wy����f����|��:-AHX�a<�0vD��A�����5��O�$wY��ok�����^�9�s�����?F(�1y��V3��0��H�T���W��7W�f�;�����#��@��<t��@�D�JM�W����{��G��P���n��B��������U�l0�X�q_�Gg�����aQ���'R��N�(iq]�
��b���0K�W��Ui4���\�'���9gz�G�>)�';��"�7�tS9�5�l.5X}���Ysq.���c0|��+�����0Pw��c(��e+�%k��V[0�y�1�@q��IUR��5.�~U����8��I�����p�	���.�vo%��7WY�h0$�C`�-�l)���3Jc��	A�OYH��X6$�4���h���^�>�$xw�.����w�Y��/I.��
�������4��i�M�\q���Wj4�q�a!(;{F��2��:!��w^�1���@\3��(3#n%���y�{�p���9�i�or��q��kR�h�3�H����x�`!cl���h8���.@���&�b1���]����s�9��4m��.��4H�T�@k���j3��m��?��E{;<��g��,]e������'�!���}����g�W,�3�X���+�>�������Q�(Oxc��������*f���W^�<�.CP
���T�t�����grK|�9�
0N�%�8�$���QN"�&����4)kS�o��^�����x���������e��"��@ W���67�s����5�����	H`:h00���g����Ng�`
n9Q2�!K?$1��S�o�
�@(U����0��TXC�5�c&D]�5�a�G�tP�W�P,���N*�3=����X������b����A/|l=����j|u�3�`�n�����=���.�]�U
(t��[n����'�u�qI,C��`�������P0F\�0���r���W�� �v|0XJ��0�B���flRn�7C0K�M��^�~_����B���^ZO���<�4��'5���?�����?�Wk���o�
��&�~��W�o�����8�a]��k��B�M&���D�e��Y�.�drl���K��$������Ri�><�5x<j*���^q��+�W�2�����/�SP���/A}K<]�!�*|C���J+�NQ�bE��}��	m����uQ���+B,�@pf�����I;�:>m��'f�2c:�!�����/gU�7�|e]�C�,�
!�?�;H�Yd�E��@#�p��9e|	[��K�
2���'��������3�q��'���u4-L��<uux��<u,c�^Z�-'��T&����MU�-W{)�s�[�8f�sv�L��yN3�@�r7Umn���s�k��g��lZ$ �Q"���Z�0����{v\���n�z���g������(&����^dvB:��^�of.���s�����N_�����7����x]�5 >�D�z"�\UhD�r�)��N�N3���q�45�Zm tc��'��R��%	P��v�m-���}�7F&<wfg���c�:	�����R]���0&��/�|��%����O9`�z������:�8������-�
���a	0[�:��A
m<"M_�U��P� �����A�]����z2UPU��~���#L�m�|�a���[L/�{_��C���������[o���n��b��N�������#�XC�S;���(�9��nA���S��.���W}?e�������x�w��6��[fN���Y����7(��K�a���[F{EE/�s��N!|b4� d7A�E�i?V�k�h�&����M��4��0���0�/]_:(#��SSZM��W��q���������?�.� F�u2L9�����d�O�������l/�z�|��X��	�e#c�I����F�@�r7Umn��s�k��G��7���L ���Lx
]�p��G���.AjOa���03�Sa��������:�GL�}z�x��g�%3�P��33Q�s-.�����>�c�e�)X�����?�9X
�|��-�q�K�v����*��Lg<1#h��6����u���o_*@�Zj�j4eh���J�T&#=t�pk�r��uI7��0��3��\p��s����.*��i����.�D:�
�
&�Kp��J�f�nf?�|\���F��g�r
4$�t����:q1�g�>`,R��`k�i���:���!�������nk���V[��3�N<��t0���e�T�0�+������@�0e!�Tu������-3�S~�t�j�^���O����;��{�	�}a6;�9f�cp�P����NR��x�;
�]���)�NY�$�S�z'��/���84��i�#r�B=�L������>�a�q6�b�7�*��q�UW-�7��[�HT$0,���>���J��hO���?m��y���ka��G�8	�o��Qp���{����&u%����4�z���7�����K`lK>�h�I����o/
�i?F����6�`�R�O;3<-DX���]vY�-�����p����?i�W���/m`�7T=�F���"0h��H�k�y�1����W���Zs�5�����^5\��*/���M���j��j]�7��o,X~��:<Ov"2h9�_��d�O�)k��o��^�9�^`�o�y�)�d�W����j���T�������Y��������I@�L@��Q~zS��N��Ah��0g���<��]�J*��/��1{sx`�m:$��@ 
U�cPq��8�a[M+�/����3�Y�b|������1���W�`e8��M\	��I��s�}j�5n���}l&���y4��"@Y�����>�Z����4K-���M(q��7
��:�f1�	E����
+�P�Q�,X?C��&3��L�dz$0���X�a�%�,���&���\sM��e�dQf����*3��~�8����b�R�pI3
�A�`�J���`XG����#Z�4chE�H��~��M�c��C`��G[�A�����,/��)��nx�1��=��A&�2��7h9��3*���o���G���N	�S���U����ls����4H@3��3������2�AI5)��$ 	H@��$ 	H@��$ 	H@��$���
 �(g�~�[�jC�����t��v�	H@��$ 	H@��$ 	H@��$ 	H@	��c��D�a`���)��$ 	H@��$ 	H@��$ 	H@��$���9i���4����I@��$ 	H@��$ 	H@��$ 	H@cI@���|��g���|��Fs�1G��;�������Z����$ 	H@��$ 	H@��$ 	H@��$ ��!����<+S*	H@��$ 	H@��$ 	H@��$ 	H@�F@��l(�H��$ 	H@��$ 	H@��$ 	H@��$0:4�geJ% 	H@��$ 	H@��$ 	H@��$ 	H@�h0�
�I@��$ 	H@��$ 	H@��$ 	H@��F�����L�$ 	H@��$ 	H@��$ 	H@��$ 	H 
��4"	H@��$ 	H@��$ 	H@��$ 	H@����``t��)��$ 	H@��$ 	H@��$ 	H@��$ 	d#��@6�F$	H@��$ 	H@��$ 	H@��$ 	H@���2���$ 	H@��$ 	H@��$ 	H@��$ �l4����$ 	H@��$ 	H@��$ 	H@��$ 	H@�C@���yV�T��$ 	H@��$ 	H@��$ 	H@��$����P�$ 	H@��$ 	H@��$ 	H@��$ 	H`th00:���J@��$ 	H@��$ 	H@��$ 	H@����` J#��$ 	H@��$ 	H@��$ 	H@��$ 	�
F�Y�R	H@��$ 	H@��$ 	H@��$ 	H@�@6dCiD��$ 	H@��$ 	H@��$ 	H@��$ ��!����<+S*	H@��$ 	H@��$ 	H@��$ 	H@�F@��l(�H��$ 	H@��$ 	H@��$ 	H@��$0:4�geJ% 	H@��$ 	H@��$ 	H@��$ 	H@�h0�
�I@��$ 	H@��$ 	H@��$ 	H@��F�����L�$ 	H@��$ 	H@��$ 	H@��$ 	H 
��4"	H@��$ 	H@��$ 	H@��$ 	H@����``t��)��$ 	H@��$ 	H@��$ 	H@��$ 	d#��@6�F$	H@��$ 	H@��$ 	H@��$ 	H@��g5�<�����4	H@��$ 	H@��$ 	H@��$ 	H@�O����L�
7�i00���$ 	H@��$ 	H@��$ 	H@��$0�4��o�% 	H@��$ 	H@��$ 	H@��$ 	H@cH@c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``�Y��$ 	H@��$ 	H@��$ 	H@��$ 	h0�; 	H@��$ 	H@��$ 	H@��$ 	H@C��C7���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@cH@��1|�fY��$ 	H@��$ 	H@��$ 	H@��$�����$ 	H@��$ 	H@��$ 	H@��$ 	H`	h00��,K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	�!
����e	H@��$ 	H@��$ 	H@��$ 	H@�����$ 	H@��$ 	H@��$ 	H@��$ �1$���>t�,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4��n�% 	H@��$ 	H@��$ 	H@��$ 	H@�H@��$ 	H@��$ 	H@��$ 	H@�����c����$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``L�s�Q�v�i�\s����-��R��������c&2�~���]w��
�a�V���?o;�dg�5�(�8����'�tR��"	H`T	<��O,^x�b���/���������d%�}�����3O��C���N/��E]�Xp��;�������������;o��������f�9�,Zh��-w�q��qM�����"0��s�,����w���Ue^���1�� ��(���J�b%"�Jj��`��LQ����
��R�Hy/��2$.�\�(�d$����w�y�������}�y�1�Y{��\��k�9����[}�����u��z�R�oQ�����E���]
���~��nw�[]?��4O�ckP�A=�g�&�6���q�{�u����������������w��{��V����[�p�
���7�;��y����&��e�{���;�P_/|�?����u$ 	H@��& �``��������U46���.��:���*�	��O��fWt>������y��e��o�fu��G���;��;��>��5��|9����N;m����^�q�k�m�/8
�?����0-�G>�����D:�����	��o�vu���ov������^�����7}���3o��-�*tL��%/iZ�z��T����Tw���f�!���K���;�����g��~��8�����w���m��*�]8�����TW]uUu���W�\rI�b����������a{X�#?�#�mn�����_�r��w���������(�/��/T~������'��W_]���.�������������~��~lV���k����O��b_����^�y�������nQ�����|u	����s����}��������g'��W����}�3���up�lY~�c������~�z���\������������^}�_��<�����n�-����_��5��}�������"/��<�Z��:����/�h�Q�
�N�������[n�%fO2{R�y���Tq���v�����~D��/��/��o�}�r���M��uJ~3;����d�{�����}����~���'T���Qw>��x_]{���[���5��X>f:U}z�$m<����|�;WO{����;�J�q��\/��x�;z�F��9�XN%����)Q�g>��������9�=��7��s�����mc��s�����e��6K|�qPRq��������������m���F�����N��~���;����������b����sWlc_N% �n��������kV���\����.u�>����p=����}O?<������7��OY������#�J��y�(/������=�������V�G��)7O�'�|rk�)�;����mo{[c��oy�[�wA[���/��>��}�{��~�W~��������!p&_y��C6q]	4����g?�#�u�0�;��j�������;��l~�c��0�~}���z���^��WV_���Z��"C��
�XA��������}j��|.���'���'@���o~s���G�����Ix��?�����en3��'�pBI�m=��6~g���1��?��M�����~z��G?�m7�_��_U�����O/c������6�DND)k3#��(6��6g�~�/�e"���ef��c����9���+:�M;Z�����gLu��r9_��f$�``�����i/�e�����{����=�q�E��w�Ss�1�v� D�A�#��p����m���% ���c�Q��u	���G�G���"%����`�#����D#�h:�����i�Mu���,O��K81a��'5�J�KFTF7����T�&L�
������������3[y�e����]G6��������'��N4���NB��F$�����������z��^�n�������\��)O�� �Sn�`�o��o�{1_��{������1�r�	t�G�/���\D�@�����p@�5���6r#���"��c�E���������ztu������o|�����~����n�����g+B��,�� �#�|��ud)B�k���{:�~��~n��S�'�E�;�w�;�wPn�x�P�;�k_�Z�����C��t�MU�^�6I�)�m���w��N?�$u�C:���"�-��r����������vJ��h�������_^y��}W��7�l���c�}�p���*	H@-�����L{L��������������ID���p�T@�L�@�I`Z�;�����I0@g9�L���u�0�a���d�n���mX���q����/��g��$e��qT<�3�:��������!(����Z���!N?�����8-9��Z���N�������B$s��������N�����{��WCr���(�,��������|�3�~v�f$1�Ya/{���O~������_��QQ�9������"�0!�	?�{"RI�N���:��S���Y$r��!�0A��<����'�'�������Mw�3��ra�(�m���,�H�:���o�bBC��fT i
�F��� ��S�K<;���|�``*��~.������$�H/[���N���3�Q����?�.2T,�;{���s�3;������Bo:�)�L�f������(kl���N��!	<���^����Nz�I0�3����t����(W�!f�G�P�:,Q,0�}��D�C�{�hD7Cl���2�I�8Lyo���na���k�H\w���4Z�+D�ac����S	,3����8�T���B�X�O���"w�Z-M6�IDAT��}l�J�S�����29O��f&�``�������u#9).j�����]n�!���>Uw4�]���!���~��G'HW�m�1j5
s\Z��``^l����.����6�8��D�f��]����vLa��o��@� �%��?����.N�N�HC�$��;���7�Y��J<#S�7���Gt�0Bx3277r\��9�h$�����S'��p�NmF����>�Tg�u�l�)���.�NP8��~�����:��	��4:���J�����?�����dTAn����>0���O|�v��z�����k������������<��oN�5�����P��'�Q��<���"�6��+,�3{�K�QtF��>����}~�}�����?�� f"
�0��W�<���#��eK���~��u:����j���x���1���<��90Z�Q�a�)�Q7��?��Ymlgh�o��I9�;����AaZ�K���HY�T�����.������\�?���^#���C=t
Rv�����<|L�9����}�:�����H�C�PE��!6U}z�$m���s���zD���ENv����8��Y:��$�L�z"e��N����z�D��2�9�S���c�S?/��% 	H��l�_Ab�S`t ��&k�,��_��Z���B��-���K���4�����>sB0��t~0����;��h <"
4����E�@�7��|����r8.QC����u�a���\:����#���������
�D�nJi�8oT����c����_��"�-��h�������#�������po���z�t��pft�i������Oh�E#OQvG�>�1�h ���H6:�h��66����Pzl?K`�@�S:F���y���7����Ms}3��N��w����+5`S����R�p3">:����7�q�w]����:%�F�����g?;���?%�Q[�|�|��'7��^���g~�g�������P��+g�G~o��hMWOG���
9�
���g�}|������t"��Lq�2j�����%aF���$��@�����~����AN�_c�u�(����^�d��e����g��{�]w�V�!<����#<��g����He��u�E
�/��<�Z�K��J"F�)��.�/i�����
�#������37�+���$�"E��1�Q��a�l�V�(�m������(H���o�6G����A}�d��B���v�m��wDD"f��>�lm��t���6��������J��)��������u�6��is��&�e&0��B�F{9�sS������0��1��Ker�$ ��N@���L)����z��<�pF�p�A���uh��c"���n:�Yo��w���)��8D.���u�	!G2F�[��3=�,��@�JQ�0�04D�I�����r� ��"^,�+ D|������s�uL�t����~F4@H�]v�e���
���(�iL��b9���<��5'�	l��|�S�R�-�i�Cr�G�6��O��O��	�����M0@����M�zFw6
a�������4��n�T�!�y�����/���u�c98)oD3�II��0���[1���!���b�)�i�CWg^*�z0�+��;��C���C!�O��c�o=�����z����^k���-�s�&"�&������
���c.����}�M��wB�`��i����[�N��3�<���J�g�h�@�E>��^����7�tm�{�:�#��B�4"P_j����G�'��iJ���id���zJ�\3�_�&RN"z�.I#��Ny5��y���	����+����������&�:�)�m��G���~�*K,G00���:����N����?lHz�!��-?��z�T����w	H@�
6�/a*��NN�Pr7���N>�$�e�4D`D*��>����:�������j�:M�m����
P)������������gDD_�������F�1�h�e��P��yMm����U4�T}�*��7�u*��B�Q�����:wpBw	x�"�!�JX�` ������atP12ij��8i�eD����g�B�?���F���Z�@D���d4�X�vl���$������:%A��!2����8��<bB��NS��W_]G�I�7}NG�Z��������3��R:�p��t�@�N���9f����<�l���:3����M-���C������y&r,FNo
�@�E=���%���H^p���y��lk�4�8��y�c�Vm��5�O�����40m����ME��Z��+��0�7��0�������;�8C��S�������Zm���c�w���������G������hK^q�����"����	l%c�)h �
F�F���K���[�&(|
�JQ��������[����yy�.	H@�O@���%L)�s�T$p������c?L�D��$$ 7*a`Tz���F��T���c����$�u��9B%�I
��m�e�_}�I��%����\��������|#zN��|�ox�f!|�lcEt�! �y���yCQ��x�"���#���7	�G0Pb4�`���|e��c��Ej�<
M��C��{�;���x�c�����c�=vMQ���F�%�M��MW����{�|t�5xt2 F�x#�B@: u��8���$�+@�va��	��N8��X�nJ4�,�u9qc=��t��0���`u����b�X�yt\�2���}��e�x������<�~FD���G��eL�SNN�0�Y����&�����7��}/��<����}� �QzQ��>�dt����`�@_��'�[�{��W],����Fj( ,�>��:77�i������H ������8R�
��LU�.��4ok�IJ�:����x��V� Ho���wtnDE��
��u��S�9�}�Y�@���B��8�_!�<�R��N���mB�t���]eK�_D=c�����Y���P0�����6�`U?�
�@�|��e�tN���~u��t��S���i(���u�]+���BS���@E%F2����;���������0���'?������z��;�X�K��(%��q�6��P�1����s���������#�<r]��%|��.�@������8�	M�>�,�����X����/Br�1�0�C�N���������}�3�``��P����V�@���}������G>��y��ys�9�������9�c����EYx����k�k�.p�����x����a�7�����������H�:�����e�5�\SG�I#�����O���|Fh���)�8�?�}a�+��eT"
�����c�\9���&��\�����L����Y�(��at�3"�d8���	�y����'�����tn.Z0���"���^�`�t��;��J�Fp����e,�#����q"���B��?"
��u9�,�6rZ?K��������.�1��K}4UO>��XT����t�Iq���)�������5�$��1c�������"R��R��h?���/�.������e�3�o��s�� �% �>�Ju����Ud�}��#]"��y��l��E�3�w��G9�J@�@����2���;�`���o��g��(@*�K4v�a�u�]W-	�x�I'����&�i~��W������3��U�i4�H�@��������^� ������=�k�:�Bne#�0�e��y;�!8ctn*�B��K0@
�|$*�cR!��������
����"��[�/��yS������$��l���u���W��*a�J0@xJ�'!�I������6�8'�xb-�*��Q�DbA������-��@c��J0M#���g��Q0�S.��1�iS��t�� &y�s��.�����3q��EH �2���~��$�hc�Mi=�b����M�0��~�g9�h��,m���3!y�S+���9��C��?�)OY��X�`�/����S]����7��S��w�}��cS:���q�����"�O�;���!"F����0��4a���R#Bue,O�����rC=#u)
�������m�6IWy��c�mDLtR�F�%m
D��U�Y�6�"�h�}|W0$����vJ��(��(�m�����)?B��:cS���c�U�Xo�����Q���$P&�`��e��N) �s����Sev���q���_K�FE���&��*�c�=�k=���Q������S�����������Y�����f�HE$P�&��P(���U�Wf?�*3�J�i��.��,t��Vj����P���C�#*�1��m4Z�����������6�o��q\O���wK����u[�g�g��}��I��(�MS1��8���)�d��N9�����/_�
#�bTr, Z
�i�sa;��S��'u�!Hs���mS����G\�q�y��O�E�g�c9�Im���4�6 ZB.�����>������{��j��v���&���8�)Cs�Sc.S���z�#�%�s���w��#-���12�N��&��T������{�����l������~.Ou-�����!���DwT���^�(�]����NU:d��z���1L��M�;s���F?��c�E�J�����,��������'�0�w�q��NQ�n;��h�����l����$�����������/��k!�3����<��0`����q�F&��N��x�RO-0`��-���R��:�*�[T=�}�9>�i��$�N@�@;��\�W(di�OZ�RgyS����H+%�!�X��:�u�y��_�5M�H{F������u�	��4��TJjh58 s�s�fj�1B1w	K(���>��bnG���!�!�:p�2�uJ�DD���Z���;
Xo�``��PS��/�U"�;�q�!�Jmke��,
�hs:���y������}�"�@�3)}�H?��<:�G?��������Tp�����n`�]v���tPb�������|��A�<���/�����n����,r�G�	vG�T�K�sDd�H�.CD�1�!A��������
��u��%0���������F��w?���)ZH���"j
9��9�QG�uMF� �.J00�������E����O ����-���{�]����$R�����O�p�=8�Z� 5r�S6���$�$Hy��5�(��w�O�[:��g8u�6�>���S��m��)���c�������c�$��t�so�K�u�<D*���K��{��^VG#����rv,c�` ���U"��NI��6i������v���-���u�1��6��6#��O%`�(�Rs+��K0@G>�%�����i�GGF4��t�;U8c�k�61�1]���r�=�1��F���y��W!���N���W:�Px���������^xaE>��P����
G��6D0�����������^S��z�Tj\?*�CG�����S��
EY�J`U	���NxF�ai
�����`����i�k|g�}vZ��?/�8{���QN�0R��{���_������z�����}5[x��4�*�{�p��x_�g+ND�Q��O?}�.��!�������p��3�\s}�x�q�H�)v�������d pcc;_���|	t�l":�\Q_+p��w��g9#1����(gI
�O����KShQG$"Kq��%�x��������C�~o8k���(����\G4�yK������?�?��{�G�R0-��7����5`���7�g?��3�NN���N�	R	������:1�|��k��S����n�6IZ�y>w��<��\��.�����q�k�s���4��J��Sb�B.��9�z��3?���__=��O�W���l��gt����$ �ML@������1�t���a�M0@gq>�}������������cqE�/�8,c��la�#/X��T������ZS��{��^���X����a�%��G>R��������:�B:��4�H�6F0�n��3�A�Q�� 5�N�������?O!�����F�
%�A�I��V���\n�����t���o������:�I�QY(�I	�<�m����H4?��*�3��� ���k���'��#���<s���tl�!t���d�bdB�l��S2�}8���QH��k����I�o��H�s�D�����������G�v~��T�:���E����o���A���w��g9�F��$#�]w�u������~g�p_��D,a'�1��iN�z��!Be?�D�s�7�|��6�x���"��0���	68mS�����i�����HG;��A�����-�O���E����1������m�7���u��3f��k��MF��U��o|c�n��>�!�!�=����D�(m�Y���m�8�)�m��������Z?W����:�pAr�
ms6���X6C�)m�OS� |B�3���mk�3��?�y��$ ��F@����M0������'��<���;V{��W-���q���}*�@V�c�p=��C�>m����n��"�+�%@u�W���v��~Q�} �Ea����L��r�(K[��1�����J���V�@�hs~t��"�|�3���T���3��#�sm���|���y���=�N5�3��6��	��$F�T��������&cT�	'�P/�yK�������I��-DM���.�`����9����O:�m?D�!�6�����I`���N<:�"}#���5����/�Y�v~�s�{�z3����mM�^���T��{n����CO�\�����7�����D�i�4�?�����'�"���[n����UJ����'����W�C��(uU�g_��W[O<
sO����w����6���}����eiD�����{�U��O/C����g����#���.�0�}�3��"%[W��!m����A�@W;�xD#j@�� t�����lS�3J�i;~i}�I@�@����2�������M?F�����@�:�<�|��|���|G����D��������c��tx�y��I�<4d�����]�F��8N�P���M�4��q����)��(_:�R[�X���+��7����%����1�y���N"��]���^���ICcR&Dcm��> �
c�%���9�!��1/��q���y����1�0A]|��w��]+F����w���uz�#��
0"1
����<1�8_'$��D��������w	�!0��t��'�F�Q/�����[��>�
)���/�OD�����"(P7��iO�:��p6���S=���M����A��@D�����RG��O~����3�����-����?�0�}r����v�y���S�Qn=Y.5����~�_�t?�^������'��'������V�<�9���S��Q.K�����O����}�>S�I���>Oyo��}���q������4�&�is�6N%���S����6/z��*��6Y*.������o+������������S	H@�&�`�������(�	Y��1:������l���#�q�F���h	�����c�Z�N���^��W�S	�7�\i�����F'��8��i����!rPv	8��b.��.��nH��|O:��
�En�������HC@���m^��������I`��$�#�T>��{���lq8��D"�g��u��N<�ExkC%�x������8���s;F���Jsq��g]����xV>�Q����h��^a�v��W�"�TV/���8��2q��Y�
b~L��hKC ��d����^���������w%!��ww��0�O{����c;_c_N%0�@_g�gy���8V�������rF��w����F��������Bd�������������It��W��Q�������a<�sy�k�t~��<��5L�rx�u�<u ���-[�+��b��h��3���q!�K�wm����#@��wp��!�
�2Hy���~����^!/��\����"�=��H�����O�1��vH�g�6I��i:���s!��������'�_�Fj�y��o�3������)o}�[g`I����L���$�Bd�!>��S�Un+����R���_Z�y��$P&�`��e��n4�?�����8.����k_�ZE�S��9��a�5"��|=�*�����|��������)���X�R0@����h��	�h�����Z=�IO�������w�;�������E
>��OU4��)�i�T���oz���k�t��P�\(�MD`�}������	OxB�����a�;�v� !��Z,0�qr��:�[��~{��J�X#�W���+�2p�%���
R�ixx������G��e����>��j�v�-:���+�����(�q�` g+�"���5e!�
���	a�������U������}7��5��Tc	�u6��%/����:-������A��������c�9fMHs�����F���Od����~�x�$����w��z��\����k�|�[����{-b}���m�4�u�c�=�"�G�AT�b]���/����!:$� ��D��J������I���[������!�DX��=��Y��8���'@[�wK�g9cRi0Hd����":��9�W���aC�3e}�2,[�$���S��<�����T��0�I�%�n���z���/}�K��G_��>m��������j�|��k:�������7;3����S��GY]~���u�|�*[�}��g��5��K�v�$ ��D@����M0b*���D����>@C w4�vJ�1��#i���*�Qf�cn%�8[p�`��
��{��o����"|��^i���k�H��V8y�E�8����1�o�}h�@U����r����~�#;}W�<N;�J�y���7�n�����s�����t��|'��w�u�����,�[J_p��g�q`�	y������c�=�E�y���U���of���kG��4��p��Rv��9:��1b
"$Dt�8�\�:��x���"���^g}��BFac;_�}�]c�q6�����.!dm�0�V�m����,G�C���'�9Q��#1������&�����XGa�X�2��e���Z���y���:;���������8����!�!��0��u-l�8�����l�x<�@�NB���
����y� #�S�#8�wF��0�4�k��w�Y��
!.�T������.X#T�m��a�����I�N�{�ACyD�\/�}�Cg�d�D;
�u�6�js�m�2	,3��v
�	-�?��o����9��>��i�r����(�m�v��m�tY�zF�
��:~�_�K@�ll�+^��fD���l��r��*|9f��TB����/_�	QZ�yt\��B�&l��������(�>�c�H�����G1]F���g�Y+��uKb�\T�3����s'��q1b�<��-R0@G#@~�'~����	�������yC]et�6��]��#�8�:��c$RM��k�����YHg:
�.�i���),/�s��}�h�x�;Z�?����Rf��e��%Dh���m9Hg#���|�']�����a�0r����u�,�E��l��8��C��0b��C�,��~����.#�����k��7�i�t�XGa�>O�xk=��\��<���<�Y��#��5�����h���i����Ju�
�?���g�Qh��me��M����u�j`�G��rF�C�|�~�']�\���������>OQ�^�6I�y�l�{����H�tl��\����M���w�9g+�A�@�v
���&��?�0�mo{�$�������3��Mu�t�~��$�	(��W����bK�Ct�7��/�p���k��v�+8�.W�����������>���������:�����
jbw�%.�@d=��4�v�i�u)
h��~����A2%�(/���	���bST����gk�@)�\��R\_BD���AD�/5�K�

�\:O�Rz�e�����LTl��������q}	�*�x���hr��}l�=����r�-�xS�����F�W}m��0Z�(4���]����9�y�3���m������$b2�y#$+e���eF�v�
7�9c)s�c�T;DH�	D��Dd���J�����B������$0%�R�x�#�]��E���G	q����e��}��*�+����L
>t��;�_�B�5e�a�*#}K^�����o����k�����&��=�qu�����>��3��!��I�D{����������?���g�}�G[�lY'8������i�t�q����]����{��w\��2_�}�g!B%�����3�������w�E�?�[�^�6I�)�mB�
2��GE�OD���XW���>\G�H���e&�uh��0�+��|
�~��-���yh=#�1��cN% 	lV
6�����M������=��t(�� �b_#w
%OF�
�ma�@��)���PiC��������'���
]��|=�e�
�/�s$ ��F�N~�q�����8�K$P:G�CG>v����x����IPW�O�y�O8�3��"p3���\���[�nFB�����
�)��H@�I���������	��W����,�D��������nV��GB��|G{��M��+����>W�,�������ZX��Y�c)/��7�x�b��7=��e�4���gRd������OOU���$}�3����#�E�KxF Fd`�&	'�a�]v�	���B�i�G���$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@���_a�O��$ 	H@��$ 	H@��$ 	H@��$P �`��Y��$ 	H@��$ 	H@��$ 	H@��$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@���_a�O��$ 	H@��$ 	H@��$ 	H@��$P �`��Y��$ 	H@��$ 	H@��$ 	H@��$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@���_a�O��$ 	H@��$ 	H@��$ 	H@��$P �`��Y��$ 	H@��$ 	H@��$ 	H@��$ �U'�``����'	H@��$ 	H@��$ 	H@��$ 	H@(P0P��,	H@��$ 	H@��$ 	H@��$ 	H@���P0��W����$ 	H@��$ 	H@��$ 	H@��$ 	((@q�$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(X�+��I@��$ 	H@��$ 	H@��$ 	H@��
�8K��$ 	H@��$ 	H@��$ 	H@��$������$ 	H@��$ 	H@��$ 	H@��$ 	H@

P�%	H@��$ 	H@��$ 	H@��$ 	H@Xu
V�
{~��$ 	H@��$ 	H@��$ 	H@��$ �(���$ 	H@��$ 	H@��$ 	H@��$ 	�:�~�=?	H@��$ 	H@��$ 	H@��$ 	H@�@����gI@��$ 	H@��$ 	H@��$ 	H@��V����U����$ 	H@��$ 	H@��$ 	H@��$ 	H�@@�@��$ 	H@��$ 	H@��$ 	H@��$ 	H@�N��n��POY'�IEND�B`�
hardware_counter_results.pngimage/png; name=hardware_counter_results.pngDownload
�PNG


IHDR�l�sRGB����eXIfMM*>F(�iN��������ASCIIScreenshots��	pHYs%%IR$��iTXtXML:com.adobe.xmp<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <exif:PixelYDimension>512</exif:PixelYDimension>
         <exif:PixelXDimension>2060</exif:PixelXDimension>
         <exif:UserComment>Screenshot</exif:UserComment>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>
�0Y�iDOT(��R��G@IDATx���$E���"( %
$� ����D$KI� "��
�H$	��x��3�s����5_MM�9z��y�yvg������}:T��j��[��`R@P@P@P@P@P@P@P@�1%0�cj��
(��
(��
(��
(��
(��
(��
(��
x (��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@���cp���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��cP���1���dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�A��Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�1(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@���cp���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��cP���1���dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�A��Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�1(`����n�
(��
(��
(��
(��
(��
(��
(��x(��
(��
(��
(��
(��
(��
(��
(0�;�MV@P@P@P@P@P@P@P���P@P@P@P@P@P@P@���cp���
(��
(��
(��
(��
(��
(��
(��
0�1��
(��
(��
(��
(��
(��
(��
(��0``�t7YP@P@P@P@P@P@P@<P@P@P@P@P@P@P@�����&+��
(��
(��
(��
(��
(��
(��
(`����
(��
(��
(��
(��
(��
(��
(��cP���1���dP@P@P@P@P@P@P@�P@P@P@P@P@P@P@P`
00w����
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
(��
�A��Nw�P@P@P@P@P@P@P@0`�c@P@P@P@P@P@P@P@�1(`����ca�7�x�0n���M���{��;�X7�
(���$���;���_�.���_��X7�
(��
(��
(��
(��
(��
(�@+��4���?��a�5����;��N:����s��M/������e�Y����^{-�?>��	5���na������C=�Zk��i~P@&$������S��T]�������V[�M��
(��
(��
(��
(��
(��
(����(
�<_�����{���CZ��|��
��	e��C��o���>�|.�.&��gF[�i���<��S7��/������i~�xZ
���x��[��
(��
(��
(��
(��
(�@/��n�m�@9��.N����n���o|�n�^}����u3�a�h5`�cc���f^P@P@P@P@P@��	0�7������rW�]�:q	l���a��6��(�Yn�����a�h5`�cc���n�
(��
(��
(��
(��
(���0`���}X�����8u��Rx����l��(9�
(��
(��
(��
(��
(��
�*`�@�RC:� �����y��7L1������>�l�J�N:i�e�Y�TSM�{�����w�;�:����7��?�xx��wj����8�$��:�m��
���~:<��c�n�����3�X�M7]x���3�<�x�����j���~���a��/�P'W�����z9���O��c�0��3��=�����1���r;��,��m�}����s�Y���x�����z%��;``��8��
(��
(��
(��
(��
(�����L8�0@���k�V^y�0�������w�uW��������^z�������G��{������o�y��v�a�����b�f�m���^?�)��2���Za�u�
s�5W�����+���o�=��o�1�0���/O���O����^7y��?�����a�-��<�H�t�N~�D��������[o�&�#����N���?��f�Z��,�:��p���_=N����/8�W[m�0��S7�����
�_~y8��������	T��7.|�_�}�{�o�����?.���p��g�{�����w��]���O�;���C	W^ye���-P��&��r��1���?��S���o�[o�@pCL���G
?����E]'�K/�t�k��������t��������p����M��@�mj�o9�#�b��n[�A+�n�i��\`���VT"�������vZq������8�F
����v������
(��
(��
(��
(��
(�����~j��~P	K%�K,�4/�������[oM'�������i��o~SL[q��������.\s�5�{*�L��?�0_:���N
�N;mX{�������*�
h�~�%�*��4~��p������J��6��n��w������nzY�=|�s���7�
����a��&����@v�i�Z�w��:�Ne��[o6�x���Q�L*�iU_V��������
��e�����<����_���k�R�1�~q��A�4�/�����?�y>9l���J�f�=%���7~�N h#0������7�����.l��V��"X��c��6��=��r]f��.�������~�5Fe�-><p����ei���4R�@��F��n��P@P@P@P@P@P`��}4b�0@%����@���$�(�u��O>Y�YYe�o����7��y�g�yj��
y��0��h����-��+�(*���TS�����??�#A�h-���|$�T\@GzF�E{;�����~H[��������z9h'����EP@���'��V��&z8���k?�E%o�q�	��n%���I��R��c�l�Z�[.6b���YnU���*�������7���p��g�����X�U�@U���WP@P@P@P@P@�0�0�S�\�#`���+m1�4S�'�|r��;N*��������o}�[EK��yZ��0���nX�S��������~�)���j�G��/}���y���?^���{������/�N8���+A����Ee<���J���j���~����W�����"��C�u���
�
����*f�E%o��}��x�f���|����hw���r�m��N�[��q�{�������@@�P3�<s��CI$E��^K��r�����
(��
(��
(��
(��
(��C-`��P���3�,`���=�����>�P����Yf�@7�Tx��Oj���3�:c�{���
+�Pt��0�����*_z�����+�J���{�����b��f=<������n
�%��}�i��i��'?��p�QG��-*cc�TB�x��
��	TX3��1�����<\m���3�<3�{��gC����//��g_���@0��s�U]��w�SP�M���4�1�
Kx��G��^n������0&}��'��_��W���p>K�8eY7�|sXh���k�Q��< k��f`����w����;������h����,�������L3��]v�b���b�5���ML�7�xc������i�Xf��2�:Z�t�Um���g���M���*�vM?����'���#�8"���(&��X)`��c��m�=���
(��
(��
(��
(��
(���-`��p��Qs�,``��2C�v�i���t�{*U����4�U��"�����U����a��w/*�Y~��Zj�0~��tR�=��5pL�2f���?���!�Jq���f�m��^���^{���n���C0�W���b���URQ�������~��w*�	~�R4M_|q�6�����,������+��1Q	z�y�5�A��PSq�Yg��k��|��i%�\s�Um1�TS���o6�d��b�����{*�w�u�ZO	��t�Ia������-��rK�3o��~���F�M{����r�-W7�U��i����L�L�d�Un����>�!g�n�i��?�Y7��J�}u�E�Q���ci���4s�Uns��+��
(��
(��
(��
(��
(���00��h��:``��g_����E�g69,�������*&7�d�����>�i��
��7���;�SY�=��|>��c�K,��Z:���k�	Gyd�%wm��M��f-��!
�v�������'�m+��?�D����B��l��?MT�/����I������.Z�<�G�8��Z�8�{��6k�Ig(���'�(z������v���JT�����A������J���Oz
�&M�����������������N�p��@�6������2��C'��r�\p�p�i�5���[o
�zh�[E��0��M�P���fNW@P@P@P@P@P@��0``8�K��D��`t�N�oZ�O3�4����[��U:2Z������D%r��_��W�������I&���>� (�h���k�^���+�SO=um��\rIXu�Uk�Y7y ����-�D�}��7����O�����t��(KK.�d�m������?^x��b�������:�4��l�T������_�b�����g�SO=�0}��'o8���e��f�6n���0yb��K/�4�\t����;�-`����Z�Ckp<�����~���P7����fN�e���-�e���N�[��1��p^+K��@C���?��O��=9�z���������
(��
(��
(��
(��
(��
(0���i-c�h����/����������!	��SL1E�/�0<����������%Z���0�G���*�N>��@�4�e��?����3��L������e�i"���W_-�t��VZi���8��A9�U2��j�=��{o1{7e�7�=����m��e��j!]C�C.P��0�h^V	~��g����i�����
(sjXy�1P�M��-����;��g��n���[��q>"������O(sD��^Ke�z�u�����*]u[�U�����.~P@P@P@P@P@P@��0``�w��l0@���7�<�����n����=Oi��U3V����������~����C9���Z���L~�n?My���]vY�n����������w�S�N��]v���������	'�P��77�pCC���t�k����uy���FmT��&`�l��=6����e=��c����|������������7*�{Q�[V�����a����.s���m�@��@;��o�H�;Yn��6�d��<0���*#e��;��~�����:�6��R�������FP@P@P@P@P@&&���<����/`���4u0������ ]?������X��w\Xl�����<`�/	T�G�4�8�
��|T�2�=���i�<�H�i�������c�	�!�A;���������������'������W\q�v�S�[���_=|�S�j���_��5hN@D�J^z�W�<-����c��'�
6� �~����v*�{0P����&�c��mja��Y:Yn��Ff�@g(���\�P'�$Z��#��R��o��rL
(��
(��
(��
(��
(��
(0�00������:`������
�������W^�
����
+=�3w0P�[�����TT����3=�=����,���SN)*	���)V�����u=�u�]Ez��]���}L�v�g�}�m�������wa�N�}:�K.��h?)�g	Z��������_�B�o���g�i�>���mc~*z}����26=�n�����"��Y%/�+yO,�J����/_���9ustR���T2���V�my������~����LX`���8b�8�z0�nw���.��
(��
(��
(��
(��
(��
(0��>1��8���"�,R����2�V�i�e>�y�6``�vn�a�����J�<�3����|ris�5W8��s��}��g����g*����n���>&*�_x�������E��r�y����[6�@��"���i�������V���N�$���i��������f��w��sN���=��t�A
�O?��p���w����/�KC�0�{��w�����0��~��"x���^��k3�N��N*��2��C'��z��d�6�������o|#0�I����Z�%�8��	hvl��o���mn�{�+��
(��
(��
(��
(��
(��p
00����\�:`����s�=w]~��=o�O��������3�\7/�
Xn���G��\*���~�p�5���#��SO
�"�SY�SVA����K/
C����������O��R�>ma��#����_���^�:}�=�l�a��/*��n�|����>
��-��7�.�hik���{�:!(%�����������a�m#p��_�j]/3�4S 0��<m��6��k�-&�w�ya�9�������Z+<������=R��]��M�o0������0M��:=��n���;�I�,��mcs���}�9(�l����z�n����n���cc��q�nsj�{P@P@P@P@P@n�{����^��z��W��b�zh��?�����s�1G�|�C���e����y����Ja� ������=�l��f{��WQ\���N���/3I��TJ���7�v�'*�t�Yg�3�<30�vt�����*��t�w�O����{.�����C�n�����8|������'M���W_]L/����{�����[o�5,����+_�J��/�^$>���Z`����~���O.�M�[z���b�)��!�#`��/t��c�=�����<B�T�1�I�~�����.��mk6\�/~��p����zV��*�g�e���������,N��Xj5`��c��m����
(��
(��
(��
(��
(��
�����F�a��^{���F�P����H*E��&5Xm�����f����J��v!�8�����|7����gFl����o��������?����~mv���`z X}��C����0�,�y<��"H!���������*~���'P6�F�a�n��R�1�i�~�����.��m#@�J������w�&�l�@�������G����V�96������
(��
(��
(��
(��
(��
(0���i)g�*]7�x��u�hah*��DK}*�����e]���i���������h)>�l�5[�����8����K.i�������i�w�y�����{�._c�5�����8�����K_�R-_��9����>�����-�WV�9����?�A1�D:o�V��<e��������;�}�>��7�e�n�Q>�#`�a�9���������N+�Ga+"�����6z��'�|X������?�x1�/�P���c��o&�����c��m�m�oP@P@P@P@P@P`��]4r{0���Zj��s�������^+*.������.U0��t?~|�Z�����W^YT���?M�����N+���n���c�t1���/��������J��4��N:i�n����nX���i��N�T����f�b�������_�BKKy����.������7�Oko�Rhu�X���&��7����K�#�<r�`�j����w����~�R��`�P�[�������a�j�����v1�D3�����/���_H��<UK���v����9n��
(��
(��
(��
(��
(��
(0���5wt�~�4���z������az>a�vh�`}������/_WA�X������������������|Z������:��3�|��W�=oN:��p�QG�Mk�a�f(�K��L3M�lO>�d�2����*����������7����o6�h����J c��	s����^{�.� �\�<,�T`2��
+�&�|�Z��*��������o��{���O:�7.����y�B�o�[q|�1RZb�%�:��V\q���~��k����%����iQ����}`��go���n(���r�)�)��R�=������+��s�s\_z��
y�y����e�`���Z��
c�Yf)f!���g���lSY��M�b��n[�����o�����'O/��R���{��~����D:U��A�#MI}�;�I'���{lT���L�FP@P@P@P@P@�V�����5��1Z��=�����o��Vx���A�N�&�w�i�-���G�3�<��lt��aq$�c�9�T2�?�E��������NT�R�I~Z�8cX����+���+me�������X�E�9CFpP�
���	`Xp��a�'��{����aM��#����a;�4�r����(�G��  ���v�0K�Uls;>���
(��
(��
(��
(��
(���0`����QP@P@P@P@P@P@P@��00�]`P@P@P@P@P@P@P@����7w�
(��
(��
(��
(��
(��
(��
(��
\�����3��
(��
(��
(��
(��
(��
(��
(�@����kT@P@P@P@P@P@P@P`�|�P@P@P@P@P@P@P@�/`�@��]�
(��
(��
(��
(��
(��
(��
(��0``���(��
(��
(��
(��
(��
(��
(��
(��o�P@P@P@P@P@P@P@���f@P@P@P@P@P@P@P@��0�s���
(��
(��
(��
(��
(��
(��
(����.0
(��
(��
(��
(��
(��
(��
(��
�_������FP@P@P@P@P@P@P@.`���w�P@P@P@P@P@P@P@P�����5*��
(��
(��
(��
(��
(��
(��
(0p���
(��
(��
(��
(��
(��
(��
(���0`����QP@P@P@P@P@P@P@��00�]`P@P@P@P@P@P@P@����7w�
(��
(��
(��
(��
(��
(��
(��
\�����3��
(��
(��
(��
(��
(��
(��
(�@����kT@P@P@P@P@P@P@P`�|�P@P@P@P@P@P@P@�/`�@��]�
(��
(��
(��
(��
(��
(��
(��0``���(��
(��
(��
(��
(��
(��
(��
(��o�P@P@P@P@P@P@P@���f@P@P@P@P@P@P@P@��0�s���
(��
(��
(��
(��
(��
(��
(����.0
(��
(��
(��
(��
(��
(��
(��
�_������FP@P@P@P@P@P@P@.`���w�P@P@P@P@P@P@P@P�����5*��
(��
(��
(��
(��
(��
(��
(0p���
(��
(��
(��
(��
(��
(��
(���0`����QP@P@P@P@P@P@P@��00�]`P@P@P@P@P@P@P@����7w�
(��
(��
(��
(��
(��
(��
(��
\�����3��
(��
(��
(��
(��
(��
(��
(�@����kT@P@P@P@P@P@P@P`�|�P@P@P@P@P@P@P@�/`�@��]�
(��
(��
(��
(��
(��
(��
(��0``���(��
(��
(��
(��
(��
(��
(��
(��o�P@P@P@P@P@P@P@���f@P@P@P@P@P@P@P@��0�s���
(��
(��
(��
(��
(��
(��
(����.0
(��
(��
(��
(��
(��
(��
(��
�_������FP@P@P@P@P@P@P@.`���w�P@P@P@P@P@P@P@P�����5*��
(��
(��
(��
(��
(��
(��
(0p���
(��
(��
(��
(��
(��
(��
(���0`����QP@P@P@P@P@P@P@��00�]`P@P@P@P@P@P@P@����7w�
(��
(��
(��
(��
(��
(��
(��
\�����3��
(��
(��
(��
(��
(��
(��
(�@����kT@P@P@P@P@P@P@P`�|�P@P@P@P@P@P@P@�/`�@��]�
(��
(��
(��
(��
(��
(��
(��0``���(��
(��
(��
(��
(��
(��
(��
(��o�P@P@P@P@P@P@P@���f@P@P@P@P@P@P@P@��0�s���
(��
(��
(��
(��
(��
(��
(����.0
(��
(��
(��
(��
(��
(��
(��
�_������FP@P@P@P@P@P@P@.`���w�P@P@P@P@P@P@P@P�����5*��
(��
(��
(��
(��
(��
(��
(0p���
(��
(��
(��
(��
(��
(��
(���0`����QP@P@P@P@P@P@P@��00�]`P@P@P@P@P@P@P@����7w�
(��
(��
(��
(��
(��
(��
(��
\�����3��
(��
(��
(��
(��
(��
(��
(�@����kT@P@P@P@P@P@P@P`�|�P@P@P@P@P@P@P@�/`�@��]�
(��
(��
(��
(��
(��
(��
(��0``���(��
(��
(��
(��
(��
(��
(��
(��o�P@P@P@P@P@P@P@���f@P@P@P@P@P@P@P@��0�s���
(��
(��
(��
(��
(��
(��
(����.0
(��
(��
(��
(��
(��
(��
(��
�_������FP@P@P@P@P@P@P@.`���w�P@P@P@P@P@P@P@P�����5*��
(��
(��
(��
(��
(��
(��
(0p���
(��
(��
(��
(��
(��
(��
(���0`����QP@P@P�G�L2IXr�%��+�n�����?�)����=Z��U@P@�^xm����W@���]��KR���S���z�{�X`����o����+���}\��R@��M7]�}����=�\x��'��	�b�V[n�e-������~���g�(��
L8_��W��;�\�������g��g�(�@o&�|�0����Yf�%��?�	O=�Tq?hyDo�]j(�;&����O��0��3�v�n����g�������w
�$0!����]~�\`�����������7
�����W_=,���a��
s�5W�t�I�-�A����T~\|�����������+��
��<���[o��5��<=����������P�3w�yg�����o��P`	|���,�Lm�������_����7�+����&|���e��Jz���F���L`�������"�C�P�q������{�
����^�?�x��_�������?����������j��u�]�(���q^������p���ZQ|�J`by����/�O?}�c��v
W\qE����&�z����,�r�)�y����+_	���J1{\�9��S<G�exm��*�(01���)e�^4l����z[v8M���Zt�{���v�e�0n��Q���;���N:)�?����M6���9��3��?<�r�5����_�G����n�m�h��Z��#�<v�q�p�=��4�g2`����O�����VZi�ZF������n��0�+��/�pXu�Uk�<�������>�.�����k��F��Z>���F;_-������NkkS�������[�~8�����?<�1��f��~��'�>i�`R�]�������*0�������5|���������������.������:�6�k{��7
�&��bm���fB{��G~��J��~��9�^q�&��m�_���������D����x[k��}�vh���SL1EmY���[]Do�����
���*��}���ATW��J^y����{��������:�}�ve
Ly�0��{dZ1n��v���
MZ%�i���|p�f�i����h�bR`b�|�I�V|n������w�RK-X/������~��B��
L��l��P����.�����/��;�>M��D�R������������z^L��������V]�ZW���sv���m������^�^	0�+�>-���l�A��~�V��<�������0����":M�<Q��m�������p>P`B�l����[n��	o��v1�&�,�@���<Qx���|'������g���J��������V��TSM������y���g�(�C���W�^~��"W�Vch��D�=J�GX�u�Y��
���7�p��� ,;O��rK�x��= �hE`b|�`�'�
�����q��9�����+��q8�t�<`�����B���y1��Z=@��[u=Pj������{��n��p�M���
�J���^��a��L2I�J3������������������a��w.n��<����:�c���u��[�0��kq3�M�`��o��K�����6),z��Gk�F�@T����(�?K2``X���P`x�p�o�	|n����|U0���]w�Ud���Yf�%����EP(��i���~N8�������/|�s��}�
�?����E]Tr� �n���u�i���
\pA:��
�
L��l��P����N$x�_�B�|���3�8c���K�����^��,01���:���2���J����^��L��|���@/��j��9���6<`����V[�M7���;Zy���
E_����_���k�����X���s�=�����/�����"����"�,R|u�)��~�]v�e�'>����
cmv�}��;���X�e�]V�=!�j7q]�N7�ta���*�1�m�������R�<�p��k��?ixO~	���>�����'�|�������m�JWk��l���^[�������-*��������q�����.e�:M�]��7�n�_|q��l�x��y��a�E��
cZR�T�9r��f*
��q�������v[�����u�]�:O�,���E����:|`\/�>��p�w����L��j��V\)�g9/��R����������7�X�?(�@���<`��~�����_>,���?zZ��C�_��E�n�D�`�'�"�s��>�`��@�Z��w'��ey�~��=<����GkY���K��<��z��SO5mU��yz�m�-���f�!b�����$Z*�?�h��O~2����q�p��7���;��9}3������������^\7�����y"p�sb�@�w,�%�\��cY<�\���g��ke\v��@���
�v�-` d�_���Eo�q:��_�����3�<s���<����=M��������=����n
���7�I�W�T�����L�
k��FQ6��e�9��=�\�|�s��������=����p=�o���
�<�\s�5����
��a�<C����������^h�C:��g�tY����?�oF�mo��w��lY�Z��w{-���lK����<��:m���y����y��tz0�����x����7�l���8����ZO�f������^;|��N�L{V�K�~��!M���o��U�E����WU�����t��������4�}��c:��C9$��x��e���f��n�o'��dt���
6NN�`'t�
��8�5�o�@IDAT�?��3J��P:�'���zjQ���=]
�H���KXo��j__z�����J+�T���O<�6�����W��X�#�v�a�����#=@��K�����
������SN'5�r@���?����n���R���O}�Sqr��/~�8����.m��d���y�������xq��~��p�a����*���t�ID���D�U#\q��z�&��VUy����<V������������4�0@��Y�FJT^x����B���Z��"����|�QG���z��|~����������a
�hM[�(L����^��_�z�~���*��e<��Ca��v+
`���{��<s������=1���q�t%L�21q��������N��c���V[`�{*���H���W_]�f��[\F[6�?��O���Z`�����{�]w����J�A����c _�����h��vP����J�(J��P$�8����?�y8��c�I
�)|O����!��h���~��<&��|�3�u5}����W���v��y��	8��������W�{(#H8My��_ip\:?��TX��D���xVI�������������Y�������\����v��*�A�yhf���G���E�a�2���29�+�o���4Uq��3y����^�zL
&�M)Mp@X}��k�(������[�R[Ho��b��=�)��s��������i"�#
��l���^�i����^�6;gw�Y~����v����
�WL�(`��0���DC���������8i��NN�yac���BE
"���j��D!I���$����VQ��v���4���B�vS ����9����

2OyA+�o���E4z>��P@�A�U�S�M%�h��$Z��DK��:G�=��u��<��
�suL�P����=���'#�R(H����m
�k%�[M^ ����G���Ghe�T�����u�M���/�{V��������=r���Uts��E��a�]w���~��+}.(+m��������EPA2i��t>���@������h��v��E��������{�����|o�Z:�8���2���~���OZ��tk5���t~
N;��Z��we�)��z��k�c�'��(�]>�r+*q����xV�����������zp�[�2O��M�n�@��Sq�����}�m���:q���tS.���L3MQ�1�\s��=��[nY�;b����t��G���-�	#��Hz����3�<3���?���,]N����b}�K��b���&A�5/M���@L��%���o�SO��<K��a��Z6� _�Q���a�+m���n�D�2t-JE]�������
��0v���>M�����D�mT��Z-l�-
�0����^.�t��vi�:���:�77�6�Y�H��e}���&�(��D���.a�i"r3O�r#��9���!����������}����F;�G�^��R��WP`�A��*M������T�9��n��D7��*
��&L1��WE�}���}��b�he�7T�������/��2� 	�����+z�I]{��
���,�L1�M���T��u8N�U�#���0��"�f� O[�9�D��6�����B0�0�"�^?���s�)Z�vr���=|U����>��b���y�U,�����@=R�Q��^�{��A�/�(y�P��E�@��p�f(�|<��(�������+0��*/�E�{�8�`.��+�������������O�
�k_�F�.z����;9�&z�������i�l�J�b����t���9!m8�����b������]���J[�V�����k�@9dZ�D����������@������n�����<w���C��u���y��\:*>���E�&�9��z��	�"HU�w������9'�|r]�
7�P���Fy�������C�$�q9��VQ�:���.�U�'�;�������Yg�����aG�t����$����e���u���F��8�5i�������?�q�����O+UX6cS�)/@������Q�����Q��7�<��o(������P����v�).�xm5D�1������e]�@O$h����m�����<S�G4e���
$c�b���0
Zb�����3�'�lQ��P`�T�p�����*����U�#��?���s9=����1��VD10�|�0��}E�v�G��&���b`<90�`4"�4,����������o���zB`�&��@^�J�
��������������{����@&�!Iy���B kL�VB�1Q0�r�����#�{_U�@�i�?������fTq���?����l�����?g=���@h���
D����g.�F��"��<��XUq�|�����
��p��Mx�lN�$z�J���!M
�B ?���n�?(���%&��t�L@�����B�&�rfMR�3�l��6���n����G�����K�5���at�N1/���7�Xf�����>���cU�*q�������u.��P~��� �c7�jI0yL�t{-���U��n��|��zq^$0-�F�2{���S�<I����sO���|T��q\~+�8U���>���������'I�m���3���V������U�Q��98�����Q�D�W�PS4���-�q�B�WL�]Q�E�y�yZ���Yr����
��M�*`�����6�U�]`��3v3D�����������Cm:���P����V�q�����HK�4��?�?���F��~����r��x�?������c���r� �o~��
nei���k����-R^�\��T��Q���
(�� �(�[n���b�y��I�5�\���us�����pi�2h�{�)`��F�=&
)0����<������o���D>g�q����>����<�s
���@~�������������{��o>�����nq���97q�$8 o�A�DZ�Q1��|�c��s�m��V���V����,�#��W0P�y�����P�A�.��1��C�������J<�����@��(@d��D/�����|�	'�Tu���:6F;_�0@/Tp���%��'*�HSZ8�N��U����������x��q�����k��6Ba�k���V�\_����d!��p�]w]�1�� (�g��zD�xi�=$�B�T��J�����?T:��Z��]IS��i��es�1E�J\��N�@���n_�>�6����_��E����?�z�d�F�=���H<Vu�b+�8U���>�Y(�I{Q�n��wZ�S6�X;���v�ZU=�����s�Nq�.K��|��w_�P'���������������%��zk�`����a0``X�D�� �����j%Q�E+*=�����������N�rGzO�v�c����[O����1�-4�Da-����/~�.H�n"�xx��%M�RP�'*������n��������W^�V��M7g1�]��i�*����M�zLT�,���u#��v^�9G�U��-7�|=��b��&���6�Hy!=���q�yT~Z�H�5�����)Z3�'���P`x������]��W\1v�au��
+����G�..�/����(*�8G���y����#��v�����<M��(�8�����a OT��������
D�s~�,��N[c\�����t}�{�����{�#����@���1U	�O�L��Q8L��3�=��Z��Z�W���I�C�PFEOiPr`GOf\�cj�����=�q��L��W`���b�����K���^�������*���������PAS�~�w?~|������1��GO�)i]O>�3VZy��F�|��Z���s�N�A�y���N��8/���H�
��������&��`hRU������_+�8y�;����+������u0�HV�Z�/���|�YE=P��	eR�����CJ�������a��q�p���H����V��z����e���u���E�>���]�P!Q6�P�h�{�h�VN�,#/l�-�������7*�x�@����R�l{���l�#M��,�#h�H�4��+oM�'�;
�������r�����<���O"6M
(��0	p� �8Mt�MY7��s$�<Sy��u�]7�s�=��Q��0�9��N���_+,���/��(|�z���z�
N /|-`�n�)�c.��u1`���.���>��)D�B�usnhv/��{�*�:O�QE��Gq��%*C���k_��M������6����.����/�|mRZ!T�1P[�o���h�����V�(���?�*@|<��A���w��l�Q��^=�n*;�F1%�(���<�i2�c�$aZZ��g*M�[i7��z��� Oy��4`��g�C�m{���������4�a��R�N	x`�8z ��o~^<��;O������n������}�mj����zq^��i#
7TV��m��?�;��g�*����x�<�s�o��0~�J~����m\O|����-�P<,�@/�#-�y���z�����*e>�-�<��
�81]{��uA_UT�,9L��������e�����-`�@����>*����B1����'*�iUS��<`��T��Y�����^k5u0@T2�N�p��g�}���0F��}��i��q��D=H0BLq����YL3�O�m��WP`�<4���&�iTq�];�;=Gr������'?Y�jn5�
;t��C���.z;I�r�!����j_do�����1m����G��@^>Z�@������b��0�|�=[��}�D������zu_E�@U�il�(��H����rJ�0.&*r���6X���4`��Vq���:6�c,?_u0@��N;�TT���/�2�,�Iir����@��?Yd�bh�t(������s�H+NF[V�>���o��+��_�^�M���������U:����?T$Q���o����kC�<�'�	`�^K��}U���<Dg_'~�^��sZ^����U������������u���S��_�Fz��<�P������Z�/���|;��;����y'&x&MbR��t������g>~ �����cUe�n���
����Z���d�`���z)`�@/u�h��N;m������4[��<Nk���n����@�D[���u0@W�|p������������+���Z��%��ib<��a
���SY�@�����>!�,�(.�WP`�Ze{���s�h��j�����O>Y�Y��HT�
y��n��4R����Eo��]W����jZ��������cZ�����zzt������+?+�@���������
f8/p��w�yG���� ���{�VB�" &��L#Uu�fYU��g�����8nt�l[���0�]���W� ��c����sNi/Ry+���z�h���H��}�������7�tS�����x���'>Q������)�<*}va�4` �%����oht�/��sU=��sh3�4������'X�p?���;��#P�F��h���k�8t0@���v����A���+�O��8/��4�v��,�U�����W}��3N�lo����o�p�
��f�����N�����Oo�������_�9���1��3���_�rQ�������U�TU�@��['e~�t��F�
F	_�I���a�m�e���@�D��-��?6��]��9��p�q���m���j)���n
��<�c�U=���o��];
 R��i�0�/��������f�b�����'�Z����-�2&Zb)��^LvP8cR@�M��^zH�c<�@���S�����4���������sd�9��o'�0��~��+�������I���D�>���X1�O��
�^ /�e�@�5��ya�E
���J��3�G�aO=�T��R�fn������3�<3P��'
�(p�)
��<���(��;�P�r=n�\����L��e�V��0�r���1����cO`��UY��w�uW�H�sqFZ�m��f�c����t���1����t~�+�@/�?��2�� ]��9��H���_.��
&
rI�����Z�{UT`�y��Y�a����f�����ex������
&�sb�'*�bJ{f�"` .��n������}����m�����C����f�.��*K�l�M��#��uy�����z�<������hu?�l����{����U������J~�]'��^���'���'����8�x��J����&�^l����������g�N����z�:����\���0``��]�;S�H>"�x�)K�8a�C�'���[�2,~_�)l,"�i<d�)�jk%`�,D�]k��JF���*����(<�;��{h������g+^��o�.cblk*cSz8��^x!���
(0T��2>M������ ��o;�T4��N��e��<!��Hx�����)`�qy�^{���@���=$�fl��,Pg�^S���MDgW�B���_�&Pp����-��������������������~2�����^�bJ�:O��<`��p���;��U�#P���`]�v�D��AT79>WT] Z���C��@���A���We�������+�l�PNt�Z���z�@l�nb*+\����@*�_��������j>�C���u6
K����x>x��G��e=T�p���2�!��&��
�</�zV����C~�IVZi������q��g+��:` ]g����~��}0Z�����/P�y1?����hXG�OZ^N��I@�����g�<����e�IAL�Yj%�e�keZ/����r�b�������0^�������/�=�:(�k1��H1��X�]+^e�n���MH�[���� �zE��+7X,�����k���e�fx`��~A8���D�L.11�X�Z(No'`�,�y�
��f�q����!	Z�=�-5)������4�2b�M7�U��w�����<��.�`b8��a���b'.�Y������8o���;���
(�� �d�BE�a��.�D�!��.Z����W(��6M��#�����i�������iAu���w����;�,
���hy���T6�Q�<<�J"�l�-�(���7�t��#�D��)�0` ������{0@etz��}y������^���n}0��=r;���/oI���`��n���Zr���"
�s�i�����+M���w
:ZU�����1>s���_����AEC-���)xJS'=Tu������|Ue����L#��g�|X(�u"�?#������I�T�����i�g\pA�"&&�[�� 
��4``�e�	G}t�I�J/'��sP������
h��lUT`T��R�!m~��?i��d�M.�������x�]Km�	��Z�������!��:6�>/��e�4z�J{	A�{��]}��<�������c��+*��g�}���h9O��1�������z��8���J~k3��&/������zO[b�%x[��^1�=���������4��<���zU�,9,�[������(`��0���D�!��uz���@�2�z<�3&X����QQC�}�� ��������7�X�W�k����p������x�f�Vi*�a���1,�4���V
t1GP&D;���SO-.��+�5|��Mgi�}��"1�����������}�4P`X�J�������h���{�y�)��.��

����9r����+�c�������@��XliJ+����4`�BCZ��9�����m���)C1&gz~'*����x��5������?���J��t�\L
(����T~�]s����s*�R
��$Mi�<��z���=<��^�4q~��f������`�y���*��,w��W���i�c����b�u��t%=ZU��B�nP�G`0��0�r��/{��G1������4��{�����������ti�Dw��~L�������=�]j���9���1q�x�	~fR`T�*�?tfH��(clz��f�i�kMZ9�K�?��s������2~3���^z���a9�S�H��
�*�Ub�:y��?i���v�m���|�H��uL�t{-���U��n�};U�������{}����O��9r?q����U�����3N���KL��5��A�eG1Q�y�i\#�{���E��M��J~���y��z ���{c���v�i��eY�:�������U�*�%��z���e�����a0``��H���b�����=�����MK�G������^���Na#7�\rI]�e������?�E�7Q��&�D�G�������H�fc1��t,���|,R�������W����s������K��P@�a�7�s�����&c��������9��Q��y�l��4	h�H��X���0�j��6��b���x���m�L
(�����G�ph��B�Aij���{x�?��3�j����Tq�f�TR�~��M�B��{�P�EtY�P�����:�
�SU�hU�@�|;}l�v��:`U���sQ+��RA��I�V�|��e(��vS0�o�\r������l�eroO��_����lUT`��*�Uj�j�M~���l#�/M�Q�����V�(�Z�H��n�����<v���C��ulTy^D��c�eTu��H�>�t������i�je=p@Q���9���[�o��v�W]��Zh�@�<�p�	u=m���5���4T�u5O#�����zU�,9L�[����0
00�{��<1&3�/SM5UK��K��9��S��7Z
���L���e�]���=�yO\\�+�yieOY�@��c�����q�%
	����<�p�wT����tIJ/B�4�VL#��,����n�(81)�����]i��o�x��=� �M��H��a���A����*������t��J�Y:�A\y�w�}�kb�����=��W�
F /�E�[��<]��m�m5]=��wt��=r���!��)��!��/�<`�������g���N��
X��y�D�0#C/i1UY Z�1�����|�������g�8��h���=��hW���z��enz���Bb���7�<`��SWV��+�m�=���4UU��2�}VI���������t�k>�=+u0�2���v�{���>�"��4v�:/F1�a�U�p����������\\��1�k��y;���'��O>��Y���������������I�`����v����+�����X7���^zi]o�L'8���4�U���5���0��W����t��l0=R|?l��0?����R*?��5��s�����`�|��t��[e����=�\y�����w)FW�Tl���XclP^���Gy$s�1���"��9�r�S+�������7c��u����������G���+�tg�����xS�������G����==.pqH��V�"�W@�a�`�B2����o�����V[�uz���8*���;^�|�E.������<ha�5�,��6�=���n���*���P0�2�3f �.}���?��v
'Y7��|cR@��	�����V1T�4S�������bl��p%tw�����I��?���7�#2N&-7�
3��7�#��r��j��2�+Cy��H�_�|�����q~���zT��<����s0��$F@��,���m��6�l����[������M����_��W�����-�	�}�����x�@w�l{��c����/Z���Uq���������|�}C���7�
�����C�������$�*M9GPMA�h��������@U����&r=I�-�\~���������<�)O����:���h&���!��yb]��:km��[o]	Z��o��CPa��*�U�e��9?�l��V������\���=E���<��g*��b�
xf����^K��=y�vT��h��������'��F�������`���,+�����u����|�N���s
�G������?~|��>M��7�];���b�x`q��s*
#i,�&�W�k=���4O����M;^�<K���������000{��<����\ s�^�x����n/��B[kcy���C~�J|.l$*���i'<�1�77�<���
�"S������[9�8�<����B�jM5h�t�g����?|�>H�IAl@(��P@�!��l���*��T�s#����Z����:Gr����9������*q}�p��/*���RI�?P��>����P�5�BDNM
(��
(��
(��
(��
(��
�K���~I��	N �0$����	�r�D`-���!M��H%Y�������|\��w~V@���������FP@P@P@P@P@�a0``���y*��q� �t�H�YZ��nc���i�-���W���YZ�����t��X�&P`,
x��{�mV@P@P@P@P@�a/����}���1M[���W_��k�������D�b���q�.��������
���ceO��
(��
(��
(��
(��
(���&`�����3t+��B p����%�(`X�O<�/;���2������k���������
�)��cjw��
(��
(��
(��
(��
(��C$`����2�SL1E�o������[��l����	����p�]w�x���l6�`�0�l��<���������rKx�������
(����9fv���
(��
(��
(��
(��
(0d�1;
(��
(��
(��
(��
(��
(��
(��
�C���~(�P@P@P@P@P@P@P@�L���!�!fGP@P@P@P@P@P@P@�~0�e���
(��
(��
(��
(��
(��
(��
(���	00d;��(��
(��
(��
(��
(��
(��
(��
(����:P@P@P@P@P@P@P@2�l��P@P@P@P@P@P@P@�!`�@?�]�
(��
(��
(��
(��
(��
(��
(��C&`�������
(��
(��
(��
(��
(��
(��
(�@?����P@P@P@P@P@P@P@P`��bvP@P@P@P@P@P@P@����Pv
(��
(��
(��
(��
(��
(��
(��
��C�C��
(��
(��
(��
(��
(��
(��
(���0`���CP@P@P@P@P@P@P@�!0``�v��Q@P@P@P@P@P@P@P��C�u(��
(��
(��
(��
(��
(������r�h0�efN)���233�)������Sfn������������)�����}}w&���%����v����
(��m&`�@��7GP@P@P@P@P@P@P@�V0�
e���
(��
(��
(��
(��
(��
(��
(�@�	0�f;��Q@P@P@P@P@P@P@P��B�u(��
(��
(��
(��
(��
(��
(��
(�f��qsP@P@P@P@P@P@P@h���Pv
(��
(��
(��
(��
(��
(��
(��
���m�C�P@P@P@P@P@P@P@Z!`�@+�]�
(��
(��
(��
(��
(��
(��
(��m&`�@���z6�O�>����
(��
(��
(��
(��
(��
(��
(��u
|���u��sf7`�s�� [j�� $NP@P@P@P@P@P@P@r0` WN��
(��
(��
(��
(��
(��
(��
(��E�a��=��P@P@P@P@P@P@P@(@����]�
(��
(��
(��
(��
(��
(��
(��E0P�p�
(��
(��
(��
(��
(��
(��
(��
 `�@��RP@P@P@P@P@P@P@��(z�~P@P@P@P@P@P@P@
0`�tW��
(��
(��
(��
(��
(��
(��
(�@��\�
(��
(��
(��
(��
(��
(��
(��0P��T@P@P@P@P@P@P@P�h���_P@P@P@P@P@P@P@�(�U*��
(��
(��
(��
(��
(��
(��
(P��E����
(��
(��
(��
(��
(��
(��
(�@��*P@P@P@P@P@P@P@(Z�������W@P@P@P@P@P@P@P�
@w�
(��
(��
(��
(��
(��
(��
(��
-`�@�{��+��
(��
(��
(��
(��
(��
(��
(P����JP@P@P@P@P@P@P@�0`��=��P@P@P@P@P@P@P@(@����]�
(��
(��
(��
(��
(��
(��
(��E0P�p�
(��
(��
(��
(��
(��
(��
(��
 `�@��RP@P@P@P@P@P@P@��(z�~P@P@P@P@P@P@P@
0`�tW��
(��
(��
(��
(��
(��
(��
(�@��\�
(��
(��
(��
(��
(��
(��
(��0P��T@P@P@P@P@P@P@P�h���_P@P@P@P@P@P@P@�(�U*��
(��
(��
(��
(��
(��
(��
(P��E����
(��
(��
(��
(��
(��
(��
(�@��*P@P@P@P@P@P@P@(Z�������W@P@P@P@P@P@P@P�
@w�
(��
(��
(��
(��
(��
(��
(��
-`�@�{��+��
(��
(��
(��
(��
(��
(��
(P����JP@P@P@P@P@P@P@�0`��=��P@P@P@P@P@P@P@(@����]e{5�Pa�����{���J5����u�]7L>����;���{n���OK��
(��
(��
(��
(��
(��
(��
(��
{��P��3�<s�l��B�>}������+x�����n
#�0B���[���_Z����>��Sz�iO�9��0����6�����'���>Q@�P`����2J�����v�rSGu������������v�a�c��?�������oL
�c?=��a�q�	��>z���g���fgQ�8��F)�;����<u��?�X���`�=�K�b�0��c���4�^�)K�uqO�z�Y|g
p��5�c�8.�/(�����V ?��L0A�M������g~�,i������q��Yt�/�q�*}�<��Fq�0�D%��������K��:]������7^s�1��~�����Y������n�.r�
(�0`������_>,��R]>�o��v�q��oT���9��#����[���;��p�UW%v|p�y�`�g�y:����/O�%�?����~����$�+��
	L7�ta�M7
C9d��K.�$<��
-�7M5�Ta���L3M���_�q����^{-���+��{�	O?�tM����b�-��SO��O��n��V����EM�x4"�������_=�Px����.��?����+���}��M�g=������?�����X�:����{�n�g`�N:��������3��h���52�Bf�g�}6�p�
5�����q[|�l�<4�����+�)���C�G}}��p��'V=Gm�����Zzo-O�:���#��y��Sd]:���&��8��>����z�	�z�����{������>���z�o��.��l��(����%@��[o^x���7�g8.�y����o���sy�\f�m������:��9[uY���E��]W38d�5����z�!h�y��7�c��g�����0���'��O<q0��>�4�K_y����_��P��.��8F������:(�,���mb��v�!8[z���&�l��������O=��]�����@�4RG���Y�m�Y�u�YKm<L�����z��.�=��zT�jh�o�Q���fP�@
��s�\ps!����]�\s��������k��f�y��+nm�����ty��7�����Nzn�@'�-�U����l�
7L������~|Y�#�8dtI7ng�H���?>\|���?uy=�$�$�jSN9ei:
�+�VX!����U��{�9��p���7H�(x:�f�q�J��Lg��N;�T��/�e{��a���=�?����a���KO��y^�y�YfI���@����B ���_��S�u3���������m�=�o�����.[���}��7<��3e�+w�Zv��D:�~������Y��!��SNI��m�W\��I�Sn���$�C=�a�|0l��v]��W]�B[u,��|�k86�|��U�e�jB��[o����&`�k�t�%�����r��uY�mpZg�YWO8��I�k�:�	2&���BV�#�<2�{�V�fpO���d�Pv�D8��T��Mq��v��vq�J�����/nf�G�6hQ���#���n�m���dd!����.j�)���f��ul�7*��m `�@���n'�t��j�R��0k�%���C��#�<�t�p;���{/�;�8�����������n�-y���0��{�mV��H�N#�x��F6�x�$@zy��`���lK�i�)W�K��0�������~�dDL�
���o�	4�e����'�������E��vZ�>?�.F�q�M�ta�;��|�����y��b�@��5��,3��^���~fj�/���d8��#�t�`��-R��G"�U|W��Lo�w��Zz�@�
�:��\r�.0��R�pk�t�^�`�
�9�B�+��)�4����Rd]J�:=�u"����
*�����������������[u,��3;gp��s�=������O>�$�Q��=��H��_|����V[%A��Uhe]��._w�@^u5�|��w^�sp��	�#�%{,&��l`d(����kd3�p�J������$[��������(]�4{����n�Ml����X8�z��w�@�H�A��?��*�H�g%��#��z�[p��-L���3�H���jy�W{�j�o�Q�Z�Ghg�y�t�m�y��J+u3gHFT�Q�_-�,��t��IJ��[�H���4q�^ ����
h���6(�{H���^{��G���j$`���;�����O�K�i�i\�xGp�n��*
=�� ���3�Y�B��J�r#cAl,����w�}wr_qf�m�dt0��X��s�����No���?��@"h����8��b(��J�T��.y.+����[v{U7�u��~&�����(�W�]
��[e7���A@#���f|��x�?IDAT������C ��#��6_~�e���SO%�_F:r�F��B�O��d�r�-������~{�@��{)Y�}���K	�����t��E��/L:v���.��jt��B�U�-cxo�cY\&��9�p�%;1�������Y|�]��3)�V��/~�������AF)�+����f:�T\F���V�eq;|�l���jF�s��Xn����hx�i)c�5Vr���N�O�X=�c�������Jn��5������a�y����5�BTK!s�"�,2�����M��i��&�����������P_\@��E�Nh�� ����.+];$�rh��pMM�3u�������a�e�I�	5��W{�j�o���Eh{�~U����Z+AYy���%�4��x�������Fa�����N��s�G���^�����IG`%IGA#�Un�yLc4$'a����.�s~�$��B���>�����&74S	H7����j�%�B]V����g�=��x��]R�s���/8�=�t��p�����o�t�1�>[yD�G��z��I�bv�J�����1��(U2!���-0�4����	��y.���]�+1OOK^���7�b!58����i��`,������.�u��{z���wE]�Ci�#(��l���Ig������9�h��K�u�����%���2���C�O�>	� �����>]���@}����[u,������C�,A���%��t#�;��RZ��v���'X`���NVK�#��u���V�e�����@��:������
�2s�=w�'M�������
7�P:.��>g�����H�x��j���=<f�_	���!���foSz�x�n�Mde"�	���y�|����q-��D|���k�!����#�H���������[6d�2����zjr���|�^�������n����v�
(�It���l��k���)NO&����Q�	`��0�d���
��UW]5�9����
��(y��'�	'�P���b���i��&�M'�t�������&��3����������7�|3�����.R��R��i���c�A���D� 
�DJra;sx���>��*b�H�-D�3
,]�x�D*]�p���B@��}J��clH&J�tt\��?�����AY�P��0$�
�DQ3����A����
P���/^p�����K.g�a�d���/�����q���T�����{�2���j�E\�R*u�����~�9�U*�H�z��p�6�R�30������K6�x��"W
�.��Q����N5��s,W8&048W��)��.���u�@���f�)i��
�7�s�
�o��������D�-��:��^t]J�NV
��~.��t�p���Z�����sm:�s��m���cK,y���:�m��w	 G�)��K�3�urr����s*J���L���tp�:�J�:*^WhE]V�Gq������@@2����k���1�����'s��{��G������i���K[O0����:�nCCa��q/;_|�9	�q$<���^zi8��S�Y*4s�����v;o���k�x-@��1������t
��O?���X�wb��:M���#����;J������7�v���������W{@3��:V�
(�@�	0�a;,����:n���d�����'` �I�28	�B�R'
�F$����Xd���	R1�!]HF�)Y���H�aR�vW��_��;bh@�Q0]t�^Nt<\}����
�������8-��)N'm*i�(��#�]��}����#e-�?�#[����U�pq��I5���w��{?sdQ@�������it�R�2����<�����:��=<��(�)4��A :�HeM�<iv)�u0�nd/�A��c:`��3R|�Z8��6?�j[�c1����iy.�c#i(����m��c^��4��^���l���6�}�������.�(y���r�p��5y�6���`&�%������_l��JA����~���������M+�.M�J,�A��^2t�;���d���2y����/�
���X���[u,���c�Hg��wC#�(t:�����u3��xN3�������V�e�~&��\���j:�c�	����:�)�A51�����n���z�Y�H_n�O����_e�U�I���?�L�4s�����v;o�������r�z+������^z���NS�-�#�����d��\�����<���f��u����W@�E���v�
lG�(�"���8�4#`����`\��z�Z�^���CJ�JA�e���U��$;��`�\�q�l!�4����}L�Fv�(�D"��Z
�A��X�4�������0%}T@�z��r�����/�2����nC�b��0>�q�����w�y���Zb�q|un�@���/����v(�Vgd^=%=r��w�[������'�M'�*%M���,.�qC!e?��4���_�R��4d�hVn�bz��x��~�u��"|,t�>��������q�|lo�<~�h�7E��#t�U��hCF�Bv����?�L��L�-�e��o���[l���Y���h)�.�'����$S�3��_}��$���|�N����4�CJ��y���<�k���-@`����[����Y��[���9��\�[�~gP�s1�#2�0@��f�e�~&��L����1�#�~���Sm�>V��z��)\C�����y���632
�[�U���6�}�9��~�t���9Ew�~�z���r����s(�M)���y�R���v��� h\�=NW�]zRG�E�$
v	��H�H�sl�v.Xlv��=�Y���86���+������~G��@IDAT��	�S����-IRB��k�P�,�+[*��6K(K�-�RBi�&B��F�BB�P�*!R��y����;��{��;w{����<��������3���r��*��7S&��r�-�-��R�g�������������mk��F����i[��E]4�����jw�����e�|�+�|����{�������]~���<���-��������������C=�i[q�mo{[��n�7�����o�����=/��w��t�W\���-oil���?����/n���7��M����&{�^�}��_n���#�d�m�]����>����~6[m����a��G��������w�m�e�}�k������w�1�g�}fWu�����=���U�8	H@m	|�K_�^����|����N8����w��o�[l���������'��_r�%������IQ_So#|������������h���(��_���1�y�}�!���%��n�j���{��������[gtP�x�=Gyd����6��������7g/����r�)��?���z��+����e�G�'��o;������\R��|�i�e�{l��t_��y�e��ym���������&�l�=��e�6�
�]n\�A��������I��;����W���K�"�
���>���X��7��-��b���Q_,����������r��f]��o|#[|���l���?����w���g>����������?�)�x�����x�������y��������I�U�[4�&�0�Yd��z����VR|g��n����?��F������g�:}�W\1������XE�4��,��r��TW�G�}����gl�A����gO}�Scsc���G>�����Ec[�?���g����VZ)O��cWW]uU�e;��S��_�������������^���d�w\~�����{�E��S�k�[����p�M@{h��vj��|��g��=�����|���QG��xwJ`�[G�c��|��_��]^����=�S3g��1����x� �v��faz��FE�q�
���;(��|0o0���#��L���!C�����>[g�uf��Fe������/��1q���l�Mv�]w��Zh�����s��d������[�m�R(��<����l���1��T1 ?d)�{���W��3�>��O�
.�_a�Ji�~������E��/����~�\���+_�Jn���$��;��|ph����;��,�L�����vP����/	H@3	��d}�K_��q����?�@.���0��w��TQr��s���\���[QP���x7�|sv���g7�xc�����{��2�1�J��o�����_x��y���^�J������?���6`�w�a����������\��!��9������>�x������p�D��l`��@��O}�S���DqA��(�h�u���gs�=w��A�b{4�c��C�F�7�tS������K1����`�E� �
���_��2KN��������n�5�Ro�I]u1i�[Tvn�\E���^��������c���q{�sb;�L�
F����j2��j00��,���� P��f��1��"�e���~[����k���+�l{\��(�<���[��z����^x�F��>�)��h��!F
H/u��U^���V����>E���T�q������t�2�TqR*M��2�~���c�����/�=������GzD���c?<W��8�``��FMy��V�W_}u#��sL���k7���U3����N#������������^���a�o��������h������K���t@�D08(���U8(�:	�$���"(d�D�R����T�f���]tQ��i/�:�X��!-�E"�K@�HW���^�}�;��1V&D�A�K=^E�A�N�$�M����U�x����G���2��P�s�x��~��{�w-"'0HJT�����w��� �.L�������^���N�<����/7��^:I��r����	�U6ROZ��E�����!Ax��>���d��vsZ�(�D)��M�.z!����[o�M=-�Y���d��P���3m������k�^Ooz��2�+��D+�T��[�{��0�EqM��M��(n���jkTI�c�����uYU�"n����m����lV1e]��rv�RWc��kQ�~�}��iO{Z�7m�p,�F�g��W!]"��	qD����<�����Oy�S�C���/d���g��b0�o�/�1n�&�R�.�l��O<1c�����m���'?���w�v��O#'PG�qLj�7���O���?�������w������8��e��u��:8vs�+	H`�	h00�O���
�`�,�������)��i�
��(�S�#q�e������u*���A����.����W��`���;B���KK�H����X�n��B�o�T�d09:��,���Ra���M�����?>=4����$n��� P�����^��C<�����V�4�WUr��a��:	u-u+���
�����+K�{���,v]i|��y���>�l������20�`J������������EaJ"S �1�m�8����w��u�>�*�~�ck(�QR�@`�-Z�~o�2#O�b��0���7���o������6$Q��*+e�.���=-�Y��L��c�2��3���/x�3��O�T�X�2����w4�j�O�{��Z;���b�4�oQ��w��(�w2�a`�!���L_B]E6�]��UFY��=��|U�j��L��
��D�b��TP%3c<"v�*��xn%|�hw��.��pN:�FN����z1�7O������nJ�S�V��XfL�!Gq���yn����QG����b ��|������)�S�*�9��8��e��u��:8v}�� 	H`L	h00���l
�`��{���-���C�
��(�S)v��*�c�
oxCz���t�~����
X�B3�8)�Pl�a��W^y����zy%���,�[Yn��������%L&Dkq.k�yxA��c�N4���}	��@�V�2�_��MTjQ��](F�)��*J.�R�E�=�����g�\sMv�wd,�@���w/<|��!��Wv��m��(
�a �N6�et�	�I�*�0*#@�!_gZ�y�{rA��"�(eR��'d!F�J���<�m�4BJ>�}U��w��u=n<	�Y6Zy���i��������h���=?%u�cQ� D)
�$�o��C�
���Wv]J�O�Q"�t��8�`H��0��n���'����o]���xX��~�x�x(�������F����M����w�yg�������1M�!m�b��������oV�ZWS=���=��A������������;��s%#�4��7�R��!��8���O�p���/1��\*�p~�yJ�]�;e�o���v��a�M�C����\m���C����;�}�����!9a|\6����.�;MD4����g�q~�������:�v]��w���$0�4�'�G�a0���T�2�[���b��Z�o�+t�Z
�����A�������L���X)�1�e�w�������h����>P�:����-��o	H@���u�UW�Cs�}�05
~������8a��q�]t~����K�[q,�$Bg�4<����x��Qx�j����
(�����L�|�!Fq��x����&�����_g�~��������s���r1
���^�����n����%Pg���bd�I�;#�'�p1:�k�x�sB"?��+�x1uH��x��*��K������4����s��b��ua�m�I����s��G�LQ���&Xg]<�oQ����aw����e��tz�[l�E�$�a�I����e�'!B��HP�(y��b0�q�����2����y�1�
)���X��|���izl�����'���t�>ML��~^����������@1�;�����mQ���Q8�J���v��G�0"d�&��h'�w�k_�Z�����@�u�:�!1�p����DJ����q��w��l������\	H@�D@��qz5�e��m�0@�CB�p�1��VT�A����N���w��,����i�����H,b?s�m��fsg�1�E1�SQP:]r�%3�5(�r]���0���1�0G5F[��������������Ay�1FuU��S�Ga.@�y�����Xc��<hS�:�j����4�kD�)S�z7��yV\�y
	-���]�6o?���
����#����z���
7���c���~�����
����?0�zk�*��K1�����E>�n�������1����c�F>�(�t�������U�[��f�1��.#���t���K"h���������_Mt%���D����-�����a��91;e����/;���:������ �M]��*�4��k�vh{��;��)�iuFq�9�\�S���ol��%�d��dD��)�f��<��h�����S�sz�>�vFN1�D��cg��azY��^���$P7�:���!�	�OZ	a��aS��kC�J���v�u��:9v��K@�L���"��h0���B-����J���Xx�	�<:{Udi���<<���y��4d:�R����yY�
���_�A���,��"�QCq�E"�K@��W����K��fZ�8k'���y��tRra��Kdk%x�`�s[w3��wR|��8���_�k�e`��1�`�i���x&j@�:��m��A<g��r`���N�q\���w�,M�M.�a���PZ'1XG���#Lx���.�� M+Ux�S��T�=Nui�g��o|�!R�n��4~�tE�S���
�vRW]�>w�7�oQ��q��H��c��s���;��v�e�V����	mn��w�>�(���s����������#�8��s�Gr���U8��T(��V��4�6F?�����v������&H]yju�t������(����J�xK����gD�I�Q�m.%0.��#��{�l��vj��z������J�0��w�#���D:i7~��S�x@]e�N��}�[��$�``��^��O�������aP4��"���y��'����O�M;+u`����n�p��jq>'B�n��F���HO���?���s��3Q��9�)� o����W
�D\���!���������:�l��G�0���t��������tJ�N�h
���:��_�b
?��n�@9Fqs��)��zO�	_s�5u��}\t�E
��D�ZI�d�����9;�p�yv
��*.�y��i�>��*�u�u��g���c�B��'EoyB�&��������(�e�c�O�V���>���I������+�ln��m��6�F&����h]�uJ��H������x���v����%@���\D�u~�
�������g��;�����x�������;'�@/u�����G��;�_Qh��r���6E#��e�4�>������l#b%N�1
Rl��������N��v��4r,`^&�����.�#G�h�e��M�$Pg��N��N}���:*7��x��"�b��j��M����l����}�]����``��X��N���3E�n�7^��2V�DH���j;��[���'��O���^��/����=[v�tB4�������Ez���Bg�}��W�xb��T��%����u�'h�h0PF�m�@��Q�b��G'����t��4OEC(,�Q��Ff������b<�B0DK
b{,S��u
���d���Pg���qs�V?���a4�L����t��|
������g<����������m��x���'�;��e
���Kv��.'��s���l����Z$� ,b����;�(BP����F��k�������O��F����U�Y���D����o_}�z�:�%���)�>D���#�B����]\W]<�oQU&7Y6�p�����Afz'�o'ML{B���2���h� �����/�F0�k�$Zs#7�|sn��o��:!�����ob	�ZWc@�Q
�7��$��Ea��q<�C:E3��X�^�����?�)=���h�@�B�#���~>O��?06Xq�{C9��!������H���n"�D������MQ4 
��4NL7��s���@�u�>D�#�r�����e�8p���0����5Evu��Q���X�_�% 	L*
&�����$���?J�Th�\|���<�����cQP�:���i0P������{��H�N&s=3x�'���Bg���n�-�0O������g�����h0�+9������d-^SOR�=��#���1��rz�
6hl�C��a�I'%��/����d.�������jl�#��Q���P�������c?8����!��GE��e�]6�c�?���c�9&N�5-�SO�t�Q�3�N�d2����;g�^{m�v\������,��������1 �~������A���Ql����;�� U�����6��P~���-	_|�e�5�3�gPx����!P��?�Y�2�3��(.��o�=/��Td�S����:���m5vT��\��-������w_�3�����-�xS0��f��y���"R��"��a��u��G}tn���C0u�**��%����_>_mI�����"�.'�@�u5�<��(����,%jXcR��iD����*�m�����K�[�I�h�=|W\qE��cF�1l��vm�YkJ��V�Zk���#�m���3f����T����C?'���9����a��	L:�*u���cc�i��+��2w�K�����l��9��g� �J���,�U9V��q�������tz��$p�t��:6�n�J(�������55p@9��ALN(�R�
�H=Vp�"���B�:����������E4����H@���dE�u�I'5�D��S���e��K.�|c?�bp��������c�2�M:E����oS�p�P�qu?����*V~�S�jx��yp-�X`��)iRa��<�u������s�kc��@���������RK5���w
a�q�����^{�\��~GhM���u��
7�0��/����w9�q9;�U6Pn3�8�O!����axD���m������b���6�"��x�2}��!�~�J�~\�v]�N�B�)�(\0��AqD`?�����V�wiWG��]��b�u��������C�#���H�@?������|?C��A�m�C�VGD����6�x�U
FU��y��d����Nq���s��P��=y��^������N��u��s�0��h�{I��N�q��*��*����ql7��&��r�-�@J���N��z3�������'�CH�j��}���o2���������cVXa�l��k"��/9�h��a���.3���
��-	H`�	h00����N����������0��`Fj����:x����aU�
���p
�j��r+�XgI'�?�-��tLU�*��%�P�Ci�
Z<@���<J�[l�i0����% �^��d����t'ap{�}�m�3=������.�'��^�[�\rI�Cg��cK���v�i���
x�B���WgZ)�M�����
�E�x�E%C�|�����I�r���7y�*���&L�[�h7�.�e�(���+�������Vi���R�3���������(��^��|����O%�
���D�k�Y�[yw9���`��vB���(��R��A?5%������U
HluY�����$�o]�M��O""���~��;��c���w#7��N;��VYi��%���4��&"�b����G�vSq�����c��2�k��W�xG����'.P�x@$9���
���K	H@�J@��I}rm��\����/�f���Id�%N;7(,��J1���:�����ON��s����,���J��?��
�H�;��r�)36��vK�b~l��sr��7�q������u�YM��}��'#D4a�R!_0�{����p#�x��R���K��Pxq�`�N���V�R���)!����b����4��y��e���V������z!���K^���T������O�:<�������\�x����.�"�X�#x�3�o+!j����������;2���~�
8�m����RT 2UQk0v�����h;0��s�5�L|;a��m?��s����q���c�����.����&�@]e�v&����jM�� �@5��^z������O���~��q0���/�<���w���Z��.��hi4�������w1��Eh?����i��!Y�I���x���n��c'����n�����M���=}j��e���L	���6}�n�;xp��z�)�F	��X�.����,u��L�E����<h��d��f
�#���z�r�e����g��o>m��t�\��B�"D�a*�v2�<q�ql7I�z����������LE?L��l!�mA� b��e���2�>�a��n9����$ �I#����=�)�/sx��C��B�PpT�y��Bg�����o�<\$���:���+M0�s;[yUe�q��d���a���-��R�H��;'45Fs�9g�c�Ay��D�Z��D����|z�u���%$
B
������^����~�������@]e�z
Or��M�b�C�n����6�>��QB`x:RW]J;^�0�b:�a�5�����Q����
�~M��}�n�� �1��s�u��S��K������C����q��w��<*(�B�O{��{������"�5|����ey�v�	�����q:cgLk�:���x}	��m�'�#)�1@�Vm������v�O��$ 	4�`���k��$ 	H@��$ 	H@��$ 	H@��$ �� ���T<foR��$ 	H@��$ 	H@��$ 	H@��$�L@��f�I@��$ 	H@��$ 	H@��$ 	H@�����S���I	H@��$ 	H@��$ 	H@��$ 	H@�@3
�y�&	H@��$ 	H@��$ 	H@��$ 	H@�
L�c�&% 	H@��$ 	H@��$ 	H@��$ 	H@�4h���$ 	H@��$ 	H@��$ 	H@��$ 	H`*h00�����$ 	H@��$ 	H@��$ 	H@��$ 	4�`���k��$ 	H@��$ 	H@��$ 	H@��$ �� ���T<foR��$ 	H@��$ 	H@��$ 	H@��$�L@��f�I@��$ 	H@��$ 	H@��$ 	H@�����S���I	H@��$ 	H@��$ 	H@��$ 	H@�@3
�y�&	H@��$ 	H@��$ 	H@��$ 	H@�
L�c�&% 	H@��$ 	H@��$ 	H@��$ 	H@�4h���$ 	H@��$ 	H@��$ 	H@��$ 	H`*h00�����$ 	H@��$ 	H@��$ 	H@��$ 	4�`���k��$ 	H@��$ 	H@��$ 	H@��$ �� ���T<foR��$ 	H@��$ 	H@��$ 	H@��$�L@��f�I@��$ 	H@��$ 	H@��$ 	H@�����S���I	H@��$ 	H@��$ 	H@��$ 	H@�@3
�y�&	H@��$ 	H@��$ 	H@��$ 	H@�
L�c�&% 	H@��$ 	H@��$ 	H@��$ 	H@�4h���$ 	H@��$ 	H@��$ 	H@��$ 	H`*h00�����$ 	H@��$ 	H@��$ 	H@��$ 	4�`���k��$ 	H@��$ 	H@��$ 	H@��$ �� ���T<foR��$ 	H@��$ 	H@��$ 	H@��$�L@��f�I@��$ 	H@��$ 	H@��$ 	H@�����S���I	H@��$ 	H@��$ 	H@��$ 	H@�@3
�y�&	H@��$ 	H@��$ 	H@��$ 	H@�
L�c�{��'8�f]��$ 	H@��$ 	H@��$ 	H@���x���?�=�P�����i��S0��$ 	H@��$ 	H@��$ 	H@��l&���l~���$ 	H@��$ 	H@��$ 	H@��$ 	H`
	a`
��,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4����-K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	L!
���{���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@SH@��)|���$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``
��,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4����-K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	L!
���{���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@SH@��)|���$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``
��,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4����-K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	L!
���{���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@SH@��)|���$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``
��,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@��$ 	H@��$ 	H@��$ 	H@��$0�4����-K@��$ 	H@��$ 	H@��$ 	H@��4���$ 	H@��$ 	H@��$ 	H@��$ 	L!
���{���$ 	H@��$ 	H@��$ 	H@��$ 
|$ 	H@��$ 	H@��$ 	H@��$ 	H@SH@��)|���$ 	H@��$ 	H@��$ 	H@��$ 	H@��	H@��$ 	H@��$ 	H@��$ 	H@���``
��,	H@��$ 	H@��$ 	H@��$ 	H@�`�w@S@`����v�i�l�%���;���K_�Rv��wO��{�U<��O�����������=�������d���;�~	H@��$ 	H@��$ 	H@��$ �1&���?�&�:�9����g�����~�|���Z�r����v�u�������e?���������>����9�����7��M����7�'�G?Ly��,�LF�[l�l���xG�;��3�j���.���a��UVY%?���}nn0���;;�����}�{M��"�i!0�\se,�@����-{����zh,n�2���<'�w�y����+����4�|����O6���g�|�3s�?���=]g\9�t3�4x����ggOx��[o�57�����&��h;<�Y���'�����iO{Z���g�A�������{���v�3����/�K������	>�)OyJ����H�
�:�_��y��M�q�{\6��s�m�^�-���<�:�Ku<�����J`��U�������6�x���F.
��������o�V^y���E1��}���<a�l��f�>�������Zk�:����-�m�����Q�	��F������Ptm���M�&m�&���M7�4;��C3�}E������6����c0
H�5v>����p��o}+���)!���;fk��f������O~���������?7j��~���g���c5_���J�[����mUVP���[%7u��^��l�m���\r���H�w��]v���f�{l���7�u���}�����+�,V]u���O|b��{��'���'������ll����K/������GB�Zs��Wg���w��.�,6�.��H]E}�1����,��%��Y"5aT��B5��=u��7f���/��M�(�{-��L$?�L+I6o3t[�0\�s�=�
6����#����?>�����^��7�7�|��MozS���6������[�O���E]���������e���/��'(���M7�����\rI��m�y���u��Gf��	u9��
+��-��r�"�,��F�^���3����������)&PW��!��^{��t��?����+�l�+u��H���'@]��������.�a|�!��~����|��|�R:�*'���t[���o�u��z}�tP���=/�Ty�x�8	L����0�����u�k��'��7��� 	h00H�CH�3��L����w}%�|�+�>������N�t���>7#�t�N9����x���5�i���J?�q���:��e�����=��O/=�h0����g���_��l�`�%�Y������^���V�����.{��P��2C'��(�R�;�L/�������|*��z��_��9������j{\����]<��o{G�x�b����~�xz����E��G���x2����y���]�z�]t�\A��RK5��w�5�h��C��0�wEr;�>�,VQ�G:���8?]��V�n/e���S��T��@�&�����������:Q>���g���Nc[��i��#���]�j�g�����}���-5�-ksw�
�����3�CcO��H�|�;[�;�}��@]��:���7�^�
����I���,}��N�pJ(3~�;�-J{���O�M3��,'����R��o�u���y������(p�����/�8�{����qu��a�������ls���l&$ �1"���=�^���@/�f�9�_~y7��p��x8����H9�������qj-K
fb����������??����=#��o�=�k�A�o~����D!�d�M��x��G�i&��c:�U����x`V�k��6�y��+N�
����������������1@���7:R�<<��3��|���a(QU���4M",m(qLE��~:��`X�go�BD�#�8�i�o.<]	N��TP�����H��w����������wN��&$��H�������M)��c�W�`�;��.���B�	%+�������A���e����Kc�#<�e�����<:C��zc�{��7mZ�J�J�n������/�� %>����>������
������+����'�����B�.�����w�^����/�����!�����w���+�H�����u�o�=�����9��*/�k�>{	���u*��|c�7�j���G�2�r2��I/em���`[g{����}�nE��n�y��	�Y���������^��=����K@�H@��q|*]�I��.`��C�1����dp����k�[�Q���7�@�OdfzX�C����o}������p�������9]z7N,�t f��w���n��D��"��G�
7�p��et���f��lx��_��P���+c0�p�U��������
C��|���OS��l��QV�n�;������}�1@����w�y�!��9p�y�V6b\��[��H��/.��!|0�=3�@�W�W��#��{���F^PlQ�����82(L���[/�O���D\����_��\�3��>uB����>�d@�������SZ.{)���3-��O#�@j���/|!W�S�b��7��[o����O?}��Y�$�	'��8C����=y�i62�
����g���>�&t#x9����}�#�#2Q_b���j��fhG�����m�$:��sfM����)-�{*(����6?�#M�P�`(�F�����aE#�4]�~u��nHQ�N:��&C�8���@]�%��rvx�S���o�H��%���c4���h4��X����
F~�����kYd�-���^��9�lQ1����MjD]G��4}K`��*w�js������z�6���R���&������<���r��7'G���\��M�n�X]su�L�S��`/��x�p~t���[��^���S��
�I0���9�L�G`^^����I�t��KY` �a*(:N=��tS�7��^�x-���w�qL$�!d�[1�����������3Rf0�uZ�W`P�!��-��J�s�>��FY@)���UQ�1x`Cy_<6]���)��B����(+��b��
1��&�vU��] �p�x����}m��!����#��P�6�w���<�9������q9}��!�1��@���`�d�m��v�m�V�e�,�:���{-cD���'�l��z���Dc��V�~<��@FP�����w�I�K�6��E���`���?�R�I����S�X �����������T*�s�3 ��/9�]�7}��b!��DR�8�(_�%d�m�1�S���e���*>�W��Yf���?��Xog0PGy��O��|��	�p���(L��Y����4M�(�I������OYT�-����Ku=�4o�~���"|C���J��&�������u��u�k�����z-	H`�h00IO�$�e����ua���E!d1���0���\*|�$����X�qa1��Z{����S\Q�����
�o�)�DJ��y����F"���>��W�J���n�'���^���P��e����~��i���d x�5����-�@8U�M-���:��,����]v�\P����lOc���W_}u�5�����l�V����"��D�z���-���a�R6�j?�qj�"��	��E=��/�����w��V��&��q?�v�Y1������o'������K^������4��3����1!S�������jx������O~2Vs�l/e�(1��y��2�����=E��N��neJ�F��1+	`0���8�7���:�t�?�[%	urx��c0@��ba@o��A���Xy��s�T�;��C��8b�����>REq��}�M9��s^��f��VB������n��nY�B�o/s��	�<�a�1��P��1���o6
���[.��`�����[|?�(m�v�����/�~���K<��#
Ew�5{-��N+M��2������7��4
�3�p0F���u�����K�j�)����������?���X��v}�b�������N#9�M��*�;}+���u��^��X.����w3���7�}.g?���_7���)�����g���A�z����M^=v�	�
-<K�c���
��B��t5�('e�d[7�C�_@IDAT�^����m�=��^��9��+�M���|�;����������,=�I`��*w�ls�U��U����[��$ �I!����<����`����N;-W������k�l+�=��(:�:���8`�~����`g�P<����BeGyd�a��X�h�j�}�*O�/��q~�l����%�����y�o�`P����gcs�I=1	�����Jc�#B��o��VJ7���Ro.�JRy�����o��2�<���b����>��?����n��[���|�aT������g0��� �~�Ta����oFa�
�C(e�)7`XSE��L��U��P�}�PWP�!���oG����[�osgSo�k0��u�����<�V����%��Sy�,o7�Aqn��6����$�<�v/�M���F�w0���b�����S�6���Z	��x/��~����:9�Lc^q���0p�` G����F��C��?�
a`W�D:�O�EX�VRg]WgZi~{-cid�N����b"�y��Q�?Z�o(&S(�*@V�t����B���`��40H����U~��1�KH7L�Sf�i����*U)����1B��|���*u���y���'��*�d�<f��0���N���-�%FeD�
v9�����O�)k�����Sg{�������w��[c����&�a���
��]W�[W�f�{�o����&�����Z��_��E���EAQ
���>��!R��wT�W6��4��i8�NIC�����A>v�q�N�h��3*
�^G~e0�>���FPU���("��r<�-.�8���+��D@��*�0EiWU������n���(�P�U��nD,��/�(C�5Ro�~��)Y�A���=ePf������f�}�ss�n���<�����wB��1e�Ah�I��9�B_��)���{D���S;����%#�Y����~����U�.QcP�#*.����*��<B�Ig�Bt��!��xh#ur�x�o�o���T5H����� E��4+���4~��V1�^��B^xa����?���^�m��������6��d0a"��C�I���*�:'�Nt��S����(�y�s��Ts�9g������
�����j��:��/�p>��}���Gfb{;I#<��� �l��m�
7�y��v�q�����U��tb��y��,R�`���R5�7R�Z��4�\0�r��z7��~�� �m��������Ni�{�����#��H+��N��_�B�]�V������z�6�����S&
�I{���`�l1�^?�`s��=���x������W?�p�C���?�����V�K4���	/k��!/�)#c;K2�l�y��qN�#?(�1��"����a�ln{��r���E)�g�I9^<?]oe0���wj��`����xo��/<U1R	�d�M�}�C�Zy�T���7���1aP�c��e�F�����#�G���_$��R�wEAa��bd�*�y�dH��g�%������l-�N�N����<�xG�D"�I�C1 �7:B~�-����8
O��ip��)�0
�z\�(��w���9���7�����Q��������r�-���~P�>�����8��a H�6��QFH}V���2��W�i�����������u��H����0@06#��P����1���'��u�Q�o��sc:������K0E���j��Q�B�@{�����,�t.Y�6��1�*
����e�������H��)y%�4�[xw�����O���W��4��F�j0PWy�<��n�u��b��-cL���(d��$�[\v�?�����o+�K7�U�K����������i���|�����N��_I�S�V������z�6�D��fZ0
x���p�v�����^
�?�	y��3;��.�l,�R)z��S�_y���<�4�	w��Zk�I���K�<����/�8����?>��!
�+��'���[s#�[�	�	�<2	QM�y�bS�����{�����;�1�;�{�&����'�PM������u��s����K�+8���b0����Oz�
GL�KLSp��G�����%�_7�xc���r<=��w;��)��LPF��4�_����W��!���r�����cEw�W�~���.��0���,��W����:K����'!�S���ho��_����A�C�*��b�����0\����[g��+�r����g����Q�s��;����!@�F��B�=�����0I�-�����~
0<����-��RM�D��M()�x��0]��(��7J�e�Y&Oe�l0�^�&a���@Y�[�Xc�|j�0�b� �!���wRf�q.%P'�e�)�P�vOx���2��WgZi��~w*c�6m�4
H1�4=��^��A�������]�*���N���#���n:)Y���x�oNQh�F�7�|sv���7������~��N����J�%����t�M���7�(�k��uwY�-";`0�!�2��,��������	S���u��N�u��$����4o�rw���[n����>9}��^f9iG�j����Vw���}���M{)M�����_��7c�S�������WU�����u��u�k�����5_��(	h00J�5\���@��S��86�����%
b<}R��V�p:j((����1���]�?~�m��/�2����0o)^���}����x�E��*Oh0�B���c9���s�`�D?��������d�o�}�%2�1,�_~�4�\I��i]���/����<�W�\�*xN�g����M%lK�_��D�p~�R�3�A'ie0@(m�*�������.�F$,�$^s�5cW�d��T�=�|�����+^����4"C�	�����9^i����w�l���)o��h�i���,D��"I��C�W&�@�1(X{���u�H�H�m�e�q�2���Q�c�i�c-<��xC�k!�`���P�PV1��ER/8�O��H�(�w����.��
�����.J
"m�D��d��o\Z���5qn�K�7��-��(�xR��c�v�|DQ��"�A�]� ����Q��^�L+����T�h��FB��REM�x<�~������ByN���)��8��~�s�3�U��/��/�x�S���+
mB�`I�}�	�6����v:��[�I��	Q:}�`w��L/�:�_'��i��v�m���V�``��k+�C�����6?�"}�T�YN��������Q������������b��<�b�������y�m�������o	L*�*�nXm�:��A�k��'�-7��� h00�CL�N�<��4���e��g��;�8#s+e8���1�
��|��:(IQDO�VX!=%,��W<9�{��-��B���/x��pA�P�M��EQ�������M]��t�4�4�%^Qj�����\�K����/S�|��Y?{��w����0���*(�[
�r����=����(���^���X����;�������$�����������+c�t���\q�y��\��U"M
���~P�	���	S���r��L��g>3��|0�I����������r�����Q��!�������7��?�qF=�rC1���+
l���J�]4�!}�L\�~C��B}��l�8��&��v���,xw!|�	M\|����#i�tRf�q.%P�t��4	��{�F����G��L+����T�(��T�e�c�@{.c��Od����w�]�9�$"ZD|��H��a�}����ou:J�Th���C���f!|C0|�=�F��mD�A��+b{�%Qy�gH�V�f��:�_;Z�w��D{���v�g4�R�`����tqW����h%�����^{m��a���K~T���U������N�M����	����i�:�@�����c�H����@�r7�6w��o���m�q}���$0J��~
���`�A%��e��W��wLzL+/�2ex1������(n����_������NQ�������eyb��H
Ea02B���0 D�a����U�s���u�'�Q��?�d����5�W����?�g_���`�����>z	���������������2����9sq�R�� ���w��c�HP6�[f��KY�kj0$\�C�=�yO�MFS��I����I9
)vQ����J��Q~���v��#L���x��J�h&(��;�\��oR�}�������W-������0��@�?(��8"5�����/�U�H/����q�K	�A��Xi}v�m��s���Y�*������������N������k�����
�L�tBYN]Wl��9��@�hYH1<z�jI���c�����5�\��q�y=�10��h8�E�8.(�|#����E������}L[3��,\�|�x�!D(���)�0c�����S%��)Fv�4\�nu��V�x71$z���\����@��U^�>�	���
����������=NTH���0�I~����O�,ku��Z�R��������9����tl�w����Z�r�$���
��]g�[W�f�{��r�.	����;�������K.i{�4�y��c�=6�^��:�S?���]e�����.{��0�X6��]m�G���x�1�M��R�b����;7�&��	#	�)J�H�}a0�!L{��u�'�Q����X��`k\��r����/���t�F�����#��ei��e����SZ�^��{��_���B���@�p�/��+�M���*&��y����+��0E��B4���j0�2��/H�B|P�b��_� 46�uX�#�1S���!��K.���[���������#
�MT���]����|���0��!���%�/���;)3��q�z!��E�0��`���.��:�Y��L����T�0K����$�R+�mO�3$5������0�����N�8�n�����K���FUE�������������������D~a���t�8�G"&��{���z��}�|���V;#�H���$Pg�kE�U�zU����%����JQ�pN��xm�%�����S����/~��86�r��	T������.��V��v��n_7��v���k�����{��sc����aL^v�I`��-w�js�]�F��z�6���V�/	�+
���T�W����������'<����;o�!��_�Y�'�?�2I�I��1��M:�����q<�b("����,O��6�)��=�}G�!�+?q�:
P���ne�D1�-�EI_��m�2��gV��0gQ��J���:U
H�������i!�/��@���F@(�Sw���(xO�����3L]^�<�@KE�<���������k�8���n��xF��O"��,b:"�`��V:�"0X��y�Lu�`Y������c�0��c�T*�����%������!|���RU��Xv�N���s�&�n	����c/��"���[�;��^�e����������1
��7�)b{,�F;	a������6��7��?�~�(�C9����$D�!M�zZ	S���i�-��[2=� ���
7��!���c�6-��v����^u��2JD� z��S�(�����1u�0�B[����/;���V����0�h{3���}aL����I;�U�'�,k��m�����n�K��i���s.;�1�0���D��{����P�I`b	�R����U���^��=�����L@��t�u�$EY�J}��|�i	R)S���p�(bSa`�
�R�l�����s(���C3��,�J��@v������/���.z����,e�z1`��e0P�r"�Gy$������(�0�`n�TP��z����2�x�S�2A���&D�`��2c�3`���T�����/������[/_-{�(il�$�X���+cR<?�	!����6��mu��H/m,�6���Q&�9�1�)F);�m��uFx�5 <ew��s�h���cZv^�m�l��f���(!�(����C'�O}��:��9���;���z��P�2(��Doh��Z��7�z�9�C����c\7]vRf���[�x�^���1�KV�Nj%u��:�j��v����t*%B������5B��!����M=E=�*���/������w�=����b��2�g8�,�k+��w��6�?&���Q�"j�����tSh:u
��|g��g*�v�Q������B�v�(�G���WF�8�_vL�m����H]���5�?{,���y_�z�~y;)�����]�A��vy��?�����okw_e�zi/E:u=�H�%L1`�i����wW��l"�k�V��u��u�k��gS	�^$ �:	h0P'��U���J+������>�n�l��2e8�� '�a���E��
��Lo��Fqx�D���5
7Dg���������,O�(�������r��P�����?��������������%?�x�`�U:	�Z��"DlX�3��^�R����e 5�AF�:�kX��J-��f�9���@��,
�Tx�B����[,����F���T��}xo���}�u�il�����@q����r���e��r�4�����K���M�� ��
<8/�����J����'-OMB��;��C~��_D�a@(��
M]v#(��H	��3�<��G
�Dl���iT����1�� ��b[�<���sb�]
���*�����?�z���,�:9��_E�Yv��$P������������q���K�����8����\�xL�2��~Dc^`~G�&M��fL���w�q�C�mW��M��N�$��4�W�9�
�3���Q|�Z	�����/~��y{������An���<:Z�R����tJ����N]h�������1@I2���k�k����`���u��2Lu+1�*/eyu��#����7��z���;�ly���0uP��q��� �I\����RgY���V��v����H�����1��2�I���&�@?�nXmn��Q��Y��������K@�$��� �!�2��]P��<_�
A���8J�T��cx������2<�e��.(nI�A*x1����.��xF��"3
�TP
�-��YY�zU��=Y��p%	��X*3��><@	U]g~H��K/�a,k����=��d{j0� k��s�,�s
�|��sO� ����0�uh��n2�6^SD9����������Kf��x�Bi6�T�lO�q��%/(��(�}���` �.0��#}��|�n����@Z��������%��2�H��l�FE{�W��!�t�EY$[q����J4�E!.�:������������H����h+lGP b��`%!u�7�1�&�k����>WV�y����*�2.����!�Z�Ls�g���������XL��*�����&�N[O]�t#����vE���,�u��.���U)cDK��0K��v�.�(�h��F�����k�%�Eh�V���nq�7��!D(K
b{,So~��4�]`
���L1-�tJ5�
p1���o(��cL'�J1���Dd�*S�	�oV�����^f�e�2�;��~���h�_��xnbT�
�Wo�����]�m���n�Z��c�� �X�a<�0vD��ARW9������I�e��~[����O��%�Q�s�<3}����aLi���8����F��k�U��U����7��$ �f4����2��*7�*59���`[xF���MaB�GDB��a��)����U�l0�X�q_�Gg�������,g.O�,O�Q��.��b�����y�UW�F���e*pB�N����H�'��d`�.�{�-�����d��R���W^9���}�$l��.�`��N�:�@�5�����������jM�1����!�3N��F`�qy����.�6�Q�N��og0@���O��\r��K�x�(���u����A�e?��b����tP>�4f������N�iC��*K�����k�����.��*~�*��b��<2�� q}��l�MO��U����4���W^�{�FG�F����aaK<o��	9�����	U���Ar����|��@U|�)�a��y��F�)U�|�k��Vz�*e��9���y�]x���xc�h��F�q��t�9|k�(P�?�u!�>�'<�	y{��n�\��S�a���^{5z��D��F���f��`\�N��2�hm�k
�HC�Z9���|�]v��8#�8�v�1����2u�?����2���0�������p����7�������t}�(�����%�	�9N'�hl���i7C�('�V�� �'U����mu���z��l<�����u�������H`6���
��
������5����x�� h00�CL�����N=P�ECXN�t�R���z��)��b@	�R%��1(�kU�9d��9<!�����
"������b�tR�:�Czx��4������"0z�c������������1�F���=���,�m�
(t��Zj����;�:��$��hg0�yx`�
�H�<�H����j0$\�C�oK�Q�Q(�����&��z3��4�tl���F�����{@#5��K�I"�p�(�0�I
���8�������t�����o�
��&������
�VXa��qR�����l$�
����=�%��Fg�����XE�Y�G�I�����R�2?<�5D<�*���Ni��Vz��e�)��Q_���.�MC_��$�D�"BJQ������k����0�����}���QS��?�ET�����H�_A�v2u|�V���`�c:�!�p��7��{U�3�<y]�8�>
Y�+������`�@���,�4���0�D�S��@���8]/��U��<�:���>���s�4N:����@����'�SWGt�S��S���o9!��2��I��6�~[]��:�3�J�1c��]d�����$0N�*w�js������z�6�8���E'����!/�0�G�bxvB��x�l��V�3SAY�'4��2e8��x'�}����s�nYXW<��O;}��c��$����ey��`���c���}Ea���)����Uw~�(b�eR�`�si�a���5�x3�2�)	P��~������u�7F&<w��BP��m@��VB�(;ih��$`;�����^:k�$����O>`u2��V�+�:���������,D~4.�%��u\��D��E�*�(���HA�{S��^�]<���z2UP���v�m�1��U��4#�6�b:	����:�W��t|������m��6V���8VUf6e�	t ����Y�NEAp�9��;�i_7e�����:�J����1W:�U�N�.���t���	'����O���18@)T�� =��o�e��PTt"�>ke��'FB�\���cQ8��p�"D_`^�4�L��<fv�����CeDDz�J��3����DZ.g?�h��*��L�Qs��SN��+�6��I��6�~[�����3�jK"�1md8��=/�I`��Y�����q�o]��m�I{���$0���q�QG���n/�%6�C�x8��`
�{������(
�b����J��%�C(ES�L��KH���w����Xb�%2��g.���'��#���O>�Y ��Acj�t��5�������A�n���&�K��n�\��b����@��9�PJ�2����"�)�q��%�l�aJ�g����w��s����.���i���ep�w"��B���	��m����,��G�Oh�NB��S���N��$�.��6�A'-��L��E����!b�C��#�������6�9�7�l�Xm,aA��r�|z����~�z1��,b�J&p%\x����H��,D��!��^�c=�e�Gu���vQ-�s�=�	`p�Qu�\s�5��y_�f���W�s��:�h4e��0 ���j�������O	u��'i��38I��������U�;'/��x���w���Y�&�H��c@��E�W\1������H�_g�}vS4�����������{�W���$�m�Q%M�������(8mG�����vS��O�aJ�b�K��o~��y��~�)0��>�h�I���;��
�i?F�����]w�\�O;3"-���/����[r��w���%a�i�6/�q�����P�tP����@��#i��������^K?k�UW�7�N�h{��b�������/���+��|n�������#�d+"���V����MYt����R����cs�=w�XaL^|��K`��.w�js������z�6���^�'	�3
���LP�Z���`Ga��!5xH���t�0�(���!��(���($���@4�0������8�a[�+�/��B�3�Yb|�c�h��kE�=��7X�~�P�ei��x��g���t������6�e��{4��"@Y�����>�Z�������[�!�M(q��7
��2�j)�s�#���,�L^G��`�p��M����q2?�T�IL���"�����&���]w]��e�dQf���*�D�J
���D�b�R�p�3
�^�`���������eiD��y���<���*q�^��f�^�m9�������������#�;�Q=�I"�p��H��^�������Ob����<)��|J`��]W�[w�f�{�B� 	�����?����``���"	H@��$ 	H@��$ 	H@��$ 	H`V�``V<������@��$ 	H@��$ 	H@��$ 	H@�@74�����$��@K4���$ 	H@��$ 	H@��$ 	H@��$0�4��2y��``���9��$ 	H@��$ 	H@��$ 	H@��������k��'>�������=���o�y��wf7�pCc���$ 	H@��$ 	H@��$ 	H@��$0>4�gaN$ 	H@��$ 	H@��$ 	H@��$ 	H@C#����P{!	H@��$ 	H@��$ 	H@��$ 	H@����``|��9��$ 	H@��$ 	H@��$ 	H@��$ 	��CC��$ 	H@��$ 	H@��$ 	H@��$ 	H@�C@���y�D��$ 	H@��$ 	H@��$ 	H@��$04
���$ 	H@��$ 	H@��$ 	H@��$ 	�
��Y�	H@��$ 	H@��$ 	H@��$ 	H@���h004�^H��$ 	H@��$ 	H@��$ 	H@��$0>4�gaN$ 	H@��$ 	H@��$ 	H@��$ 	H@C#����P{!	H@��$ 	H@��$ 	H@��$ 	H@����``|��9��$ 	H@��$ 	H@��$ 	H@��$ 	��CC��$ 	H@��$ 	H@��$ 	H@��$ 	H@�C@���y�D��$ 	H@��$ 	H@��$ 	H@��$04
���$ 	H@��$ 	H@��$ 	H@��$ 	�
��Y�	H@��$ 	H@��$ 	H@��$ 	H@���h004�^H��$ 	H@��$ 	H@��$ 	H@��$0>4�gaN$ 	H@��$ 	H@��$ 	H@��$ 	H@C#����P{!	H@��$ 	H@��$ 	H@��$ 	H@����``|��9��$ 	H@��$ 	H@��$ 	H@��$ 	��CC��$ 	H@��$ 	H@��$ 	H@��$ 	H@�C@���y�D��$ 	H@��$ 	H@��$ 	H@��$04
���$ 	H@��$ 	H@��$ 	H@��$ 	�
��Y�	H@��$ 	H@��$ 	H@��$ 	H@���h004�^H��$ 	H@��$ 	H@��$ 	H@��$0>4�g�uN��{����	H@��$ 	H@��$ 	H@��$ 	H@�N���~������=�4��4�-	H@��$ 	H@��$ 	H@��$ 	H�~���% 	H@��$ 	H@��$ 	H@��$ 	H@!#�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@��$ 	����"�u% 	H@��$ 	H@��$ 	H@��$ 	H@#$����{i	H@��$ 	H@��$ 	H@��$ 	H@���h00*�^W��$ 	H@��$ 	H@��$ 	H@��$0B�����$ 	H@��$ 	H@��$ 	H@����5UY����[I ���~� x!T����h�����"^2A#
!�*�)x�P���`��Anj(��aZ������:��}��������9g��Y3��7{�����$ 	H`�(X)��W��$ 	H@��$ 	H@��$ 	H@��$��� |O-	H@��$ 	H@��$ 	H@��$ 	H@X)
V�����$ 	H@��$ 	H@��$ 	H@��$ 	� +�SK@��$ 	H@��$ 	H@��$ 	H@��V�����"�y% 	H@��$ 	H@��$ 	H@��$ 	H@+H@��
�_M���_����3�(nw��M�u�5��}�s'���jd����|���{l��/~q��._��������~z��&	H`^	��/�r�������Q\w�u�����R�<�/��/����^���W����lp~yo���w-6�x��[��V���}o����x�;����~P����_������/�R��&�,���7�9�X��
	H`U����Tl��f��~��������WU�f��
].��:<�b������w��]��u�i��
���(;4	4�������e�����*����)y��;������~�����k����������cl��>��$]���lS��b�-��E��O��.�7�$ 	H@�@
:@Z�I�������1�]t�E�)��R�������K�������/Y��_V#�?��?.9��%���O�����>�d]�/{��Gq�	',I�����8�������/tq���a���|�#�'>��t��% �x��^T������?��?�W��U��u����[�n]�������u�����>����xDq���v����^X�u�Y����?Y?��X��8�z��������n��
:������^\v�e��g�]\p������;�~���=�A�mns��>�_}���}�x�{�S�����d����w~�w������}A�@'���_^����������3���b���*~�Wu����+�(������X����N�u����3��nV�����}q	���������s�����8��s'���������6���up�l������������x��Xl�����������]|�K_*N>����[n�l���������]N=���eg�8��,�����V�k�b��=�y�?�Wa������o/n���X=�r��I=�	OxB�3�1��j�R0@_�#�5��[�z�������7�3�)��l�����A,���_��_��i��?�y��W���Q9��}u��Woy�[���c���X����&i�1��}����x�S�R���~�P:��}�~Q�x�;��I4����r)��N�������^<�a���K��o|�[�5%����c�gp�1���7�I@X$
��n�AI�ycp�F�j,��������`��&M�}���S*�1P/y�K����.���=u�6��Rh'���>�x��_�$!��t�5�6�lSz@����=IF�C�����������}�;�Y����P�<\?b���>����r5�a�V���aS�r�
�r�x�A0x�1�4��L����,�����z
@l��7��|4e�o��o�����<I�{��{�����N���@g���^�g�J��u�g>���X�at�Q�����������8�����V��~HY#���?��������xE���~�1]�a�T�Fig�yf������gY.�����'@��MozS��G�\}�����|2��/��/
��d�+�<����TS:�-6~g���ch2���u���'�xb���?��0�����L�����O��6I�1�m�!���R�dF�#P���m����^��@�vJ��Ic�|�#�k���K.i��;H���gh=c������������9��
��yT$V���y����Y���<��I?���C=t���4�H�3:��U������R��c�Y���	��J'��������3D�xx�k_��#����D��h:���!� S_�<x��,O��Ktb��wOj��<W^������"`6aV�4o{����4}��xla�Aj�����~��(��?��?Gu�2�J~-p���X���AS�����n��W�2���g�Q���!O� �Sn�`����g1O��=�����~HYN���}���zQn�"
RtPAdW��h#�!��1��\r/r>~_[�y�{�����.���|�;�l�t=�3�7�p����<���x���D(���p��7���p��=��������%O������	��A�!��CA��o|�eh�/Q,��!6V}z5�I�x��ls�w��]e��8'�#2���/h���19GIDATqo�T�[�6g���%�	�i�D��F����]|�����5�$���Mv�>�gtm�e���$ �5M@���~��<�����?�$D�k�����"x��\����d
���M�`���{����u���e����/��U��OH��6����4t�����#\_2��e/{�d ������8�<���c��������!����_���C�~f7�!����g�}JD�?>��L���9>�;�����>z2��rw���.����)^�������5�g?���8;(��I�`V�K_������d|-����D���N;����^�~���=�$�N��G��������'b�2 �0A��4��Hy�k��k����������a�\X:�q��}�r��0iG�w���R��kh�if���a�M���tI�D��zw��Cc1�u�<�^�k�"�Tl��n;y/R�@�G#����2�P���r����������3��L)�f�"��iv�m�IDYC=M���$���=�x�^0�;.�i $�x���u�[2F��\����>�0��a�b���&Bb<;@#��cc��Wc������6�������}�>QOK�EP�B46������j&�����
�y^C���%�[���<=�����XC�c��*O���$�����}�S��l&'�C�etj����.7�~�S�*���gVB����|}���� H[���1k5us\���``Z�O�)m6�p��6����D�f���������@��Pk�L �%�����e']\����N0��w:|�u�0��ed����i��] �������|�I�����X�Ig�"\`P�1����.�)��2Y}�q�-�@'(��x?|��_���%��t���?1X	������<g��A@f����~������'��H��p���:�	���|���]�CJ��DW�3������"j��@^�q,�h���q����re�i�`��};�f�����KYN>x���b&<�0�[�q�K�L����u���]s�5e:�������x����{Qw�_�-����T�����_����6t04�7��$g�u�����0����g�w�,��SFz��K��o���o�A��?��^����}��w	Bv�����:���s~���\���<u��}�C*������O��6I�1��\t�}�Qe��"&;m���8��Yu�I`5�����k;��_�b9A���e�k�&o����3�<��K@X,�]�]�q����PgM���~��Ke?3
Q�����/,���xb@j�������lg��YW{��G9�@�P����,�b�� ��G�q+G�%jH\��3���o��3���h0�{�UWW\qEA�D��nLi��nT���b`������� �-��h�������(�w����po�������pfv�	'���\�k�Y3OQvG�>�1�h ���L6�h��6�����Pzn?K`�@E�t����y���?��S�����fV�>�o�}�7V��M;��=^��g��1h��7�aI'z���<i�d��8�?����&��s��xT�kK\��9����x���W����/��_(]y�&�60s���XUGk�<����*��7`��������T��e1�eIg/�&1?�=Y%�(�O	�q�qq{�����)��x����2P����9*p�w?�,�y������JByWg�������1�I�G���=�|�41�e�<�^�K[�J"F�)���j_�6�������#�;�����37�W@��N4E�$\�c�Q��y\��V�(�M��_����(������%�Q�����*#$�_��[n)v_����u���jk�T�J���l�@l����J^�1a�~P�2�%/yI���C����I`5�N��I�F{9��1�uh���0��1�����:	H@�N@����14SQ�3������k�%����~tL�F�C���:���z��\�dp���.�h�v\����Y���|�\��^�[���!8

Q�Bk)��<_t�pM�
/�w�������c����:�Vu����~F4�K�m��f���
���(�iL��b9���4��%�	���|���T^-������M��;����g\�b�%m��6bd�����uFC�1�l��O?�.���c�����N��W�R
���l�
bp���fB'%��x��n�����x*��tc,�����T0��`�W3���b��k��(B:��0���rE�?�e��.w�K�j��
�s�"�M�	�!.��n��
\f��Z��M��wB�`��e���-\�����&�A�����x���1�e�<�^�������h����������z���R���$<B�>�MC��O=����S��"����u�Gh��C�I�B/�%���|�)����4��5aZ]z����u9V}z��I�.|�gAz�#Q���_����ms��.%�Z	m�����?�Ox�>��-?��z�X����w	H@k������c	@CL�Pr����N>�J0��e�8��T�]�'?�Iq�A�]v�$9M�ml��P)�A%	��~�c�]�A �c�"�������A\m�5�iD�V��R�}���``��P����
f���>�J����	�&��E�����6�@�k[���aP13il�<��yD����g�B?��F���u�R��G:�q��l��
���wm�@��w�k� ����Y�a�[:���cB�I������//=����>���u�\w��Mxn�L����*�F0@G:b f�cC������i�r�!.��L���"����c~5Uei<v�D����
!hc<�ry�{Q��uk��s�9gR#�7�mu��g���xD]�����$,������6�nXS�!����R�
�}�h#|^8�1/n����W|<V}�.��
�&��;�{��M^8�"�(�>�Q�b"m�K.�$�.[�����d���"0������`�l�����v��a��O�T���.�74o����3�:��K@X+,��S0�	:���R��q���W%$ 6*n`Tz���F��T�p��#M��P'��M���$�f��������$�kj����/]J����X]>��&�A<�����������
�<l�������K	����"��+�M�@vT1K0��W��to�9�"�N����}�M{�;���xC�$v�y��v����u6�xK`����&����{�|��5:�d@���F���p@t�����c�����#�O��p��G��eK��f!��7��d�5�	g�qFq����f��	�i\2���s��e�dx����e��{�Y��wfw��bK���9�g�g77���1����
6k�@��(���9C��x3J�#��'��UV� �j���}K�c��v*�E�I�a�&�*����?X��f;���B�	��7U�C|!�����U���W��
�&�:w�u]�m�s����AxS�N��s�+���9O�~�����X
��)����c�+���2+5���Wb�I�����-o����g�9�?K@Xk,�[0��W�T �|X�n�jN���n����S���i(���v�m���\S���@E%f2FZb��}���W��@F�{��X|�[�*Wm����,���R"�h�e�v"F~�����Y?�c�M7-<��e�H��:8am��<�s���t>�W}t�2�"
�>
_���c&,nZ���UbDt.����z�1������tX���1�5�J
���������N+Kc3r�G>��egy�=����/y�!��#���(���K�%fy�>M�g����]����@�17:x_�]q�������N<�����g������#���F��m�@%� |m;��%���D��1������������>�`>3���N~�D�1a��y;�)|B���|����]��\��^S�k�@>��W���SN$,c[��(O�~����X�:u��(��o���{�=��i~�,��&��v!�!�eX�G�P��c��M���}�N4�L\�r��t�a����m�e'oY1��F��W��"B�R��h?=���/.����d������h=�	$�
��VU;ow�e������%��;���-�?�z��z���K	H@k������c
�?����mB�Y�T"�hl�o��������Z%`���G]
b�X���b]�-'�tR$)���#l���A*�����'�0f;n��&�� M���}��8�i^8a����:cvnd*�B��M0@�|&*�cB!��M��Ss�#��
�Y�p_>���
��

���I`�l���e��W�*a+%�=%�I��$���rqLz���:�HU��Y�xbA����t�-����L;B >��`F��	e��Y0dP.��9�e]��t�� &y����������3��k����e_���9�I`��v6��.�9�b'�]������rB���Y��K�2!q�S��2�������?�IOZRv�R0������X�"e���C�8��!�v�u�e������x��ap@A8�.6����oDU��#�nMu��@�0���R�Cue,�����x����:��}m��t��6t��-?����6"&)sc��6"k�MU�IK��Dv4�?�+.�@[;%
I���@�6<?������!�#��jq�X��-��������?��R��Z%�``�����8��lp����G�����/�V	�Mn�b�X2�h�v�����'f-��`�N��Bt(��}���7�4t��/��5�E*"�*��e��;�Y�{e���2s7�������m0��`MjU�c�3���H�G0�wD�1�X6�F�z��#>�������M��z�I`�	 ��x�xq�N����2���~w9s���a����Os���)_g���;�����/^��u1+96����4���������v�!Hc�F��%�Z	y@G\�q�y�P����"�3�1���6�}LB�-!p�v�e�e��8�g?�����C_�W�@_C:��)�s<SC.c���*����9�e����va��� en�SA*i�������y��Kv��`�+�������P~Y3ra}���
��0����f�|2���l�Q/`��0�i}�.���������z�2/[i[�wy���c�=�x��_�D�r����;F}���+�&i�O����6��p���#�8���W���.�O{��&������&S0�D�m�L������n�.�NZ`��[&���}�����-ooV�������$ 	�u
��W����>��W
���NNq���P%�� 3��n�NU�|�~���k2f�3����`���P�����}�A��F
��1��Z35�������lj�rHelG��!�>���e��F��j�;w�Q@����iCuys��@�)M����6�`�Y������6gPnL��<������h|&�i����{���G?Zl��f�K�S��<U���f���f�#�w�L����tD��h��E�^{m�fg{=<Lp8b��.5��!3�A�cF1B�:�#u��1�9���z	LK`HgSZ������]`����ey����7���b�s�.��+���$<@.���`��1����E����O ����)���;�\���e���l��'u8����x-A�1���~f�k��B���E���O�[:��2��k�QF����q��c�����s�������C�$Uyi[7���K�u�<x*���+O������F�������������@[;%}V��Ks�%�EL��!���6�zF���\��H@XD
���%`�(�Rs�:~�`��|�,�_��n����mo[���^����(���[*'��S���o����u�YB�������
���9����>�������[65��t��FG���G0�m����nw���i	[BO�9���Jg����1����iC��XT��a��iXB%��
)�<bP:usM�����fi���<����r���P9t��}�(��v��Z<�9�Y���l\�!u���^<�t5�W��Hg+�
�r#?'�x�$-��!���[�$E�p��'/�?i�u�/B)D����/��3tcC_���z	�����w���6T�2��~Ve931����(gI�'\A��	��!��#��%�8F�Y	�0�\������v�����z>7����{��b������r%�O��i���Q�L����G�z'a������x�3�9�����p�	A*���?h��NL���]-�w��tz��l�����s��M����0��r����e>��F>1'M�` ���E"���rAn�������#\}�������<I��my�u=����.����������U�C<,g���&�����d���C�{XT�vb>��������a3'+>0���tJ�% �*,�����t�M'�������a�&��G>R0���S���2�B���4�H�6D0����3�A�Q� 5�N�������?�!�����g�%0'�Mg�3`L�\n��	����������};o`'Kxe!�'�����!�Cxx���OZ�%��@Da\/\���<�}0:p�O��f��e`3��uF8!f&���/>U����&����+�,c��7"�\0�o��6*�(G}�)�Q���%0���M��"�[~��_}������eYN�#����`DDW]uU���}�|��9�W ��K����G�:z��\���P9�>�����o�y�~����*�gy/�0�<�mp��z����i�����HG;��A�������'�C�"Q6�aL�k��� @��
oxC�v���0����e��+\��;����JO�����r�)K�rT��fY�^�6I\���g�x��7�E��j2��Q��#H���m����^��@�vJS��� ��LcMy�����Os]�+	H`�(X�;��z�M0������[bOc[n�e��N;��*PWY��%���rN��������
��x�
7�u�����J����8.�{��6k�3����:S��3����t���c	�s��
���Y�H �hr}��"��i���Z*��Rf3{$-�������~��<���}�Pt�3`�d�;a:4���3���a���{�`����{��G��)o���4��3	���������p�9�L���u����Nk:|���
|-w������ �v���x��kc��g]�7]_Z��Sof�x6�n��^����3������/�������@�8wh�E�B{����ROD��@X�dc?�L�P�o������+y���sLcz7.6&�0�Q���������O��S/������r�������?�������de���=G������MRs���c=���r�X�@�t���g����m�O�srq~��hk��/�����G�
�BvA�����U�i:Uz�I@X�,���7�@�G��?f�G�+���uy4��l��1fg��2��� J���~u��c�$`�#���O\H��!��=�Y�&`6*���p������K��w��Om��*���e�*�Y�8����1~C�u�Y�H`�}:o��0HDy��Z��}z��5&yB4����0��,������ f���ty�I'����C|���!��aX��{����X0�'f_����,�C�/x6��X�,�:�=����<=�������6?��%0�@�����:j2#�z)��]��,~�y��'?�M�_���$����<(P7��aO�:���(���!��*���u����A�@x��p����������''mg��7������~>S7�]b��q���[o]�q�8����UM���G��A��Y���T���/�wO�9��!��*C p�����S��/�U��uc��������m�1�$i~�>��l����/�q�6����V7�&��is�>.%0��)��	k�����p�,�=�u�H�7�m�zFz���t�H�R���B���
�M0������c���.��FN�8��Q�aFP�1�-A��'?�I$/��xH��/y9�1�`�c3���ljt������">3���5D�6��{�QK����+�(F����>�@l��,�{�8/b��|l�V00�oh�k�xXm�h�������;���dst�1��K�:��y�v�q,�[�1T�1^w�.��9�����~tz��8����mtFb��{��&�7��W���]z���-����CG�t������Y�a��J�>����hK] �e2�e������@�/���_���lO��q|��?�)O)�|�c���P];��=K���P��,~�c���d�w�C���������Bd�������U����!b����//�Q��U����x�ry�{Qw}�_��s�%L�bx�u�<t ���u��K.�d�h��3����q.��,��a	��G�:5��IC�&e���1S����g�!/��\���t���p[���jc�����s���3f�$�S����\@�!�����Fn��OHaX��-����m�t?K`��S����L<�v%
7�^�$�Bd�!>����$�?7�m�zFU���_��u���*x��M0@���h��-�����.*���o>���#

:`Q#�h�g�3������g�k����Y����1h���
\9a�M��|��������6���o\HEgtz�.�g)���>U����X�s��SqNbk���o����1~C�'p���]w�u�
���=�q���K�
�����	���b�1��w�����u���F�Kw�4���1�qUj��R/\pA� 
��2���0:Rs�9�-_����}��b�-&��>��!��0��8E0Fg+�"����5y��
���	a�9����XU
R�����}7t�5��RC	t�lz��_\�19uZ���~���N�����e������9�F�K=}���g�x��~�x�J��=�yOq����LV�����}��\�|v�����#@[6
�C]���+����^{���H����u�0D���CD��?m!�b�Xvy>�P��R�0ro|�'��m�}��w�)��r�	�V���Y��PL�cy�~����nN���6�BX���Y�&��M\��c>��S��~z�h�?��������@����~�8��C�k��K��rGWJ`�hk�����K��R���?�\�������<�����'i�|h�[�cv�gTk��W�u������E��?��y�m*���D����>@C w4�J�9p��#i���*�Qf�cnU��l���XT�v�y�|����CX�`�tUib���,Z����Z,�9�p�iCC���b��F[��n��Vvd��
:��A�*��<j����7�yp}z�i�Mf�s��|�����v�I�9�X0�*|�������A�/��<�;����������Moz��l�;<��a~(��K�������5���q�dT0s1���`�<
 �����Nz�����������������f����6yi��J�����������&��� &�� LI�6���7<��vV�kZ��\&�]�E�5�n�@��`g��x?��1���7a�u�~��>�x]"���|�![8�B�(0HHY�Z1x���������Z��3�/��O����~�XU���RO�J��9��%B��N-��O��6I����l3i(�(B9���
��>p"N&O��:Qi��6g��n��j&��NA��<�����:��7�X�������>���1�BE��e[���M�u�g���y������$ �E#�``�������fF���l��r��*|9g���*�{��^�d�*��`@�
M�FmT�)�}�,�.F�&�"1;sL�<,h���#'�|r��N�V�rQ����N;w�c���"fl':�Y
c���t���7�El����c��
����X+�l�u�p���G�#�j���� c�����t�mF�="�:��t�S�w����h����J��{�;�igl���A��Y�f��^x���o�y�C���4������fM�Kg��>��Sf�;����]`5������w�	��������u����v�����7T���^�����E��xF���������G��p�M�<��U��}������?���@;��h+�n��7�����="�M�+�������A|�V��^N�S� =V��1����M�t�l���O��Qx$�;7bl�������$��mm�IB?H`�ti��]oB]�'����o�B��u9Q�zFz����������������$[j�b���h��{��Kf^y���X��~�b�mtP>��U����?���^��W).`�;����&�q�[�����S���V[m�,D�=�0��w��� ��1�v\�F����U��>��R(P��	�yL)�/.�S���AD�/5���

�\:��Rz���9��M���R��kCC}�cz	,*�x���lr��.���;���n����x��1�@\_��W]m��0[/4���]����1��yO����&��G���z�{���<����<sO�<#B���k������c�P;xH�	D���g����,
���+�:QE�������K=�!)�.�S���q���
\V���oYN�,B�<��^23)�0�B��/}�K�j�������-y���A�b�!�����+�-&��<�1e�����>���*�Cf�:��$��#�8��������.��!���[�Lpt�
7�����
���}�	�>���j?��2De��c����J�����3���?���M�?O[�^�m�6c>��H�d�"��
O���
t��6g�c�F��@[;%�����x1a�Wnc�)�����t���}�q����s)	H`Q	(X�;;��E����l�I�B�:-p����G�����'cP��J3���A������>���o�O����y�����}����j�
-��k$ �y#� ?�8\w�nC��&��F��@>�����x���NPWu�.�x�p.�g�kE�0d�3���n���� ��x���*�%_���V'�7f-�����	����������r�!�����a��G\�o��=������%�\Rz�+WV�����7�\�u��h��_�1����������y�M��iA/�����fl�>=V��j�t��X�6B��.��@���"M�O�~�m����$��?�"LK�#��$ 	�;�~��$ 	H@��$ 	H@��$ 	H@��$ 	H`���$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(��;h�% 	H@��$ 	H@��$ 	H@��$ 	H@(�]$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@����A�/	H@��$ 	H@��$ 	H@��$ 	H@@@��h�"	H@��$ 	H@��$ 	H@��$ 	H@�w
���	H@��$ 	H@��$ 	H@��$ 	H@��
@s	H@��$ 	H@��$ 	H@��$ 	H@���P00�w��K@��$ 	H@��$ 	H@��$ 	H@��P00��H@��$ 	H@��$ 	H@��$ 	H@�������y���_��$ 	H@��$ 	H@��$ 	H@��$0������E��$ 	H@��$ 	H@��$ 	H@��$0���4���$ 	H@��$ 	H@��$ 	H@��$ ���.��$ 	H@��$ 	H@��$ 	H@��$ �y'�``������$ 	H@��$ 	H@��$ 	H@��$ 	 �``4w��$ 	H@��$ 	H@��$ 	H@��$ 	�;�~��$ 	H@��$ 	H@��$ 	H@��$ 	H`���$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(��;h�% 	H@��$ 	H@��$ 	H@��$ 	H@(�]$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@����A�/	H@��$ 	H@��$ 	H@��$ 	H@@@��h�"	H@��$ 	H@��$ 	H@��$ 	H@�w
���	H@��$ 	H@��$ 	H@��$ 	H@��
@s	H@��$ 	H@��$ 	H@��$ 	H@���P00�w��K@��$ 	H@��$ 	H@��$ 	H@��P00��H@��$ 	H@��$ 	H@��$ 	H@�������y���_��$ 	H@��$ 	H@��$ 	H@��$0������E��$ 	H@��$ 	H@��$ 	H@��$0���4���$ 	H@��$ 	H@��$ 	H@��$ ���.��$ 	H@��$ 	H@��$ 	H@��$ �y'�``������$ 	H@��$ 	H@��$ 	H@��$ 	 �``4w��$ 	H@��$ 	H@��$ 	H@��$ 	�;�~��$ 	H@��$ 	H@��$ 	H@��$ 	H`���$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(��;h�% 	H@��$ 	H@��$ 	H@��$ 	H@(�]$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@����A�/	H@��$ 	H@��$ 	H@��$ 	H@@@��h�"	H@��$ 	H@��$ 	H@��$ 	H@�w
���	H@��$ 	H@��$ 	H@��$ 	H@��
@s	H@��$ 	H@��$ 	H@��$ 	H@���P00�w��K@��$ 	H@��$ 	H@��$ 	H@��P00��H@��$ 	H@��$ 	H@��$ 	H@�������y���_��$ 	H@��$ 	H@��$ 	H@��$0������E��$ 	H@��$ 	H@��$ 	H@��$0���4���$ 	H@��$ 	H@��$ 	H@��$ ���.��$ 	H@��$ 	H@��$ 	H@��$ �y'�``������$ 	H@��$ 	H@��$ 	H@��$ 	 �``4w��$ 	H@��$ 	H@��$ 	H@��$ 	�;�~��$ 	H@��$ 	H@��$ 	H@��$ 	H`���$ 	H@��$ 	H@��$ 	H@��$ 	H`�	(��;h�% 	H@��$ 	H@��$ 	H@��$ 	H@(�]$ 	H@��$ 	H@��$ 	H@��$ 	H@�N@����A�/	H@��$ 	H@��$ 	H@��$ 	H@@@��h�"	H@��$ 	H@��$ 	H@��$ 	H@�w
���	H@��$ 	H@��$ 	H@��$ 	H@��
@s	H@��$ 	H@��$ 	H@��$ 	H@���P00�w��K@��$ 	H@��$ 	H@��$ 	H@��P00��H@��$ 	H@��$ 	H@��$ 	H@�������y���_��$ 	H@��$ 	H@��$ 	H@��$0������E��$ 	H@��$ 	H@��$ 	H@��$0���4���$ 	H@��$ 	H@��$ 	H@��$ �����P�3Q�IEND�B`�
#8Andres Freund
andres@anarazel.de
In reply to: Xuneng Zhou (#1)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On 2025-06-08 22:33:39 +0800, Xuneng Zhou wrote:

This patch implements progressive backoff in XactLockTableWait() and
ConditionalXactLockTableWait().

As Kevin reported in this thread [1], XactLockTableWait() can enter a
tight polling loop during logical replication slot creation on standby
servers, sleeping for fixed 1ms intervals that can continue for a long
time. This creates significant CPU overhead.

The patch implements a time-based threshold approach based on Fujii’s
idea [1]: keep sleeping for 1ms until the total sleep time reaches 10
seconds, then start exponential backoff (doubling the sleep duration
each cycle) up to a maximum of 10 seconds per sleep. This balances
responsiveness for normal operations (which typically complete within
seconds) against CPU efficiency for the long waits in some logical
replication scenarios.

ISTM that this is going to wrong way - the real problem is that we seem to
have extended periods where XactLockTableWait() doesn't actually work, not
that the sleep time is too short. The sleep in XactLockTableWait() was
intended to address a very short race, not something that's essentially
unbound.

Greetings,

Andres Freund

#9Xuneng Zhou
xunengzhou@gmail.com
In reply to: Andres Freund (#8)
Re: Add progressive backoff to XactLockTableWait functions

Hi Andres,

Thanks for looking into this!

On Tue, Jun 17, 2025 at 10:17 PM Andres Freund <andres@anarazel.de> wrote:

Hi,

On 2025-06-08 22:33:39 +0800, Xuneng Zhou wrote:

This patch implements progressive backoff in XactLockTableWait() and
ConditionalXactLockTableWait().

As Kevin reported in this thread [1], XactLockTableWait() can enter a
tight polling loop during logical replication slot creation on standby
servers, sleeping for fixed 1ms intervals that can continue for a long
time. This creates significant CPU overhead.

The patch implements a time-based threshold approach based on Fujii’s
idea [1]: keep sleeping for 1ms until the total sleep time reaches 10
seconds, then start exponential backoff (doubling the sleep duration
each cycle) up to a maximum of 10 seconds per sleep. This balances
responsiveness for normal operations (which typically complete within
seconds) against CPU efficiency for the long waits in some logical
replication scenarios.

ISTM that this is going to wrong way - the real problem is that we seem to
have extended periods where XactLockTableWait() doesn't actually work, not
that the sleep time is too short.

Yeah, XactLockTableWait() works well when the targeted XID lock exists and
can be waited for. However, this assumption breaks down on hot standby
because transactions from the primary aren't running locally—no exclusive
locks are registered in the standby's lock table, leading to potentially
unbounded polling instead of proper blocking waits.

The purpose of XactLockTableWait() is to wait for a specified transaction
to commit or abort, which remains semantically correct for
SnapBuildWaitSnapshot() during logical decoding. How about adding special
handling for the hot standby case within XactLockTableWait() by detecting
RecoveryInProgres(). Although after studying the various calls of
XactLockTableWait(), I'm uncertain whether this condition is proper and
sufficient to avoid affecting other use cases.

The sleep in XactLockTableWait() was

intended to address a very short race, not something that's essentially

unbound.

The sleep in function is used to address the possible race between txn in
ProcArray and locktable that can occur in
building snapshots for logical decoding. But in the hot standby case, the
race does not exist and it becomes a polling.

Best regards,
Xuneng

#10Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#9)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

Here's patch version 4.

1. The problem

I conducted further investigation on this issue. The 1ms sleep in
XactLockTableWait that falls back to polling was not problematic in certain
scenarios prior to v16. It became an potential issue after the "Allow
logical decoding on standbys" feature was introduced [1]https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=0fdab27ad68a059a1663fa5ce48d76333f1bd74c. After that
commit, we can now create logical replication slots on hot standby servers
and perform many other logical decoding operations. [2]https://bdrouvot.github.io/2023/04/19/postgres-16-highlight-logical-decoding-on-standby/

2. The analysis

Is this issue limited to calling sites related to logical decoding? I
believe so. As we've discussed, the core issue is that primary transactions
are not running locally on the standby, which breaks the assumption of
XactLockTableWait—that there is an xid lock to wait on. Other call stacks
of this function, except those from logical decoding, are unlikely to
encounter this problem because they are unlikely to be invoked from standby
servers.

Analysis of XactLockTableWait calling sites:

Problematic Case (Hot Standby):

- Logical decoding operations in snapbuild.c during snapshot building

- This is the case that can run on hot standby and experience the issue

Non-problematic Cases (Primary Only):

- Heap operations (heapam.c): DML operations not possible on read-only
standby

- B-tree operations (nbtinsert.c): Index modifications impossible on
standby

- Logical apply workers (execReplication.c): Cannot start during recovery
(BgWorkerStart_RecoveryFinished)

- All other cases: Require write operations unavailable on standby

3. The proposed solution

If the above analysis is sound, one potential fix would be to add separate
branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry in
the lock table for waiting. We could implement a new function for this
logic, but it's hard to find a proper place for it to fit well: lmgr.c is
for locks, while standby.c or procarray.c are not that ideal either.
Therefore, I placed the special handling for standby in
SnapBuildWaitSnapshot.

The waiting strategy for this version uses threshold-based sleep. A more
ideal approach might be a continuous sleep that's only woken up when the
transaction completes, but I didn't find the proper infrastructure to
support it.

The CHECK_FOR_INTERRUPTS() calls in the sleep sections have been removed.
With separate handling for primary and standby, unbounded waiting seems
unlikely to occur here.

[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=0fdab27ad68a059a1663fa5ce48d76333f1bd74c
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=0fdab27ad68a059a1663fa5ce48d76333f1bd74c

[2]: https://bdrouvot.github.io/2023/04/19/postgres-16-highlight-logical-decoding-on-standby/
https://bdrouvot.github.io/2023/04/19/postgres-16-highlight-logical-decoding-on-standby/

Best regards,
Xuneng

Show quoted text

Attachments:

v4-0001-Add-threshold-based-sleep-to-SnapBuildWaitSnapshot.patchapplication/octet-stream; name=v4-0001-Add-threshold-based-sleep-to-SnapBuildWaitSnapshot.patchDownload
From f4e17832ad6c3729f552189575767637e9fc2bd3 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Mon, 23 Jun 2025 21:48:51 +0800
Subject: [PATCH v4] Add threshold-based sleep to SnapBuildWaitSnapshot for hot
 standby

Optimize transaction waiting during logical decoding on hot standby servers.
On hot standby servers, XactLockTableWait falls back to polling
TransactionIdIsInProgress() with fixed 1ms sleeps when transactions from
the primary have no local lock table entries, causing excessive CPU usage.

Implement threshold-based sleep in SnapBuildWaitSnapshot: sleep 1ms for
the first 5 seconds to keep normal operations responsive, then switch to
1s sleeps to reduce CPU overhead during long waits.

This change only affects logical decoding on hot standby servers, with no
impact on primary server operations.
---
 src/backend/replication/logical/snapbuild.c | 40 ++++++++++++++++++++-
 src/backend/storage/lmgr/lmgr.c             |  2 --
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 0d7bddbe4ed..1c2d6795531 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1443,7 +1443,45 @@ SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff)
 		if (TransactionIdFollows(xid, cutoff))
 			continue;
 
-		XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		/*
+		 * Wait for the transaction to complete. On primary servers, we can
+		 * use XactLockTableWait which efficiently acquires ShareLocks on
+		 * the transaction. On hot standby servers, transactions from the
+		 * primary have no local lock table entries, causing XactLockTableWait
+		 * to fall back to polling TransactionIdIsInProgress() with fixed 1ms
+		 * sleeps. This can result in excessive CPU usage during long waits.
+		 *
+		 * To optimize the standby case, we implement threshold-based sleep:
+		 * sleep 1ms for the first 5 seconds to keep normal operations
+		 * responsive, then switch to 1s sleeps to reduce CPU overhead
+		 * during potentially long waits for primary server transactions.
+		 */
+		if (RecoveryInProgress())
+		{
+			int left_till_hibernate = 5000;
+
+			for (;;)
+			{
+				if (!TransactionIdIsInProgress(xid))
+					break;
+
+				CHECK_FOR_INTERRUPTS();
+
+				if (left_till_hibernate > 0)
+				{
+					pg_usleep(1000L);		/* 1ms */
+					left_till_hibernate--;
+				}
+				else
+				{
+					pg_usleep(1000000L);	/* 1s */
+				}
+			}
+		}
+		else
+		{
+			XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		}
 	}
 
 	/*
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..b5270fb86b1 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -718,7 +718,6 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -761,7 +760,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
-- 
2.49.0

#11Fujii Masao
masao.fujii@oss.nttdata.com
In reply to: Xuneng Zhou (#10)
Re: Add progressive backoff to XactLockTableWait functions

On 2025/06/24 1:32, Xuneng Zhou wrote:

Hi,

Here's patch version 4.

1. The problem

I conducted further investigation on this issue. The 1ms sleep in XactLockTableWait that falls back to polling was not problematic in certain scenarios prior to v16. It became an potential issue after the "Allow logical decoding on standbys" feature was introduced [1]. After that commit, we can now create logical replication slots on hot standby servers and perform many other logical decoding operations. [2]

2. The analysis

Is this issue limited to calling sites related to logical decoding? I believe so. As we've discussed, the core issue is that primary transactions are not running locally on the standby, which breaks the assumption of XactLockTableWait—that there is an xid lock to wait on. Other call stacks of this function, except those from logical decoding, are unlikely to encounter this problem because they are unlikely to be invoked from standby servers.

Analysis of XactLockTableWait calling sites:

Problematic Case (Hot Standby):

- Logical decoding operations in snapbuild.c during snapshot building

- This is thecase that can run on hot standby and experience the issue

Non-problematic Cases (Primary Only):

- Heap operations (heapam.c): DML operations not possible on read-only standby

- B-tree operations (nbtinsert.c): Index modifications impossible on standby

- Logical apply workers (execReplication.c): Cannot start during recovery (BgWorkerStart_RecoveryFinished)

- All other cases: Require write operations unavailable on standby

3. The proposed solution

If the above analysis is sound, one potential fix would be to add separate branching for standby in XactLockTableWait. However, this seems inconsistent with the function's definition—there's simply no lock entry in the lock table for waiting. We could implement a new function for this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.
But if these functions aren't intended to be used during recovery and
the loop shouldn't reach that many iterations, I'm also okay with
the v4 approach of introducing a separate function specifically for recovery.

But this amakes me wonder if we should add something like
Assert(!RecoveryInProgress()) to those two functions, to prevent them
from being used during recovery in the future.

but it's hard to find a proper place for it to fit well: lmgr.c is for locks, while standby.c or procarray.c are not that ideal either. Therefore, I placed the special handling for standby in SnapBuildWaitSnapshot.

Since the purpose and logic of the new function are similar to
XactLockTableWait(), I think it would be better to place it nearby
in lmgr.c, even though it doesn't handle a lock directly. That would
help keep the related logic together and improve readability.

Regards,

--
Fujii Masao
NTT DATA Japan Corporation

#12Andres Freund
andres@anarazel.de
In reply to: Fujii Masao (#11)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry
in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

I think neither v3 nor v4 are viable patches.

Greetings,

Andres Freund

#13Fujii Masao
masao.fujii@oss.nttdata.com
In reply to: Andres Freund (#12)
Re: Add progressive backoff to XactLockTableWait functions

On 2025/07/02 23:04, Andres Freund wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry
in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.
But are you suggesting that this doesn't need to be addressed?
Or do you have another idea for how to handle it?

Regards,

--
Fujii Masao
NTT DATA Japan Corporation

#14Andres Freund
andres@anarazel.de
In reply to: Fujii Masao (#13)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On July 2, 2025 10:15:09 AM EDT, Fujii Masao <masao.fujii@oss.nttdata.com> wrote:

On 2025/07/02 23:04, Andres Freund wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry
in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.

Right.

But are you suggesting that this doesn't need to be addressed?

No.

Or do you have another idea for how to handle it?

We have all the information to make it work properly on standby. I've not find through the code to figure out not, but that's what needs to happen, instead on putting on another layer of hacks.

Andres

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

#15Fujii Masao
masao.fujii@oss.nttdata.com
In reply to: Andres Freund (#14)
Re: Add progressive backoff to XactLockTableWait functions

On 2025/07/02 23:19, Andres Freund wrote:

Hi,

On July 2, 2025 10:15:09 AM EDT, Fujii Masao <masao.fujii@oss.nttdata.com> wrote:

On 2025/07/02 23:04, Andres Freund wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry
in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.

Right.

But are you suggesting that this doesn't need to be addressed?

No.

Or do you have another idea for how to handle it?

We have all the information to make it work properly on standby. I've not find through the code to figure out not, but that's what needs to happen, instead on putting on another layer of hacks.

Sorry, maybe I failed to get your point...
Could you explain your idea or reasoning in a bit more detail?

Regards,

--
Fujii Masao
NTT DATA Japan Corporation

#16Xuneng Zhou
xunengzhou@gmail.com
In reply to: Fujii Masao (#15)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Wed, Jul 2, 2025 at 10:56 PM Fujii Masao <masao.fujii@oss.nttdata.com>
wrote:

On 2025/07/02 23:19, Andres Freund wrote:

Hi,

On July 2, 2025 10:15:09 AM EDT, Fujii Masao <

masao.fujii@oss.nttdata.com> wrote:

On 2025/07/02 23:04, Andres Freund wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this

seems

inconsistent with the function's definition—there's simply no lock

entry

in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.

Right.

But are you suggesting that this doesn't need to be addressed?

No.

Or do you have another idea for how to handle it?

We have all the information to make it work properly on standby. I've

not find through the code to figure out not, but that's what needs to
happen, instead on putting on another layer of hacks.

Sorry, maybe I failed to get your point...
Could you explain your idea or reasoning in a bit more detail?

My take is that XactLockTableWait() isn’t really designed to work on
standby. Instead of adding another layer on top like v4 did, maybe we can
tweak the function itself to support standby. One possible approach could
be to add a check like RecoveryInProgress() to handle the logic when
running on a standby.

Best regards,
Xuneng

#17Xuneng Zhou
xunengzhou@gmail.com
In reply to: Fujii Masao (#11)
Re: Add progressive backoff to XactLockTableWait functions

Thanks for the feedbacks!

To be honest, I'm fine with v3, since it only increases the sleep time

after 5000 loop iterations, which has negligible performance impact.
But if these functions aren't intended to be used during recovery and
the loop shouldn't reach that many iterations, I'm also okay with
the v4 approach of introducing a separate function specifically for
recovery.

But this amakes me wonder if we should add something like
Assert(!RecoveryInProgress()) to those two functions, to prevent them
from being used during recovery in the future.

but it's hard to find a proper place for it to fit well: lmgr.c is for

locks, while standby.c or procarray.c are not that ideal either. Therefore,
I placed the special handling for standby in SnapBuildWaitSnapshot.

Since the purpose and logic of the new function are similar to
XactLockTableWait(), I think it would be better to place it nearby
in lmgr.c, even though it doesn't handle a lock directly. That would
help keep the related logic together and improve readability.

Now I see two possible approaches here. One is to extend
XactLockTableWait(), and the other is to introduce a new wait function
specifically for standby. For the first option, adding standby-specific
logic might not align well with the function’s name or its original design.
If we go with a new function, we might need to consider what other
scenarios it could be reused in. If this is the only place it would apply,
whether it’s worth introducing a separate function just for this case.

Best regards,
Xuneng

Show quoted text
#18Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#16)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Thu, Jul 3, 2025 at 9:30 AM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this

seems

inconsistent with the function's definition—there's simply no lock

entry

in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep

time

after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.

Right.

But are you suggesting that this doesn't need to be addressed?

No.

Or do you have another idea for how to handle it?

We have all the information to make it work properly on standby. I've

not find through the code to figure out not, but that's what needs to
happen, instead on putting on another layer of hacks.

Sorry, maybe I failed to get your point...
Could you explain your idea or reasoning in a bit more detail?

My take is that XactLockTableWait() isn’t really designed to work on
standby. Instead of adding another layer on top like v4 did, maybe we can
tweak the function itself to support standby. One possible approach could
be to add a check like RecoveryInProgress() to handle the logic when
running on a standby.

After thinking about this further, Andres's suggestion might be replacing
polling(whether smart or not) with event-driven like waiting in
XactLockTableWait. To achieve this, implementing a new notification
mechanism for standby servers seems to be required. From what I can
observe, the codebase appears to lack IPC infrastructure for waiting on
remote transaction completion and receiving notifications when those
transactions finish. I'm not familiar with this area, so additional inputs
would be very helpful here.

#19Fujii Masao
masao.fujii@oss.nttdata.com
In reply to: Xuneng Zhou (#18)
Re: Add progressive backoff to XactLockTableWait functions

On 2025/07/04 17:57, Xuneng Zhou wrote:

Hi,

On Thu, Jul 3, 2025 at 9:30 AM Xuneng Zhou <xunengzhou@gmail.com <mailto:xunengzhou@gmail.com>> wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry
in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.

Right.

But are you suggesting that this doesn't need to be addressed?

No.

Or do you have another idea for how to handle it?

We have all the information to make it work properly on standby. I've not find through the code to figure out not, but that's what needs to happen, instead on putting on another layer of hacks.

Sorry, maybe I failed to get your point...
Could you explain your idea or reasoning in a bit more detail?

My take is that XactLockTableWait() isn’t really designed to work on standby. Instead of adding another layer on top like v4 did, maybe we can tweak the function itself to support standby. One possible approach could be to add a check like RecoveryInProgress() to handle the logic when running on a standby.

After thinking about this further, Andres's suggestion might be replacing polling(whether smart or not) with event-driven like waiting in XactLockTableWait. To achieve this, implementing a new notification mechanism for standby servers seems to be required. From what I can observe, the codebase appears to lack IPC infrastructure for waiting on remote transaction completion and receiving notifications when those transactions finish. I'm not familiar with this area, so additional inputs would be very helpful here.

Your guess might be right, or maybe not. It's hard for me to say for sure.
It seems better to wait for Andres to explain his idea in more detail,
rather than trying to guess...

Regards,

--
Fujii Masao
NTT DATA Japan Corporation

#20Andres Freund
andres@anarazel.de
In reply to: Fujii Masao (#19)
Re: Add progressive backoff to XactLockTableWait functions

On 2025-07-05 01:14:45 +0900, Fujii Masao wrote:

On 2025/07/04 17:57, Xuneng Zhou wrote:

Hi,

On Thu, Jul 3, 2025 at 9:30 AM Xuneng Zhou <xunengzhou@gmail.com <mailto:xunengzhou@gmail.com>> wrote:

Hi,

On 2025-07-02 22:55:16 +0900, Fujii Masao wrote:

On 2025/06/24 1:32, Xuneng Zhou wrote:

3. The proposed solution

If the above analysis is sound, one potential fix would be to add
separate branching for standby in XactLockTableWait. However, this seems
inconsistent with the function's definition—there's simply no lock entry
in the lock table for waiting. We could implement a new function for
this logic,

To be honest, I'm fine with v3, since it only increases the sleep time
after 5000 loop iterations, which has negligible performance impact.

I think this is completely the wrong direction. We should make
XactLockTableWait() on standbys, not make the polling smarter.

On standby, XactLockTableWait() can enter a busy loop with 1ms sleeps.

Right.

But are you suggesting that this doesn't need to be addressed?

No.

Or do you have another idea for how to handle it?

We have all the information to make it work properly on standby. I've not find through the code to figure out not, but that's what needs to happen, instead on putting on another layer of hacks.

Sorry, maybe I failed to get your point...
Could you explain your idea or reasoning in a bit more detail?

My take is that XactLockTableWait() isn’t really designed to work on standby. Instead of adding another layer on top like v4 did, maybe we can tweak the function itself to support standby. One possible approach could be to add a check like RecoveryInProgress() to handle the logic when running on a standby.

After thinking about this further, Andres's suggestion might be replacing polling(whether smart or not) with event-driven like waiting in XactLockTableWait. To achieve this, implementing a new notification mechanism for standby servers seems to be required. From what I can observe, the codebase appears to lack IPC infrastructure for waiting on remote transaction completion and receiving notifications when those transactions finish. I'm not familiar with this area, so additional inputs would be very helpful here.

Your guess might be right, or maybe not. It's hard for me to say for sure.
It seems better to wait for Andres to explain his idea in more detail,
rather than trying to guess...

My position is basically:

1) We should *never* add new long-duration polling loops to postgres. We've
regretted it every time. It just ends up masking bugs and biting us in
scenarios we didn't predict (increased wakeups increasing power usage,
increased latency because our more eager wakeup mechanisms were racy).

2) We should try rather hard to not even have any new very short lived polling
code. The existing code in XactLockTableWait() isn't great, even on the
primary, but the window during the polling addresses is really short, so
it's *kinda* acceptable.

3) There are many ways to address the XactLockTableWait() issue here. One way
would be to simply make XactLockTableWait() work on standbys, by
maintaining the lock table. Another would be to teach it to add some
helper to procarray.c that allows XactLockTableWait() to work based on the
KnownAssignedXids machinery.

I don't have a clear preference for how to make this work in a non-polling
way. But it's clear to me that making it poll smarter is the completely wrong
direction.

Greetings,

Andres Freund

#21Xuneng Zhou
xunengzhou@gmail.com
In reply to: Andres Freund (#20)
2 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi Andres, hi all,

Thanks a lot for the advice.

My position is basically:

1) We should *never* add new long-duration polling loops to postgres. We've
regretted it every time. It just ends up masking bugs and biting us in
scenarios we didn't predict (increased wakeups increasing power usage,
increased latency because our more eager wakeup mechanisms were racy).

2) We should try rather hard to not even have any new very short lived polling
code. The existing code in XactLockTableWait() isn't great, even on the
primary, but the window during the polling addresses is really short, so
it's *kinda* acceptable.

I’m not familiar with the historical problems that polling has caused,
it does seem that explicit waiting is generally more efficient in its
own right.

3) There are many ways to address the XactLockTableWait() issue here. One way
would be to simply make XactLockTableWait() work on standbys, by
maintaining the lock table. Another would be to teach it to add some
helper to procarray.c that allows XactLockTableWait() to work based on the
KnownAssignedXids machinery.

I don't have a clear preference for how to make this work in a non-polling
way. But it's clear to me that making it poll smarter is the completely wrong
direction.

Greetings,

Andres Freund

I’ve tried to replace polling with waiting using KnownAssignedXids mechanisms.

What changed
1. Each XID now has a small hash-table entry with a condition variable.
2. XactLockTableWait() on a standby registers on that CV instead of polling.
3. Whenever a transaction (or sub-xid) is pruned from
KnownAssignedXids we call WakeXidWaiters(), which broadcasts to the
exact XID’s CV.

Feedback welcome.

Best,
Xuneng

Attachments:

v5-0001-Replace-polling-with-waiting-in-XactLockTableWait.patchapplication/octet-stream; name=v5-0001-Replace-polling-with-waiting-in-XactLockTableWait.patchDownload
From ba51fa5bbf865addb34a75aec35882c61d66f344 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Mon, 7 Jul 2025 21:19:21 +0800
Subject: [PATCH v5] Replace polling with waiting in XactLockTableWait on 
 standby servers

Previously, XactLockTableWait() and ConditionalXactLockTableWait() used
inefficient polling when waiting for transactions to complete on standby servers.
This caused excessive CPU usage and poor response latency during transaction waits.

This polling occurred because standby servers do not maintain the primary's
lock table, so these functions fall back to repeatedly checking
TransactionIdIsInProgress() until the target transaction completes.
This situation commonly arises during logical replication slot creation on hot standby.

Replace the polling mechanism with per-XID event-driven waiting using a hash table
of condition variables. When transactions complete during KnownAssignedXids updates,
WakeXidWaiters() immediately wakes only the processes waiting for specific XIDs.
This eliminates polling entirely while providing precise, low-latency notifications.

The changes include a new XACT_COMPLETE wait event, a partitioned XidWaitHash table
mapping transaction IDs to condition variables, and new functions StandbyXidWait(),
WakeXidWaiters(), and WakeAllXidWaiters(). XactLockTableWait() now tries per-XID
waiting on standby servers instead of falling back to inefficient polling.
---
 src/backend/storage/ipc/procarray.c           | 235 ++++++++++++++++++
 src/backend/storage/lmgr/lmgr.c               |  34 +++
 .../utils/activity/wait_event_names.txt       |   1 +
 src/include/storage/procarray.h               |   5 +
 4 files changed, 275 insertions(+)

diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index e5b945a9ee3..4a7f2c6cfa8 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -306,6 +306,41 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+/*
+ * XID waiter hash table configuration
+ *
+ * NUM_XID_WAIT_PARTITIONS must be a power of 2 to work with the hash
+ * table partitioning scheme used by dynahash.c. The value of 16 partitions
+ * matches the lock manager's partitioning to minimize contention under
+ * high concurrency workloads.
+ */
+#define NUM_XID_WAIT_PARTITIONS  16   /* Must be power of 2 */
+
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ *
+ * This structure is stored in a partitioned hash table and provides
+ * condition variable-based waiting for specific transaction IDs during
+ * hot standby operations. Each entry represents waiters for a single XID.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+	pg_atomic_uint32 waiter_count;	/* number of backends waiting */
+	bool		initialized;		/* true when entry is fully set up */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * The table is partitioned to reduce lock contention and uses the
+ * same infrastructure as PostgreSQL's lock manager.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -369,6 +404,32 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
 
+/*
+ * Calculate shared memory size for XID waiter hash table.
+ *
+ * This function estimates the memory requirements for the hash table
+ * used to track per-XID waiters on standby servers. The estimation
+ * assumes an average of 2 concurrent waiters per backend.
+ *
+ * Only called during PostgreSQL startup as part of shared memory
+ * size calculation. Returns 0 if hot standby is not enabled.
+ */
+static Size
+XidWaitShmemSize(void)
+{
+	/* Only allocate memory when hot standby could be used */
+	if (!EnableHotStandby)
+		return 0;
+
+	/*
+	 * Estimate maximum concurrent XID waiters.
+	 * Conservative estimate: 2 waiters per backend on average.
+	 * This provides headroom for burst scenarios while avoiding
+	 * excessive memory usage in typical workloads.
+	 */
+	return hash_estimate_size(MaxBackends * 2, sizeof(XidWaitEntry));
+}
+
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
  */
@@ -406,6 +467,7 @@ ProcArrayShmemSize(void)
 								 TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+		size = add_size(size, XidWaitShmemSize());
 	}
 
 	return size;
@@ -458,6 +520,24 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+
+		/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+			long max_xid_waiters;
+
+			max_xid_waiters = MaxBackends * 2;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+			info.num_partitions = NUM_XID_WAIT_PARTITIONS;
+
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+									   max_xid_waiters / 2,  /* init_size */
+									   max_xid_waiters,      /* max_size */
+									   &info,
+									   HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
+		}
 	}
 }
 
@@ -1370,6 +1450,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
 		procArray->lastOverflowedXid = max_xid;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up waiters for expired subtransactions */
+	for (i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4488,6 +4572,11 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
 	TransamVariables->xactCompletionCount++;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up per-XID waiters */
+	WakeXidWaiters(xid);
+	for (int i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4521,6 +4610,9 @@ ExpireAllKnownAssignedTransactionIds(void)
 	 */
 	procArray->lastOverflowedXid = InvalidTransactionId;
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since all transactions are being expired */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -4553,6 +4645,9 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 		procArray->lastOverflowedXid = InvalidTransactionId;
 	KnownAssignedXidsRemovePreceding(xid);
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since we may have expired transactions they're waiting for */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -5265,3 +5360,143 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID. This replaces polling-based approaches with direct
+ * event notification.
+ *
+ * The function handles the complete lifecycle of waiting: finding or
+ * creating the hash entry, managing waiter counts, and cleaning up
+ * when the last waiter finishes.
+ *
+ * Returns true if we waited (and the XID completed), false if waiting
+ * was not applicable (not in recovery, XID already complete, etc.).
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+bool
+StandbyXidWait(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	uint32		hashcode;
+
+	/* Only meaningful during recovery */
+	if (!InHotStandby || !XidWaitHash)
+		return false;
+
+	/* Quick exit if transaction already complete */
+	if (!TransactionIdIsInProgress(xid))
+		return false;
+
+	/* Get hash code for partition locking */
+	hashcode = get_hash_value(XidWaitHash, &xid);
+
+	/* Find or create hash entry */
+	entry = hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+									   HASH_ENTER, &found);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = xid;
+		ConditionVariableInit(&entry->cv);
+		pg_atomic_init_u32(&entry->waiter_count, 0);
+		entry->initialized = true;
+	}
+
+	/* Increment waiter count */
+	pg_atomic_fetch_add_u32(&entry->waiter_count, 1);
+
+	/* Standard PostgreSQL condition variable waiting pattern */
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/* Standard cleanup - PostgreSQL's exception system handles errors */
+	ConditionVariableCancelSleep();
+
+	/* Decrement waiter count and cleanup if last waiter */
+	if (pg_atomic_fetch_sub_u32(&entry->waiter_count, 1) == 1)
+	{
+		hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+								   HASH_REMOVE, NULL);
+	}
+
+	return true;
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to efficiently locate waiters for the specified
+ * XID and broadcasts on the associated condition variable to wake all
+ * waiting backends simultaneously.
+ *
+ * Safe to call even if no one is waiting on the XID - the hash lookup
+ * will simply find no entry and return immediately.
+ */
+void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	uint32		hashcode;
+
+	/* Skip if not in hot standby or hash table not initialized */
+	if (!InHotStandby || !XidWaitHash)
+		return;
+
+	hashcode = get_hash_value(XidWaitHash, &xid);
+
+	entry = hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+									   HASH_FIND, NULL);
+	if (entry && entry->initialized)
+	{
+		/* Wake all waiters for this specific XID */
+		ConditionVariableBroadcast(&entry->cv);
+	}
+}
+
+/*
+ * Wake all XID waiters.
+ *
+ * This function wakes up all backends waiting on any transaction ID.
+ * It is primarily used during standby promotion when the server is
+ * transitioning from recovery mode to normal operation, at which point
+ * all XID-based waiting becomes invalid.
+ *
+ * Note: This is a relatively expensive operation as it must examine
+ * every hash table entry, but it is only called during infrequent
+ * administrative operations like promotion.
+ */
+void
+WakeAllXidWaiters(void)
+{
+	HASH_SEQ_STATUS status;
+	XidWaitEntry *entry;
+
+	/* Skip if not in hot standby or hash table not initialized */
+	if (!InHotStandby || !XidWaitHash)
+		return;
+
+	hash_seq_init(&status, XidWaitHash);
+	while ((entry = (XidWaitEntry *) hash_seq_search(&status)) != NULL)
+	{
+		if (entry->initialized)
+			ConditionVariableBroadcast(&entry->cv);
+	}
+}
\ No newline at end of file
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..c230914e27c 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -652,6 +652,10 @@ XactLockTableDelete(TransactionId xid)
  * is specified, an error context callback is set up.  If 'oper' is passed as
  * None, no error context callback is set up.
  *
+ * On standby servers, uses efficient per-XID condition variable waiting
+ * instead of traditional lock acquisition.  On primary servers, uses the
+ * standard lock table approach.
+ *
  * Note that this does the right thing for subtransactions: if we wait on a
  * subtransaction, we will exit as soon as it aborts or its top parent commits.
  * It takes some extra work to ensure this, because to save on shared memory
@@ -687,6 +691,20 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		error_context_stack = &callback;
 	}
 
+	/* Try efficient per-XID wait first on standby */
+	if (unlikely(RecoveryInProgress()))
+	{
+		Assert(TransactionIdIsValid(xid));
+		Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+		StandbyXidWait(xid);
+
+		if (oper != XLTW_None)
+			error_context_stack = callback.previous;
+
+		return;
+	}
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -734,6 +752,10 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
  *
  * As above, but only lock if we can get the lock without blocking.
  * Returns true if the lock was acquired.
+ *
+ * On standby servers, returns false if the transaction is still in progress
+ * (since condition variable waiting would block).  On primary servers, uses
+ * conditional lock acquisition.
  */
 bool
 ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
@@ -741,6 +763,18 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	/* Try efficient per-XID wait first on standby */
+	if (unlikely(RecoveryInProgress()))
+	{
+		Assert(TransactionIdIsValid(xid));
+		Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+		if (!TransactionIdIsInProgress(xid))
+			return true;
+
+		return false;
+	}
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 4da68312b5f..fdf3652cf46 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -160,6 +160,7 @@ WAL_BUFFER_INIT	"Waiting on WAL buffer to be initialized."
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index ef0b733ebe8..fa4a43790dd 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,9 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+/* Per-XID waiting support for hot standby servers */
+extern bool StandbyXidWait(TransactionId xid);
+extern void WakeXidWaiters(TransactionId xid);
+extern void WakeAllXidWaiters(void);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0

v5_flamegraph.svgimage/svg+xml; name=v5_flamegraph.svgDownload
#22Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#21)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

I spent some time digging deeper into the KnownAssignedXids logic in
procarray.c and made a few refinements. Below are some observations
and questions I’d like to discuss.

1) Present usage (AFAICS)
It appears that logical decoding is the only place that waits for an
XID on a standby. The single call-site is SnapBuildWaitSnapshot(),
which waits in a simple loop:

for (off = 0; off < running->xcnt; off++)
{
TransactionId xid = running->xids[off];

if (TransactionIdIsCurrentTransactionId(xid))
elog(ERROR, "waiting for ourselves");

if (TransactionIdFollows(xid, cutoff))
continue;

XactLockTableWait(xid, NULL, NULL, XLTW_None);
}

So each backend seems to block on one XID at a time.

2) Picking the waiter data structure
Given that behaviour, the total number of concurrent waits can’t exceed
MaxBackends. If logical-slot creation stays the primary consumer for
now and for future, I’m wondering
whether a simple fixed-size array (or even a single global
ConditionVariable) might be sufficient.

In the patch I currently size the hash table the same as
KnownAssignedXids (TOTAL_MAX_CACHED_SUBXIDS), but that may well be
conservative.

3) Some trims
I’ve removed WakeAllXidWaiters() and call WakeXidWaiters() at each
point where an XID is deleted from KnownAssignedXids.

Feedback would be much appreciated.

Best,
Xuneng

Attachments:

v6-0001-Replace-polling-with-waiting-in-XactLockTableWait.patchapplication/octet-stream; name=v6-0001-Replace-polling-with-waiting-in-XactLockTableWait.patchDownload
From 6a0b0e58d43c185c391eaeda73ba00bccd1dff95 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Mon, 14 Jul 2025 22:31:15 +0800
Subject: [PATCH v6] Replace polling with waiting in XactLockTableWait on 
 standby servers

Previously, XactLockTableWait() and ConditionalXactLockTableWait() used
inefficient polling when waiting for transactions to complete on standby servers.
This caused excessive CPU usage and poor response latency during transaction waits.

This polling occurred because standby servers do not maintain the primary's
lock table, so these functions fall back to repeatedly checking
TransactionIdIsInProgress() until the target transaction completes.
This situation commonly arises during logical replication slot creation on hot standby.

Replace the polling mechanism with per-XID event-driven waiting using a hash table
of condition variables. When transactions complete during KnownAssignedXids updates,
WakeXidWaiters() immediately wakes only the processes waiting for specific XIDs.
This eliminates polling while providing precise notifications.

The changes include a new XACT_COMPLETE wait event, a partitioned XidWaitHash table
mapping transaction IDs to condition variables, and new functions StandbyXidWait(),
WakeXidWaiters(). XactLockTableWait() now tries per-XID waiting on standby servers
instead of falling back to inefficient polling.
---
 src/backend/storage/ipc/procarray.c           | 157 ++++++++++++++++++
 src/backend/storage/lmgr/lmgr.c               |  36 +++-
 .../utils/activity/wait_event_names.txt       |   1 +
 src/include/storage/procarray.h               |   3 +
 4 files changed, 195 insertions(+), 2 deletions(-)

diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index e5b945a9ee3..448e5b1d491 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -306,6 +306,32 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+/*
+ * XID waiter hash table partition count
+ */
+#define NUM_XID_WAIT_PARTITIONS  16   /* Must be power of 2 */
+
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+	pg_atomic_uint32 waiter_count;	/* number of backends waiting */
+	bool		initialized;		/* true when entry is fully set up */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * The table is partitioned to reduce lock contention and uses the
+ * same infrastructure as PostgreSQL's lock manager.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -368,6 +394,7 @@ static void MaintainLatestCompletedXidRecovery(TransactionId latestXid);
 static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
+static void WakeXidWaiters(TransactionId xid);
 
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
@@ -406,6 +433,12 @@ ProcArrayShmemSize(void)
 								 TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+
+		/*
+		 * XID waiter hash table sizing: allocate memory for the maximum
+		 * theoretical capacity but start with a smaller initial size.
+		 */
+		size = add_size(size, hash_estimate_size(TOTAL_MAX_CACHED_SUBXIDS, sizeof(XidWaitEntry)));
 	}
 
 	return size;
@@ -458,6 +491,25 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+
+		/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+			info.num_partitions = NUM_XID_WAIT_PARTITIONS;
+
+			/*
+			 * Start with 50% of theoretical capacity as baseline, but allow
+			 * growth up to full capacity if needed.
+			 */
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+									   TOTAL_MAX_CACHED_SUBXIDS / 2,  /* init_size */
+									   TOTAL_MAX_CACHED_SUBXIDS,      /* max_size */
+									   &info,
+									   HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
+		}
 	}
 }
 
@@ -5001,6 +5053,9 @@ KnownAssignedXidsRemove(TransactionId xid)
 	 * So, just ignore the search result.
 	 */
 	(void) KnownAssignedXidsSearch(xid, true);
+
+	/* Wake waiters for this specific XID as we expire it */
+	WakeXidWaiters(xid);
 }
 
 /*
@@ -5069,6 +5124,8 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 			if (!StandbyTransactionIdIsPrepared(knownXid))
 			{
 				KnownAssignedXidsValid[i] = false;
+				/* Wake waiters for this specific XID as we expire it */
+				WakeXidWaiters(knownXid);
 				count++;
 			}
 		}
@@ -5265,3 +5322,103 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID. This replaces polling-based approaches with direct
+ * event notification.
+ *
+ * The function handles the complete lifecycle of waiting: finding or
+ * creating the hash entry, managing waiter counts, and cleaning up
+ * when the last waiter finishes.
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+void
+StandbyXidWait(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	uint32		hashcode;
+
+	Assert(XidWaitHash);
+
+	/* Quick exit if not in hot standby mode yet or transaction already complete */
+	if (!InHotStandby || !TransactionIdIsInProgress(xid))
+		return;
+
+	/* Get hash code for partition locking */
+	hashcode = get_hash_value(XidWaitHash, &xid);
+
+	/* Find or create hash entry */
+	entry = hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+									   HASH_ENTER, &found);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = xid;
+		ConditionVariableInit(&entry->cv);
+		pg_atomic_init_u32(&entry->waiter_count, 0);
+		entry->initialized = true;
+	}
+
+	/* Increment waiter count */
+	pg_atomic_fetch_add_u32(&entry->waiter_count, 1);
+
+	/* Standard PostgreSQL condition variable waiting pattern */
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	/* Standard cleanup - PostgreSQL's exception system handles errors */
+	ConditionVariableCancelSleep();
+
+	/* Decrement waiter count and cleanup if last waiter */
+	if (pg_atomic_fetch_sub_u32(&entry->waiter_count, 1) == 1)
+	{
+		hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+								   HASH_REMOVE, NULL);
+	}
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to locate waiters for the specified XID and
+ * broadcasts on the associated condition variable to wake all waiting
+ * backends simultaneously.
+ */
+static void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	uint32		hashcode;
+
+	/* Quick exit if not in hot standby mode yet or hash table not available */
+	if (!InHotStandby || !XidWaitHash)
+		return;
+
+	hashcode = get_hash_value(XidWaitHash, &xid);
+
+	entry = hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+									   HASH_FIND, NULL);
+	if (entry && entry->initialized)
+	{
+		/* Wake all waiters for this specific XID */
+		ConditionVariableBroadcast(&entry->cv);
+	}
+}
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..24d502e9e57 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -652,6 +652,10 @@ XactLockTableDelete(TransactionId xid)
  * is specified, an error context callback is set up.  If 'oper' is passed as
  * None, no error context callback is set up.
  *
+ * On standby servers, uses per-XID condition variable waiting instead of
+ * lock acquisition.  On primary servers, uses the standard lock table
+ * approach.
+ *
  * Note that this does the right thing for subtransactions: if we wait on a
  * subtransaction, we will exit as soon as it aborts or its top parent commits.
  * It takes some extra work to ensure this, because to save on shared memory
@@ -687,6 +691,21 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		error_context_stack = &callback;
 	}
 
+	/* Try per-XID wait on standby */
+	if (unlikely(RecoveryInProgress()))
+	{
+		Assert(TransactionIdIsValid(xid));
+		Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+		StandbyXidWait(xid);
+
+		if (oper != XLTW_None)
+			error_context_stack = callback.previous;
+
+		return;
+	}
+
+	/* Try lock table wait on primary */
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -718,7 +737,6 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -734,6 +752,9 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
  *
  * As above, but only lock if we can get the lock without blocking.
  * Returns true if the lock was acquired.
+ *
+ * On standby servers, returns false if the transaction is still in progress
+ * On primary servers, uses conditional lock acquisition.
  */
 bool
 ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
@@ -741,6 +762,18 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	if (unlikely(RecoveryInProgress()))
+	{
+		Assert(TransactionIdIsValid(xid));
+		Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+		/* If the transaction is not in progress, we can return true immediately. */
+		if (!TransactionIdIsInProgress(xid))
+			return true;
+
+		return false;
+	}
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -761,7 +794,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 4da68312b5f..fdf3652cf46 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -160,6 +160,7 @@ WAL_BUFFER_INIT	"Waiting on WAL buffer to be initialized."
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index ef0b733ebe8..5166d97c424 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,7 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+/* Per-XID waiting support for standby servers */
+extern void StandbyXidWait(TransactionId xid);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0

#23Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#22)
Re: Add progressive backoff to XactLockTableWait functions

Hi all,

I spent some extra time walking the code to see where
XactLockTableWait() actually fires.
A condensed recap:

1) Current call-paths

A. Logical walsender (XLogSendLogical → … → SnapBuildWaitSnapshot) in
cascading standby

B. SQL slot functions
(pg_logical_slot_get_changes[_peek])
create_logical_replication_slot
pg_sync_replication_slots
pg_replication_slot_advance
binary_upgrade_logical_slot_has_caught_up

2) How many backends and XIDs in practice

A. Logical walsenders on a cascading standby
One per replication connection, capped by max_wal_senders.
default 10; hubs might run 10–40.

B. Logical slot creation is infrequent and bounded by
max_replication_slots, default 10;
other functions are not called that often either.

C. Wait pattern
XIDs waited-for during a snapshot build: SnapBuildWaitSnapshot wait
for one xid a time;

So, under today’s workloads both the number of xids and waiters stay
modest concurrently.

3) Future growth
Some features could multiply the number of concurrent waiters, but I
don’t have enough knowledge to predict those shapes.

Feedbacks welcome.

Best,
Xuneng

#24Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#23)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

After studying proarray and lmgr more closely, I have found several
critical issues in the two patches and underestimated their complexity
and subtlety. Sorry for posting immature patches that may have created
noise.

I now realize that making lock acquisition— (void) LockAcquire(&tag,
ShareLock, false, false); in XactLockTableWait
work on a standby, following Andres’ first suggestion, may be simpler
and require fewer new helpers.

XactLockTableWait fails on a standby simply because we never call
XactLockTableInsert. I am considering invoking XactLockTableInsert
when an XID is added to KnownAssignedXids, and XactLockTableDelete(the
constraint for delete now is not used for main xid in primary) when it
is removed. A preliminary implementation and test shows this approach
kinda works, but still need to confirm it is safe on a standby and
does not break other things.

patched:
Performance counter stats for process id '2331196':

233,947,559 cycles
106,270,044 instructions # 0.45
insn per cycle
12,464,449 cache-misses
9,397 context-switches

60.001191369 seconds time elapsed

head:
Performance counter stats for process id '2435004':

1,258,615,994 cycles
575,248,830 instructions # 0.46
insn per cycle
72,508,027 cache-misses
43,791 context-switches

60.001040589 seconds time elapsed

Best,
Xuneng

Attachments:

flamegraph.svgimage/svg+xml; name=flamegraph.svgDownload
#25Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#24)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Thu, Jul 17, 2025 at 10:54 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

After studying proarray and lmgr more closely, I have found several
critical issues in the two patches and underestimated their complexity
and subtlety. Sorry for posting immature patches that may have created
noise.

I now realize that making lock acquisition— (void) LockAcquire(&tag,
ShareLock, false, false); in XactLockTableWait
work on a standby, following Andres’ first suggestion, may be simpler
and require fewer new helpers.

XactLockTableWait fails on a standby simply because we never call
XactLockTableInsert. I am considering invoking XactLockTableInsert
when an XID is added to KnownAssignedXids, and XactLockTableDelete(the
constraint for delete now is not used for main xid in primary) when it
is removed. A preliminary implementation and test shows this approach
kinda works, but still need to confirm it is safe on a standby and
does not break other things.

Adding an xact lock for every tracked assigned XID on a standby—by
enabling XactLockTableInsert and XactLockTableDelete in the
KnownAssignedXids infrastructure— appears less attractive than I first
thought. The main concern is that the actual rate of xact-lock usage
may not justify the added overhead, even if that overhead is modest.

1) Usage
On a primary server, a xact lock is taken for every assigned XID, and
the cost is justified because xact locks are referenced in many code
paths. On a standby, however—especially in versions where logical
decoding is disabled—xact locks are used far less, if at all. The
current call stacks for XactLockTableWait on a standby (HEAD) are
listed in [1]/messages/by-id/CABPTF7Wbp7MRPGsqd9NA4GbcSzUcNz1ymgWfir=Yf+N0oDRbjA@mail.gmail.com. The only high-frequency caller is the logical walsender
in a cascading standby; all other callers are infrequent. Does that
single use case warrant creating a xact lock for every known assigned
XID? I don't think so, given that typical configurations have few
cascading standbys. In practice, most xact locks may never be touched
after they are created.

2) Cost
Low usage would be fine if the additional cost were negligible, but
that does not appear to be the case AFAICS.

* There are 5 main uses of the KnownAssignedXids data structure:
* * backends taking snapshots - all valid XIDs need to be copied out
* * backends seeking to determine presence of a specific XID
* * startup process adding new known-assigned XIDs
* * startup process removing specific XIDs as transactions end
* * startup process pruning array when special WAL records arrive
*
* This data structure is known to be a hot spot during Hot Standby, so we
* go to some lengths to make these operations as efficient and as concurrent
* as possible.

KnownAssignedXids is a hot spot like the comments state. The existing
design replaces a hash table with a single array and minimizes
exclusive locks and memory barriers to preserve concurrency. To
respect that design, calls to XactLockTableInsert and
XactLockTableDelete would need to occur outside any exclusive lock.
Unfortunately, that re-introduces the polling we are trying to
eliminate in XactLockTableWait: there is a window between registering
the XIDs and adding their xact locks. During that window, a backend
calling XactLockTableWait may need to poll because
TransactionIdIsInProgress shows the transaction as running while the
xact lock is still missing. If the window were short, this might be
acceptable, but it can be lengthy because XIDs are inserted and
deleted from the array in bulk. Some unlucky backends will therefore
spin before they can actually wait.

Placing the XactLockTableInsert/Delete calls inside the exclusive lock
removes the race window but hurts concurrency—the very issue this
module strives to avoid. Operations on the shared-memory hash table in
lmgr are slower and hold the lock longer than simple array updates, so
backends invoking GetSnapshotData could experience longer wait times.

3) Alternative
Adopt the hash-table + condition-variable design from patch v6, with
additional fixes and polishes.
Back-ends that call XactLockTableWait() sleep on the condition
variable. The startup process broadcasts a wake-up as the XID is
removed from KnownAssignedXids. The broadcast happens after releasing
the exclusive lock. This may be safe—sleeping back-ends remain blocked
until the CV signal arrives, so no extra polling occurs even though
the XID has already vanished from the array. For consistency, all
removal paths (including those used during shutdown or promotion,
where contention is minimal) follow the same pattern. The hash table
is sized at 2 × MaxBackends, which is already conservative for today’s
workload. For more potential concurrent use cases in the future, it
could be switched to larger numbers like TOTAL_MAX_CACHED_SUBXIDS if
necessary; even that would consume only a few megabytes.

Feedbacks welcome.

[1]: /messages/by-id/CABPTF7Wbp7MRPGsqd9NA4GbcSzUcNz1ymgWfir=Yf+N0oDRbjA@mail.gmail.com

Best,
Xuneng

Attachments:

v7-0001-Replace-polling-with-waiting-in-XactLockTableWait.patchapplication/octet-stream; name=v7-0001-Replace-polling-with-waiting-in-XactLockTableWait.patchDownload
From 98b71ccfb51ddb5ae5bdd6ade29afc7cff3b5a89 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Mon, 28 Jul 2025 17:20:32 +0800
Subject: [PATCH v7] Replace polling with waiting in XactLockTableWait on
 standby servers

Previously, XactLockTableWait() and ConditionalXactLockTableWait() used
inefficient polling when waiting for transactions to complete on standby servers.
This caused excessive CPU usage and poor response latency during transaction waits.

This polling occurred because standby servers do not maintain the primary's
lock table, so these functions fall back to repeatedly checking
TransactionIdIsInProgress() until the target transaction completes.
This situation commonly arises during logical replication operations on hot standby.

Replace the polling mechanism with per-XID event-driven waiting using a hash table
of condition variables. When transactions complete during KnownAssignedXids updates,
WakeXidWaiters() or WakeAllXidWaiters wakes the processes waiting for specific XIDs.
---
 src/backend/storage/ipc/procarray.c           | 219 +++++++++++++++++-
 src/backend/storage/lmgr/lmgr.c               |  36 ++-
 .../utils/activity/wait_event_names.txt       |   1 +
 src/include/storage/procarray.h               |   2 +
 4 files changed, 250 insertions(+), 8 deletions(-)

diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index bf987aed8d3..f2b58a3d186 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -62,6 +62,7 @@
 #include "storage/procarray.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
+#include "utils/hsearch.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 
@@ -282,6 +283,11 @@ static TransactionId *KnownAssignedXids;
 static bool *KnownAssignedXidsValid;
 static TransactionId latestObservedXid = InvalidTransactionId;
 
+/*
+ * Array of XIDs to wake up on standby
+ */
+static TransactionId *KnownAssignedXidsToWakeup;
+
 /*
  * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
  * the highest xid that might still be running that we don't have in
@@ -306,6 +312,32 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+/*
+ * XID waiter hash table partition count
+ */
+#define NUM_XID_WAIT_PARTITIONS  16
+
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+	pg_atomic_uint32 waiter_count;	/* number of backends waiting */
+	bool		initialized;		/* true when entry is fully set up */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * The table is partitioned to reduce lock contention and uses the
+ * same infrastructure as PostgreSQL's lock manager.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -352,7 +384,7 @@ static bool KnownAssignedXidExists(TransactionId xid);
 static void KnownAssignedXidsRemove(TransactionId xid);
 static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
 										TransactionId *subxids);
-static void KnownAssignedXidsRemovePreceding(TransactionId removeXid);
+static int	KnownAssignedXidsRemovePreceding(TransactionId removeXid);
 static int	KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax);
 static int	KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
 										   TransactionId *xmin,
@@ -369,6 +401,9 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
 
+static void WakeXidWaiters(TransactionId xid);
+static void WakeAllXidWaiters(void);
+
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
  */
@@ -403,9 +438,11 @@ ProcArrayShmemSize(void)
 	{
 		size = add_size(size,
 						mul_size(sizeof(TransactionId),
-								 TOTAL_MAX_CACHED_SUBXIDS));
+								 2 * TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+		size = add_size(size,
+						hash_estimate_size(MaxBackends * 2, sizeof(XidWaitEntry)));
 	}
 
 	return size;
@@ -458,6 +495,26 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+		KnownAssignedXidsToWakeup = (TransactionId *)
+			ShmemInitStruct("KnownAssignedXidsToWakeup",
+							mul_size(sizeof(TransactionId),
+									 TOTAL_MAX_CACHED_SUBXIDS),
+							&found);
+
+		/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+			info.num_partitions = NUM_XID_WAIT_PARTITIONS;
+
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+									   MaxBackends,  	/* init_size */
+									   MaxBackends * 2,      /* max_size */
+									   &info,
+									   HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
+		}
 	}
 }
 
@@ -1113,6 +1170,7 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
 			 * throw them away before we apply the recovery snapshot.
 			 */
 			KnownAssignedXidsReset();
+			WakeAllXidWaiters();
 			standbyState = STANDBY_INITIALIZED;
 		}
 		else
@@ -1370,6 +1428,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
 		procArray->lastOverflowedXid = max_xid;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up waiters for expired subtransactions */
+	for (i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4450,6 +4512,11 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
 	TransamVariables->xactCompletionCount++;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up per-XID waiters */
+	WakeXidWaiters(xid);
+	for (int i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4462,7 +4529,7 @@ ExpireAllKnownAssignedTransactionIds(void)
 	FullTransactionId latestXid;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
-	KnownAssignedXidsRemovePreceding(InvalidTransactionId);
+	(void) KnownAssignedXidsRemovePreceding(InvalidTransactionId);
 
 	/* Reset latestCompletedXid to nextXid - 1 */
 	Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
@@ -4483,6 +4550,9 @@ ExpireAllKnownAssignedTransactionIds(void)
 	 */
 	procArray->lastOverflowedXid = InvalidTransactionId;
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since all transactions are being expired */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -4494,6 +4564,8 @@ void
 ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 {
 	TransactionId latestXid;
+	int			i;
+	int			count;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
@@ -4513,8 +4585,12 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 	 */
 	if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
 		procArray->lastOverflowedXid = InvalidTransactionId;
-	KnownAssignedXidsRemovePreceding(xid);
+	count = KnownAssignedXidsRemovePreceding(xid);
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake XID waiters that have expired transactions they're waiting for */
+	for (i = 0; i < count; i++)
+		WakeXidWaiters(KnownAssignedXidsToWakeup[i]);
 }
 
 /*
@@ -4991,9 +5067,11 @@ KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
  * Prune KnownAssignedXids up to, but *not* including xid. If xid is invalid
  * then clear the whole table.
  *
+ * Returns the number of XIDs removed.
+ *
  * Caller must hold ProcArrayLock in exclusive mode.
  */
-static void
+static int
 KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 {
 	ProcArrayStruct *pArray = procArray;
@@ -5005,9 +5083,10 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 	if (!TransactionIdIsValid(removeXid))
 	{
 		elog(DEBUG4, "removing all KnownAssignedXids");
+		count = pArray->numKnownAssignedXids;
 		pArray->numKnownAssignedXids = 0;
 		pArray->headKnownAssignedXids = pArray->tailKnownAssignedXids = 0;
-		return;
+		return count;
 	}
 
 	elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);
@@ -5031,6 +5110,7 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 			if (!StandbyTransactionIdIsPrepared(knownXid))
 			{
 				KnownAssignedXidsValid[i] = false;
+				KnownAssignedXidsToWakeup[count] = knownXid;
 				count++;
 			}
 		}
@@ -5060,6 +5140,8 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 
 	/* Opportunistically compress the array */
 	KnownAssignedXidsCompress(KAX_PRUNE, true);
+
+	return count;
 }
 
 /*
@@ -5227,3 +5309,128 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID. This replaces polling-based approaches with direct
+ * event notification.
+ *
+ * The function handles the complete lifecycle of waiting: finding or
+ * creating the hash entry, managing waiter counts, and cleaning up
+ * when the last waiter finishes.
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+void
+StandbyXidWait(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	uint32		hashcode;
+	TransactionId wait_xid;
+
+	/* Skip if not in hot standby or hash table not initialized */
+	if (!InHotStandby || !XidWaitHash)
+		return;
+
+	/* Quick exit if transaction already complete */
+	if (!TransactionIdIsInProgress(xid))
+		return;
+
+	/* Always wait on the topmost transaction to avoid lost wake-ups */
+	wait_xid = SubTransGetTopmostTransaction(xid);
+
+	hashcode = get_hash_value(XidWaitHash, &wait_xid);
+
+	entry = hash_search_with_hash_value(XidWaitHash, &wait_xid, hashcode,
+									   HASH_ENTER, &found);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = wait_xid;
+		ConditionVariableInit(&entry->cv);
+		pg_atomic_init_u32(&entry->waiter_count, 0);
+		entry->initialized = true;
+	}
+
+	pg_atomic_fetch_add_u32(&entry->waiter_count, 1);
+
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	ConditionVariableCancelSleep();
+
+	/* Decrement waiter count and cleanup if last waiter */
+	if (pg_atomic_fetch_sub_u32(&entry->waiter_count, 1) == 1)
+	{
+		hash_search_with_hash_value(XidWaitHash, &wait_xid, hashcode,
+								   HASH_REMOVE, NULL);
+	}
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to locate waiters for the specified XID and
+ * broadcasts on the associated condition variable to wake all waiting
+ * backends simultaneously.
+ */
+static void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	uint32		hashcode;
+
+	if (!InHotStandby || !XidWaitHash)
+		return;
+
+	hashcode = get_hash_value(XidWaitHash, &xid);
+
+	entry = hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+									   HASH_FIND, NULL);
+	if (entry && entry->initialized)
+	{
+		/* Wake all waiters for this specific XID */
+		ConditionVariableBroadcast(&entry->cv);
+	}
+}
+
+/*
+ * Wake all XID waiters.
+ *
+ * This function wakes up all backends waiting on any transaction ID.
+ * It is primarily used during standby promotion when the server is
+ * transitioning from recovery mode to normal operation, at which point
+ * all XID-based waiting becomes invalid.
+ */
+static void
+WakeAllXidWaiters(void)
+{
+	HASH_SEQ_STATUS status;
+	XidWaitEntry *entry;
+
+	if (!InHotStandby || !XidWaitHash)
+		return;
+
+	hash_seq_init(&status, XidWaitHash);
+	while ((entry = (XidWaitEntry *) hash_seq_search(&status)) != NULL)
+	{
+		if (entry->initialized)
+			ConditionVariableBroadcast(&entry->cv);
+	}
+}
\ No newline at end of file
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..8b1b99f0175 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -652,6 +652,10 @@ XactLockTableDelete(TransactionId xid)
  * is specified, an error context callback is set up.  If 'oper' is passed as
  * None, no error context callback is set up.
  *
+ * On standby servers, uses efficient per-XID condition variable waiting
+ * instead of traditional lock acquisition.  On primary servers, uses the
+ * standard lock table approach.
+ *
  * Note that this does the right thing for subtransactions: if we wait on a
  * subtransaction, we will exit as soon as it aborts or its top parent commits.
  * It takes some extra work to ensure this, because to save on shared memory
@@ -687,6 +691,20 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		error_context_stack = &callback;
 	}
 
+	/* Try efficient per-XID wait first on standby */
+	if (RecoveryInProgress())
+	{
+		Assert(TransactionIdIsValid(xid));
+		Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+		StandbyXidWait(xid);
+
+		if (oper != XLTW_None)
+			error_context_stack = callback.previous;
+
+		return;
+	}
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -718,7 +736,6 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -734,6 +751,10 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
  *
  * As above, but only lock if we can get the lock without blocking.
  * Returns true if the lock was acquired.
+ *
+ * On standby servers, returns false if the transaction is still in progress
+ * (since condition variable waiting would block).  On primary servers, uses
+ * conditional lock acquisition.
  */
 bool
 ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
@@ -741,6 +762,18 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	/* Try efficient per-XID wait on standby */
+	if (RecoveryInProgress())
+	{
+		Assert(TransactionIdIsValid(xid));
+		Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+		if (!TransactionIdIsInProgress(xid))
+			return true;
+
+		return false;
+	}
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -761,7 +794,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0be307d2ca0..775cc7313ad 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -160,6 +160,7 @@ WAL_BUFFER_INIT	"Waiting on WAL buffer to be initialized."
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 2f4ae06c279..6e35f21f6e8 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,6 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+extern void StandbyXidWait(TransactionId xid);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0

#26Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#25)
3 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

During a short 100-second pg_create_logical_replication_slot benchmark
in standby, I compared HEAD with patch v7. v7 removes the
XactLockTableWait polling hot-spot (it no longer shows up in the flame
graph), yet the overall perf-counter numbers are only modestly lower,
suggesting something abnormal .

HEAD

cycles: 2,930,606,156
instructions: 1,003,179,713 (0.34 IPC)
cache-misses: 144,808,110
context-switches: 77,278
elapsed: 100 s

v7

cycles: 2,121,614,632
instructions: 802,200,231 (0.38 IPC)
cache-misses: 100,615,485
context-switches: 78,120
elapsed: 100 s

Profiling shows a second hot-spot in read_local_xlog_page_guts(),
which still relies on a check/sleep loop.
There’s also a todo suggesting further improvements:
/*
* Loop waiting for xlog to be available if necessary
*
* TODO: The walsender has its own version of this function, which uses a
* condition variable to wake up whenever WAL is flushed. We could use the
* same infrastructure here, instead of the check/sleep/repeat style of
* loop.
*/

To test the idea, I implemented an experimental patch. With both v7
and this change applied, the polling disappears from the flame graph
and the counters drop by roughly orders of magnitude:

v7 + CV in read_local_xlog_page_guts

cycles: 6,284,633
instructions: 3,990,034 (0.63 IPC)
cache-misses: 163,394
context-switches: 6
elapsed: 100 s

I plan to post a new patch to fix this as well after further
refinements and tests.

Best,
Xuneng

Attachments:

head.svgimage/svg+xml; name=head.svgDownload
patch-v7.svgimage/svg+xml; name=patch-v7.svgDownload
v7+readxlogpage_cv.svgimage/svg+xml; name=v7+readxlogpage_cv.svgDownload
#27Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#25)
2 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Mon, Jul 28, 2025 at 7:14 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

On Thu, Jul 17, 2025 at 10:54 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

After studying proarray and lmgr more closely, I have found several
critical issues in the two patches and underestimated their complexity
and subtlety. Sorry for posting immature patches that may have created
noise.

I now realize that making lock acquisition— (void) LockAcquire(&tag,
ShareLock, false, false); in XactLockTableWait
work on a standby, following Andres’ first suggestion, may be simpler
and require fewer new helpers.

XactLockTableWait fails on a standby simply because we never call
XactLockTableInsert. I am considering invoking XactLockTableInsert
when an XID is added to KnownAssignedXids, and XactLockTableDelete(the
constraint for delete now is not used for main xid in primary) when it
is removed. A preliminary implementation and test shows this approach
kinda works, but still need to confirm it is safe on a standby and
does not break other things.

Adding an xact lock for every tracked assigned XID on a standby—by
enabling XactLockTableInsert and XactLockTableDelete in the
KnownAssignedXids infrastructure— appears less attractive than I first
thought. The main concern is that the actual rate of xact-lock usage
may not justify the added overhead, even if that overhead is modest.

1) Usage
On a primary server, a xact lock is taken for every assigned XID, and
the cost is justified because xact locks are referenced in many code
paths. On a standby, however—especially in versions where logical
decoding is disabled—xact locks are used far less, if at all. The
current call stacks for XactLockTableWait on a standby (HEAD) are
listed in [1]. The only high-frequency caller is the logical walsender
in a cascading standby; all other callers are infrequent. Does that
single use case warrant creating a xact lock for every known assigned
XID? I don't think so, given that typical configurations have few
cascading standbys. In practice, most xact locks may never be touched
after they are created.

2) Cost
Low usage would be fine if the additional cost were negligible, but
that does not appear to be the case AFAICS.

* There are 5 main uses of the KnownAssignedXids data structure:
* * backends taking snapshots - all valid XIDs need to be copied out
* * backends seeking to determine presence of a specific XID
* * startup process adding new known-assigned XIDs
* * startup process removing specific XIDs as transactions end
* * startup process pruning array when special WAL records arrive
*
* This data structure is known to be a hot spot during Hot Standby, so we
* go to some lengths to make these operations as efficient and as concurrent
* as possible.

KnownAssignedXids is a hot spot like the comments state. The existing
design replaces a hash table with a single array and minimizes
exclusive locks and memory barriers to preserve concurrency. To
respect that design, calls to XactLockTableInsert and
XactLockTableDelete would need to occur outside any exclusive lock.
Unfortunately, that re-introduces the polling we are trying to
eliminate in XactLockTableWait: there is a window between registering
the XIDs and adding their xact locks. During that window, a backend
calling XactLockTableWait may need to poll because
TransactionIdIsInProgress shows the transaction as running while the
xact lock is still missing. If the window were short, this might be
acceptable, but it can be lengthy because XIDs are inserted and
deleted from the array in bulk. Some unlucky backends will therefore
spin before they can actually wait.

Placing the XactLockTableInsert/Delete calls inside the exclusive lock
removes the race window but hurts concurrency—the very issue this
module strives to avoid. Operations on the shared-memory hash table in
lmgr are slower and hold the lock longer than simple array updates, so
backends invoking GetSnapshotData could experience longer wait times.

3) Alternative
Adopt the hash-table + condition-variable design from patch v6, with
additional fixes and polishes.
Back-ends that call XactLockTableWait() sleep on the condition
variable. The startup process broadcasts a wake-up as the XID is
removed from KnownAssignedXids. The broadcast happens after releasing
the exclusive lock. This may be safe—sleeping back-ends remain blocked
until the CV signal arrives, so no extra polling occurs even though
the XID has already vanished from the array. For consistency, all
removal paths (including those used during shutdown or promotion,
where contention is minimal) follow the same pattern. The hash table
is sized at 2 × MaxBackends, which is already conservative for today’s
workload. For more potential concurrent use cases in the future, it
could be switched to larger numbers like TOTAL_MAX_CACHED_SUBXIDS if
necessary; even that would consume only a few megabytes.

Feedbacks welcome.

[1] /messages/by-id/CABPTF7Wbp7MRPGsqd9NA4GbcSzUcNz1ymgWfir=Yf+N0oDRbjA@mail.gmail.com

Because XactLocks are not maintained on a standby server, and the
current waiting approach does not rely on Xact locks as well; I
therefore added assertions to both functions to prevent their use on a
standby and introduced an explicit primary-versus-standby branch in
SnapBuildWaitSnapshot in v8.

In procarray.c, two corrections are made compared with v7:
Removed the seemingly redundant initialized field from XidWaitEntry.
Removed the erroneous InHotStandby checks in the wait and wake helpers.

With these changes applied, here's some perf stats for v8, which are
about one order of magnitude smaller than those of head.

Performance counter stats for process id '3273840':

351,183,876 cycles
126,586,090 instructions # 0.36
insn per cycle
16,670,633 cache-misses
10,030 context-switches

100.001419856 seconds time elapsed

Best,
Xuneng

Attachments:

v8-0001-Optimize-transaction-waiting-in-standby.patchapplication/octet-stream; name=v8-0001-Optimize-transaction-waiting-in-standby.patchDownload
From 919359849b6df0e3e8d18316f26bc41b0580840f Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Wed, 30 Jul 2025 23:07:03 +0800
Subject: [PATCH v8] Optimize transaction waiting during logical decoding on
 hot standby servers. On hot standby servers, XactLockTableWait falls back to
 polling TransactionIdIsInProgress() with fixed 1ms sleeps when transactions
 from the primary have no local lock table entries, causing excessive CPU
 usage.

Introduce a new waiting waiting path for hot-standby that uses the existing
KnownAssignedXids infrastructure combined with a condition variable to replace
the use of XactLockTableWait in standby, eliminating the polling loop.
---
 src/backend/replication/logical/snapbuild.c   |  10 +-
 src/backend/storage/ipc/procarray.c           | 208 +++++++++++++++++-
 src/backend/storage/lmgr/lmgr.c               |   6 +-
 .../utils/activity/wait_event_names.txt       |   1 +
 src/include/storage/procarray.h               |   2 +
 5 files changed, 218 insertions(+), 9 deletions(-)

diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 8532bfd27e5..87e9f4725ff 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1451,7 +1451,15 @@ SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff)
 		if (TransactionIdFollows(xid, cutoff))
 			continue;
 
-		XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		/*
+		 * In primary, we use XactLockTableWait to wait for the transaction to finish.
+		 * In standby, since xact lock table is not maintained, we use XidWaitInStandby
+		 * to accomplish the same.
+		 */
+		if (!RecoveryInProgress())
+			XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		else
+			XidWaitInStandby(xid);
 	}
 
 	/*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index bf987aed8d3..26174e9c31a 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -62,6 +62,7 @@
 #include "storage/procarray.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
+#include "utils/hsearch.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 
@@ -282,6 +283,11 @@ static TransactionId *KnownAssignedXids;
 static bool *KnownAssignedXidsValid;
 static TransactionId latestObservedXid = InvalidTransactionId;
 
+/*
+ * Array of XIDs to wake up on standby
+ */
+static TransactionId *KnownAssignedXidsToWakeup;
+
 /*
  * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
  * the highest xid that might still be running that we don't have in
@@ -306,6 +312,31 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+/*
+ * XID waiter hash table partition count
+ */
+#define NUM_XID_WAIT_PARTITIONS  16
+
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+	pg_atomic_uint32 waiter_count;	/* number of backends waiting */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * The table is partitioned to reduce lock contention and uses the
+ * same infrastructure as PostgreSQL's lock manager.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -352,7 +383,7 @@ static bool KnownAssignedXidExists(TransactionId xid);
 static void KnownAssignedXidsRemove(TransactionId xid);
 static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
 										TransactionId *subxids);
-static void KnownAssignedXidsRemovePreceding(TransactionId removeXid);
+static int	KnownAssignedXidsRemovePreceding(TransactionId removeXid);
 static int	KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax);
 static int	KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
 										   TransactionId *xmin,
@@ -369,6 +400,9 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
 
+static void WakeXidWaiters(TransactionId xid);
+static void WakeAllXidWaiters(void);
+
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
  */
@@ -403,9 +437,11 @@ ProcArrayShmemSize(void)
 	{
 		size = add_size(size,
 						mul_size(sizeof(TransactionId),
-								 TOTAL_MAX_CACHED_SUBXIDS));
+								 2 * TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+		size = add_size(size,
+						hash_estimate_size(MaxBackends * 2, sizeof(XidWaitEntry)));
 	}
 
 	return size;
@@ -458,6 +494,26 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+		KnownAssignedXidsToWakeup = (TransactionId *)
+			ShmemInitStruct("KnownAssignedXidsToWakeup",
+							mul_size(sizeof(TransactionId),
+									 TOTAL_MAX_CACHED_SUBXIDS),
+							&found);
+
+		/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+			info.num_partitions = NUM_XID_WAIT_PARTITIONS;
+
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+									   MaxBackends,  	/* init_size */
+									   MaxBackends * 2,      /* max_size */
+									   &info,
+									   HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
+		}
 	}
 }
 
@@ -1113,6 +1169,7 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
 			 * throw them away before we apply the recovery snapshot.
 			 */
 			KnownAssignedXidsReset();
+			WakeAllXidWaiters();
 			standbyState = STANDBY_INITIALIZED;
 		}
 		else
@@ -1370,6 +1427,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
 		procArray->lastOverflowedXid = max_xid;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up waiters for expired subtransactions */
+	for (i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4450,6 +4511,11 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
 	TransamVariables->xactCompletionCount++;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up per-XID waiters */
+	WakeXidWaiters(xid);
+	for (int i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4462,7 +4528,7 @@ ExpireAllKnownAssignedTransactionIds(void)
 	FullTransactionId latestXid;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
-	KnownAssignedXidsRemovePreceding(InvalidTransactionId);
+	(void) KnownAssignedXidsRemovePreceding(InvalidTransactionId);
 
 	/* Reset latestCompletedXid to nextXid - 1 */
 	Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
@@ -4483,6 +4549,9 @@ ExpireAllKnownAssignedTransactionIds(void)
 	 */
 	procArray->lastOverflowedXid = InvalidTransactionId;
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since all transactions are being expired */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -4494,6 +4563,8 @@ void
 ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 {
 	TransactionId latestXid;
+	int			i;
+	int			count;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
@@ -4513,8 +4584,12 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 	 */
 	if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
 		procArray->lastOverflowedXid = InvalidTransactionId;
-	KnownAssignedXidsRemovePreceding(xid);
+	count = KnownAssignedXidsRemovePreceding(xid);
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake XID waiters that have expired transactions they're waiting for */
+	for (i = 0; i < count; i++)
+		WakeXidWaiters(KnownAssignedXidsToWakeup[i]);
 }
 
 /*
@@ -4991,9 +5066,11 @@ KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
  * Prune KnownAssignedXids up to, but *not* including xid. If xid is invalid
  * then clear the whole table.
  *
+ * Returns the number of XIDs removed.
+ *
  * Caller must hold ProcArrayLock in exclusive mode.
  */
-static void
+static int
 KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 {
 	ProcArrayStruct *pArray = procArray;
@@ -5005,9 +5082,10 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 	if (!TransactionIdIsValid(removeXid))
 	{
 		elog(DEBUG4, "removing all KnownAssignedXids");
+		count = pArray->numKnownAssignedXids;
 		pArray->numKnownAssignedXids = 0;
 		pArray->headKnownAssignedXids = pArray->tailKnownAssignedXids = 0;
-		return;
+		return count;
 	}
 
 	elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);
@@ -5031,6 +5109,7 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 			if (!StandbyTransactionIdIsPrepared(knownXid))
 			{
 				KnownAssignedXidsValid[i] = false;
+				KnownAssignedXidsToWakeup[count] = knownXid;
 				count++;
 			}
 		}
@@ -5060,6 +5139,8 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 
 	/* Opportunistically compress the array */
 	KnownAssignedXidsCompress(KAX_PRUNE, true);
+
+	return count;
 }
 
 /*
@@ -5227,3 +5308,118 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID.
+ *
+ * The function handles the complete lifecycle of waiting: finding or
+ * creating the hash entry, managing waiter counts, and cleaning up
+ * when the last waiter finishes.
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+void
+XidWaitInStandby(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	uint32		hashcode;
+	TransactionId wait_xid;
+
+	Assert(XidWaitHash);
+	Assert(TransactionIdIsValid(xid));
+	Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+	/* Quick exit if transaction already complete */
+	if (!TransactionIdIsInProgress(xid))
+		return;
+
+	/* Always wait on the topmost transaction to avoid lost wake-ups */
+	wait_xid = SubTransGetTopmostTransaction(xid);
+
+	hashcode = get_hash_value(XidWaitHash, &wait_xid);
+
+	entry = hash_search_with_hash_value(XidWaitHash, &wait_xid, hashcode,
+									   HASH_ENTER, &found);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = wait_xid;
+		ConditionVariableInit(&entry->cv);
+		pg_atomic_init_u32(&entry->waiter_count, 0);
+	}
+
+	pg_atomic_fetch_add_u32(&entry->waiter_count, 1);
+
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	ConditionVariableCancelSleep();
+
+	/* Decrement waiter count and cleanup if last waiter */
+	if (pg_atomic_fetch_sub_u32(&entry->waiter_count, 1) == 1)
+	{
+		hash_search_with_hash_value(XidWaitHash, &wait_xid, hashcode,
+								   HASH_REMOVE, NULL);
+	}
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to locate waiters for the specified XID and
+ * broadcasts on the associated condition variable to wake all waiting
+ * backends simultaneously.
+ */
+static void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	uint32		hashcode;
+
+	Assert(XidWaitHash);
+
+	hashcode = get_hash_value(XidWaitHash, &xid);
+
+	entry = hash_search_with_hash_value(XidWaitHash, &xid, hashcode,
+									   HASH_FIND, NULL);
+	if (entry)
+		ConditionVariableBroadcast(&entry->cv);
+}
+
+/*
+ * Wake all XID waiters.
+ *
+ * This function wakes up all backends waiting on any transaction ID.
+ * It is primarily used during standby promotion when the server is
+ * transitioning from recovery mode to normal operation, at which point
+ * all XID-based waiting becomes invalid.
+ */
+static void
+WakeAllXidWaiters(void)
+{
+	HASH_SEQ_STATUS status;
+	XidWaitEntry *entry;
+
+	Assert(XidWaitHash);
+
+	hash_seq_init(&status, XidWaitHash);
+	while ((entry = (XidWaitEntry *) hash_seq_search(&status)) != NULL)
+		ConditionVariableBroadcast(&entry->cv);
+}
\ No newline at end of file
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..536b1542a09 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -668,6 +668,8 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 	ErrorContextCallback callback;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	/*
 	 * If an operation is specified, set up our verbose error context
 	 * callback.
@@ -718,7 +720,6 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -741,6 +742,8 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -761,7 +764,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0be307d2ca0..775cc7313ad 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -160,6 +160,7 @@ WAL_BUFFER_INIT	"Waiting on WAL buffer to be initialized."
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 2f4ae06c279..0f8354173b2 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,6 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+extern void XidWaitInStandby(TransactionId xid);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0

v8.svgimage/svg+xml; name=v8.svgDownload
#28Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#27)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Wed, Jul 30, 2025 at 11:42 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

On Mon, Jul 28, 2025 at 7:14 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

On Thu, Jul 17, 2025 at 10:54 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi,

After studying proarray and lmgr more closely, I have found several
critical issues in the two patches and underestimated their complexity
and subtlety. Sorry for posting immature patches that may have created
noise.

I now realize that making lock acquisition— (void) LockAcquire(&tag,
ShareLock, false, false); in XactLockTableWait
work on a standby, following Andres’ first suggestion, may be simpler
and require fewer new helpers.

XactLockTableWait fails on a standby simply because we never call
XactLockTableInsert. I am considering invoking XactLockTableInsert
when an XID is added to KnownAssignedXids, and XactLockTableDelete(the
constraint for delete now is not used for main xid in primary) when it
is removed. A preliminary implementation and test shows this approach
kinda works, but still need to confirm it is safe on a standby and
does not break other things.

Adding an xact lock for every tracked assigned XID on a standby—by
enabling XactLockTableInsert and XactLockTableDelete in the
KnownAssignedXids infrastructure— appears less attractive than I first
thought. The main concern is that the actual rate of xact-lock usage
may not justify the added overhead, even if that overhead is modest.

1) Usage
On a primary server, a xact lock is taken for every assigned XID, and
the cost is justified because xact locks are referenced in many code
paths. On a standby, however—especially in versions where logical
decoding is disabled—xact locks are used far less, if at all. The
current call stacks for XactLockTableWait on a standby (HEAD) are
listed in [1]. The only high-frequency caller is the logical walsender
in a cascading standby; all other callers are infrequent. Does that
single use case warrant creating a xact lock for every known assigned
XID? I don't think so, given that typical configurations have few
cascading standbys. In practice, most xact locks may never be touched
after they are created.

2) Cost
Low usage would be fine if the additional cost were negligible, but
that does not appear to be the case AFAICS.

* There are 5 main uses of the KnownAssignedXids data structure:
* * backends taking snapshots - all valid XIDs need to be copied out
* * backends seeking to determine presence of a specific XID
* * startup process adding new known-assigned XIDs
* * startup process removing specific XIDs as transactions end
* * startup process pruning array when special WAL records arrive
*
* This data structure is known to be a hot spot during Hot Standby, so we
* go to some lengths to make these operations as efficient and as concurrent
* as possible.

KnownAssignedXids is a hot spot like the comments state. The existing
design replaces a hash table with a single array and minimizes
exclusive locks and memory barriers to preserve concurrency. To
respect that design, calls to XactLockTableInsert and
XactLockTableDelete would need to occur outside any exclusive lock.
Unfortunately, that re-introduces the polling we are trying to
eliminate in XactLockTableWait: there is a window between registering
the XIDs and adding their xact locks. During that window, a backend
calling XactLockTableWait may need to poll because
TransactionIdIsInProgress shows the transaction as running while the
xact lock is still missing. If the window were short, this might be
acceptable, but it can be lengthy because XIDs are inserted and
deleted from the array in bulk. Some unlucky backends will therefore
spin before they can actually wait.

Placing the XactLockTableInsert/Delete calls inside the exclusive lock
removes the race window but hurts concurrency—the very issue this
module strives to avoid. Operations on the shared-memory hash table in
lmgr are slower and hold the lock longer than simple array updates, so
backends invoking GetSnapshotData could experience longer wait times.

3) Alternative
Adopt the hash-table + condition-variable design from patch v6, with
additional fixes and polishes.
Back-ends that call XactLockTableWait() sleep on the condition
variable. The startup process broadcasts a wake-up as the XID is
removed from KnownAssignedXids. The broadcast happens after releasing
the exclusive lock. This may be safe—sleeping back-ends remain blocked
until the CV signal arrives, so no extra polling occurs even though
the XID has already vanished from the array. For consistency, all
removal paths (including those used during shutdown or promotion,
where contention is minimal) follow the same pattern. The hash table
is sized at 2 × MaxBackends, which is already conservative for today’s
workload. For more potential concurrent use cases in the future, it
could be switched to larger numbers like TOTAL_MAX_CACHED_SUBXIDS if
necessary; even that would consume only a few megabytes.

Feedbacks welcome.

[1] /messages/by-id/CABPTF7Wbp7MRPGsqd9NA4GbcSzUcNz1ymgWfir=Yf+N0oDRbjA@mail.gmail.com

Because XactLocks are not maintained on a standby server, and the
current waiting approach does not rely on Xact locks as well; I
therefore added assertions to both functions to prevent their use on a
standby and introduced an explicit primary-versus-standby branch in
SnapBuildWaitSnapshot in v8.

In procarray.c, two corrections are made compared with v7:
Removed the seemingly redundant initialized field from XidWaitEntry.
Removed the erroneous InHotStandby checks in the wait and wake helpers.

With these changes applied, here's some perf stats for v8, which are
about one order of magnitude smaller than those of head.

Performance counter stats for process id '3273840':

351,183,876 cycles
126,586,090 instructions # 0.36
insn per cycle
16,670,633 cache-misses
10,030 context-switches

100.001419856 seconds time elapsed

V9 replaces the original partitioned xid-wait htab with a single,
unified one, reflecting the modest entry count and rare contention for
waiting. To prevent possible races when multiple backends wait on the
same XID for the first time in XidWaitOnStandby, a dedicated lock has
been added to protect the hash table.

Best,
Xuneng

Attachments:

v9-0001-Optimize-transaction-waiting-during-logical-decod.patchapplication/octet-stream; name=v9-0001-Optimize-transaction-waiting-during-logical-decod.patchDownload
From 892a67b31497f020a8f272001fe950aa7b03134c Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Fri, 1 Aug 2025 16:18:11 +0800
Subject: [PATCH v9] Optimize transaction waiting during logical decoding on
 hot standby servers. On hot standby servers, XactLockTableWait falls back to
 polling TransactionIdIsInProgress() with fixed 1ms sleeps when transactions
 from the primary have no local lock table entries, causing excessive CPU
 usage.

Introduce a new waiting waiting path for hot-standby that uses the existing
KnownAssignedXids infrastructure combined with a condition variable to replace
the use of XactLockTableWait in standby, eliminating the polling loop.
---
 src/backend/replication/logical/snapbuild.c   |  10 +-
 src/backend/storage/ipc/procarray.c           | 198 +++++++++++++++++-
 src/backend/storage/lmgr/lmgr.c               |   6 +-
 .../utils/activity/wait_event_names.txt       |   2 +
 src/include/storage/lwlocklist.h              |   1 +
 src/include/storage/procarray.h               |   2 +
 6 files changed, 210 insertions(+), 9 deletions(-)

diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 8532bfd27e5..87e9f4725ff 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1451,7 +1451,15 @@ SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff)
 		if (TransactionIdFollows(xid, cutoff))
 			continue;
 
-		XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		/*
+		 * In primary, we use XactLockTableWait to wait for the transaction to finish.
+		 * In standby, since xact lock table is not maintained, we use XidWaitOnStandby
+		 * to accomplish the same.
+		 */
+		if (!RecoveryInProgress())
+			XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		else
+			XidWaitOnStandby(xid);
 	}
 
 	/*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index bf987aed8d3..caefb0cde72 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -62,6 +62,7 @@
 #include "storage/procarray.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
+#include "utils/hsearch.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 
@@ -282,6 +283,11 @@ static TransactionId *KnownAssignedXids;
 static bool *KnownAssignedXidsValid;
 static TransactionId latestObservedXid = InvalidTransactionId;
 
+/*
+ * Array of XIDs to wake up on standby
+ */
+static TransactionId *KnownAssignedXidsToWakeup;
+
 /*
  * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
  * the highest xid that might still be running that we don't have in
@@ -306,6 +312,25 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+	pg_atomic_uint32 waiter_count;	/* number of backends waiting */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * XidWaitHash is a unified shared hash table protected by a single LWLock.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -352,7 +377,7 @@ static bool KnownAssignedXidExists(TransactionId xid);
 static void KnownAssignedXidsRemove(TransactionId xid);
 static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
 										TransactionId *subxids);
-static void KnownAssignedXidsRemovePreceding(TransactionId removeXid);
+static int	KnownAssignedXidsRemovePreceding(TransactionId removeXid);
 static int	KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax);
 static int	KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
 										   TransactionId *xmin,
@@ -369,6 +394,9 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
 
+static void WakeXidWaiters(TransactionId xid);
+static void WakeAllXidWaiters(void);
+
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
  */
@@ -403,9 +431,11 @@ ProcArrayShmemSize(void)
 	{
 		size = add_size(size,
 						mul_size(sizeof(TransactionId),
-								 TOTAL_MAX_CACHED_SUBXIDS));
+								 2 * TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+		size = add_size(size,
+						hash_estimate_size(MaxBackends * 2, sizeof(XidWaitEntry)));
 	}
 
 	return size;
@@ -458,6 +488,26 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+		KnownAssignedXidsToWakeup = (TransactionId *)
+			ShmemInitStruct("KnownAssignedXidsToWakeup",
+							mul_size(sizeof(TransactionId),
+									 TOTAL_MAX_CACHED_SUBXIDS),
+							&found);
+
+		/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+									   MaxBackends,  	/* init_size */
+									   MaxBackends * 2,      /* max_size */
+									   &info,
+									   HASH_ELEM | HASH_BLOBS | HASH_SHARED_MEM);
+		}
+
 	}
 }
 
@@ -1113,6 +1163,7 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
 			 * throw them away before we apply the recovery snapshot.
 			 */
 			KnownAssignedXidsReset();
+			WakeAllXidWaiters();
 			standbyState = STANDBY_INITIALIZED;
 		}
 		else
@@ -1370,6 +1421,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
 		procArray->lastOverflowedXid = max_xid;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up waiters for expired subtransactions */
+	for (i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4450,6 +4505,11 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
 	TransamVariables->xactCompletionCount++;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up per-XID waiters */
+	WakeXidWaiters(xid);
+	for (int i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4462,7 +4522,7 @@ ExpireAllKnownAssignedTransactionIds(void)
 	FullTransactionId latestXid;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
-	KnownAssignedXidsRemovePreceding(InvalidTransactionId);
+	(void) KnownAssignedXidsRemovePreceding(InvalidTransactionId);
 
 	/* Reset latestCompletedXid to nextXid - 1 */
 	Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
@@ -4483,6 +4543,9 @@ ExpireAllKnownAssignedTransactionIds(void)
 	 */
 	procArray->lastOverflowedXid = InvalidTransactionId;
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since all transactions are being expired */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -4494,6 +4557,8 @@ void
 ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 {
 	TransactionId latestXid;
+	int			i;
+	int			count;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
@@ -4513,8 +4578,12 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 	 */
 	if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
 		procArray->lastOverflowedXid = InvalidTransactionId;
-	KnownAssignedXidsRemovePreceding(xid);
+	count = KnownAssignedXidsRemovePreceding(xid);
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake XID waiters that have expired transactions they're waiting for */
+	for (i = 0; i < count; i++)
+		WakeXidWaiters(KnownAssignedXidsToWakeup[i]);
 }
 
 /*
@@ -4991,9 +5060,11 @@ KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
  * Prune KnownAssignedXids up to, but *not* including xid. If xid is invalid
  * then clear the whole table.
  *
+ * Returns the number of XIDs removed.
+ *
  * Caller must hold ProcArrayLock in exclusive mode.
  */
-static void
+static int
 KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 {
 	ProcArrayStruct *pArray = procArray;
@@ -5005,9 +5076,10 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 	if (!TransactionIdIsValid(removeXid))
 	{
 		elog(DEBUG4, "removing all KnownAssignedXids");
+		count = pArray->numKnownAssignedXids;
 		pArray->numKnownAssignedXids = 0;
 		pArray->headKnownAssignedXids = pArray->tailKnownAssignedXids = 0;
-		return;
+		return count;
 	}
 
 	elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);
@@ -5031,6 +5103,7 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 			if (!StandbyTransactionIdIsPrepared(knownXid))
 			{
 				KnownAssignedXidsValid[i] = false;
+				KnownAssignedXidsToWakeup[count] = knownXid;
 				count++;
 			}
 		}
@@ -5060,6 +5133,8 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 
 	/* Opportunistically compress the array */
 	KnownAssignedXidsCompress(KAX_PRUNE, true);
+
+	return count;
 }
 
 /*
@@ -5227,3 +5302,114 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID.
+ *
+ * The function handles the complete lifecycle of waiting: finding or
+ * creating the hash entry, managing waiter counts, and cleaning up
+ * when the last waiter finishes.
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+void
+XidWaitOnStandby(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	TransactionId wait_xid;
+
+	Assert(XidWaitHash);
+	Assert(TransactionIdIsValid(xid));
+	Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+	/* Quick exit if transaction already complete */
+	if (!TransactionIdIsInProgress(xid))
+		return;
+
+	/* Always wait on the topmost transaction to avoid lost wake-ups */
+	wait_xid = SubTransGetTopmostTransaction(xid);
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+
+	entry = (XidWaitEntry *)
+		hash_search(XidWaitHash, &wait_xid, HASH_ENTER, &found);
+
+	LWLockRelease(XidWaitHashLock);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = wait_xid;
+		ConditionVariableInit(&entry->cv);
+		pg_atomic_init_u32(&entry->waiter_count, 0);
+	}
+
+	pg_atomic_fetch_add_u32(&entry->waiter_count, 1);
+
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	ConditionVariableCancelSleep();
+
+	/* Decrement waiter count and cleanup if last waiter */
+	if (pg_atomic_fetch_sub_u32(&entry->waiter_count, 1) == 1)
+		hash_search(XidWaitHash, &wait_xid, HASH_REMOVE, NULL);
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to locate waiters for the specified XID and
+ * broadcasts on the associated condition variable to wake all waiting
+ * backends simultaneously.
+ */
+static void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+
+	Assert(XidWaitHash);
+
+	entry = (XidWaitEntry *)
+		hash_search(XidWaitHash, &xid, HASH_FIND, NULL);
+
+	if (entry)
+		ConditionVariableBroadcast(&entry->cv);
+}
+
+/*
+ * Wake all XID waiters.
+ *
+ * This function wakes up all backends waiting on any transaction ID.
+ * It is primarily used during standby promotion when the server is
+ * transitioning from recovery mode to normal operation, at which point
+ * all XID-based waiting becomes invalid.
+ */
+static void
+WakeAllXidWaiters(void)
+{
+	HASH_SEQ_STATUS status;
+	XidWaitEntry *entry;
+
+	Assert(XidWaitHash);
+
+	hash_seq_init(&status, XidWaitHash);
+	while ((entry = (XidWaitEntry *) hash_seq_search(&status)) != NULL)
+		ConditionVariableBroadcast(&entry->cv);
+}
\ No newline at end of file
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..536b1542a09 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -668,6 +668,8 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 	ErrorContextCallback callback;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	/*
 	 * If an operation is specified, set up our verbose error context
 	 * callback.
@@ -718,7 +720,6 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -741,6 +742,8 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -761,7 +764,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 0be307d2ca0..3a4769e3d8f 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -160,6 +160,7 @@ WAL_BUFFER_INIT	"Waiting on WAL buffer to be initialized."
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
@@ -352,6 +353,7 @@ DSMRegistry	"Waiting to read or update the dynamic shared memory registry."
 InjectionPoint	"Waiting to read or update information related to injection points."
 SerialControl	"Waiting to read or update shared <filename>pg_serial</filename> state."
 AioWorkerSubmissionQueue	"Waiting to access AIO worker submission queue."
+XidWaitHash	"Waiting to access XID wait hash table."
 
 #
 # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
diff --git a/src/include/storage/lwlocklist.h b/src/include/storage/lwlocklist.h
index 208d2e3a8ed..7878f0b46e4 100644
--- a/src/include/storage/lwlocklist.h
+++ b/src/include/storage/lwlocklist.h
@@ -85,6 +85,7 @@ PG_LWLOCK(50, DSMRegistry)
 PG_LWLOCK(51, InjectionPoint)
 PG_LWLOCK(52, SerialControl)
 PG_LWLOCK(53, AioWorkerSubmissionQueue)
+PG_LWLOCK(54, XidWaitHash)
 
 /*
  * There also exist several built-in LWLock tranches.  As with the predefined
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 2f4ae06c279..0f8354173b2 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,6 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+extern void XidWaitOnStandby(TransactionId xid);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0

#29Tom Lane
tgl@sss.pgh.pa.us
In reply to: Xuneng Zhou (#28)
Re: Add progressive backoff to XactLockTableWait functions

Xuneng Zhou <xunengzhou@gmail.com> writes:

V9 replaces the original partitioned xid-wait htab with a single,
unified one, reflecting the modest entry count and rare contention for
waiting. To prevent possible races when multiple backends wait on the
same XID for the first time in XidWaitOnStandby, a dedicated lock has
been added to protect the hash table.

This seems like adding quite a lot of extremely subtle code in
order to solve a very small problem. I thought the v1 patch
was about the right amount of complexity.

regards, tom lane

#30Xuneng Zhou
xunengzhou@gmail.com
In reply to: Tom Lane (#29)
Re: Add progressive backoff to XactLockTableWait functions

Hi, Tom!

Thanks for looking at this.

On Fri, Aug 8, 2025 at 2:20 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Xuneng Zhou <xunengzhou@gmail.com> writes:

V9 replaces the original partitioned xid-wait htab with a single,
unified one, reflecting the modest entry count and rare contention for
waiting. To prevent possible races when multiple backends wait on the
same XID for the first time in XidWaitOnStandby, a dedicated lock has
been added to protect the hash table.

This seems like adding quite a lot of extremely subtle code in
order to solve a very small problem. I thought the v1 patch
was about the right amount of complexity.

Yeah, this patch is indeed complex, and the complexity might not be
well-justified—given the current use cases, it feels like we’re paying
a lot for very little. TBH, getting the balance right between
efficiency gains and cost, in terms of both code complexity and
runtime overhead, is beyond my current ability here, since I’m
touching many parts of the code for the first time. Every time I
thought I’d figured it out, new subtleties surfaced—though I’ve
learned a lot from the exploration and hacking. We may agree on the
necessity of fixing this issue, but not yet on how to fix it. I’m open
to discussion and suggestions.

Best,
Xuneng

#31Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#30)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

On Fri, Aug 8, 2025 at 7:06 PM Xuneng Zhou <xunengzhou@gmail.com> wrote:

Hi, Tom!

Thanks for looking at this.

On Fri, Aug 8, 2025 at 2:20 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Xuneng Zhou <xunengzhou@gmail.com> writes:

V9 replaces the original partitioned xid-wait htab with a single,
unified one, reflecting the modest entry count and rare contention for
waiting. To prevent possible races when multiple backends wait on the
same XID for the first time in XidWaitOnStandby, a dedicated lock has
been added to protect the hash table.

This seems like adding quite a lot of extremely subtle code in
order to solve a very small problem. I thought the v1 patch
was about the right amount of complexity.

Yeah, this patch is indeed complex, and the complexity might not be
well-justified—given the current use cases, it feels like we’re paying
a lot for very little. TBH, getting the balance right between
efficiency gains and cost, in terms of both code complexity and
runtime overhead, is beyond my current ability here, since I’m
touching many parts of the code for the first time. Every time I
thought I’d figured it out, new subtleties surfaced—though I’ve
learned a lot from the exploration and hacking. We may agree on the
necessity of fixing this issue, but not yet on how to fix it. I’m open
to discussion and suggestions.

Some changes in v10:

1) XidWaitHashLock is used for all operations on XidWaitHash though
might be unnecessary for some cases.
2) Field pg_atomic_uint32 waiter_count was removed from the
XidWaitEntry. The start process now takes charge of cleaning up the
XidWaitHash entry after waking up processes.
3) pg_atomic_uint32 xidWaiterNum is added to avoid unnecessary lock
acquire & release and htab look-up while there's no xid waiting.

Hope this could eliminate some subtleties.

Exponential backoff in earlier patches is simple and effective for
alleviating cpu overhead in extended waiting; however it could also
bring unwanted latency for more sensitive use cases like logical
walsender on cascading standbys. Unfortunately, I am unable to come up
with a solution that is correct, effective and simple in all cases.

Best,
Xuneng

Attachments:

v10-0001-Optimize-transaction-waiting-during-logical-deco.patchapplication/x-patch; name=v10-0001-Optimize-transaction-waiting-during-logical-deco.patchDownload
From a845e40c3aaea70e572cf12bfc0cbe482ff1e9c7 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Fri, 29 Aug 2025 14:55:20 +0800
Subject: [PATCH v10] Optimize transaction waiting during logical decoding on 
 hot standby servers. On hot standby servers, XactLockTableWait falls back to 
 polling TransactionIdIsInProgress() with fixed 1ms sleeps when transactions 
 from the primary have no local lock table entries, causing excessive CPU 
 usage.

Introduce a new waiting waiting path for hot-standby that uses the existing
KnownAssignedXids infrastructure combined with a condition variable to replace
the use of XactLockTableWait in standby, eliminating the polling loop.
---
 src/backend/replication/logical/snapbuild.c   |  10 +-
 src/backend/storage/ipc/procarray.c           | 223 +++++++++++++++++-
 src/backend/storage/lmgr/lmgr.c               |   6 +-
 .../utils/activity/wait_event_names.txt       |   2 +
 src/include/storage/lwlocklist.h              |   1 +
 src/include/storage/procarray.h               |   2 +
 6 files changed, 235 insertions(+), 9 deletions(-)

diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 98ddee20929..25a7733f770 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1451,7 +1451,15 @@ SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff)
 		if (TransactionIdFollows(xid, cutoff))
 			continue;
 
-		XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		/*
+		 * In primary, we use XactLockTableWait to wait for the transaction to finish.
+		 * In standby, since xact lock table is not maintained, we use XidWaitOnStandby
+		 * to accomplish the same.
+		 */
+		if (!RecoveryInProgress())
+			XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		else
+			XidWaitOnStandby(xid);
 	}
 
 	/*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index bf987aed8d3..ee732e7fd86 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -62,6 +62,7 @@
 #include "storage/procarray.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
+#include "utils/hsearch.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 
@@ -282,6 +283,11 @@ static TransactionId *KnownAssignedXids;
 static bool *KnownAssignedXidsValid;
 static TransactionId latestObservedXid = InvalidTransactionId;
 
+/*
+ * Array of XIDs to wake up on standby
+ */
+static TransactionId *KnownAssignedXidsToWakeup;
+
 /*
  * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
  * the highest xid that might still be running that we don't have in
@@ -306,6 +312,31 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+
+/*
+ * Atomic counter tracking the number of entries in XidWaitHash.
+ * Used for lock-free early exit optimization in WakeXidWaiters().
+ */
+static pg_atomic_uint32 xidWaitHashEntries;
+
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * XidWaitHash is a unified shared hash table protected by a single LWLock.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -352,7 +383,7 @@ static bool KnownAssignedXidExists(TransactionId xid);
 static void KnownAssignedXidsRemove(TransactionId xid);
 static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
 										TransactionId *subxids);
-static void KnownAssignedXidsRemovePreceding(TransactionId removeXid);
+static int	KnownAssignedXidsRemovePreceding(TransactionId removeXid);
 static int	KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax);
 static int	KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
 										   TransactionId *xmin,
@@ -369,6 +400,9 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
 
+static void WakeXidWaiters(TransactionId xid);
+static void WakeAllXidWaiters(void);
+
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
  */
@@ -403,9 +437,12 @@ ProcArrayShmemSize(void)
 	{
 		size = add_size(size,
 						mul_size(sizeof(TransactionId),
-								 TOTAL_MAX_CACHED_SUBXIDS));
+								 2 * TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+		size = add_size(size,
+						hash_estimate_size(MaxBackends + NUM_AUXILIARY_PROCS, 
+							sizeof(XidWaitEntry)));
 	}
 
 	return size;
@@ -458,6 +495,31 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+		KnownAssignedXidsToWakeup = (TransactionId *)
+			ShmemInitStruct("KnownAssignedXidsToWakeup",
+							mul_size(sizeof(TransactionId),
+									 TOTAL_MAX_CACHED_SUBXIDS),
+							&found);
+
+				/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+										MaxBackends + NUM_AUXILIARY_PROCS,
+										MaxBackends + NUM_AUXILIARY_PROCS,
+										&info,
+										HASH_ELEM | HASH_BLOBS | HASH_SHARED_MEM);
+		}
+
+		/* Initialize atomic counter for XID waiters optimization */
+		if (!found)
+		{
+			pg_atomic_init_u32(&xidWaitHashEntries, 0);
+		}
 	}
 }
 
@@ -1113,6 +1175,7 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
 			 * throw them away before we apply the recovery snapshot.
 			 */
 			KnownAssignedXidsReset();
+			WakeAllXidWaiters();
 			standbyState = STANDBY_INITIALIZED;
 		}
 		else
@@ -1370,6 +1433,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
 		procArray->lastOverflowedXid = max_xid;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up waiters for expired subtransactions */
+	for (i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4450,6 +4517,11 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
 	TransamVariables->xactCompletionCount++;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up per-XID waiters */
+	WakeXidWaiters(xid);
+	for (int i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4462,7 +4534,7 @@ ExpireAllKnownAssignedTransactionIds(void)
 	FullTransactionId latestXid;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
-	KnownAssignedXidsRemovePreceding(InvalidTransactionId);
+	(void) KnownAssignedXidsRemovePreceding(InvalidTransactionId);
 
 	/* Reset latestCompletedXid to nextXid - 1 */
 	Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
@@ -4483,6 +4555,9 @@ ExpireAllKnownAssignedTransactionIds(void)
 	 */
 	procArray->lastOverflowedXid = InvalidTransactionId;
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since all transactions are being expired */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -4494,6 +4569,8 @@ void
 ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 {
 	TransactionId latestXid;
+	int			i;
+	int			count;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
@@ -4513,8 +4590,12 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 	 */
 	if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
 		procArray->lastOverflowedXid = InvalidTransactionId;
-	KnownAssignedXidsRemovePreceding(xid);
+	count = KnownAssignedXidsRemovePreceding(xid);
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake XID waiters that have expired transactions they're waiting for */
+	for (i = 0; i < count; i++)
+		WakeXidWaiters(KnownAssignedXidsToWakeup[i]);
 }
 
 /*
@@ -4991,9 +5072,11 @@ KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
  * Prune KnownAssignedXids up to, but *not* including xid. If xid is invalid
  * then clear the whole table.
  *
+ * Returns the number of XIDs removed.
+ *
  * Caller must hold ProcArrayLock in exclusive mode.
  */
-static void
+static int
 KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 {
 	ProcArrayStruct *pArray = procArray;
@@ -5005,9 +5088,10 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 	if (!TransactionIdIsValid(removeXid))
 	{
 		elog(DEBUG4, "removing all KnownAssignedXids");
+		count = pArray->numKnownAssignedXids;
 		pArray->numKnownAssignedXids = 0;
 		pArray->headKnownAssignedXids = pArray->tailKnownAssignedXids = 0;
-		return;
+		return count;
 	}
 
 	elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);
@@ -5031,6 +5115,7 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 			if (!StandbyTransactionIdIsPrepared(knownXid))
 			{
 				KnownAssignedXidsValid[i] = false;
+				KnownAssignedXidsToWakeup[count] = knownXid;
 				count++;
 			}
 		}
@@ -5060,6 +5145,8 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 
 	/* Opportunistically compress the array */
 	KnownAssignedXidsCompress(KAX_PRUNE, true);
+
+	return count;
 }
 
 /*
@@ -5227,3 +5314,127 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+void
+XidWaitOnStandby(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	TransactionId wait_xid;
+
+	Assert(XidWaitHash);
+	Assert(TransactionIdIsValid(xid));
+	Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+	/* Quick exit if transaction already complete */
+	if (!TransactionIdIsInProgress(xid))
+		return;
+
+	/* Always wait on the topmost transaction to avoid lost wake-ups */
+	wait_xid = SubTransGetTopmostTransaction(xid);
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+
+	entry = (XidWaitEntry *)
+		hash_search(XidWaitHash, &wait_xid, HASH_ENTER, &found);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = wait_xid;
+		ConditionVariableInit(&entry->cv);
+		pg_atomic_fetch_add_u32(&xidWaitHashEntries, 1);
+	}
+
+	LWLockRelease(XidWaitHashLock);
+
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	ConditionVariableCancelSleep();
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to locate waiters for the specified XID and
+ * broadcasts on the associated condition variable to wake all waiting
+ * backends simultaneously.
+ */
+static void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+
+	Assert(XidWaitHash);
+
+	/* Early exit optimization: no waiters to wake */
+	if (pg_atomic_read_u32(&xidWaitHashEntries) == 0)
+		return;
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+	entry = (XidWaitEntry *)
+		hash_search(XidWaitHash, &xid, HASH_FIND, &found);
+
+	if (found)
+	{
+		ConditionVariableBroadcast(&entry->cv);
+		hash_search(XidWaitHash, &xid, HASH_REMOVE, NULL);
+		pg_atomic_fetch_sub_u32(&xidWaitHashEntries, 1);
+	}
+
+	LWLockRelease(XidWaitHashLock);
+}
+
+/*
+ * Wake all XID waiters.
+ *
+ * This function wakes up all backends waiting on any transaction ID.
+ * It is primarily used during standby promotion when the server is
+ * transitioning from recovery mode to normal operation, at which point
+ * all XID-based waiting becomes invalid.
+ */
+static void
+WakeAllXidWaiters(void)
+{
+	HASH_SEQ_STATUS status;
+	XidWaitEntry *entry;
+
+	Assert(XidWaitHash);
+
+	/* Early exit optimization: no waiters to wake */
+	if (pg_atomic_read_u32(&xidWaitHashEntries) == 0)
+		return;
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+
+	hash_seq_init(&status, XidWaitHash);
+	while ((entry = (XidWaitEntry *) hash_seq_search(&status)) != NULL)
+		ConditionVariableBroadcast(&entry->cv);
+
+	/* Reset counter since we're waking all waiters */
+	pg_atomic_write_u32(&xidWaitHashEntries, 0);
+
+	LWLockRelease(XidWaitHashLock);
+}
\ No newline at end of file
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 3f6bf70bd3c..536b1542a09 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -668,6 +668,8 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 	ErrorContextCallback callback;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	/*
 	 * If an operation is specified, set up our verbose error context
 	 * callback.
@@ -718,7 +720,6 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -741,6 +742,8 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -761,7 +764,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 5427da5bc1b..c3bc115da30 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -159,6 +159,7 @@ SYNC_REP	"Waiting for confirmation from a remote server during synchronous repli
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
@@ -352,6 +353,7 @@ DSMRegistry	"Waiting to read or update the dynamic shared memory registry."
 InjectionPoint	"Waiting to read or update information related to injection points."
 SerialControl	"Waiting to read or update shared <filename>pg_serial</filename> state."
 AioWorkerSubmissionQueue	"Waiting to access AIO worker submission queue."
+XidWaitHash	"Waiting to access XID wait hash table."
 
 #
 # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
diff --git a/src/include/storage/lwlocklist.h b/src/include/storage/lwlocklist.h
index 06a1ffd4b08..0a21ceaf04e 100644
--- a/src/include/storage/lwlocklist.h
+++ b/src/include/storage/lwlocklist.h
@@ -85,6 +85,7 @@ PG_LWLOCK(50, DSMRegistry)
 PG_LWLOCK(51, InjectionPoint)
 PG_LWLOCK(52, SerialControl)
 PG_LWLOCK(53, AioWorkerSubmissionQueue)
+PG_LWLOCK(54, XidWaitHash)
 
 /*
  * There also exist several built-in LWLock tranches.  As with the predefined
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 2f4ae06c279..350c1090de9 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,6 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+extern void XidWaitOnStandby(TransactionId xid);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0

#32Xuneng Zhou
xunengzhou@gmail.com
In reply to: Xuneng Zhou (#31)
1 attachment(s)
Re: Add progressive backoff to XactLockTableWait functions

Hi,

Some changes in v10:

1) XidWaitHashLock is used for all operations on XidWaitHash though
might be unnecessary for some cases.
2) Field pg_atomic_uint32 waiter_count was removed from the
XidWaitEntry. The start process now takes charge of cleaning up the
XidWaitHash entry after waking up processes.
3) pg_atomic_uint32 xidWaiterNum is added to avoid unnecessary lock
acquire & release and htab look-up while there's no xid waiting.

Hope this could eliminate some subtleties.

Exponential backoff in earlier patches is simple and effective for
alleviating cpu overhead in extended waiting; however it could also
bring unwanted latency for more sensitive use cases like logical
walsender on cascading standbys. Unfortunately, I am unable to come up
with a solution that is correct, effective and simple in all cases.

v11 removed this erroneous optimization:

3) pg_atomic_uint32 xidWaiterNum is added to avoid unnecessary lock

acquire & release and htab look-up while there's no xid waiting.

Best,
Xuneng

Attachments:

v11-0001-Optimize-transaction-waiting-during-logical-deco.patchapplication/octet-stream; name=v11-0001-Optimize-transaction-waiting-during-logical-deco.patchDownload
From 3af1307633447f61d6fc57d50b9a10c9329c2af5 Mon Sep 17 00:00:00 2001
From: alterego665 <824662526@qq.com>
Date: Mon, 1 Sep 2025 08:37:45 +0800
Subject: [PATCH v11] Optimize transaction waiting during logical decoding on 
 hot standby servers. On hot standby servers, XactLockTableWait falls back to 
 polling TransactionIdIsInProgress() with fixed 1ms sleeps when transactions 
 from the primary have no local lock table entries, causing excessive CPU 
 usage.

Introduce a new waiting waiting path for hot-standby that uses the existing
KnownAssignedXids infrastructure combined with a condition variable to replace
the use of XactLockTableWait in standby, eliminating the polling loop.
---
 src/backend/replication/logical/snapbuild.c   |  10 +-
 src/backend/storage/ipc/procarray.c           | 201 +++++++++++++++++-
 src/backend/storage/lmgr/lmgr.c               |   6 +-
 .../utils/activity/wait_event_names.txt       |   2 +
 src/include/storage/lwlocklist.h              |   1 +
 src/include/storage/procarray.h               |   2 +
 6 files changed, 213 insertions(+), 9 deletions(-)

diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 98ddee20929..25a7733f770 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1451,7 +1451,15 @@ SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff)
 		if (TransactionIdFollows(xid, cutoff))
 			continue;
 
-		XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		/*
+		 * In primary, we use XactLockTableWait to wait for the transaction to finish.
+		 * In standby, since xact lock table is not maintained, we use XidWaitOnStandby
+		 * to accomplish the same.
+		 */
+		if (!RecoveryInProgress())
+			XactLockTableWait(xid, NULL, NULL, XLTW_None);
+		else
+			XidWaitOnStandby(xid);
 	}
 
 	/*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 200f72c6e25..896c33c2ca2 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -62,6 +62,7 @@
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
+#include "utils/hsearch.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 
@@ -282,6 +283,11 @@ static TransactionId *KnownAssignedXids;
 static bool *KnownAssignedXidsValid;
 static TransactionId latestObservedXid = InvalidTransactionId;
 
+/*
+ * Array of XIDs to wake up on standby
+ */
+static TransactionId *KnownAssignedXidsToWakeup;
+
 /*
  * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
  * the highest xid that might still be running that we don't have in
@@ -306,6 +312,24 @@ static GlobalVisState GlobalVisTempRels;
  */
 static TransactionId ComputeXidHorizonsResultLastXmin;
 
+/*
+ * Hash table entry for per-XID waiting on standby servers.
+ */
+typedef struct XidWaitEntry
+{
+	TransactionId xid;				/* transaction ID being waited for */
+	ConditionVariable cv;			/* condition variable for this XID */
+} XidWaitEntry;
+
+/*
+ * Global hash table for XID waiting.
+ *
+ * This hash table maps transaction IDs to XidWaitEntry structures,
+ * enabling efficient per-XID waiting during hot standby recovery.
+ * XidWaitHash is a unified shared hash table protected by a single LWLock.
+ */
+static HTAB *XidWaitHash = NULL;
+
 #ifdef XIDCACHE_DEBUG
 
 /* counters for XidCache measurement */
@@ -352,7 +376,7 @@ static bool KnownAssignedXidExists(TransactionId xid);
 static void KnownAssignedXidsRemove(TransactionId xid);
 static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
 										TransactionId *subxids);
-static void KnownAssignedXidsRemovePreceding(TransactionId removeXid);
+static int	KnownAssignedXidsRemovePreceding(TransactionId removeXid);
 static int	KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax);
 static int	KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
 										   TransactionId *xmin,
@@ -369,6 +393,9 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
 												  TransactionId xid);
 static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
 
+static void WakeXidWaiters(TransactionId xid);
+static void WakeAllXidWaiters(void);
+
 /*
  * Report shared-memory space needed by ProcArrayShmemInit
  */
@@ -403,9 +430,12 @@ ProcArrayShmemSize(void)
 	{
 		size = add_size(size,
 						mul_size(sizeof(TransactionId),
-								 TOTAL_MAX_CACHED_SUBXIDS));
+								 2 * TOTAL_MAX_CACHED_SUBXIDS));
 		size = add_size(size,
 						mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS));
+		size = add_size(size,
+						hash_estimate_size(MaxBackends + NUM_AUXILIARY_PROCS,
+							sizeof(XidWaitEntry)));
 	}
 
 	return size;
@@ -458,6 +488,25 @@ ProcArrayShmemInit(void)
 			ShmemInitStruct("KnownAssignedXidsValid",
 							mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
 							&found);
+		KnownAssignedXidsToWakeup = (TransactionId *)
+			ShmemInitStruct("KnownAssignedXidsToWakeup",
+							mul_size(sizeof(TransactionId),
+									 TOTAL_MAX_CACHED_SUBXIDS),
+							&found);
+
+				/* Initialize XID waiter hash table for standby XID waiting */
+		{
+			HASHCTL info;
+
+			info.keysize = sizeof(TransactionId);
+			info.entrysize = sizeof(XidWaitEntry);
+
+			XidWaitHash = ShmemInitHash("XID Wait Hash",
+										MaxBackends + NUM_AUXILIARY_PROCS,
+										MaxBackends + NUM_AUXILIARY_PROCS,
+										&info,
+										HASH_ELEM | HASH_BLOBS | HASH_SHARED_MEM);
+		}
 	}
 }
 
@@ -1113,6 +1162,7 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
 			 * throw them away before we apply the recovery snapshot.
 			 */
 			KnownAssignedXidsReset();
+			WakeAllXidWaiters();
 			standbyState = STANDBY_INITIALIZED;
 		}
 		else
@@ -1370,6 +1420,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
 		procArray->lastOverflowedXid = max_xid;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up waiters for expired subtransactions */
+	for (i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4450,6 +4504,11 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
 	TransamVariables->xactCompletionCount++;
 
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake up per-XID waiters */
+	WakeXidWaiters(xid);
+	for (int i = 0; i < nsubxids; i++)
+		WakeXidWaiters(subxids[i]);
 }
 
 /*
@@ -4462,7 +4521,7 @@ ExpireAllKnownAssignedTransactionIds(void)
 	FullTransactionId latestXid;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
-	KnownAssignedXidsRemovePreceding(InvalidTransactionId);
+	(void) KnownAssignedXidsRemovePreceding(InvalidTransactionId);
 
 	/* Reset latestCompletedXid to nextXid - 1 */
 	Assert(FullTransactionIdIsValid(TransamVariables->nextXid));
@@ -4483,6 +4542,9 @@ ExpireAllKnownAssignedTransactionIds(void)
 	 */
 	procArray->lastOverflowedXid = InvalidTransactionId;
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake all XID waiters since all transactions are being expired */
+	WakeAllXidWaiters();
 }
 
 /*
@@ -4494,6 +4556,8 @@ void
 ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 {
 	TransactionId latestXid;
+	int			i;
+	int			count;
 
 	LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
@@ -4513,8 +4577,12 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
 	 */
 	if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
 		procArray->lastOverflowedXid = InvalidTransactionId;
-	KnownAssignedXidsRemovePreceding(xid);
+	count = KnownAssignedXidsRemovePreceding(xid);
 	LWLockRelease(ProcArrayLock);
+
+	/* Wake XID waiters that have expired transactions they're waiting for */
+	for (i = 0; i < count; i++)
+		WakeXidWaiters(KnownAssignedXidsToWakeup[i]);
 }
 
 /*
@@ -4991,9 +5059,11 @@ KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids,
  * Prune KnownAssignedXids up to, but *not* including xid. If xid is invalid
  * then clear the whole table.
  *
+ * Returns the number of XIDs removed.
+ *
  * Caller must hold ProcArrayLock in exclusive mode.
  */
-static void
+static int
 KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 {
 	ProcArrayStruct *pArray = procArray;
@@ -5005,9 +5075,10 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 	if (!TransactionIdIsValid(removeXid))
 	{
 		elog(DEBUG4, "removing all KnownAssignedXids");
+		count = pArray->numKnownAssignedXids;
 		pArray->numKnownAssignedXids = 0;
 		pArray->headKnownAssignedXids = pArray->tailKnownAssignedXids = 0;
-		return;
+		return count;
 	}
 
 	elog(DEBUG4, "prune KnownAssignedXids to %u", removeXid);
@@ -5031,6 +5102,7 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 			if (!StandbyTransactionIdIsPrepared(knownXid))
 			{
 				KnownAssignedXidsValid[i] = false;
+				KnownAssignedXidsToWakeup[count] = knownXid;
 				count++;
 			}
 		}
@@ -5060,6 +5132,8 @@ KnownAssignedXidsRemovePreceding(TransactionId removeXid)
 
 	/* Opportunistically compress the array */
 	KnownAssignedXidsCompress(KAX_PRUNE, true);
+
+	return count;
 }
 
 /*
@@ -5227,3 +5301,118 @@ KnownAssignedXidsReset(void)
 
 	LWLockRelease(ProcArrayLock);
 }
+
+/*
+ * Wait for XID completion using condition variables.
+ *
+ * This function implements efficient waiting for transaction completion
+ * on standby servers by using a hash table of condition variables keyed
+ * by transaction ID
+ *
+ * Note: This function is only meaningful during hot standby recovery.
+ * Primary servers should use the lock-based waiting mechanisms.
+ */
+void
+XidWaitOnStandby(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+	TransactionId wait_xid;
+
+	Assert(XidWaitHash);
+	Assert(TransactionIdIsValid(xid));
+	Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
+
+	/* Quick exit if transaction already complete */
+	if (!TransactionIdIsInProgress(xid))
+	{
+		return;
+	}
+
+	/* Always wait on the topmost transaction to avoid lost wake-ups */
+	wait_xid = SubTransGetTopmostTransaction(xid);
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+
+	entry = (XidWaitEntry *)
+		hash_search(XidWaitHash, &wait_xid, HASH_ENTER, &found);
+
+	if (!found)
+	{
+		/* Initialize new entry */
+		entry->xid = wait_xid;
+		ConditionVariableInit(&entry->cv);
+	}
+
+	LWLockRelease(XidWaitHashLock);
+
+	ConditionVariablePrepareToSleep(&entry->cv);
+
+	/* Wait loop with condition re-checking */
+	while (TransactionIdIsInProgress(xid))
+	{
+		ConditionVariableSleep(&entry->cv, WAIT_EVENT_XACT_COMPLETE);
+		CHECK_FOR_INTERRUPTS();
+	}
+
+	ConditionVariableCancelSleep();
+}
+
+/*
+ * Wake waiters for a specific XID.
+ *
+ * This function is called when a transaction completes on the primary
+ * server and we need to wake up any standby processes that were waiting
+ * for that specific transaction ID.
+ *
+ * Uses the hash table to locate waiters for the specified XID and
+ * broadcasts on the associated condition variable to wake all waiting
+ * backends simultaneously.
+ */
+static void
+WakeXidWaiters(TransactionId xid)
+{
+	XidWaitEntry *entry;
+	bool		found;
+
+	Assert(XidWaitHash);
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+	entry = (XidWaitEntry *)
+		hash_search(XidWaitHash, &xid, HASH_FIND, &found);
+
+	if (found)
+	{
+		ConditionVariableBroadcast(&entry->cv);
+		hash_search(XidWaitHash, &xid, HASH_REMOVE, NULL);
+	}
+
+	LWLockRelease(XidWaitHashLock);
+}
+
+/*
+ * Wake all XID waiters.
+ *
+ * This function wakes up all backends waiting on any transaction ID.
+ * It is primarily used during standby promotion when the server is
+ * transitioning from recovery mode to normal operation, at which point
+ * all XID-based waiting becomes invalid.
+ */
+static void
+WakeAllXidWaiters(void)
+{
+	HASH_SEQ_STATUS status;
+	XidWaitEntry *entry;
+
+	Assert(XidWaitHash);
+
+	LWLockAcquire(XidWaitHashLock, LW_EXCLUSIVE);
+
+	hash_seq_init(&status, XidWaitHash);
+	while ((entry = (XidWaitEntry *) hash_seq_search(&status)) != NULL)
+	{
+		ConditionVariableBroadcast(&entry->cv);
+	}
+
+	LWLockRelease(XidWaitHashLock);
+}
\ No newline at end of file
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 4798eb79003..6c48e75f15c 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -668,6 +668,8 @@ XactLockTableWait(TransactionId xid, Relation rel, const ItemPointerData *ctid,
 	ErrorContextCallback callback;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	/*
 	 * If an operation is specified, set up our verbose error context
 	 * callback.
@@ -718,7 +720,6 @@ XactLockTableWait(TransactionId xid, Relation rel, const ItemPointerData *ctid,
 		 */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
@@ -741,6 +742,8 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 	LOCKTAG		tag;
 	bool		first = true;
 
+	Assert(!RecoveryInProgress());
+
 	for (;;)
 	{
 		Assert(TransactionIdIsValid(xid));
@@ -761,7 +764,6 @@ ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
 		/* See XactLockTableWait about this case */
 		if (!first)
 		{
-			CHECK_FOR_INTERRUPTS();
 			pg_usleep(1000L);
 		}
 		first = false;
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index 5427da5bc1b..c3bc115da30 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -159,6 +159,7 @@ SYNC_REP	"Waiting for confirmation from a remote server during synchronous repli
 WAL_RECEIVER_EXIT	"Waiting for the WAL receiver to exit."
 WAL_RECEIVER_WAIT_START	"Waiting for startup process to send initial data for streaming replication."
 WAL_SUMMARY_READY	"Waiting for a new WAL summary to be generated."
+XACT_COMPLETE	"Waiting for a transaction to complete."
 XACT_GROUP_UPDATE	"Waiting for the group leader to update transaction status at transaction end."
 
 ABI_compatibility:
@@ -352,6 +353,7 @@ DSMRegistry	"Waiting to read or update the dynamic shared memory registry."
 InjectionPoint	"Waiting to read or update information related to injection points."
 SerialControl	"Waiting to read or update shared <filename>pg_serial</filename> state."
 AioWorkerSubmissionQueue	"Waiting to access AIO worker submission queue."
+XidWaitHash	"Waiting to access XID wait hash table."
 
 #
 # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
diff --git a/src/include/storage/lwlocklist.h b/src/include/storage/lwlocklist.h
index 06a1ffd4b08..0a21ceaf04e 100644
--- a/src/include/storage/lwlocklist.h
+++ b/src/include/storage/lwlocklist.h
@@ -85,6 +85,7 @@ PG_LWLOCK(50, DSMRegistry)
 PG_LWLOCK(51, InjectionPoint)
 PG_LWLOCK(52, SerialControl)
 PG_LWLOCK(53, AioWorkerSubmissionQueue)
+PG_LWLOCK(54, XidWaitHash)
 
 /*
  * There also exist several built-in LWLock tranches.  As with the predefined
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 2f4ae06c279..350c1090de9 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -100,4 +100,6 @@ extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
 extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
 											TransactionId *catalog_xmin);
 
+extern void XidWaitOnStandby(TransactionId xid);
+
 #endif							/* PROCARRAY_H */
-- 
2.49.0