graph representation of data structures in optimizer

Started by Adriano Langealmost 17 years ago10 messages
#1Adriano Lange
adriano@c3sl.ufpr.br
1 attachment(s)

Hi,

I'm interested in data representation and debug of optimizer routines.
Thus, I've changed the debug functions of allpaths.c to make a
graphviz-like output of RelOptInfo structure.

Any idea about this?
Is there some project or improvement like this?

Tanks,
Adriano Lange
C3SL/UFPR - www.c3sl.ufpr.br

Attachments:

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


IHDR}��;sRGB���bKGD�������	pHYs��tIME��&G� IDATx���wx������M6��FB$]��
HAl�rQ�*pm|TD/6��
�j���		���&�~���%��%r^�3���N=3s�y���(,��@ �@ �h���@ �@ 
�@ �@ B �@ �@(�@ �@ �@ ��A�2���Q�"�@��~�B��`����}��q��9���o�R����V�Z��wo��o�V�E�Tb�XP(�A����i�@ 4G�?%%�m�������Q�������������
������NBB����O�>���
%�@ �@ ��v+
{��a��}<���t������l6�����V��<y2���B	 ��@ ������'��g3f�����/��M�6����4iJ��$���� ��Y�P(0��DGG3a�Y�7�����S[[{�G��f3���XYY0j�(V�ZERR���E B �@p;����m���l�R^WRR��)S����-����%<<�R�I�&$$���T��i#+�@ h�5�@ ����R���Q�T
���_�����`�������U���j�y
��w'11�^/�@ �@ ��v���d�&L��{�m�~��Q�H~S,X����`kkKqq1&�I<�@ 4+��@ �f��d"77����������n�n���(

���a��I����R����_

��^���C���q���+�����/
�@ ��@ A�A�P\3���hl$�'$$��O:u���#3f�F�T�������Q�����SVVv�k�@ �@ ���������������kiiil������������d2���Iee�U��P(D@�@ 4;��@ ��Y�����%66��[���OBCCqrr.��_KAP_8W��X,�j5j�Z^�����;x������/�����h4�V�1�����+_�TRVV��~��������F��-.��Je�u�y�@ �@ ��0�wWW;���{i]uu5������4���������T������T*��o��hd���W=fNN;vd��Y���RXXH��}qqq�g�������0v�X:t�@\\G���O?��W_e��M$%%5y��@TTUUU�t:����������V���������(�vpp���777\]]qss���+++4�U�VVV7�4�V�D�@ �@ ��������k��%""�-Z4�O�Pp��!���G�R��k6����;;;����&�S(;v���|"""S�P`0����������jVB�t���s��q��9RSS��{w�}L&qqq8;;���p������m������=��������������f���������C��SQQAee%���MNeee\�x���*�������l6�V�Q�TW����������#NNN888`gg������������;;;�Z-*�JX�@(�������-,,���D���������n0*.	o7�����6l�����n���f���b.\�@�n���X�&//��y�����7�Jii)���o��'O�$))��^z�Y(l�yii)���_�p���tt:��A�v�P�����+++�������3���`cc�H��F��^�^�G��QSS�N�k4���PYYIYY���dddP]]Mmmm��J�B��bkk���-������\qruu���Y����B�����_UU�G}Dvv6�Z�"33S���l�U�Vdgg��h�={6���7t�BAVV��#G�p��az��E������A�R�������	'))����E��]�����$$$���D>��>H�V��p���mc�����1{�llmm�0a999�?���7c�X�����������0���xV�ZE~~>Z��������������{��e�������m�6�?�����3gg��!**�x�v������W:����������-[����LYY��������S':w�L��-��a��������_��;�DX,��V���b���oo�VD�/�Z���=������K�
�Fc����+++)..������"���)++#77��g�RVV&O�����f�����
ggg���i����@Zvww�������[���C B ����E�X�`����U��
999,^��#F0j�������!++���d:DJJ
���*�/&--
???�l�������(..&<<�O?��w�}���l.\������a��W^y��#G�|�r��]��?L\\;v����^�z1t�P��oOuu5			�7����~����V�^��ba��������[7&M�Dnn.&L &&�e����g���W/��CLL]�t����_|�c���|�r���+���|@hh�m��$����������'��������8q�^@hh(C��s��t�����p\]]��M&��������?�;;;
�[�&%%�^���
p)>@@@m�����eee�y�:���Ct��	[[�~ooVPV*�h4��RX\k}EEPXX�h���Baa�<�O��T*qqq����
-Z��'\]]o�D��@ 
�@ �eBdLL_}�?��3pi��v� �z�����/����T*5j�
G���a�,X���
S�L��W_e��
___|}}�QX�~����SO��3�0r�H
}�����C��z�n�����	0555<�����j�l�����w��k���i���Lpp0��mk)^:��d"88rss��R�d��<kkkF���M�nXp���R�;��������xIJJ���
�h���c���>�>}�\S�S��
|���]�ta��=�����}{,����X����s
�B�;v�(����:�V�w���E6�o���u�d2QTT$O����� !!������0�����#�H��$��4pqqA�R]�t3�CX#���@xT(�;w�����W��m�����4�!����������?�����:���t����:���R)�h�F9h�R��'Ix��N�Q�T������rz��E��=?~<�|�
}��%55��"�
�B�W�V�T*Q�T����B�$d)
Y��O�S�I�H��?��~�P��|����9yqq1������+��+
�Z���^XXHpp0���4�Q�Fr]�����_f�M�
O>�$K�.e���t����
r�8z��~�oooZ�n����n��T*���xzz^�>������RVVFII	��������%%%dffR^^� ��`@��6�lll�l�"���GGG����I��$YSk�@ �@�G���Z���6>��S���+
��(�������������_�P������S��e�.^����Gy��G��������;w���8�F#NNN�>}������qss`��Q����RSS���i�������#QQQt�����b�����!C8z�(qqq��_�b��5����E�������CBB������E~~>����>}{{{
���%==���O������#Y�b����:u��s�^Ux�~������!���� 33���<Y�`ee����Z�b��A�i�N�:ELL���'  �g�y������G�&S,^�95u������'�x����S�N1y���P:wll,��m#$$���G�V��?����������u�[]]-gI���������Jy�����b���(//G���
$��,[uIJ7[[[���Rf)�����<����dS��@ �#��a�*�BN�8���g�<y2J�R��EDD�}��fs����{�����r��	�?���=z�����X,|||;v,7n$''��=�-Z��������O?���������S����2p�@F�Ibb"j����:��mKvv6EEEq��9�zvv6!!!�;w+++��m�R�$99�J���
���SSS���-�[�&//���<���HNN�e���������N�#<<������������[[[����d2���G�6m8w�~~~(�J������3���������3���rj�6m�4*�����=K||<			���RXX��l���Z�lI��mi��-���
%)s���~�������b����=�v����
��x��eQQ1118p�F�����������������	

b��A���	��6)n�=���R�5E��uz�����V�
��l6cmm-[
899��	����������quu���M�!��@(��a���t�����;7�t57��O>IPP���>/��YYY
\��g����b!((�^x�O>�����f��(**���>�������;w�d������W�o�`�wu�������S�����^�����:��C������3��������\V�\��o�	�o����qvv����/�o��f�������8�<������666���.�BXk�
���.������Z�������O���r,�M��I
�hgg'���/C������
*++�%�������������L�0������j���c��e4��={�h�"�l�B^^nnnL�6����L����g�uYTWW_������i���m�L���fS�^Ix���$&&K\\�O�&!!���J4
!!!t��������;��k��:�����r��A^|�E���x����5k�������rU*����aoo����m8��{���J��~���=oWWW���n�]����"������O~~>YYY?~\�]WW'�J�77�+fO���+�������u�e��sy��������q���+}�B �Z�N��Gt>�s�����GGG>��3���9~�8��-c������AAA�t:���***7n\�WJJJ�������������y�4"���HJJ
����������F�������0|�A,X@XX���7}M
����:��9�|����1co���<�_��&�i�4O��
8::���x��JJJd��i�IJ�XUU%�3HA����Rv�-����Fs����J���=��RH�!eee����H�� ��uvv���__�t�@ ���?�����7�:u���&99���{��� ����h�@�l����~�����^M�N�
�������Sff&iii����������#����3h� ���h��5���M����������|����������s��a�`,�Ie���+�����0�������A6���2JKK��������4�e`�X���B�V�si���YXppp��������4���amm-�4���m����d2���%,k]�����'0��xyy1a�T*U��P(��cggGFF[�n��yyyQVV&��vqq������T^x�"##1������T*�Y��N�/..����������Bjj�xP�srr����^�z�����$������{#��z�j�{�=�t����k���O�������,��MZ[[�u��0�L�t:jjj��������������r9(bFFz��^/[�_������NV����A%E����Q
dz��Osy����.^^^�3������Eaa!���c���,^�+++�
�@ h��Y������9s�j����0p�@����4iJ����2,����/��BsR��R'W���� ��������DYYp�#((���`F�E���qttl��\q�����>K�x��'�|����%K�0z�h�e] �����R��Q��Q�F�F#���yII��������rss9{�,%%%����Y�J��Z�������<yzz�����������S�k�g�����W(|����o��Q�F�R�d����.���$���xxx�����U+�����%K��@ �(//o�N2	dAh5�������M�����,N�>���'�������dffb6�����K�.���3e��t�Bppp����������rrr����ppp ::Z��p'�����,P�TM*/���,)
������������Cvv6'N��������YYY�������<I��������y���;���
����T,=���~��u���+��] �;0��,Y��W_}��]�R^^���;v,�E(���N���yNW�$9�x]]555$''Obb"III$%%����j��i��.]�����N�N��t���������QQQ�?�������?
�_ ��+n�����J���/����u���93Bnn�����%55���\��M�H������www�%J�Z�h���7������4Hg*��T�J�R^nJ���};J���={���"GW���ox��7����������h�6�����p��Je|�}���1WU�X[[S[[+?;;;9����r%�Z-vvv�K���GR*��s�N��"�@P+++��p7�w�"�r��m�M����}bKJJ���'%%���t9JwII	xzz��m[&O�Lhh(���k��{���o�����������o����_ �.��T�Hq
:v�x��M&��zPXXHQQ���PXXHVV�N����J��F#���r�)��V����9����#���X[[��Wnnn���������K�}�Y
������wM?��G������\lllX�f
UUU�����=z���_~��v=�999�����m����{�����-�����G����������O7�G�R1}�t:t���u�����d2�u����NNN$''��sg���<��0��|
���w|��z�^�l�h4r��E222�p�dffr��E���P��r�DBBB2d~~~������sC����I���~����~�E���SO	�_ �1����
R�������������������
���)++��RJ���j


��uuu��f�f3��RIjj*�N�����&44���;����?�>}��v�Z�����������������ggg~��7222#,,GGG6l�@YYS�N�_�~$''�����hd���$&&r��9���>|8���/������������������U+^x����9y�$.\ 22�w�}�9s�P\\���c��!;;�R������+��
c��}���`2��8q"f����J~���&-�IX[[c4e�Q��zt��������hh���
�X��l}$������B���IHH����*++qrr���ooo:t(���8::���,��?ns������W^y��\����+
y�z2&HA�����A��W^y��������z�<���*&M�D��m�������L�8���T�=��u�0`O=��N�"//��������������/��.����������$���R�$11�y�����@rr2�
������,
)))r�#��i4|||�8q"�'Of��]l��E����!''�>}�0z�h�|�M�M���l����?��Dqq��M�@ ��������[~���������F��cmm}K�'��h�W:fnn.6l����:u���8�������m�����1d�:u�$�TH>���T�+���
���Y�l�����_���@ ��+
.���z�JVe:���m����IDD�������#G�p�����l5
�7of��DGG���O�n�&;;�C�a�X��eo��&����~�����BzNF����~FF���r;{����j�*.\�@JJ���jkkIMMmr��b��� NNN(
�m$33���2������HKK������1��F(��Ov&�G�������r�X?���dB�T6���L%sD�J%�����B��e�P(���D���a��{�=lll�k�\�F�J��=zp��1:�O?����qvv���d2]�H��o����h�4I����fri�X8p�����K�.0�_|���p���������;��������?g�������_y!� IDAT �N��l6�u�������IW������X,h�Z�/_����`!w��V�P0�|Y�q��y���CLL�<����L�<�i�������x��+�w��Fj���^JKK������lF�All,����L&���1� �P(���j�?$]�t
����?��n��T�9�@ ��
������H�����e#F��������������+�2e
������<�F��������LXX*���{����KXX�_��������+++L&���+������1l�0�F#�}�&��V�Z����9}�4_}��F���V�4B������*�
F����?���?pttd������3k�,���~���3fvvvM�����Y�~�u�w��+�������?#G��k�B ���E�>�z=/^$%%���������������5^^^���NNN�M<�����L�2r�����1�U�V1~�x&M���}�pttd���X[[�t�R����t�3����SWW��3g�c�k��������������?����M�W�^����e�V�X��9s��q#������r����H���9�<qqq� CVV��p����������k�����
�@ �F�f3���t��ggg&M�DUUyyyh4t:yyy(
�;�����x�"������H&N��g�}����K�-���CVVVt�����h�Z-�������?g��%�e���~��_���G)))���b�0s�Lbbb������W�����������,X��M�6�����y�f�L����ky��wx���s������m������v��_}�o���u�#��(
rrr���$''�n��1n�8�bI���T*Q������m�6���7]�v���D�v������r\\��)f��E
����$22�����t�{����"��Kit/g������>����M�6�i�������R�d���%��?���6,����P�m�8��f�����N�G������C<������������3�Z�"77���BBBB���d����O����1����������\����PN�<I��}quu���_&88�����c���z����
���	 99��Lqq1������\Upss���z��f���K��9�%�K�222���#""���KLL$##�I�&���#����������o�����M�r������������~C����o_��qr���F���B oe�VSQQ!��w���c���������|�������v����7n�����[����5_�5AAA������>��z���Q($%%1o�<f��I��m��s'Z����|<������/�HNN���
b)���;���D�-d��}���J�"00P��1b��^Ojj*VVVM�����5j�~�i��R
���K����y��W����-�~mm-K�,����g�}���
+V� >>�e��]Q@)))���������
����=�
B����1��*���d��~`�������.�{�n��I��c0���'���t��777~��WZ�lI@@�_��w��E�\�@p������������M�61a�
���>\6�stt$))�������R��l6�a�����#���xxx�%Zn�T����#??���pV�X����O������;j���������2g���o���;y���y��G�U�V,Y��BADD�f����&&&�
6��h��������9r$��
����T{�1BBBnI��V��:u*���W���{�i��f�|�wbb"����7N^��h2d���P(�����/���_�w�����6y�#G�`6��3g�U�M�������o��S ���r��jjjd�.�E�9s�-�z'
�E9h6�Y�p!;vD�T���G�6mHLL�e��7U��(�����������#����t���	�@ ���)+++9R��k8//�����j5
}��!,,L6u���={�������Ki���3����o���ba�����.]���K��M�8�Q�q��!2D^��K/5:�O<�`���@���'�3�xxx����$`�L�>33��/RPP���#[�n%99���`F�A~~>����o���>���]����N�^����K�,�O�>�L&���9{�,IIIt�����Ctt4�{��S�N�������������{y������������I�;w�]�vQQQA�=HMMe��
���`ooOaa!���|���<��CDEE��_?z�����9|�0K�,a������������4h�F.������;vl�����;|=�����\I���Y�l���wE�N75�j����QWW�J�j`�v9...r~u
��(((h����C��d��w�����m�G��}��w�����q�������-�wg&�@�7 U����B� ++�����ZZ����{?w�t�>�����}����`{W�O�T��������o(..&33���7��j�;w.�|�	K�.����c���<��#�������=����5k�����X,���<��c,]����`������1��_����'�T*quu�k�������C�2c��u����=-[�d��
�{��L�2��[�b�X8r��[����<������q�����3��i�&~�a&L���a�HMM��{�`��yl����;w����3i�$4
�
�����~��{�����Y
�7�[r�����b��BA^^nnn7��qyJ���X���i�������vIII�M�����2q�D~��:u���={��u+�Z�B�Vs��9����������'--
{{{���>JJJ�h4dee5K�G�RQWWw���eee���^Q�"�E������6�Rp;�������04�-=������}i����ww�F���l��pi0���GG�j��;Gppp�u�r������JJ�@��B�r<���h4��uk�����|�RIPP���W�$e��0I��{+�I��J%���:t�A��Fp���Q�T��J���������]���4hF�����]����{��t����o����/����b����������;;;�������������^��h4�����
p)3������Y�d0�X,���0`���Xtt�|���"6o���i����$�_�{�t�R6n����O=�g���S�b0(//G�R�f�V�\)*�������[�x�;0�L8p�U�V�e�F���I����'�;w��_.�di��%~~~���c2�d�K/������)p�_��]�P�T*Q*��T*4
666��jT*z����x�n����������������h4����666����R������T*�h4�o����������Yw�m���r[r���Z���5��q������
����J8 �;}�4�|�M�m��������JKKY�f
yyy7���Y�h����������l��@p4��������U�nnnX[[���l�Z-��;s������)++���PN�(u��j�����NB�����B���	G��b6�<x0=z���G�d2�#0R'.���U������L&���hXdH�!G�Raee�B����[�Pdff��eK�Z��G������_��.�d���_�����MC��6�����	

�S������;x��g		id6-���IUU�������F#=z�`���t�������:w����/��2��-#''���J"##��t���c0���?`����:u�Y�Ayy9���K�u��y��=K��}qrr������26n�(����ddd��kW������@����U+RRRpuu�����{�b04hVVVdddp��i�u����f����T���i���U�m��
h�Z�z��g�BAtt4-Z� ==�x���6n�H�-6lt��UV�J����),,d������ckkK�����e���S����gO�j5[�n�`00r�HlllHNN��������}�6h���O/_�P(���f����T*��iC`` ������???<==i��U�cH���Us��}t��{{{�m���a��������d��Q��=���rN�:��;�������s���*_��C����'33SV2^~
���l��H^^{����h�UILL���7�RX�����y3_~������2,..f��e�>}�o)G�^Ouu5UUUw�T]]MMM�]�X�����o�����h�"�/_�k�����{���"&&�����r��q�����s����f��}TUU��K/����W_�i�&RSS���/���y��h��_|������������������o������2c������#G���S'����7�|��u�HOO�����}�v�n�JQQYYY��������8q"g��a��y���3~�x�������?��<�N�����x���x���x������f��y,^����t~�a8�?������5k���f���L�>�������
���s�=�s�=����������o3g�����f��=��;���o���/�0e�V�\�����f���L�0�%K����r��Y���Y�h�<�����_e���;v�����������O>Iee�h�q�����J�"11���W�������J�b��U
��(��������������������B� 11��7����Ouu�le'������;v��gO��]K^^qqqDGGc�X��g���|��G8::�����o�IZZ�w��w��,Y����l�����{7���M��B����^�������/_�dj�'�x���$��^���g��_�~dee�p������^�f
g������g�}�c���B��l����.Y]YYY�r�J���x��W��t����x�b����s�=�������lt����^������;�����_��KKKy���ppp`�������c�����������[�[�n���'�'O��> ??���kkk���i��=�=��\EEE���3n�8
}��E���o�>�R����N�:q���F�D%�����8p��������'������/����LZZ�
%�Mr���|�Z�3�<s����1���$�bi4�ZV�y��D���m����<���m��$=777�����g���W=��@J�w���hnHp��j����|�zo����;s�\z�
�X���q:v��k��&��;EQQQ�:{{�F&���wop_�f�b��Y
F����ky��w�it?�������q�@~��,�j������b������A&�;�'�x��?���m����_���?N||<b0h��
���c���|��W���0o�<��:t�@`` S�N��o�%--
���o����{1��<��������jjjh��-Z����'--����s�����eK�O���	x���9~�8��M�e��h�Z>��z��������G��u����9��s�r��i���'M���O����'///2222dH�����///rsseW8��y�o\#�CK�,i�������hd���QZZ*� ����?���f���������X�����1���<��s��k�-]�f
�|��5�����}��+W��d2��������F�M���y��G�4i6l`���8///��[�n���b0X�r%����y���0��������<����4��X,h�Zz����Y�0�L������7s���&G����k~��'���IHH�n�[�����LVVVr���DPPaaa���\��j�j��"**��}�������������/<�����t���2���h����w�!k%��D��t:�������������Q*��F9����=F�Q�P=<<d_*�G����Z��b���H��b�PQQ�^��E���������kk��?)�l���;��={�3gJ�����J%��z���pss������d<�/�@UUvvv(�J���qvv��]u:���r@������L��X[[�����d������ZZ�h�Z�f���X,Y�j6����D�V�����g\_�!]Caa!�����Li�����������*���$��,�7�M��]������]��Q��dgg����h?�\7#�K�����h4lmmqsskTf����\�F#*���-[���(,,���__���i_og7&&��s�bee������8::������#vvv����u�V������%##C���jiY2�W���4���4	�\aVPP�SO=EMM
�}�Y��w����9���3���
��W����d


X�b��mY,y�M��m�XHKK��'/^�� ��tLI�*}K����:�$WR
��z��xy��ku����C�q�����}�Y��Gdd$��M�u�����1~�x"""���"33�����b��������x������
��DFF�����\
��s�Nv�����Y�|�lP[[��b������Z��GQQ������<���t���'�|����'''���������9::�}0�� �$$$��c�+�cccC@@����1�����+
���c���`�X���'((��G���{wN�<)=�\������/����%%%���b4���uiee%;v� ''Gn�%%��H}5���.���g��Q��?�a������/�F�Qv���JmpS�3[[[���1������������
����b�PZZ*���\IN����������B ��
��?� 66�f3S�N >>�_��q���g�}�������5���D������?�0���:c������N���3��s'EEETTTN@@�7oF��1{�l��?����y�����C�F:::���t


�7og��a��m<��#���PTTDyy9���:��_~�g�y���7����3f���-[��o��|���L�6���H���

";;��z??�F�Err2:t���s<���;v�NGQQ���G����������m��]6�����9�����R�����R��������?���INN����V�Z�P((++�����/����F�!**�c��1i�$��oOQQj�'''��;G`` %%%TWW�P(d����/En6�������h��t������.k��������e��������K/������������g���?G��m�p��-jt�3g���?��cG6m�����?���8q�j��k����g�V���:��N'j:����Z����''',X ���
lmm������{{{lmm�j�r@&)����������R�V�K��u:;w�d�������������rG�����s�����CFF�������T*�����WWW��}{����1c3f�h�@��	

�����B��-�gR_��T*���j9|�0={�$::��;w�n�:f���@Ip��G���HQ��SZZ*)�oM���)��Hm���4�g�%l������H>��'�>}:g��%''�F���Gqvv������T�Z-���������@bb"Z�ggg���c��BBB�������������'Hdd$�[��_�~M^����o���;JKK�������d2��SOq��Qy���0y�K�.EFF�<X���F��m9|�0���>�3g�������qss#  �)S�EHH:t����B�G}��+���&??�Y�f���q��-R�;::2i����c�����};#F������s���/����#�'��PYY��'�����8z�(�����_`` ���>|����3�������A�#G�0b���}��9#�������d��������;w�o�>��=����/�������C�;v�RI�n�8u�:�������B �	�����U�

�Mu-aaa�^���g����GLL�����?d��M�9�{�����l"""�<y2'O�d����������?>*�������7��m�6>��lll���+���r���+�M�6��jy���		�]�vb2�>|8g��e��Y�3�#G�0{�l�A��Z� IDAT

�M�6h�Z��;��q�������
�FC~~>���*��/g��u�����*bi�����c�-Z��_�������^������P������=z��G1t�P���oJ ���������������D�����M����K�n���d�LFF���<��C������T�V*���T*����x���z�j9�KJJ
#F� 88�A#nee��;0��j8p +V�`��ADGG���-�w��_�~�[���'bmmMyy9J�RBw��y�;�#�<"G��>�������8u�III�o���"(44�a��q��~���������������O+������������Zy����eIA ��?�����ATVV���Guu5���(G����ORD~kk�FJ[[[Y� �/_�~K�����e����m_|����L�6��\A�����K��g�������b������p��q~��w����s��������o�;��k��n�:������?f����*����i���.6l�b���[o�����h���\6}�����c]]����_����*���]�v?~��c�r�����			������zL&�la��������������7m�X���a��1����i����������cG���P��L�:U��0auuuL�:�ZM�6mHOO�h42}�t9;Nvv6��O������Z"""d���k��i������R����k��O?���/7o�<���$$$���|t:+V����
�Z�����E����d���������}��1'�?��;<�2���L�$�Lz%�AB�PBS�U�����D�,����?������b��HG����PC
)���L�df�?x���$!�0�u���9s��)O�����R���3pvv�U�V\�r���
��L&c���7��7�qP�=��j:t��c�=�R�$--����������+{�����P�������III!<<�:PRR�����x�"���|��G�h��_|Q��DGG��
��0`2��NGhh(������t��E �y���C�-���:��� ������`����;n�8���_���B����xV�U�����pU�8� ��K||<%%%�^����<�t�Bll,+V����YD�%o���9s�������������K������>��u����n���+��n�:&L���;���s|��G����k��d�l����'`S�a���H�d��}7�mmm1�n��w�y���l��[����H�0�{�y�*�
�Z}G�������c��yxxx��G���Chh����}VV'O�d��	DFF���aaa���3|�p����������f��1����FMM
666��hM�BAjj*p����KII	�����7�x&666�]�����N�g���������SPP�������?��^^^���\\\P�TDFF�R����!44oo�&�;���pvv&55x�$eee4k���W��T�� �)�Y��T$(�y���i�=�W��������eee�vQZZ�N�C�����Gyy�@c�������R)�
���Dj����Z-��������j����'MVV���"%�n�w3�m2�h��>>>"�����\�����y�������)S(..����Z��������R(X��w'**
����������;W�>:w��V���W^������T���x��G������	������Q(�_��B�V�e���d2���1�888�`�������L&������b�+���������������"��<�.�y���bnpHds�N2*�s988!>K���q��:$'ixx����d�e����r��e����C�XTTQ(4o��"���EL&���b_xx��5I�M;�0a���b��!C8r�]�t�_�~���\�rrr�}��" %I��m,R%��������d��Gy��u�W�~+�cH�����:�}����"m%DEC�����Z-�Ey�'t�X�AnO��������a��h4��ys\]]�>}�x-Z����TUU�}�vq��MNNf���dff�����������S������]�,j����Kbgg������P(��u+�>������_&11���T�O���}��M7wH���1�5�}LHH ::�
6��sgF�)X��sH��P��Y�2�������~���
����d2��V��\.g��1������������Q��J��{��wy���	

b����=��������{o���qgkkKYYY�����ppp����*DI���
Z�h��5k8z�(|���������Bagg���}�	�|||����[�n<xP�\��GGG*++����}��;w&==](�������9��J����4v��>�;B*c%-EEE�����:��3g�p��q�z=!!!xzz������3-����E�����,8�mggg�Z-���s.��P_	��<'����
�~����y�����H��;v�f��GI�P��������������0`���B�ms1o���c��,���\#�~w�Huu5�z�jR:[c������jjjn���S�S_�1���l�v"����5��������N������c���CE@K.���3�V����~'|J�}Ow�\sss)++�$e}
T��������~KFF���Y'.�4j2pvv&$$��KXX�������������_~���[��W/�:v�����?���s��f��E@@c������c���t��
����j��^�Z�y������,]�???��������?�����_�LF�V����O?~�EI��{�r��%����9s���:t���~�W_}������9s�Z���72u�T|}}),,d��}<���'NII	iii�d2~��W�,YByy9���Z��H�Tr��E�~�mRSSy���9|�0[�lA�T��E._�L�����h��%qqq8::�����~�:����B�%�nRRIII������JZZW�^�����p���FR~q}b4��w/t��]����r4
999����������h�����y�prr������www\]])++���~�����������o��u����F���]�������+2�����,������			|��g��3���8*++1�Lxxx������NNN�:u�c������7��o��Y|�������\.��J�RDdz�����_�|�2k��a���������$�m��[�TS���J�����^��h$==��K�r����|P'�PUU%�R�� ����IOO��WRR"��XK�o�V+"��Dj�]��Q:V�PX��4�m�YZ�L�x�	�;r'F���#�������K�f�3f�bl��"7���&=W&���_?������c-���:���<�m��wb��h�{z�l������R�"Ef�!�F�\����[���d��ixxxXGz�������f�lmm5j�E>���56���DIbVm�$''�2?p#_<44���uc�y���������?�p�M5##�F��j9q�g����w�i�K0����_���` ''���,���IOO'??���"


(,,���ZD)���$((���`���x��HHH�]�vL�8���������uk���oq�.\ ??_�~��WL&]�tA�P`0�|�2����o����rN�:E�������j���-���c�������W�5������Ett4�~�)��������}{���-<�Z�ooo>��`�c���5���c����;>>���x�����O��m��������O~~>AAA(
�+��eK���n�����/���1b�1�n�������c8y�$#F�U#�9Bii)�nr�411�����?���N�����|�������v����k���c�:����sUU��E(++������R�H|	��+++����^Ouu�X�4�/�V�D�(9$�[[[T*U�E*�T����S�Tw]i�F����e��q:t��~{O�=i���K�Ipv//�����D���
)3g���'��s��w���������^�z7�W%r��e�P�T8::>�����Q%��[�l�����H�T�{9bcc��c���i)�X�������E������'���}�������ys�=��!C,���Hii)������	��F���������^�^�G����-���dff���D����Y�}+..�RRRB^^999��knn�����W�_����3	�������'�������4���������'�xB#E�<
��w���}R�EMM
���<�����'��V+J����z��!��U*� +���ooo:v�Hxx8555dgg�Q�������P��z=NNN6��(�@����h��b�����
�	������j2������g@�������|@ir����u�l�$nN���g����>��_~)�C}���P���)��A�oG�+3Hk�NGee��Z��`��t:rssIMM�8��l_}0Z��
�B�
H�y��\����{���CB�V[�h��s���9����#�K�,i``�h��)x�K��555��rQL��K����+��d���q���J%yyy<����L���d����y�f4
��������v?�Y�����nG/^�{��Gjj��V��r�V����=�l�B\\�&M�(���"H���
��+WX�dIX�U�r+��t,\����0��i�Z����~��������*�����H���{�S"�F##G�������la�������JAAyyyL�>���"���())���GGG��������7QQQ������(���Q�[E\�S�M�v��C:�����O�E�~>��Kk	Q�<F�[[[�Z������d��`�_���d2�9���0�g~�����66��vg5�-�~�����s��5���?��O���E��(�����+R�����+�U���R]]m��|����@&H�T�I�!U�0_�}���(
�j������"��<E���	{{{��<EB�� U��:.���\�x�o���F���>KUU���xxxPPP@YY*�
�^��+W#<<���R:���-��w������


��^������=d��dff����)..f�����nbb"j��n�����_
����wSVV����v�B��1p�@8{�,g���[�n����J���������w����6���
�w����_�e��<���b���Gs�����hD��<t����{��������<y�:0e�<==-���p��������/�x(`#�
�u�����s��)���7?��?�����z4����(l�:�^���r\]]IIIa��=$&&����+���Q]]�L&������ ������!88���PDmt���J��������U��V��d2�i�K�
HF�9y��w���;�����g��y$''���/3e�|||D��{i����Fi����������X��$SZZ*�?H�gddP^^.�K�������B�L&�	���R�~�SAZ4�}Y��*7�!!!xxx���/)))l����^{������b4
;w�d��y�\��i���e�Hrr2+W�d����:u��~��^x��;4
{��%::�Y�fQ]]����E��<y2~�!�/f���L�2��G��������3f/��"
��������;K�.�C�����e��1k�,-ZD\\}��|�	�g�F�V��?�	`gg�O<A��=�x�";w�$>>�/=���jJJJ���#%%ET�����w��V�>�RI��������W_e&���p>���l#�����_Md2J�R��oa0`}��������4	�*J&yc��#�R)��n�Q���1b�N�b����df.������c�o�k/��Az�!��1x�[���\�r���$���-�R����!!!�������	#,,��r%wC�l*jChQ.�a�\.V�s[�^����?�����S�������#G��>6��q��[�]���,�����1cII�E������:��������2h�,���
b�V���a����y3���%qS��jd2dee���CZZ�<�qqq����������������Z��#G�7o�:u�s���\��Pv:t���?������~���~n��}��7����\�r��{L �F�IPPo��6l����+WRQQ@����s���PMM
������@JJ��0o#RP�{��D�k�����7�"������Z����_��=�)�F�qff�E��E����������:t(s�����K888��h�~��`�6��3F86l�@jj**����_"��qpp������J�J%����G����aooO��=��y3���c���\�p{{{�Q���&$$�����m�6N�8!<n...�)��{-aaa|������U�]��=9]����****HOO'%%���������&++���\�rss#88���z��EHH!!!�2E�����E�^�����oY��V��s���s
���Z��U�V��f��na�^o������0DkG�������e��������3�;v���^��V��;#L&J�R�B5Uj�0���PZZJQQ��.33������:UV�:I����������^8�Z-NNN888`gg'^���U{��"���2%B�7�������9����'�|����
"""�|����WTT��hpww�o���Q�F	����r����)�T���w�^bbbX�f
S�La���0`��t��/�@yy�p�I��R�M�6�������������)//�����Z���;w2s�L�����9�g���&M��7��E�m�F@@�
���UJ�m���z`�����f�������'����=�NGqq1���1��T*ax8�B����3g�z�����v��������7�W��M�6�����{w��9���W��e���,_���{�>}����@pp0���xzzNjj*			���K���QSS�?�@II��>233-�Vi��"�T/���P�����OVV���Y�iUWW��jqss������0�w������5����Q�����+�\B��'����"���n�x�d2���������LF~~>			h�ZZ�ly���^����L�|il;k��o�`���'""B�.33S�w��7'O�nD]]\\F���T����=�}:77���w��W_�����A�X�re��U��:n��$.�&�:��N'�H��:�����:������"9����`��u}�_R�[r&H��Z�����b}�}j�ZT�h���������{���i���������k�(((������;�q�F�
&��~�:�/_F�V��o_v��Mll,EEE3y�d��;���g����vO�C�VSXX��={�������q������IJJ����,^���={�\��:������ys�u������-c���h�Z������"**����h�Z*++qrr������[���������X�v-111:t�V��U���:="��*++����/<�wS�R%.D���y�f&N����>�?��'�|�����IA||�0��Z-����(V�X��u�������3�n�Zg�J�������������t���;�������l�����&L�@XX��/g��
$%%	%�A���Q��*u��ViQQ���\�v���L222�v������������`�upp�z����=������xX&�l��o�e�������P(�����RI�����Z����R�r�[�c�J%�/_���D���oR��L&UUU��$�g�^����x��/]�DJJ
������P�M����~�fMM
'N�`���,Z��AH�B����30i�$�x�
���?�@hh(�
z��-�LFII	�������C�R1v�Xl��c��X��v"HH���R��,��P{]{�TJ������"�]��N����Z�"K��>+�J��4'JN�F#�e%����w��P� IDAT����r�J��mK���i������}Q.���W/�^�*����j������� ����C����SO�����#HII������Pt:��7�����<�4$�J��y(..f��%h�Z|||HJJ����'�|�W^yE�UUU���+���Q^^��Y��h4<������������@�R�����db��E���LDD�`��J����={x����������f���,X����(������xP�x�LFzz:���c��y��������}���e?��3���u~���G``�8�N�C�V�����`���>���<1�K������ ��k����
�7{.555���q��U���III���,***������������^^^t����� qtt
��H,�M�F����7n���C�n�����������qww'00���;vp��	���kbbb(,,����TTT���?���;aaa\�|�A��G}��`�����C�����?����3;v$&&��[�
W����j�l�����Rlmm4h*���������G�T����\�pA�111"��fm�K�."���G������=z� ??�={�<ps�������{���������������E��
���_�����hR%�E2���k����O)�AZ������(,,����TTT����7�(�=���G			�PT_T��DDD���6m��������������h4����{��d1$qOI�*�u�Ez��9.k���4)] 22���$�^�g~n�1%q�HH��rg����W�1c'N�`���L�4���`V�Z%���}���^]]������K��>}:{��e�������e���������*����7of�����~�v�J��]qtt$((�+W�PQQ�����pK�k^nK2�������o���U����/���"''��:P#?++���D���s��]RR��h������ �kCHHaaa���T�|i��o�o�~�
�������r���3g���ob2��������`��!,^��Q�F������`��A���2p�@F�qK4�B�`��}(
^z�%v���B�����b������r��IZ�n�G}��
0����E������d����"C�.]����k�.����R'���h4
�Hi/^$%%E<�-Z0g����x��wHK���z�j�,Y���7�V�b���}�j�[�au"����K����jo�^�o�T*F����[Q(������g��ys�y��?e���\#F�@.�>�V�ZY�S�&/���?����-,\��^^����������***x��7Y�l�
������&�	��ou�5�������`��EL�6����������1cUUU���TTT�����%Kx��w���?&L��/�$>>��={r��)F���o�Ivv6�z�b���|������0f��}�]���
HYZZ�f�n@�7o�Lff&�/_f���<����X����Dk���xs������
��z�*iii������Fff������Jhh(�F�",,L��"`����V�A�\Z��r222h��yyy��r�#�HMM
6l����^����U&�q��5<==���"���5|||D����"�,Y�|�s�='���"��;���A�d2����p�}��A�RQZZj��i~��30G6}����?@�[_�|9���.[�ne��������kjj(**��o�����C�R�v�ZH���6��J���Eu������;������Q*�V��?q~��*��$22����3i�$a�����{����uy=i��US��?��Y�����������"��9p�={��W��KV�_V���IOO���Y��#G8r�����o���N�c���sYY���|�������+>�_����RRR,���������?�������O6���WTT6]�]������|����{�x����������@��������]�U�x��h4������'�<���innn�zBRR����={���h��k��_~IAA������PXXHjj*���899��Z.��o��&8A�x�	�t���#G(**���GGG�1c�O��������`ooOzz:YYYxxx�V�Y�hs���+)r���]����F~~>�6m���^"??���\���i��5\�x�C�	(����y���8w�������nnn"e�)���=��F�����e�6mB�V�x�b&M��dG�Un����Rn�?��BBB8p`����?��3g�q%$�Lf�{���/�����e��/�/�,Y����������_��t�
@V������;��+HMM���;����@�Y�gV�Un"����Hv#�d2q��u������#77W,yyy���PPP`QjF2�<<<����U�VxzzZ,M��n���(�;��ppp`������aoo/r��Z-}��������Jf��Mrr2��A���������KYY���DEE���]'��h4��kW*++IHH ((�L�+����S�ppp�W�^��jZ�hA||<���t�����
�v��^�';;OOO�F#���w-����>}�����K/��^�'--�~����h�������:N�^xA<���;3q�D.]���������4���^+Z����/����#����p�BF�aA�hU�no��=6���?
$EC� �*,,���;yyy=z���G��#�������hs2��E����JTT���aoo_/B�������#�����.�����k���n������U����k�3�`0�m�6>��c���;v,�=���������#R��Un�5/���^���2�������Azz���������NAA%%%�L&���qvv������i��f����j�j�888�����-�y�U��'nnnw�U��6����h����!C�'���(�4���	

�h4��ukA�$��3�\�~����:����-������C�b2�DE����/��h���777��c��������2���W_}��G��];��kg����b�l��7�"Z?b��&+{j��Q��{5;v��K�r��9�����~H�N�D;���3��������B�����c������3`�V�\����7N�<���[qtt����x������+o��nnn�z=t���.�}�vL&C�%88���\RRR����9|�0m��e��]����\�r�;v��ys��?���s���c��-���������3���Y�v-�Z�B��������~KBB���U�\�������ws��)�������������������(���$%%���{[%�L&EEE�������� ����4o���N��y�2��_~����lF��J���{�L��+W8~�8��
�������c��~�:���6�;��f��Edff��/0|�p������Uv�m��;v�WQo�~�����o��m���+��H9����NOO����^/����	�M�6���*���.��4�X�:���MRR�����|Ds#���7��������;�m��d.�s��V��jGj$g�t��5�
��v�xCy�w������t���5X��=��9s8~�8'Nd����aO�����S�2s�L"##������m$$$��SOQQQA~~>���DFF��wo�l��^����^c��al����(��}������c2�X�`k���h42k�,���t:iiiSXXH��=���_���i��=%%%�����-[2y�d������gO�7o���3g��y������������o��9r�.��S'���G������J


D:���WTTDaa�X�/EEE���c0(// ;;���l��?O����1/]�T�U&�Q]]����|�
S�N������J��36���5�d2�=���'���TUU��h��t(�JA0�P(0���r���,��t��"#����IU��1�9�>��3V�\)$����as�w�������|
��i�����]g^8{�,��o��g�a���8p�]�v������o��6������4���d2222�6m���^��/��Y�fB��F����@bt�_H�F#m����Vy�&t)�j��+-���\�r���$���������������������k�����JHH�-����z�t�������a��agg��N�V��c���{6n�x��Gr�$&&�����s�N��Orr2��5�X������G���/P�Txzzr��BCC��"ES�J%j��F��S�HJJb����<y�����-���������Knn.&�������K�Q#9�5
����t:T*666�����sg�?�J�"11�����lll,"�J�{{{lll���~��������6�L���r��u�_�N~~���z����w�����n������c���ggg\]]	���WWW�����f���|��'�T*z����+���`��1
������^�777���X�p!			�:u
�FC��=	��O>A��cgg��i����|��G��^���9s�?��#��������];��o������s��?��3�������h��:uii)[�lA���������~�:_�5F���������s��i�n��J�b��!t���O>����X6o�L�.]pwwg��u8;;3a��ph��[��~��Z���
���'::�����������i�������C�0��� ���1??��K�����W/.\�@HH�uN���9n������4���
vee%nnn5b������j�����������GGG<<<�^`�� r�������������rc:��K�������QxNKJJP����j***())!//�V�Z5��z����,L&���(�Jt:%%%8;;�\���L���D��H�z=&�I(D/^�����=k��l�r�ww�z���]QQAaa!UUUTVVRUUEEE����������l���������Z(e����9?88���`���pssk��b�Is���|�����1C�]:99��������!_�j�����O?�$g^c����._���~�����������Jk���������4BCC)**����L&"�R�T&��hd@@-Z���_d��9
�C�z=F�WWW��o�x�T*INN&44��G����_���_�`�qLm��_%��v����W����
��������GAA������������R�*�
�J�F����
777\\\����u���s������8��o���y������zMC"��IKK�h4���]�Faa!�:u������z
OOO�������O�>�5�_|�LFee%;vd��TTT��3gh��--[��@��Ww�j����,[��s��cQ�������Kll,999?~�Gy���3l�0�q�������C�]����s��i��OAA555t���JuG(���l���X�|9NNN"�������pww����������t�F#'N��{������Y	Q����������pwwg�������:'Y�i����b0� !���\^^NJJ
�f����#����RRR����� i�Z&L����+qss�H3��P)OH���O>��3~��'f�������`��M���	����l�,Y���-k���-#�u��>|���[����^�g��Y<���t�����<bccENnc'������Kdd$���'//�M�6����^�g��a����g��l���3n�`\���>���D��I�9z�(���u�z���>`��������j�������PRR����1�L�t:***��tTVV������+��������cG�i��>>>��j[��Vi�k2����3�������7&L�����������+4���l�����2���wW���\�������M�6q��%z����C���X�����%K��};;v����1c�PZZ�/��B\\Z����
������!66�����v�Z�9���-���*++-��L&c��9l��	��nPVV��`@��Q\\��d���@@�
%%%�9s�3g���{���j���'))��m�������������Q]]��`�����X'�~�������t��Myy�X��%%%"�^TT$��������TWW��`0��h���G����jqrr������P�������������bi�3�v��s�=���So�w����p�t����{������O@�%TCUUG�n��r9555�����jJDr���!%�d�K�F��RY�/��,����-���T���W�^<xPD�[�hAuuu�c///�~p����E~~>,`����Gdd$p�\����3f0e��u�FZZ�>�(vvvxyyY�z����$�n���_�F������(1k5���d���
����E�h�Z:v����)++������{���Jpp� ��jd�;wND�kjj8r���X%����S\\�������������6m����T�R��K ���L����o��&�o�����J���4h�M
K___���������JFFp�]8  @t���T~��'���9w�s��E���;�������O��h��a��=��'J���y��g���F��������.]��'�@�R�m�6"""��k��^����m%%%0t�PJJJ����x���x����9s&III�Z����@�5k���J��C���������~0W�L����EY�:�r���� $$D@�\]]������I�u����N�/��"[�ne��UDGG3d�������tm�O�f��=���/�5ns�����O?��������
�x�	/^L�6mn��Y���{�>}

%77�I�&	cAz��'O�`0��i�0�1o�<�j��F���Z���RDx���\�x��D���),,d��q���bkk�SO=�B�`��1h4*++Q���F��Chh(555L�4	�R������&$$��s�������?z��R���������������n�����R	[i�����)B�R���������R\������������rF�N
b�*�=ee%)))DEE���Bee%&�	///����#�<�J����P�$(eeeNGGG~��BBB

�E�l�����T����������!22R�H�h��9			l�����x��Gtt4'N� 33�~���va0pww���T��&������#�v�����'�x��SZ�������O������$**
�!C����@�=��q#6l�����#Gr��Q�����?�� ��at�����r�J6o����������|Vg�U��@�R���_�n�:|}}ILL����<��3����f��z�-���d2����Z�&66��{���Rv����9s�gW������r�Jbcc�JmhCX��|}}i���T�#���};999<���l��I�44�r��q�u�vS/h^^d�������m��	Xj}����C�2}�t.\������VWW[�����y����������?���|��Gu� ��<y2]�ve����t:���{^{�5���{&M�D@@���DGGo��h$<<���/��������^�z1r�H�{�=�^��O?���/�����|OF�GGGf���`*Fc���b����3r�H
���_x�����t���SXXh���/����h~��wBCCY�h�����n��m��U��_�B��0s�L�����hV���(�AAAY�u���I��y������o���������w�im��o"�p��m�<y���G�JJ�R���R�>�<����N�ZQQYYY\�v�k�����i�B����N�������*���-��:  @�����D���1�����������u��������F�P0s�L���(++c���TWW����Z���W_����e��������
'N�����?l�0����j��t:�,Y��` &&�F�������&::���(�����s���U*111�?���*Z�n���������c4�����
�B��I�d�
�����O
���1����ccccQVq���}y��TWW3`����������TWW�������s[�|9+V� 88��K���K�ke���]wD� IDATH����[����t��������LF�v�0��Quqq!==��(**�e�����T*=z4,�m��t��@��4������(�L&.^�H������W^i���={63f�`��]u���Y���o�����a��Y��7����z�d�\N�V����l�����2�u�F�6mn
�W(=z�.'i�P*��L&�sww�`����������4�r9����a����Z��������[:l$�������X�l_}������?���p��	��isO����������������g���M;��&�����~���Q�T����<���(
���'z�y�
��Oz��q����a�4h��'�����'}���)J�������.�����~���O�y���ooo�5k&�)��Y�f��j�v��1�|'��a�6J����m�_��0	9i�_r��)�.&����dcc��`@�T�����h����N��B���N�ry������c\KU�{��kF���$J�����:�m�v���\.���~0������6����^}�U
+V�`�����Q�����RUU���'����?���2���D��h4RQQ!JXIya�[���j�$jgg������Jnn.AAA?~wwwZ�l�h' ��������d2���HKKC���~�z^|��F)�{���������dee��O�z������BR/^�(Hm$B��)���dee�������������Kf�����k��q#UUU��rq�������l����<'������*JJJHKKkt�� e��Iyk������P�����
ErVZ��yo�=�&�������J��So}��-���u�V�z�-JKKy����6m���Z����4T��)�oL;�8����������RSSIKK���k�HOO'//OT>�h4���������?����~~~�������t�<l����o�y���2d� �����������9���z�z����"Us���_X�`��]���_g�������d�{�0t��AL^���t��I��������\�|���h������
���`08p��������={���Ea�VTT��g�����
o�������!1������\�z���J����y�1�K2z�h��]�;��CXXX��^���8q"����k�;::��E
!!!��f���k��)���,[���]��)���+�J~��Wbcc�>}:�������R)�gq�����k��M�61~�xbcc�����?��:t@�V#�����7�v��c�������o_��KTT���#==�>}�������-[��}{�n�Jhh�(�d��&Y�LFyy9�������w���G�>��L�4	�F��/�Lvv6��M������V����;��aUUUL�:����������8�P4�$y�Kff&iiidggSTTdQ����[[[pss������(���?��5���oo�F� Y��;���&9���.M&����V���:��g�������Y�z5W�^���������TX�*��_��dJOOg����[���q������O���V�$!���������_�P`cc#>�FT*��~1h)�J�
�������J@�$]	�me���8y�$s���s����dff&K�.5W+�����j.\�@`` Z��N����!99�Gy���ddd0�|:u���)Sn�(��c_|��'Of���uXX���{�\w�����~����-*4�i�__��nR��JMQB�z=/���/~(��j?�m�n������${��!V�^M\\�G�f��5��7OT��N���w��A^x��������/�!S�}�����X6m���={pwwg����?^��Z����7�>''���\�������KNN999�'!���E=wwww�������;nnn�"����?Orss7n���_ZZJFF�C����Y3�%p?���3y��'oj#�O�O~~>�}�_}��5�g�yF���q�*wKn���������j^�F���}����k�K*�d���'�F��s��
��W���7���x8J%;w�������6;;;\]]���|v�����9s�4H@��y�`��=��c�=FVVz��+V`cc�O<qW����]4��d�g���Oddd�$V�	���K\�z�n��5y���dp���t�������fAAs�������;�w�}���+�������_����Ov����	=z4�6m�����n�[-]�����N�:��[o����
"8k~�����F���W����LRR���������Caa!666�T�D��c�=���'Z��bqpp@����k���!555��(�T��pUUU�M;0xzzZ�]0���l���|���888���/��woA�j5����8�fQS;K�������s�L&�������mw �\����o�����Z�hq[������o���w��5������eOYD��B�Z�QE-�F��|��|�J�VKUK�TQ-J��v��$�"	���I����w��������x����s������u��Vl�B������%k4���w
�N�����))))\�z�i���m������nmm���kqrr���Oz��5"66���RF�����D��S�:t(^^^�����M�����F��c������pWEz��}0�a���a�-�7--�)S�A�>}��cM�4����������$._�L||<			������Lii������������4i��f��aee�\.GOOO��Qr���V�#�����@"�H���(������dm:W2�����s��)5j������)�����{���T*��_�2��z�>�i�������>����9s���W/5jt�-��?t���L����?gT��T�����Q&�u�����~�	���_�U7��:u!�EhC��Y�~���T*C\�c�c�
��
��o���R)l���)S��Z?v�����%�����:233�����>}�=����CNj�p���G�sl��	�����A�����g���g�1u�T���#_5����/@(k;;;�l�B������O���/)**b����Y����;s��Y1�ND���������jn����K����%66���/���(��m��)������???�5k����#M���~��a�?5��u����g���7R�1������wckkK��mEm�j�///|||���+C�������QsE���v��n��������ODA��L%'c��M�;����Z��s�.������rV�\�Z�f��y$&&�b��jj��P@ee%���;S�N�����s�2~�x-;O�w���r�\���4��+��:<�@��h�����x�"������[H�RJJJ��aUUU>����l�Bqq1�Z��C�DDD����F�a������r��1���(//g��a�����pttd��A����u�V|||���;�������S�N�n�Z�������?�s����XZZAYY����U�VL�:���<N�:���1��������c�>4��_~����z3t�P���9p��������144���?��+V���Chhh��9��7n0v�X����bT�*��������O������'::��-[r��1�LgX�?��:
eee��������IHH %%���RSSQ*�XXX���E@@={�$  ��������DFFr��9T*�G��������SXXH`` >>>\�x�}��������;fff������*���	��yTVVr��y���077�s��q��iJKKi��
�7&==�S�N!�J	

����-[�p��9:Dpp0&&&>|+++���i��a��������m*""GGG>��C^�u������S��~L(���os��,X@^^�'O�?��O�����?F(
RSS�	�$P��XYY�YL]}5~�;F���{���a��DEEq��)������w��L�4���>��s�����a�6l���XZZ2y�d����-[x��ILLd��?~���G3�|�n���e�0`����<ySSS���011�y��XZZ��u�{\����qww�s��4k�����3g�����4i�f�����\N��m�|�2'N���?�����w�}`����s��Y�/_��e�X�x1�f���aooOqq1NNN���www�j5fff�j����pZ�l�@M��m?��mc���p������Y���
��,**���l��ggg8���+;vl��[��<�G�Pp��mqKOO���kdddPTTDaa!
�{{{\\\h�����OO�Nt!s:<��lbbB`` EEE�1�F���G������^c���|���q��yBBBh��1���'??�������bgg'���2����(���5j�����y�3g�`mmM���1c?��3{��E"����BZZ������������o_


���
�����y�h�����srr����������q��:v�HHH;w����A�K�^����;��i*��7�|�q��abb�������}��Tw���d�[���N�{��d����n��hDRA� �GP��_Cj�C�Vs��N�>�Z����_����R�o�����5�{�np�M"�PQQ��'������q�S}.�}�����/��M������\.f�8{�,/��2��'���dggSXX��M�())3a���PYYI�>}>|8���$''�k�.|}})**�O�>,Y��J��i�P�TZ��kDj�Zt�?|�0������������K��}��)-�~AXY		a��y�;�?�����B!��Q�F�����?�jB4w�\����8q"������/�@bb"�������D�`����^^^�����];^x���>��)S���/?��_}�7n�"��X���z(���_X<w���������z[�@#���������+������Baa!FFF���`ee���7-[����	'''qppx,�A7���Y�9��R�J�����LFFF���xxx���'����*�
ccc
UUU����c������-��|��������-Z������7�������s��������p�����R����?J������n#����
��^�����������4���-!!�~�������|��/�,�;��pt�S�A�cjj*����9s���������K����#$$�^�Jpp�����������#G����m��H$����q��Z�z K�PQQ���_��]��;g��)����h�"�� 	�TJQQ���.J��B�����f``���������9����{+++����},--�*6�.'���l��Y�C���"�%h������������
���8p�i��q��iq?�D���1������#��qss��_�]�vQPP@xx8�{�f���(�J����{S�T�����(
����T*166����?�����0���D�+A��~�����L<<<���/���m��'�*�
}}}���d2Qc�q�N��,
��X�r%]�v��zk���>}�`bb"�����3�LMMQ*�;v�M�61u�Tlllh��=x{{������O���Y�v-o��V��U"�����]����U?��u�HNN���?���J�������'��{��>���>iii���1k������������3���_�<y���8���ppp�i��b�s�&M�����MLL�{��+ct�;!��(//���
ccc�4iB\\M�6���M����j�����d����������H����#�����������R�J��������W���d������RSS144�y���T*�_����-�������"�J����
�j5r��5k�`ooO��]��x�v_QQ��q��8|�0���������W�

�ko���
�����;���}{�.]J``������Po	�\��+W8r���O����C�q��5^{�5�M���o���}����������E���/<==�r�
%%%t������n�J��m���
###������������K�0Z��m����P��������UUU���O~~�����P|-((���[�{aAHF�l%	FFFXYYamm���5�57�s���<�Oo~��h���<x�q�������!C8y�$���t�������];V�X��3h��9��������x_YY'N���_$99��s����@xx8������1{�l7nL�����?IIIxyyaiiI�6m�5k-Z��C��\c��M��i����_���#GbooO�f�h�����L�2///�����a��+W���uk:�����s���q�����Cjj*�/f��
�[��B�L&�����O?all���G���DOO��2r�H-��-���L�t��\.�����d<h�?l�0&L�@�t��������3u�T���Klmm��sss�����3x����[����<�N����77���<
4H�q}R�S�R�h�">���r��*�?m`�6�/..����DFF��@���i��=#G��]�v���T*7�d_��?�M�V�i���n�b��]����o��L��#G�<y�H�����c�����E��=)--%11��^{
}}}6o�L^^C�a�������ZeB�sss6n�Hhh(4n�����s�������V�	���C��������-��uc������ ��h��1u �H�x�";v�����/K�.e��������o_q�n��������~��u�����������ccc>��S�����������c��������}��o�>Z�l�����1tx.��F�����1g�~���x������k5`�����e7n����>B"��l�2|||x���Y�l�����yn������Oll,����_�~����T*E.�?0��Z��e��"�V��;w��u�V����_|���
����������?��U���*����9spqqy��UTT�����;w�s���������k{_PP@UUj��J�Z����P$���5���@u������N�����Y�~=3g�s�?n=+--�jOR����t����#ccc��_OBB��:PWL###>|8m��e��-�l�7z�h�O����7%%%O������T*������,>��~��G1gv�2�������/'N��X111���/,Z��m��q��M���Q(����w�^q�,;;��C�������G9}�4;v$88�����6m��P(����������P(����),,�W�^����|�r��k����������8>������o�����%eee�1+++8@tt4�������]�v1j�(~��W���9�<�����������#�=����J
�:u���H�;FBB�����KBCCy��t�Y��c��e��UZ�JNN����
���H�R1�U�\]XO"��a�B�l��B���Up��Y��;��2����h'�T*���x���	���p
B���T*	����������O��.R
�/X���#Gj���KrS m>��3v��E�^����/E�W7���y�SY��Ih�&&&����R����#  ���Ocmm���7E7fkkkZ�h���+IKK���_������,�4iRg�#�+*++Y�t)s��`��-xyy��}��q�����Z���������D�zII���Au"A��RTTT�P(������}}}LLL066]RM!LA 
���044�����[�	�T*��������Tv��!�����3`���.���t1V^�\]]),,������R1��Y��h(**b���|��WL�0��3g>���z�jF��������1c��wo���?���>���r��54
���L�8�%K������W��9�����Q�Faddt�8f�-X�j,�U�V��=���|||���7�:ub��1��}�:JNN�-"""�w�y[[[�R)�W�f���q��������4i���|�����?�J���'5j����W�^DFF�j�*�����7���7yyy���q��A$	�~�)��7�}�����sssz����m����%,�s�� IDAT,�#F���N�~��i��R��u����$$$p��q�\���7077'((�?����|}}y��C��erW��.�'�O�7����������N���������� ��>����*-�,���k���s�E�s���,����~�c=��B�E]�3�12339{�,�W�&::���;s�����	��� 	�F���R�

%::����[[[:v�Hrr2>>>���q��LLL8s�yyy����4i�DlH�w�f��)�$|R�!�Ji�����'//������M�����?�������P� 055�����<***())������b���E���"�}aa!������P\\,��W�V_ 2�A�������B�j5QQQann.n��<<<������b�|��{~�t����=S��=�={�y������?� �>�>����3Fk_�\|�/�cooOVVV��z��Q]4T����/�e�����v-����-[�����#k�<w�J�H�	FcUU��m h`������s��-����`z����S�HLLDOO���w!����b�m����������F���!*����;���FFFDFFRTT�D"Et�����=R����SVV�L����
bbb8�<���\�v
�B�����7g��q�j�
??���A�q�aL�Vo
7o������~S�rJ"�����o�����������������K��}�
���0����x���r�~�:����
y�z������[�������^�z��_����#5uh�@UU��$�
5n�sss


h������1B4�:w��R��]�vdff"��qpp@�V�����#Du��===�{�=������
��];��u�<qP�744�����=37���
***(//��������\qKMM������r
G�������J���166���kkk1�Y�������_�9<�`����l��������J�����?�H������oD��Q�}��Q:v����.t�	]�v�G�\�v
sss��['N0kb��),Z���>r�HV�ZEfff�%���7�x�-[����j�kii����	�o��Zad���L&COOOkuJOOO�\�������_�q��|����H��<��b�BpuL!�fu���*)..����7o���@uqAlT��	�>��w�l�m�FTTeeex{{D���������E$K�������5���yWW���k\\����������y�f�����\GGGf������W_}�E�,�m�p�7B�R������KA(�y��O� Qs����,_����H���=z4���xxx��?:���!EYu#A�Raaa�5�W7����Q���d2������������?���S�ku(�9���=��SCFmo24g��I�C��B�>B�^��@5�WTT���)n������q��5N�8ANN�������j�&&&899������+...�������3FFF�$���L�v���y�d26l�}��b����mrr2!!!���yzz"����q#d���|��g�5
CCCV�^Mee%�����?�����]�v������9���:w��a��������#66��z(�Hx��WX�f
{��a��aZ�]�t���,��]���7n������}�C�!���}�6.\�������a�����~���C�%**
�3,�����Z���#GbkkK��-���'22<==9t�]�v%**���RF�Mnn.��=YYY����b?�c��j5���c������������GIHH������j
�T��������j�*6o��J��S�NL�:���1���V�n��~���3~N�6�
6<��AAA<x���������=��/��GDDH@@@��������+��t�R�N����>���������<���nDD
�B+d�I���'O2s�LN�8A���Y�f
�������f���thP����j��Q\�������8(]'���j^^�f��!���;��}�7�|�>}���s�����=�u])f?���x��)��(�=*�������HOO'--M|��i���������r9���Z����nnn�������vP�*����I���$##���'�m�6�N���3000�����PZZJAAA�h���QUUEee%�W�f��U�T*:D�8z�(,X����J<<<h��	�6m��w�E&���/���� ���www�����3�����*��eK�:��op���;����_��9���c�����
�\�J��w����v��w����W_�g���]QCkkkF�I``���@0���[�wW�\��^O�8�X�Z�xiA�v��u,_����D�u���+����#	�����o�|��G��rJKK4h...�����h���O���b��������g3f�����������g��U8p���'��G�4i�������$++�Y�fajjJaa!��=����������S1y�d���/���X�p!]�v%44���B���X�r%����={���h~��G�R)��-�C�,^��\������2d����c�
p7SEff&��M��O>y�B
�,z��V�Y�h�����5��6HmH*���G�2c����>|8W�^������D �J����G�����u���3�<jY_�t	;;;���D�n���t���Z���7��};m����8v�AAA���=���z=������8P=h�t��-n��Ezz:���dddp��u"##�����������
/ptt�ccc��������,��x�����$55��K��n�:��o�������B�T��uk�L����5�-�����}�bbb"�C�HxVR����222�t�����'�p��q����1c��e��{���Bnn.����y��O�uC�{Z=�Gi��O~~>W�\a������{{{�y��~�m-!R��Z��������e��u\�t��k��d�1����|������"���3giiil������3�|��Y������������X�x1������L�:�
60t�P������������_f��������W_aggG�~�h��aaaDEE��o_��%K��m�'O�c��"IVUU���h4�8q���^���OUUJ����****h��:t���?������1�O�zzz������JTT���#44���Y������e����X����T�
������J�J��
@OO{{�����h4Z��:4LTw;-**������|:t���;wHII�-Z�n�:\]]y��wP�T���������(�J�j5M�4a������p��������>m����o�%,,�=z`nn^�������`�f���oYYYYYdeeq��m233�}�6�o�����������B�J%&&&bfccc���pvv����F�aii������������c���4o����BCC��(j�000����bl?�����7o��_�R���d"!#��q�
9�U�H$�Z���;2i�$�/_�T*��	�F�!$$�����z�<�}
y�����O�g;v��s����B�����?���S�����m�HNNc����X�wk
�
b����<xccc���������3##���`���HIIA�Tjy�(�J�J�h�VW�wss#))I��^����?j�Z���$���
�f/^���;�����?7nd��5��oAAeee�6�������O�U��
��D"������O�g�������C�������|��:�k���Jn���H������T*yF�Vccc������|���#���0~�x���/���	��#G���������h�r�
���|��b]LII����f��e6����Jt�����������|\����-���P*�PPP �O�*������ILLeee(
QQ"���Q#lllptt�
Apuu%''����s��QZ�j���ki���n �iii����_�����T*��e�������b�
^{�5�;Fqq1			(
RRR�kA��$�����};��u����/��R� ������-�z�z��*�Hpttd��A����]�f
���g��A|��wZ*���'BBBx���HJJB&�aff�D"=��1������r���i��m����W_E�VS^^^��s��-9{�,�
���#������rq���Jd2r�\�F�3O�<I�^�X�f
��O'99Y+m_M�����js���Y__���lRSS��z�����+quuE����q:<�x�g��}vv6����m#++���[3g��v����U�,�A�P3?���[�n���M��-�������077W�
zzzDFF������5W+�p��u��7u�NNN�����m[����7o#G�����������������b����H��m�x��hH$lll���C�R���~���S��i��k����nr�e$������of���J�E��VPP��7HMM%33����SPP@vv6eeeb:(WWW�r9��]C�T�������c�;�u~��
��g�~������������v�x�blll�s�
��_~����Rv�������D�Y�fl���>}�����{��Wg$���sy���?���Y�f�h�"���Pg��{��i�����022b��	�Z���~�	|||(++c��%���O8�i���q�F

y����v�]�v%..N+%d����h4,]����K6l�@�.]8z�(�;w&::���x
D^^���l���S�N1{�l:t�@NN��e��������G�=8s�J��#FEaa!�����W]\6<<���*�
���f�,,,��U���������������};���>���{���"����?��@m
I*��|�P�m�����iEE��{�����p��1bR����p�5k����8�\m�l}n��������#G�+�K�,c�,X���_�5���$%%^�]���Y	bT�D������g����[o���I���������ZW��c����v�Zbcc�������q�P�A��:,�y�TJff&3g�����t�����GSRR��k�HLL����$%%���...��U+	������?��#������Em��*��[�n�mG�B� ##C�\\\��r�?�h�����6oooz����1���6&&�Q�F�t�R��`�[��~������;��/�
&����� ��9r$*�J�
D�� ��qqq�s��b?dii	��x4x�`�R��a���T*���^�`�N�����������,�/
8PL���+� ����������uk�R)����k���V������X���k����O���Y�f
!!!��M��Y#�
��F���By<x����s��:u����i��
���Z���E t@-{xx8c��A"�p��Y�����&((H�w��Iqq�8P\�~��7�V�������H$��{7/��M�6%!!���L���� 66JJJ������k,X����R�z�-f������g�f����]��>��_9y\������cC�e���4j����l1������<����W=�������>����{OOO���"==www���u=�3�TUUq��m/^��?����?QQQt���������������q��E���O���OEE���������G�f��������f��q���l�B�n�������z����>=M�#Lpf�������g��p�P�������w��;������������14�������Yz��HMM��8i�;T��������^��?�P<���Wyyy�m�6Z�n���T�:�'��mX�#m��=�^��c����U+����5l��???q1B7)�_6� ��m�6���k���	#>>��M�>�������!���;��������T*QQQt����G���3X�p!j�������E

����V�Whh(3g�d��m���� ;������ ��]�r._�L�����#�/_����>-WM�����#G���I,,,������Bt����r9YYYl���A���U+Z�n��]�(((`��������G�w�^���h��&&&�����eKRSS���B*����@��-����C�l���I�&�����8p�999
Z
����A5++�����q�F<H�-��c]�v��@.|vpp���A���ABBqqq�����~~��W���Q(b���������NFFF����7���
Z��H��5��z9i�$�^���a���s'���
���~O%%%������`������aa!III$&&���ARR���]<�ppp�����������.k4X�d�]�F����Z+u�������DGG��~��9���)�z�b��������F#�,�&��g��h4��y���x~��w�=���9���c��q������+[t�c2�6m"))���
z��Eee���%��HJJ�E��������Z�F�R�+�oUU������PVV�R��m��t��A\%o������'==���"�����'==������>=�B�W_}���r�===lmm������
WWW������ 33###F�-�6���+`��!Z9�[�n
�u��
�;wGGGF���LOb�?O��M8���K�����{�RRRB�����e���YY��	�����3���Z$@AA���L�0A$U*,�������>����~��;(��888�J�5$�B0�R)K�,a�������}�v1���������[���;�q��{~�'''������Opp0�����������������qvv�:���������I���7������3�={V����o�|�K/�T���.�E����n��c��q��N�>�J����^b����..��W���Z?�K����o������{���������n������������4���%%%�y���P�TZ����'�q�}��iP
�zg%�Q���s��)&N���5k���sDDD0g�~��y���3P��XZZ2{�l���#''���T�^��������%77�\.����'�n�ooo���D����8�'��p��s�+�u�D����5zl����-[��������g���������������KKK���<x0VVVxxx`oo���=+W��U��������gb�d�GV�'a``�������o�@�~�zz��EXX���zM�F�����,^��������{��}VV��/��7��E�:K��i������{�n����'�|������{��E���Odd$���X[[��ys��������Z��.�e�����}����p��	

y����>}:-[�����M�u��@&�aii���!�H

���___,,,055��~@�Vcdd����y�������������sss*++�����o����t������chh�L&�o��(


�|���P�������	&������o_^x��.]���7o��6����.\HXXhP����Rt��Nj�
����
����|�2��]#..�����d���%~~~4o�����@@@�s�bY���J����7o��%***��R�������g��)��^s�QTT�7�|���+�h46������%��������e������i��:;;cbbr�s��5I$JJJHKK�����5����~}?��#C���������i�H�a���K��=���
III���u�r���5
DDD��cG&N����+�4=�?5)JNN��o����O��o�!�������SY�p!vvv;v���/�,��VVV���kkk��o����
6lX��h���KJJ��g;v����C���L��=�;w.�������Cf�&���<���T���?��5k��s'
��~����7������-�+ktx`cc�P�N ���|��{��9qU�T���0f���*��������Cii)M�4��A��:K___|}}��wss�c��Z]��=E��!1�r�FC IDAT[[�{bH�R)�����u�������]���W�Cll,����������`mmM@@�H4o�???-B�� �8����W"�p��I.\���N@@�3=�_�E�~�X�t)�}F������x�b6m����'s��e��!�V�>��YOO�Vq�G�z��d2._�Lll,~~~Z'�����K����w<�����R�d���i����qB��0a)))����y�f���D�z<(mS�c?+�H��`cc���;			����f����5	P�V�R�$**�/�����H^z�%�.]����.z���
�������;�����l�������,����5�m��"�:d�f��EII��\�&��	I�X>~�8������C�����Q#�u����y��W�!���~��~~��1�FCII	qqq�������������}C��T/��'O�~�z6m�$
�~��w���O�Z�0tx����1vvv�������L��Gq�n�
�Q���>�>���`oo�@��M������}���r�
�/_����<x���l***����q��������N��M������
CCC�W}}�����Se"����C9r��[�>���p�!!!���0|�p>��#����������C�X�z5			t�����H���I^�� �H������#dff����wo6n�H����e��a�Z��E�accC||<�&M�������cgg���>aaa���?���K�n�����[�pVV2����2�|�M���(,,���>���������[7JJJ�?>�����w���G1mW�c�����;w�T*	d��	,\����Ln�����sqww����%K�p��E�������3)'�F���'k��a��Q4i��W^y��&�.����OZZ����o'++����?h)^?�����b��q��=�i����s===�����%���P��i����������<�_�����?7�����J%������Q^^NNN����;w��/���(jR��������V{����_3�������iXXX��n�T*����ddd��[7�v�*��>�VP�����������.\����;9|�0%%%����|���0@�����������xxxp��%����� ��<@H9�C�4J.]������x<��\��4h��{UU���������Brr2			9rD�077�������������F�ammM�F������������eX���r��%����<s#��
������i��������������/caa��A�x��7�&g���n����H�V�HKKc���(
\\\���$++�~��`jjJ�.]pqq������amm��X�b�����o_LLL�=���	�����7�������E�GOO777E��W_EOO���{�'Nh�����G�2b���o���c��a����={�U�V�y�f�M�����&M",,����gBT��/��23f���������v���������7n���'9v����1e� ��G!Y���h��m��<]�z������cGbbb���	���)))������~???>��3���4h;v��������z��P"�`eeEQQ�?R���+
rrr�-33�k��q��u������C�P������/'N�U�VZB���Im�|��u~��7������9�o�����������$���"J�l#���$%%q��YbccIOOG__��m��l�2�v����R[h�:���@��-	'##ggg������s��G���a*�����HII����X��9���j
)Q��������Mvv6YYYdee���ATTEEE(

������bkk���������������b:�gAT�oee%g�����^���Rd�O�:��C������P*��o�^K)���|��g��u���r�u���	h��M�q�����\����B�p��iN�>�����������TYY�k�cc���\����r�OOOn��������SRRBPP^^^XYY���/���ALL-[�������L&�g
!g���w�#��������u�!C��{�n�v���Mrr2G����#���bllL�&M9r$����'���<����:�G�)(
�o�Nnn.���*�:u�G�����n���j�*$	��5C�T��Eqq1AAA�T*��9s��sP*�����;w�����$���IOO'//===

122����v�����*n���Ol�[����T�n������H��3P"���_?��k�O?��Z��C��u�����|�2����={���/SZZ���������kb8�0���txF���5}����/�`��yXZZbhh�����)��D���I������_���bmm��L�4pI�RQ	�&1PVVFii��������Arr27o�����������,rss122���WWW����L�fhh����F�1���1}���������5K+�Q��!�����J���S����x�����wo:t���uyu��Z���;{��e���������s��A���077����BAdd$������������������t"""����K�.�<���;;;lllHHH`���=z�;v���C�-���b����k��B!z��x�b^{�5d2111|��7�����S':u������q#��9�������L�6���tf���F������K�b``��V����]~��������W/�;��B����={������CZZ���t���1c���q�{�6>��MII��Z\�a``��o�M�6m��c���8;;��ukBCC9x� 111���RUU��k���q�111$''W�	!<D�T>�x��L�SRR������K���O~~>�777���pww�C�x{{caa������O�E7���?!!!Z����@;;;����5kD��~������8s����x{{���������[[�{����P� 4.f������1bD�S������n�������+���?5�?
1`jjz�X�F�A�V��)
�~�:��_'11��~����$�����d����������A���yO�MuL�2����-[F�f���j>Cab� W��m�����;q������d���np�?�J%���,Z��LFUU���H�R���+zs��MF�%A��M��jx����J�K�qq1��/G�Vchh��u�����_~�E$��U����#�H�����m=�r9~~~t���F���R��i���T*�H$�R�033��>@�P�-+�	 �J���o�0�#G�`eeU�}Xm��s�;w�$""�C�Q\\L���>|8���
������:7�R������~��_�����={��k��������*�#�T�u�R��;w�PQQ��x?>���I������[�<y�S�Nq��	.^�Hyy��~/00�W^y��� ����6.���J��}��;��"--���o�����B&L���k�������Q#>��sZ�n�F������;�c��x�
q���d:$�e�s�...t���/����;bnn.�c*c]����3"�3z������Z�����C������	(������(����QQ���RT@@�  Ez	�$H'}��L������@���}]s�dg���Zk��YOa���|��7<���a4��tRmI�vvv�T*222���7�W����I�P(j��[�V���h��-m���s�)�3�={���4:��+����h4b�XpwwM���D��'N���������9s&UUU�]��������7��5��j����
*�
��$n�3gk��a���W�-�X,����r���_�����J����*<�������t��BD��hD�K]��4�b5]<�J�Y�TS�r���\�.�\�+k�����p����Jrr2={�d���,Z�GG�R\�*F�{&����b����������������z�b���������?,��o!������L~~>...��������T*F������`x(��jm�d2a41�����q��Av�����9|�0EEE���K����6mm��������#��[nyyyb}�k2�8v�'O����j��V{����E��9���p��)f��%*�JJJ����[�n��;�=z�iEo�=HHH�!@�AW�X�?����S^^NVV�]	6%��4*�R��{�IpC�z��V�����j����.\� ~�������������*�]�z5�W��k�������/L�j����m��]�D!�o��xxx�R�X�h������[[[�V�5-***����K���������i�����bccsU���	Y���l�e���i�����j������'��{9�����S�Na�X�Y�S*�,[����{3c��}��ZiK�6��i�SZZJII	%%%dggs��N�<��3g�x�"NNN�����/��K�Z��/?�4i�>���������1xyy��k�����o�a���[��Y��t�f���^z����������(,,$77�p��1������������Hx��i���U]r��$���Bzz���{�%�@||<�w��b��3g2u��k�{�5���������������T��?O�n�x���i���n��e���}���!�����@TT�TS�,LH�<W(B<<<����e��u�uss������(���i��	J�����F���_�u��l��&N����~JXX�����#,[���{�^w������C����r����l,X@ff&t���������A�6m��G�P�����0�L�����:��&}�c��W��P���,]��!C������o�]�d����������p����'==������0(�J���	g��A4k��V�>I��}~���+����Ou�g�����[�l�Y���~eff�������9�<iiidee����Z���u"##�����J���{�999���_���]�j=777���)..�U�Y�f����g�T*�<�#G���-9��`0��M���+\]]�1LB�!*��[�NL�%n�._�9s�������888����_|qK��������>}:����l��
6��_]��z����Y��A��4����p��)N�:�W_}���=			W��������0N(o�<�up�g��E��]���>�L&c���������Nzz:g��!//���Rpww�������������zxxH���]A�R�T*9s�;w���?�$%%���b����A�DW4//�m�=�a�����n,��]Y%eRRs��`���QRR�W_}��O?�Z��h4RPPp���KKK�PHc��DSHHH�;%��q��Xi�����K�zf����<��c������������9#�5�h4��}���a��i2��w
���\�x�1c����#F�`��	�]�������=�
�F�����r�f���2F�Q\=w�b<���O���o��W_������AAA�����iS���qpp@����j�h4
:���6)q�TWW_��U(������(233	�}��<��s������Zm�q<�6z7����{���V���{�r��)�����n���r�������yxx��/^��i����!??�#G�4X%�������h0/�[}��������3fPPP���i����m��),_�������'�����U���{�1JJJ�� ��pss����A���h�c������$%%���v��Q����luM*�7������z�����Y���[s_�5�,�P(n���F�l��E.�_qM�=����z=���������Kvv6���������#�������J�|}}	&44�A�1u�T***�8q"�q���7#�4�I��n(��06���]\\�l�c��a������>~�8�'Of����YyM��A���K^x��z�/�W�LFaa!&L`��	<��#W�����_///^��:���3g��������-�������k�5kaaa<�������t��A��%�������hp��o����9|�p�mu	�/^�����g����{*���,
���S@@������� ��t:d2����d2��;�����9s���)//G�P`gg'�fV(TVV��jQ�T<x�]�v��SO�����`S����cooOuu�WA�X�o�������\��l����F#����z�z=666��c�����1C\�6�L����vy�����d�����\����?����5�?|�0�Z����Lz;�{��<��R^^NYY�����(
�j5*�
������������[������7~~~�������f��2e
�������A
�7B�f�n��A�d2�����(���x������S�L���t:�z=���h4��Opp0����2�j5�'''�V+eee���b�X������B��R�D�����ppp�b���O?���H�n�0b_{�������K�Uwtt�����;��3g���1S���
���8::�P(X�~=���<�����G��������r�Z��)�Z�kRRR���=Z����J�r9����V��Z�<��s�h�"��k@YYr�RRR�I�������������~��j�"�����i0����fV�SSS9y�$f��-Z��I���KFF)))4k���~�
�BAuu5�������g�JKK�h4DGGckk���{���c��������[����@���y���y���X�~=Z����<1S�����'9u�~~~4o��
6�V�1���m��F��-[prr�����}�r��E��?��}����&44���4�?Nbb�m������]�v���]�Laa!~~~bZA�L�^�����(�zk�666DEE��jqrr���GGGqrr����:��oD����#�����W^������;?���z�����z�/��DP����F�����+ d��S�;��jVM�S ���B��-���c��Mh�Z�J%�{�&''���|||����������t���������V�%((��bkk�F��_�~�X�"""X�t)��u������~�7�|���7�T*qpp����e��a�X���'!!�5k�p��Y���OVVr�&M�����n�JDD�z����3\�p��7��
P�T�|��{l�f��m��1q�D���	 00ooo�?Nll�5�9j�(�\.���������Q�1bg����O>�k��4o��=z�X�$''q]���VBBBRHHH���@.��i�~'sU9�t:����o��������s��y:w�,N�y�~��w�t�Bee%f�'''N�8AJJ
qqq���r��f����lF�����
}���d2������+*�J��HMM�w������s�N��Z+�F������@^^G�e�����3��k���o���m[~��W&M��\.�`0��U+��
���$N�o���j�����BX]�Rd
���[[[7n|EZ�[|:t���o�y[��Q	��������2a��-[F�V�8%�`�R�.���$''����N��YW��u�P(0�X,��l6�*/;����|����o����W�^����|����m[��iii��m[���3k��+\tn����=zxx�����``��)L�2�N�:��������bkk��#GHJJ����F���?k��!>>��Hvv6��
c��IL�:���;3b��f3��=s�����'''�6mJ���i��9?���f�"11��+Wr�����/���[6n�HFFJ�����J%]�ve���l���'�x�_~����S\\���sILL�Y�fxzz��>�����HJJ���#88Xt�'A���Fvv6/^����������<1�-�V�%11�
���l����m����~���+�8p�\[�P*����@BB�'g���4o����w/*�BPPP��f��fbbbjm+++#''���j�8�����c���mKPPF���*��;z�(��w�i��l��I��	�� ��F�Q�
E-����{{{����x��B��� IDATD�\��

�`0��I���{Q*�������FTTS�N%%%�S�N%�_��V+���QYYY/�QM��:*9���X�V�����������F������l�3f������?��m#""BJ�z4
?��3.����-Z���OPP666dggc2������f������Z����\���KLLAAAX,.\��^�'$$��f'1��_�GGGz�����~��~�^�g�������L&#//���WG�-8v���|��W���c��y�;��������#G�����l���^����/�z=���\�p�B�#�<R/�Mx��T*:$*z����������c��T*��I���T*	

%((���|������G	#&&�1c�������K^~�e,�`R�P�)��/_�Z�f��}�5"��j�h�����N|�BY��@^^�x��m�r�����������/fIKK��������F�������;���<��3L�<���tt:�=��������_�]JBBBRHHH�j����(�m�FLLX�V���i����kNb>��3�{��kNl�V+�v��l6Mvvv��WTT`gg���8q"7n�%�_~,�ZMYY��V+���\])))!??���:t�p�Y��d�s��l���V���G����W�������O��iS��=���+y��WIII�������J%������akk�����w/III���f;�)|��r���(--�����=�~�)666l���q��5H%� 4}���TVV��cG���Khh���������{��G��}�X,�_����jZ�h����4h�6m������p�z�-^{�5V�X���?�g�}����i��	G�%77����;�� $$���t��;'X}���0a?�����$&&��{w�n��������#i��-!!!���'��5�����IKK����f��A�X�����J�b��q������?f����Z�
�BQg��[�l6AFFaaa�A �s�\^�:��`q���t����-[PTTD`` C�����7�x������N���1.M��q��5�A���/��h4xzz����;Vg������*++#55ULC���������)������I�&4i����8���	����B�N����'''�%K���uk1v�������W���S������RII	F�QRHHH
		�;!�FFF�������>|x-�;��ba���t�����?��\.�[�nl�������?�\.����#F�y�f:w������-[���3���dgg#�\�?����u����_��!C���O�o�Nuu5/��"z���=K�V�������d2��[o�~�z�f3�������~��+WM�6m��d$&&���?��c���eK����5k6l�c��������M�v�n�tS&�q��!~��W�z�-����c�=���73f������j�*�O����3������:}��;y�i����_R]]�#�<��
h���4p]G�)|�t:Q�Mzz:���,[���-[��C���SVV����qss�j���_F�~���wzl���DEE���*
D��-#,,�����s�Nqwwg���<����5����n����C����N\\K�,������0�6m��#����qqq!((���8����zUTTT�x�b^�u0��<��s|�����������C����Mee%$33���d��?>/��2�����m����a��(
<==Y�h:�'''V�ZE�^�HII��������e���OXX�&!!��'���GIKKc�������a����(--%//����������G2ds��e���4j��>}���{L���X,���b�����g�r��q_X����@�T���Jdd$t�����������:�J����>�I�&���zxx`oo��������������(�
�$RP�����h����			I !!q�J��C��d��������H�F�ptt�b����k�U���RrrrHNN�w�������y�[�V�Z-�
�x��U05���d"((�����S-d��,N����8p �����STT���-���DEEa2�X�z��Bf6�	

�E�<����B�h4������c1�����u���k���Luu5���DDD��5j�oo�����h=���^��j���K/�m������'_Qh���u)�V+.$))���$�,YBXX�4)�N�����0***X�n={����`���Q�5j��u���	��HQQ���x{{�Q��Juu5}��e����EK�&Mx���)**j_~�%yyy<��3����$$$��V�l6�Z9wtt����'(_tt4%%%TUUQQQ�����JT]]MQQ�mg�����X�|||X�ti�2�|�����_�s���~�����|��Z��/��o��/]�$�^�v����w���Zw����N 77W�-X���7��~�}�Y�������TVVRYY�N�������
rrrHOO'++���<������������'44�N�:JHHAAA��{=+�Z-��5S������u�=z4Z�VL]z7��};999>\�$$$�����2F�Mjj*�������R��K��	��"��)..&++�=z`�X(//g��)���>T/x�>k�����b���.�F
����
�]���lF����W/���1X�VF�Q��������5����vy9a5�>��j���^�@y����W_1n�8&L���E��&�u`6����3��'����T*�
�k������1�(
������`��Qxxx���[9r��>�(AAA����a�n*���P(h��1nnn�����eK�r9�?�<K�,���st���N�:��7���{w��������}����$00�6m�������;v,[�ne��Mxyy1|�p6l�����9p��|�	UUU8@~~>'N��g��O?MPPP�Q�N�*--������B


����|����w�0���f�������������������/>>>xyy]3 ��2?��}\^6!!���l���K�
&�k�It:?����������`&!!)$$$��P*D^'??�������E������/[�WW�z�l5��{�l}||j	�UUU�����
���?�V+�����?����������/�<4�37Cuu5S�L����Z�B������={�Y!~~~��5{��Mvv6������b6�i��u�qw
�V��Q�����I�&b����$RSS����h�����r��i��m+f����/!!!b�����Z�s��j	������f���J��_�~ddd`�Z	

���P7`��zQ���r����d��B|�����(++������JKK)..����K�.�����)--������r�������������E�x{{��������RTH%z+�t'�S�6l��og�����jz�����S��,Uv����h��III��@BBRHHH�sAC&�������g����~�w����?_4�|X^��5�nZ����T��h�Nv�B���#����5���xv������4Q�������rrrx��'���F�TKPP������F��*�����]D�r�(��?���9e�pZ��V&!����j�@@@@�2^^^���d2$$���S�N�������{��k���a}�q���������QZZJii)%%%���P\\LYY�(�QRR��K�(**�`0�����R����Y����������3������������7���h�Z�j��Q�Tb��[�����k��t�B�f����a��}�:u����z��RIdd$���0OO�Z�����w������d��e8���`���(���)))y('4B�)��C����J�b���<������c������xooo���'��d2��6.7��i�R�.�E���j���n����C��g���H��Q^^NEE��������)++C����^S�������d2E���I����www\]]qss?������^�F��]z?������������T�y��LBBRHHH< �N�:����2i�$�������5}�z=��]���R.�_��������*�Z�[q����\��hn��F��������nk�
���dF����Y�l���
�>
�CmR3���&��H��/��?`4������
�^��`?5�~_����J������d(

r�\�V��888`oo���}������9���i^/����V�T�%$$$����-M�d2III��������~�������?\&��9�V*��9Ctt�P�f�~A���?m���B��lF&��������qww����4'�	B�_~>a".�H��r���(**"$$D�N�Ry�87:y�=z��L��-��:{�,:�����_�N!���������h41���s�����l6�@X!�T�,Z����~�1c������v��5%����C-T����J�y���O�f���h�Z�J%J��Z�V�?�WW�Zk4�Zelmm������V�����!�A}��$XBBBBRHHH�%�E&�1u�T�z=d��5
Jp���u�����?3e�qrr������zbbb�������L�>���z���@<<<8y�$eee�i��'%_ff&�����W.����OZZM�6����R��C�P(DFF�P(0�L������(,,d���ddd0t�PZ�l��j%%%����Zi�n���,�����j��/�������Bjj*4o�������K/���S���u+&L`����;���4�F#]�v}���B�`��y����=�/����]�6���K�.q���k�Q(�@R�R��|�7�|�r�5cB�L�Z}��k]��V�����K�.|���wU�Q�I������C�Y�
$$$�%���?���g�a��������i�����l6����}�g���j������` ((���2BCCqvvf���deeagg�;�������m�j������d������/���`���dgg�������Q�����xzzr��i��Y���^^^4n������-�g���(��5�]�v8::P\\�����m��%,,���.\�@LL���TUU�m�6���)..�������?�}I����0z�h������i�_��w]���l����Z���J�����b�{���tdff�R��Y�V����,.\��������X�p!�w�-�<�7�|#p���!(9.?��n��@BB��
.r��7�|��C�2b���?�P*��*�
lmmY�l�<����������%F����A�T��#� ��9z�(�w�F�����B�`�����iS��y<<<��������?^��b�
���7J�R������b�P^^��_]o��V��Z]���l6���Ntt4K�,��?��s��S���SO1�|Q	p��I:v���}�HNN~`��R���7���O>a��a,X�@����$��� ����}�vQ`��d�T*�J�(x
�E�P��jcc�G}$�!�\.���~�5�wy	_~M���Je����M�Vs������F�]|��������=z4:t��/�$33��`���w������_~������v�Z���G��}��������1k���vy�����IHHH<�H.�����jf��IFF�'Of��E���?T�u��^+j�U��������#F�`���
X��5�[��2����J������'Y�r%���L�8����NGk�#��i��~~~t����{���woL&F��~�i���HII!99���(�7o������l����n?V���c�����O<��`��g���Sj��rN�<���k�,@�����;��c���L�<��/�`�\]]	�O�>h4��������C�|���dee�d�:v����'9v��&Mb���4k����,���������$���4??�E��V�quu%))�-[��g��j5={��}�������Bs���T*��[�L&������D�Z-qqql�����2���+���'22���r222�Uf��m������N�>}���O�C�4j��f���������p7��_|A��}k�)�������j�*�y��:���1RSSo9���w�8(�w��c���@BBB����T7:������/�$''�i������%���x�(�J������D��1b�6n�����qrr�����D�&MHMME��������O``���Z��a�Z������J\1�+!!���LN�<���NAA����_���s�����o��L&�s�����b6����������l�r9�?����e2z����R�V+���xxx������[9z�(`��]<�������g��
����������),,���c?~���{��5��u����Z�0�~����g��G������$���������!C�����B��]�v�h����$���0�<�n��q��Y���())a����i��N���c��d<��S�����K��
4o��w�y��K����`��-DGG��;��R�d��y��=�^�zq�����9|�0�{��S�NX�V"""h��5�����G�`0PYY�������q-���P*�l���L��`��LQQ���|��7������Y�p!������`��M�;w���[PP�������'N��_��u�l���'Np��9����t��x��*���JU !!q3B���7�}������7�`������e]�j�)GGG��Gnn.NNN�1��b49r$
����*�}�]���prrb���;v��� �z�-���(--���www����j���jq�b�Xh��
III�9s�g�}{{{F���P��DFFb0�1c�������SYYIBB��������Q#Q��O���������G�9��A�7n;w���W^!44�����nV��E��y�f<==0`j����o������n�=988��BHLL$99�	&p��f������}��,���TVV�}�v233y���0�L�2R�s�N������Zr�JJJ��dTWW�f�5'�*�J\���:p����J��l����\Nuu���o�X0L�8�'N���I�.]�X,TWW�r-�X,����c�����V��_���Q����������u��9s&��8;;STT����IJJ"!!���M������qss�������N�8���>Juu5���:u�>}����Fjj��_�~�:u�={�������'�I��c�1J�=h��%TWW��?��������u������xyy���P�Tt�����.\�@QQ}�������?����x���\.'##�c��CPP�m	�5��^������"�<�RN��������������V+aaa���/��������������������Y.�����f3�A�to6����F����%��i�������x��999��� ��q��&��V�Z�:�B��C��6Axi��5�(85k�����/o!!!�������j���g�m...�����./�T*���o-A�f�t����
�/�d2�u��O?�����8p ���x{{�w�I&�QRRBAA...;v�L���
��u��1f��z=eee�0[YY���;z�������d���j���� ��[����)((�d2�R�HII���$&&�>�5i��=���������2F���!C���KUUQQQ���r��)\\\�h4��z�V+�7��_%""���Xlllx��WX�b�mY����u���������Ndd$�/�q���5���8���[�����S��0a���,]���/"���Y6�F��+

�_�~�^����'�����mv��q����TUU1l�0�����O>Irr2Z����3}�t�����V��q�HJJb���l����c��������J���W^���S|���|��W�����s���_��7���SO�{��GDD�777��]��`�w���t:�6fgg������ IDAT�9y�$o���m��V��������QYY)����wh4\\\�������	&4��			I !!q�!�P�V+���l����;����{����^���wg��y����\��Bt����\.<ej�v
e�V��BV���,�u�km��L}����v�:�V����'''����6��$��h��[�n��'��S�N���/4m���J(d�puu�@���������l6#��HHHSb�j�
'''L&��-���\��^�_|�J����^{�54
��7�������uk����j�l����g������O��Q#1��L&c�����#������b�0d��F#r�;;;�z=���4m�{{{L&:���?����A�5o�<1��)c��	b N�\�{����h�b������^�j�2d��:�n>�|~~~b@QOOOBBB���&;;���$&&���lt:�������<y�B��o�����z���;w��E"""h���7o��������???|}}�����������iCPP{��!!!��7r��9|||�������&M��c���'���������������g�SO=%�5��K���Tx�O���'����_'::ZRHHH
		��Z�����e]�t����g�y���h]\\�������u���m?�����o�������X,|}}d��d����b�
^~�e�w��O?�D\\�}U�*�JT��ry-w�Z-
�5Wb}||j	KV�ww�Z����k4,Z�V8��}�+�D���Z�$�[�R�b��Bx�k�h44j�H��l6���w[B��L/W���_�_���\������r��]Y��G�'::�I�&������:�ecc#�#1����9��Vs���������3g2j�(�t�"�Y��\��zb_��;�1c���Ei���i��������[2����KJ		I !!Q_D��J���Y�t)&L�������7����)S9r$s���q��DFF�v��bh��jfa(**���_g��%
�?	u��g�������>���ILLD�T���v�T���_o_�^��o�)���k��k��:�C��k������Z�b<��(���<L&�X������h��_O�������L&lmm�8v�>}X�`={�d��=|��������lll����t:1M�B�������4��������S���dTTT�1�j5����?V��V��
nW?��3=z�����\<X�E��b6�	'88{{{^{�5�,Y����dTBB��{�X��%		�z`��y|��G|���b���Y	 \_ii)��Mc��A�o�������;�;p�+W���g���5��������_3m�4^}�U&O�����������������Zk���g���~h���d�M�6� ��HKK���?����o�m�j����{�n
��������3gh����'QQQ\�x�^O���1����o��z�v�Jzz:yyy4i���M����!f68s�{���G�����f�Qh7h�ZQ������W^!,,��� 
�F�!--������9q�}��%++�������IAAnnnL&����Rn���6m���)S��[�|9�������_�w�y�R�L&c��m�����o������[H�ABB�^���'s��%F�����i���}-�	f�NNN��=��������ccc���������`�-u������b������\***P*�L�<��������K��	f��I8p��>�L(��888�f�#f�Y�Mo��)##��~����[���Vgj��M�===4h��M<*3��� &&���T*�b�@l7���g��et��I�_�&MD_}!-���0�N��u��6L�'44T�6"+88���@ov����o�3gN�m
�=������-g��!55��eCBB����b����LBB{���'�(o�V[��&$$���������������e���TVV��_?�o�NDDD�P8::2~�x���)--��������N ���t�,`��!��2�N*\]]��������� �Z�]��f����7n��^�G�,[�L�:q����������G.��+wz���y�&��������r9���L�4���jIHH�K�.t���
��N����������s�������/��;;�Z�?���n�<yyyu�(ht�����X,X��A����f��Uu�7o��6�F�����=zp��������J%:�N��#����w@`y���)//'11�]�v���� �r�\\I����a{�J��c���������������Z���S���n�AAA$''3s�L�u���+����]�W&�����k^�B�SW^
���eY�P(���b����d2F�)��O�j���~3�#�����j����u��_���`6����g��9����e�~��w1EbLL�{���G�c��w�=Y�V����������Z�����|OH{��=e�g������<���
���e��],]��N�:�����Y�X�f
��������c���cG�z�)��=�`�!//�����@BBB�&K�d��/�`��A�9�+V���}?_{Ma�a�$Lt'M�D������&00��_9yPWuj����#~�!�5�_�~|���>\Lw7��j�/..f��
�k����Q��X,(
�r9��M�6QYY��A�0��b�\�L&�����'��eK�|�IL&S���b�l6�� !���b-����*�L&�`0��K/��_`0��a5��Q?[�l�g��X�V


x����y={�$>>��}srr�������k��l����������ci����M��Jh���Z�b���<x�
6�~�z>��C�r9����G�������p�J�\�V�����^����j����8c�ZQ(h�Z�����{7j��Y�fQQQ��s�X�t);w�����Y�fQUU���?F����������a��1{��9~���PYY)M�$$$�����~�.]���}�2e��������d��@�]�v����S�N��~���}2���d���+���1y�d�����3�x��	����Kii)c��E&��}�v����u���9s�
6���LTT���l��	�����-]�vE�T�y]��2����������@.���[7d2;w�D��N�f�����	�7oNxx8k������l������������\.�K�.W(n����Z�3z�777F�Idd$���WMw�����K�Da{��):t�_��-[���Y31J~}�%A!0m�4v����m���u+_|����4k��6m���}{���pss�����R�6���l6��1c��y3{����g��g���;w��5����Y��a2�0�
2������KU !!q'��.]JJJ
��M�K�G��g��{��r�J�?~U�L��
!��8l�06m����G����U�n�P(h��9<��c����o�><�c�=����9�<���DEE��cGZ�hA~~>�������a�N�<yCB��s�����0`J����v��ENN���c��TWW�s�N�;���/�����F�a����BR�R�V�����V�3qrr���3,^�����N�����?��������=�F�������b1�}}�B����o����o����|����o��c����o0f�F�����������g�.]��"q����!%%�����={���cG���/v��-�W�?f��z�������V�E.���h���HHH�Hw���@���;����\.g�����H���ftt4��
��^`������������Z�����!C�0s�L�x��{��y���L&#==���H����X,TWWc6�1�L��������NwC����D��#F�����u+M�4������L&��u��������`�j�����F#��w�{�uV���5��^������"���jE��[�|9��V����W/�$������s����f�[h;...t��]����l233IOO����������F��IHH�E�w%�����y�f���[k�������������$lll������������HQQ�|�
������/�@BBRHHHH���"�����b�������V�������a���?�I�&l��Y�i�����[B�qwwg���4k���_~�#G���G�u%�\.������*�f3�[������G�h�Z1r�\.����\Nzz:������#��k44
����RA����BAaa!�-">>�f����~"##i��1*��#G�PRRB��M9~�8qqqh4,�����flllHNNF�P0d���x9u�yUU�~�)�F�"++���h�9��5kx���pqqa����9���~����0x�`6l���

�+f�Wk3>>>�����C�Jyy9�9s�m���r�J�M����;vd��$&&���|�:��sddd\�---���4������k�;t��O��*RB�C1c������������gf�!�,��%H�TT�5b�f)��R�Z-U��~�oj5b�RZ�U3FlB$Bb$!���������FR���8r����u_��^��5D5��pqq�M�68�ZM�F��"�����dff�~�zz��%������Y�f|���l���w�y�Z����������z H]FFYYY����fff������NNN�����n�Z����M||<
��z��q��]RSSi��%����D6m�D�58x� w��!00������=���g���T�Z�������&	���w���www����{�.�[����www�?���'������H�r�j�n0���|�.�L&#!!����A<���7
4`��M���1s�L�J%:��R���*�
+++,--Q�T��]Z�h��]�pvv�S�N�������h����� 0�'�B���%���T�P���bbb2d\�t�o����'�v�Z�_����
���{ {Gi�SrssY�n111���;w�5k�������iS7n\��o�����`<==E	���Q8k	��i�����kW������E���_�Nxx8s���u���BJ�������������Y���u�>�}>������G��			���<2��)"�)u����)��r��O���R�����sL�trr2��o��������R�R�b�L��\�N��y�R)��`0H��L&��+���a��V�%44��;�O*�>,�_���+
��k�X�~=��)}�~!y��-l�����8���	��7��y�����amm-Y}�F���[�����w�.v<66�N�:���b��Si�`00y�d>��i�6���hBBB��B ��.���cZ�FDD0}�t&N����3-[�&��|������o���e�h�����,(}���������Q�F��sg>��c�������+Wf�����������S���q��E�Z���$��0	�E�xxx0p��b��������
E)z��E�1)�~�o��Y�+y�Q�z�2�F4�T/r�-I�DPP}���������;w���?2u�T����Q�
6���___�D___�}����7^�V�*�F��~��b=!�@ (MB
@���IMM��>`�����WO(Jq��T*z��A�n�8x� ��7S��2��3fP�N�L�B\\3f�xlN�����
��[�n���*��p��0|���g����n�����}YslI���-[��e���?�&'N�����|������bnnN��5			�A�����Ze@@@�G�~a�K;���+����P���r��1c����N�����{7+VJ�RL������d�������R�D[�r%@�n�f���4n���K�R�V-�l�a�7f������slmm%?���^_�������'--���k��>YR��U�F�j����7o�$55U
(8{�lF�M��i��
���#  �T�9���\�~������ZI�.��N����;�Q�A			���S�z���u�@(�H@�����9���oN||<NNN��_�����{�f��q��!���E��%@��U��������

e��������E��:z�����#�9s&���������Zvz�*w.^����3Y�bE�������.W�����F�DEE��jINNf����Y��1c�P�B�w�N�>}���-��L&{��mz�}���T*	��7C�>h�m��(��(����-����;2������m�6>��S>��Z�jE��5��g7n�x@ ���q������sss�������q��#��(^�P	��MRRR��w��[(Jg{�1�}��q��Q�Ne��L�bS&����g�I�JZ\l�����w�������\.�h4��v`���l���%K��������������X�d	���T�^������;����%�|J���}�6�N�z�r��#G��d����/����2/99���L������$%%����NJJ
��'j����H,--INN&99����?w�NG�j�����!;;�K�.����s��U���?~<�V��[�n����x{{�q�F,,,1b��m#44333�/_N~~>���������X��;GHHo��'O�����$$$`ff�������� ����@��)�(��i-Z��G�,_�{{{!\����8q"���,_���={��)#�f4���t������N�J��U�*����=z4������q��4
�������
.E���=�����K��0����	WWW>��C>��C���X�v-k��e�����C7n������%Z��z=u��%..��5k�����6m�f���������/L�>�	&`mm�������III�?�����{��������@�m{����h�""""8s�j��JEAA�&M"55�o�����&N����;!!!888���o2f�����Z�j�����#G2p�@\\\�z�*�~�-��m#::����)&��	��*�R	�P(X�r%�1����b�7A�2����>}:�����{R
��'������\oZ�W�^�]�vaggG�N�X�jU��h�`0��M�P�T,Z����F���k����������,3<==�6mx�pVV���h����Q�Fq��!���C��m��};}���{��|���:tH2�/Ks�)3�^���]xzz�����'HII!$$�NGPP*��
*p��1����q����T�V
�FC�Z�����+	����Kaa!���T�^]���\��6m�`kk���+�V�"++�p��=~��7�6mJpp0#F��^�zx{{���cggGff&���C�V���/O���t������E�����G���o��}��t�U���Y�p!���c��y��P�����_��N��L���>..�J�*akk�\�����NG�^�X�\�r,Z��+V0r�H�����3���.��|������M�0���'�����em�)�^0�:t(g��%..��[��t�R������+={�����L�O����?�{�����3�R�
nnn�d2���0$''��cGRRR�U����"��9u�			DDD�R�^h3��������d2n����3g����U�V����m����'����3p�@bcc����A�=z;;;�9�N�c����\��������1J�.�"Z x:��@ (����@�/_��5k���O��_�������X�z5��{��d2���h4����~�zf��!Y��O��=�+~A���K(�J�F#'O�|h[�
U������]�vq��I7n����sd2fffXYYI�4��'����O���gQS�Y�&}��e����[���-[2}�t|}};v,w��}�5�T.��r"""�z�*���xxx`ggG�:u����l���f��Q�n]�u���8|�0u��E���P(^J��LFjj*?��#}��a��Y$&&��wo�?N�z�		������<���+���8{�,&L������=�1c�P�\9��]��C���};��U�C�4h��_~����������
6�a�t
E IDAT�������/<��AAi,M����84h���S9r��(�h�Z�N�c�������8RRRX�b����_��y�k�FCtt4���#66�C�1m��b����l�Frrr9r$���c��u4o��3f��g���I>Lhh(7n,����;���v��
L�2�.0v�X>��C������� �E�n*�\.'++��S�2k�,�7o&99��b0�qY���~����E�U������z�P��g.Z����2<�9��(<�p�����:u�������}{\\\����s���J���#����v��y��e���;w�9s�������3f;v����c|�������=z�����M�����o�����777,,,���������n�����,`��=�Y�ggg���y��w����I�&�h���>����;��?0�|\\\���/��7���3t�����;���_s��.]�������g[�ne���h�Z���X�t)�}�?��3*Tx�B����~�������U+�����U�VL�6�!C��0AB x����Md�����#�7o���?����o�%""�R�.q0N�R)���h4�d2�T��������/��fu��2��^��WYH�)�@ <�"�h4��o����3v�X�������G)�r��DEE��w�R�\����_0d�BCC9r��'Of��\�v
OOO�6m�R�������p,�X���O���'���4i���������������������q�������4k��B���u����w�A����0b�4h@�n�

���������[7����]�6����l�Z�h��
pww'&&��/r����*��B���#$%%LNNU�V����#FP�Z�b�������"**����3d��4i��i�pww�v���c4������G��J�8|||���
1B �]	��[�=z4������	+�R��hD�R1h� Z�n���;i��}�m���L)����b�`0Hm�^�^�G���������.]�m����������*{{{)��[�����tJ>���^Oaa!z��\.��)~���w1�,Y������Z�V@L���������H&�������3���%<<�U�V!���={6�&..�RI�*U

�OP��,�L����O�-1b:t`���xyy=�@�V�qvv~mw�
�\Q �=�M�@ (�J��w�c������\�rE��+e����O�>};v,:���
��7���~�	���ys
iii��r)��\.'33���"##IHH�A�<''�R���6m��s�N���P�����J�)
�/�h��F�����mm��!##�M�6��IT*���h@����E���-*��\����P���O�����������b��|����={���\���G�^������5�K�����������X�d	�������;w����/�X �-��@ (���B��_~��7h�����������R�>2����G�d�&M���)S�d��5��[�2m�4����h4��qcV�XA����u�����f�������~���Squu%**
�\�^�'==����k~~>��-c������3f�)�V����S���s���� ;;���,���K�*UX�x1���>��k�2x�`���O��m��	X�j��j��;�R������s���F�����w/��O'&&ss�bm�b�
���#���K�h��=;w�������L&#66����b
�s��w��{�n:t�P��W�\�����S���q�������r�X3�����1�^�z1a�f��%��'A�������Z��z������("�@ (����H�]����G%s�(���������+S�RR�'	��g���l����g����bmm�TeJKKc������P�V����l���A�Q�^=�-[���[�Q�M���v�b��
l���;w���O�y��'J�(x����������#
�B���,��t]`` _�5m��}.e<t�111�;w���������{Y�v��Rv$%%�T*)_�|�1E�Y?~��m�����i���q��,&@IcH���T*�:{����d���K�+����:��J���E���Y�I�i��2Y/�_>�V+��V�%W(���R�|��"�@� �@ �Z�.|v��A�&Mh��5�7o�|�����ODD��u#::����tqO��I�3q����[�L���h$33��7o���@�j�����
p��N��3g?~<qqq��1��}�>�9d2��������o_|||HIIa��O�S*x9J,'''�n�JVV�������L��$�����JEvv6����������������lll������222�{�.*T 33�7n`ii���/[�n������|>>>�����������p�...deeaaa���			XYY��j���x{{s��mrrr(((�B�
����p�B6lH������h4�]����vvv���Z�j1z�h�J�������\N~~>���X[[cee�N�c������///���((( ;;{{{�BH��H�Elll���a��-����J�"##GGG�\�r'77+++,,,$7��e�h4deeaee���%����\4
����������H2����D�����i�P�T(
�����d�4������%K�T�z��	&<�'����;w.����9s��~��?����k���hh��)���b�B ^7%����i��=}��e���":y)b��y��Y�y��1d���V)c4�T��V�z������K��F�OLLd�������������~�{.[��[�n��{w)���l�r�J~��:u�D``�3+L�z�h��&L�O�>|��w:���@�N��=Y�r%={��M�6��9�J�*�w�^�
FNN:t`��	x{{��cG�F#��g���4m����73i�$.]���!CHHH�]�v��9���$�n����������u������7�|�r���HKKc��
����T�^�#G�Hn�4�.�r��:��g6lK�,a���|��OU_�!�v������W���];4
����={sss���+���dff��C�z=���*�
����u����xzz������/��9�}�'N�������s��)|}}�v�o��v1%�L&���{>|�LFrr2�[�F��r���j5���q��Y��?@@@����9s����s��e*V����
���;���DFF��>����Y�^�g��)�?����b����oT�P���_?��[Gbb"���t�����@��@ ��J;;;.\H�^�5j�}���\J�����3f0f��|�M���_K�����"����c���T�\��J~��ro0]����F��B�@��<��_�����XXX��{w��;��?���#Jt�x\?R(��UK
ZY�re�4iBbb"�N��q��T�R��
�����3gh��1�����1���\��Y��I�puu��>�v��m�F���y���ILLd��
���{XXXP�\9j��MTT��9���R�N:����Nxx8qqq���O����V���5��4�Y�&��7����.q���d|��W�k���c�>���\.'==������{w|}}���������Hxx8���#++;;;
�/�m��.^�H���	F��Q�bE|}}�Q����(
�;�R�$##�k��ann���W���f��i\�x���`�u@&�q��.]�����9|�0��}��akkKdd$���#,,���xN�:E�6m���E����ys��[G�F��{�.����+�V���x�]����+[�n�����7o>��w��8q�
*p��9�z=w��E�P���"�@ ��u4����?>o��6�}��&Mn�D	���o���?����2k�,��U�b)*�'''��W/�2e
���{bw�L��K�HKKc������S��l�21�Jy�T��-������ �
���3�����i��?��)������]4}e�r�����z��XXX��hJ�����P��XXX���#��4�����t�E��T*RSS�3gM�4���_*��������gm������X����{���J��S�B&N�������w/^^^xxxH)>
999;v�A�IJKKK����7}��mSlWWWd2�������2����<�j5J���M����CVV*T������,��oO�����m��t(����opp0��F������9994l��]�vacc�������VK�z�X�r%�+W���;������P��p�+���Y�&K�,�e��xxx0`��(X[[3|�pz��!�.��10s�L��CTT�������Da�Q��2e
K�,)v���;$&&��.����K���h������0~��w�x��g�S;vv	����b�����*	�%�i�h��%K���sg~�����+	��+���_�����������C�1c������ccc�\.���P�CP���a�/cbbX�t)�����O�r9III�X���#G������d�������������lrrr�j��R�J��R��{��L\�|��/J>�g��%??���$:w�,���y��/�������`����o��*U�p��9����]�6{��!''���n��!=�\.'++�����9,����.]�PXX�T��o��,Z��:p��m���������n��l����7o�g��N���M��p�YYY����.<G�&M�$�A ���y{{S�Jbbb

�j��]�
^^�x{{����������fff�M^��o�s����'��������/g��	XZZ>U��d22228~�8�������m�.Su�`��V�J`` iii��q?+V�n��\�r��'OJ���...DGGcoo/�����d������?q��d\�~���$����e{{{233���������T���B�VS�~}�7o��={8p������G�P�����_�����]�U�V1|�pY�r%�k�&55�*U�p��=�U��������\�r���$f��������8p�-Z���I��u�������dddBFF���899���Sl���u��V�\I��}���o���4//�[�n�������w��Q�F4h�����W���C�������4
��7'++www,--)_�<���RY|||8w�666�����Q#���O��5�T��o�F�Pp��mZ�h������h�ZI��������w��y����S�Z-W�^%&&�BA�
�q�Z��6m�`ff�R������������J�B�V�������d�����Xw	��Hhh(����<y��'J�
����[�.F�///�����i_}���������{�1b�c��c��m���)^�i�iAY�d2K�,a��,Y����(�(m���Fxx8��
c����=^@\�z�e���h�"Z�l��3���}�4�%�g��\�B�>}�:t(���+����W/*U����3	

"''���B.\����9c������/����7o������SXX��;w�z�j�y��� ~��W|}}�cW�^���~b��q�������\�v�a���o��g��-Z0d���k�B����Hff&T�\�������B||<���/v�)
�)U�)M��U�I��T*��t�b.Q&W�5E���d2�j5Z�V:G�T���Q�T����7n�^����K�<yR��R�����r��!��P*���r�Z�4O�T*���T��n:�to�}�4
����A���Y�[�D��2�i�Cnn.��
�������a�����3g��{��4k��j��	%�sh����%K�;w.,\��-Z���~���Cvv���4���N�����&M�p��i"##�6myyy������puu�����O�B���w��r��U����t�'���"�iaa!����G�������{��(�J)���y�\s��]n��AZZw�����+��qC�I����������S�N�-��w�h>S�5��?.��5��������t��@pp0���`4�X�"��i�N�V�}�U��2
�Y4}����,}�qiV���e�K�@(���2h� �������y3U�T�+&**�������'�E�<�r����>�����OTT����o�W��=�oi����=z`cc��+����b��h4���qww'..�.��j9u�j����������i��|=


^i�F#���t�������h����w�}���}�����\�t�.p��9��;��+W�s�������������;������[,^��:0z�h|||��sE����*�hMA=��{���U=�@ 
�@ �"�F#r���>�������}{>����8_a��d2���G�J�7n_|����g�L}x����?�.]��t�R��+'E>/*����\�bfffh4������w�����W��TgJ�����[^4�ZY�����e�as�iw�����>}�'N�����s�:�����D``��&���O2�W�T���q��E/^�����5k2��[�n�8�lmm�^��k;�Liy�P�+8U*����u��4k��C��V��p�
�D�V�z�j��mK�V����B?@bb"���$$$�j�*��m+�'�v������`���������"�C;v��w��������k�]����B�Fc13l�����g
6W4
��+W���g��!>>����c4qtt�F���Q��]�R�zu�W�.��?�����h��
VVV�S����9s�������O�y�y%������i���R����qI��$��bn�@ ����dl�����0"##��u+VVV�T��IHH111L�<��k�boo/*�	��	��`�f��I�V���m���&�[���]1�����4j�������/)�d2M�6�����{&�H�x!���:����<������%??���4��;��K�HNN����\�~�L���T�^�.]�P�jU���*�>�z��slll$�'�S4
fff�Tr�����((( ''���,�����U��E�q�|I�=�|���Iaa!...��R������L����/�c�SPP���������N�R��m�h��
����X�kkk!0��6��d�5���(~��F�%�,��F6l���3X�l���t���'<���B��>�0A;##�[�nq��Mn��Ejj*III$%%���Mnn.yyy(�J\]]����Q�F�����+�������3����L<L�����deeG�&MP(��r��E?~ggg*U���`@�RI}N�������K��0a�����{%>���2����B�r9
�Br���t���I�6����c�z��I^^�d�e0�����p���o����3���%V��?{��%((�LF�.]�{�.�V�B��0h� �����@ JV888�r�J���>|8�����W������c���l��5j�L	�x�LFRR�|�	G��O�>������{V�+���u^f`��������������IHH !!�k������^����kkk�������Y�f���������+...R�E��T�_�F��}��������%**���v���V��j��T�R��g��a����qttD�T�q�F������&,,*T���_~Yb�L�����]�.]�p��-<H^^!!!T�P���/s��q4
M�6����-[��s�N*W�L�J����`���899Q�n��<-���c��a��[����*����p�...t��U:&���������b�@ ��������#::�i��1~�x�s�
��v������2`�:$*�Af���L�<���p6m�D@@@1�W�wmmmquu}��Ni@�F#...(��G��������s��iN�>M||<���'==���B�������B�
�l���U����������XXX`aa��~��z,<	j��r�����J��51�������<"��" IDAT""�9s&_|����899���=/^�R�Jxzz�a�|||���)���~
��77o�$22��r��eN�<���
�j�b�����;�;v���Fpp0������Q�jU���O���������B\\!!!��5oooP����g����IIIa������R�n]n��%^�P��������7�N�:���G�=���+R��d2���C�j�����3g�h���~������7'N�`���t����;��xF�I�~�^k����C�_����Q<jW�h4r��eN�8���'9y�$'N�����\\\�^�:���DEEQ�F
Q�������i
e���B���NNN�F�]�F���	$%%�� )?���P�T8;;�`����HMME��>Q����bee����Z�"77��;w@��U�x�"j�������{~��wF����j�;;;���0R�����/���A��4iR�>jj�?������P(x���Y�l�z���@
��'^�5i��y�����3o���C���077g�����W�7�x�X4���-�>kVV����5���p������{ @��&33�����7J3Z�ww�v��*i�����#_��]����V�V����[�9s��g�r��y��?��+W��t���P�JI�&88ss�'���s��3���������n��Irr2�"D.�����\.g���T�T�.]���w����)((��)''�V[,�
������dggs��!<<<pvv&==���D������h4>���=��]���������������������'��(Z�h��$;;���@��7�|�c%���EXXZ�V
v����F�!++��
����k��ddd��S'bcci���S-��O��U��g��_�~8p��+�6��h=<x�/���s����7���G�R�y������Z�&>>�5jPXX(��I)�\.�|��r9r�\�,z��`x��W�,:����x������c��DFF>V�5����A~~�d����y��Z{<���P(P(���������w���$##���D.]�DZZ��O��boo�������j����@���_�������{����o������G���i��	�7of�������J��` 88���OD���Y�t)'N�   ����������v��l��ggg��+'��BA�z���?��m#33���ccc��}���q#�F�B���P(��};J�R������o�>���������(����v��M��������t��M
�x��Y�777���C||<~~~�k����d�?�\.g���2����)��@ ���f����������2e�V�\�o�Qj��z{�d2z��MZZ���R���j;}����3s�Lbcc���������T����Ws��5>���b�HIIy�eS*�?~�O?���S����Ivv6����T*�����t�t:�z=7o�$88�RIVV.\���w�������p���j����bmmMNNo��6^^^������������pww'  �g�����&00ooo������o���f��1���affF~~~��h�/_���+���`kk��`���ch�Z4h�V�%--�;w��P(~h��r�
}��!((������'��P(puu���///<==������?��>|8999,\�P:��S'��__��o����S�JT�R��z�F#�
HQ����
��F#) t:r�\��/��P���t:�^�JRR���R�T������,�nAAA���q�T*� ��033��1����I�!kg�NG�j�(W���}E����0K��]�4��t�'�|�{������x�w���@�_�����a���t�������S�n]QA���?��N�:1�|>����B����e��������O?��a�R����1������������l����u���-[c��=�/�����7[�l�v��,^���={�����#G�y�&111��w�ap��5������`����W������HBBB���'�}�,�{��������������nkk[l���{7G�!22�A��`���_�J�B���o�>�
��Y�

e�������:u�<��XZZ��C<==����>vvvO�!���O=<<��wo�c&��i\L�I��\*������P%��h���OO�b���`����X�C��3�����h4Jn��
�[;?,���\��G�G��*�
333��� U ^'%��������G����0�z�m�����I��3gG����E�_��M�>}���X�z5�5*����-L�z=^^^R_P�T��S�����L���G�V��o����������������o����c��|�2��r������c�.�XXX���CBB���:c��9������8s�?����u#((kkk�����������{���R�Jj�����#K�.����T�V����M�&)���	

b���T���Y��?��>}�I���	���U����*U��������o���m��'�N�������[o��1}���R��^�������F�A��@ x�����|���\�t�.]��c����	zi�[�nM���������������v�?��������'���>|X2]��AE��Z�j��O?q��!�����*J������	�W�^t���L�V�E�R�4?_�N�[o�������R>��c>��c���'O�m�6����	

-Q���.L��R����i�����+���(T(��` ���V�w���������`4y����0a��5��*�Jlmm�U��P����9X��q��a�U��������P��Y	`ii���y��7����W����R(^r;�d2&O��������?�V�*�]���+W�0e�6m���Q�;v��K"|||�r�
666��j��o��i�X�t)���(
i�=""'''���9y�$����S�N��Q�-[����F�~��(}����������������r��N�:��/�p��!j��M�����3_}���5�|�===�q�999X[[�����7��d�������������+L�<����s��yN�<��#(,,$##��g�r��q���+&��4~mmm)W�.\�bs�����kWf����a��������z���:+Esu������-[���jE;	%��4i�$Q
��u>���i��
��������M�6�T*�x���P(���`�����I�2����^^�-b�����jV�\I��K�b�$N�>MVV�5*v<##�����^v��@����|�2...XXXPPP����y���0����,--y������������D7nL`` :�{{{|}}���~!�
OOO�j5r�OOO<==�Q�!!!�����I�Y�&o��2��6m�p��aZ�hA�5&77�L���+�j�����$%%���O�f�������3�5
[[[j��Mzz:���������w��G�bkkK�6m		yh���������j�����~�9I.�s��Q���h���$P����������),,���]D��tY���G�e�����3h� ��G (i��,��u�� HJJ�]�v��U�~�A(^Q;���_�j�����t�����A�r����L�4���TF�E��]�T�����Tw
�B2�OOOg���4l�P�V�\I�5�Z��M.�K���T�r�\
t���Y4�����{�s����L&����,{BB�g�f��9�T`-��{��1^����/_���+Y�bNNN�����'>>���t


HOO���{�}��133���
sssI��Y������B})^KL�>>>�Y��v��1a�����S�
�!,,�����>���+R�~�R�p+��o0;v,��=�{�f���R5��|t���x+++Z�h!���j��n�Z
zW��
�f:����I#���Y�����G�O��E������l:$�`���k��q��uBCC�����d<x��T�			a��Y�9sF�0=gpp0�����u�FCaa�K	<)x4r�333T*...�����������-[F�v�����O�>�O���sgN�:���C��q�#s����p��)������e�����SGR �W�E���HT**�JR�F,,,^�o?���������5���c��
u��yl9��9����|�r������k�.6m������7������r�����O@@M�4a��y����V��Y���b���s��p�@(�����z��1o�<������-[��O	qe�
�j5�F����CL�2�����Tg,Z���,/^��q�����|�
�������J�qttD�R����`0<6���+/����yvv�dYaaa�\.���;��������`����#F�e����(,,������QPP@NN*����`N�<)�ivv���vvv<����c0���������B�J%VVVdffJ
"S����<�Z-:�;;;rrrX�|9
6���MR�effbii�X�	��0���8@��M�	���Pv�)�@(������;���J��]���>�������;w.�[�&00��C���6(����t����|�����}�U�V��m��t?���"--����:��r���%���


:t(u��%%%�5j��Q#)5��9s���g��%�<y�U�V���o�|�r�J%'N�`���$&&��kW�
���/}���h4r��9���C�58p���O����f��1$$$P�~}�N����g9}�4����u��t���B���������};�/_f���|�������m�6�z=�����r���O~��G4h����F��*U�������c�ptt��R�2:AYE8�
��������g��qt���]�v3��a�j��|���L�0�U�V�r����)))>�w�}���p������M�F�y����P���y�


���<�u�����0�,CAA�S���yI�w���y�l���B�^�8x� �������-Z�T*�]���v�Z�6m���9+V��Y�f�����g���O������������ki��������AXX�'Of��}xyy��#���c���DDD���?����z����];�����������G�����+G���/�$%%EL����#,�����G��\.�k���BU(^�"�e����7��}������o���w|������W��	�!i�H�H�X�����Nm�F���7U��O�VI���J��R+1R#A���������K5B������}^��g��u��\W��.dW|��5k�:u*�����q�s��"�L&C�T"��%��:��C����&�	�J�L&C��I{�-,,$�W��coo�����4i���R9
E��W(���*k���Y�������&�z��JEzz:�/_�s�����y�h4�s�ne2������J���o��/��X�r%7o������c�"��Y�h2�;;;i��q����"IX7��Z������;s�5X[[S�N^�u�h4�)>������������<�z}%��^�G��K�V��������,^��������(E�0_w��^��V|�[�����3h� ���������O���F#,��
��7���7�d��!�;w��1����!C���'�0x�`�;�����Gy�ZM���y���?~<+W��M����`0�����?�Haa!����$V�X����)++C&������z�j��������r�o�����9z�(666�X��������?�����+W���?0�L?~���,N�8���GIHH������q���/_NNN&�	������?v���V�E.��������INNF.������%K��a�6m���KKK��]�P�@����7����8u��m�ddd���?3j�(�������HHH����W_}�
6p�����������7��h���?������[[[n��Aiii%��7o������u�r��U������A.�W�%�m��$%%�~�zz��))�*
�f�O��.**b����j����4����2������STTTe����^�^;w����#���Y.�E�@ �@�/r��wH��uk^y��_�.���L&�G���_d���dff>Ra��0b�����]�.��0z�h�)a�|>5����$N�>M�V��<y2666DDD�����'11��/R�N(..F.���'�`iiI�F�(++c�����j�
F�Z�8w����`���\�p���ws��)����2e���b[9z�(��o'..�y��a0����U����$&&baa���#����/_f��m���LTT]�tA��bee�7�|���@���Kpp0999��jn��q�9��'  ���"""8r��������S�^=:����d2������Y�`F��������������=-[�$77��7�x�b�F#, 99�y�������]�9r$G���g��m��a��9s&s��!<<��+W2b�~���
������q#�&M"33~��G-Z�����_�>#F�`��m���kkkT*/����g�����5�M�6��h&??����N����U���O?���'i�@P�[���`���O�>}?~<_�5�)�cV|�������[o���_���R�uP�~.\`����]����'3i����yZ�D�Z�8p�{��e��ih��J+������������)((�Vpu:������UR����+*_*n

"::��'V������DFF�����_~�^����C�����~���GII	111,_�������`�,�y)((`���<T]��1���b4�T����[
�����r���r?�������k3e��J���Q#5j@���puu%&&F:o��������������"���	����ukZ�n-����^�2?={� ''�	&��}{���-[��eKZ�j%������;����]{0`���g��i,Y��k���a��x�
1@?�c�xGB �-|���/_��n��1a����+io��`<>E�7�|C�^��1c�~�)*��Z���j�F�!!!���x�����gaaabBY��<<<���?������+�����d�`0�T*��a���t���_~����[��d2a41�(�JJJJ0�L��yS��_XXHNN��|�777�^��Z������j�
www���),,���k�~��'�^���!C�j�R��� !!�n��=��OLL������'r�\�O�����

%,,��K���5k���������K/1e��
�Pu&��9{�,_|�������������...�YT��|���{%??��[�2s��{~^E���h������r�A�s��U�0k�,��g�}�������������R����@��R�ppp�����
���&�m��.(����E1��'�NNN<�����9�S�N��s��x����i���3IOO�k��]�=z��_�
60~�x>��#j��U-�OM���SI+�f���(**B.�s��
N�8����<�
4@&������+W����7n`ggGii)!!!���������>+�	��dPVV���#���\�t���r
\�x��HFF���IN��233���������`���9v�j���M������(++�������������������ooo,--����k���,j��}_a���Cff&iii��W�����R���q#Z��z������Z�&--���<�
Fxx8iii�9s���@�t��PuZPP 9LIIa���[������f�INN&55��W�RVV�R�������O?srr"**���������6m����3� ��pwwG&�������*�J�QQ�%>��c�����D�V�{�nN�<I�&M�{Z ���fZ����O�D����m��>}��@�a�������u����������Z����?f��������S����{[�?
���Odff���oWJOOO���" IDAT'++K*����j5����iyyy9eee8;;K�����+++�J%8;;WZYW���������J�����N���
VVV��3�-Z������/^�d�>x�`���(++���I:����R��L��F#���XZZbgg'���<GGG�:'''��:��f��I��k{�h4������*)JJJP(�U��h$''[[[�s���%���i����|��'��=�NGYY���������Azz:dee���Evv6�;;;|}}�W���	

�L��C1P���~����2�w����*�J�O`=]�v�?����;w2{��j��M�-�@p*:�d��m���R�N&L� &��d2���<x�&M���������{��|��+W:t(iii�Z���m�V
9&���r����$@�d2���%��
�v��NNN����Wv����Fc%![.���E$�ATTM�4�to�Nw��o��y;AE�n������������d2aii���w%eR�r3������|�B����ma�6m*�'0�`���9}�4iiiR�8s����������p6lHxx8aaa��W��|����db��}\�~���zK�O�����OOOlmm���u&�@ <���<

e��2���z��u�y�G[������8|||x��7�V	P��F�a��
�������r��Ii�����������v����~���zbcc+9�����~��ic yk������V�}��%EE%[ppp��
��
������'9u�;w����������H`` ��������A������F�T�T*Q�T�T�;��?�����b��������73|��;�P�����4���2m�4���R��M�6dff���,9�B 4����c������899��];�1���d"22�������Gcgg��#��0��8q���{����y����K/U���;VVV���?�����i��$�����U���������9s��������u�VrssQ(x{{������!!!������3NNN8::bii��Z�Y����{W�OYY�������k���������PPPP��Z�hARR������G 
�@ T9!}������e����Y��V�Z	���,�t����s�2y�d�F#�F��Mh0�_RR���Y�l���c�����[��2�=>J,,,�����`x*�0;�����t����dff����������d����Z�
���C�P������~~~��SG�koo��*����};/��b�����",,�&M�p��UlmmIJJ�����s{����
���b���Y��+W����j��fep@@������akk+���P��M�����'��h���7[�n�I�&B	�����T*y��W)..f��q��f���#G�0f����O�n�P(�l������h�&��^�������������:)**�[!@�P�1�}���9����+�J���(,,|$�H�R������NG�:u�������'ml��pn>������G%�
����rss�������\�p�3g����FNN��_���///���OXX
6�A�����Q6����hj�8C�-����i���G�f���t��V�^
@xx8�������k�.����S��;w&;;�m����2�j�������!^��P��+�O�Nyy9�z�b��]�J�pu��o_��������������y���.����=��S�J�*���c�x���8x�`����d2���������osN'�����a���t�����giiI~~>�v��q���D2�B���������]�
��q���2$�{�$++����/_�����=���d���C4o�\
Ex/�O�0����7S�V-"""P���^��J��A��(4������ ��\�t)���t���6'~Oj��[�XZZ�������t�`0����j�h�Z������?9z�(�N�b����;w�Z������DGGCttt�J��R����QXXX-��'0�dggs��Y����|�	�7o&''�
6��gON�8��``��u\�~OOO����������?����]����#����y�&��)��k����&�3g��C�6��W�
��1���d�c��R��O?�������Q#�,Y��m��?>...U
~~~�3F
W�SU|��N�C%/��c������K
f��n>���o)�x�[�y��v���V��6m�$�j�Z���I~~>;w�$//�R���j��{��%--M��07������a������ Y1���ln}��ifA�������B���^��`��d��y�_|�}��0c�|}})))��w���!��-[X�b�f��Ah4�����������IHH��~F�6&*
���ppp���___��m��	X�d	)))���q��q���C��u��y3�z����OOO�u��|���[�q�F���N����*�������h��%|������/�d����sg7n\IYPTT�N�C.�s�����9}�4�����e�O����������*
>��sz��������/$aS(�$�y��$$$��gO&N����C����$��N����_����2���DN�:E����v�/��2III����6m�����/����%�6m��?�$""�-Z0�|���8{�,nnnDEEq��
6l�@yy9-[�$$$���,)�����	���c��������������EQQ�?�<���l�����4���2d�w������}��h�Z�z=�������3��x(7���o���o������/SVV���]�62��!C��������quu�n�������W_����7n�~�n�n�:�.]b��1��j�-[���3���2�c���f�i�}��$$$���Mbb"�7�������T*y�������>��#��^�'''�����-�F�������g�vm�Z��0ar�KKK�J%			,\�����s�����qppx*�z��m�\NHH!!!:T:v���9��#G��j�OOO4h@������"$$D
�hkk���E��:w�~~~Rh�����`��R����?V�\����7n\������b����@��BXA5����,]��3g�0m�4�Z�d�.x�eo������e�h��)���4h��oM�M&������h4�������,�����-[�t�R:u�DBB7n�������L�8����s��eT*?��3nnn���r��I�r9��
#""������g�QTT��h���~������T"##)))��k����Y3��i���CQ*����1y�d>��rss�������o�+++������/�O�~l{v
M�4�a��0v��AHH���.���\�r���p"##i��-���h4"""����������J!��DFF��]c��q�3����={h��)3f�`���h�Z����U�aaa�����h��m�������VK��i��Z��Z�#))	___���P(�j�Ye����
FDD������3���E�TRXX��h���h���v�n�0`�|�	{�����k9r��s���Q#��?��9s������^`��I|��7���c��]������Kyy9111|�����q�_Qv����E*8z�(r��V�Zq��i���;h�������j�^��N�#77�_S��/��@ T� ���KBB��u�?��_}�����<��_XX��Y��������������0l�0������;������w���^����QnM&z�^Zy���@�P�g������e*�J2+�e��(
N�>�R�d��]4k�L��YT*��F����N�:c2�����`0�����v�k��!//�L�N��d�����L&�V�Z����V:�Nr�WQ�U��>o�k�BNN'N�   ���")V����TZ��NW��*�d��00����r��0F��T�{�:���S�������#888��m[t:={����H�<QXXHNN�T*�m����#��9���L�<�:u� ��i��!���XXX�������`������%%%dee���AFF���g����"����LFPP�������������;����]N�w������7��
r��9N�:���5���L�4�
��j)((��������l�����s�@(����������6m�D�����B	��������+��������i��	*�
___v��A��}i��-����V�Z���X/
��JU)��J��4�5�.�S��/_�}��DGG����B���5[�C:��J�J����Zx��B�\.��/��������???������g�����1�RYIV*����B����O�{���vvvh�Zx�����������7???���0�L��U���D���ppp ++��/�������������,[�:v�Xiu���>��s233y��Wi��5?��#�.]�}��XZZRZZ���������_�CGGG�/_N�-���`���(
�^-V#F�@��s��Yh��!�5��/�$;;��?��k�����y��wqqq�����s���3���ysd23g���_�����}�>�����
�������W������e��������h())�����S�J������]����oJ~<j����[�V������Rc���DR6\�z�6�@ �@ ��W������G��M���d��iB	P��z����Y��={6�'O������<���U�{��a��!�h���7^I ��d���������w�aii��+WHII!77�_��BAnn.)))dgg�i�&F�ARRS�L�����C���~L&/���$p�����?0t�P���%����wcii���?�v��}��������RF����7Y�p!999,]�������-�d2�u�V������+K�,����������Tv����d�_�~����������N8880v�XL&J��{�=�|��]�v�S�N(�Jd2,@.���S'��
�����R����d����P(h��/���d�`>6y�dIA#���[�.�'O��5��#�}�����h40@���m��G�����!C�H��m��	��������|�r�7(�J���G�^���d@.����P#"<*%����\����TWfRRR*}/**���>�v��U�O �@ �@�h����e�z��I�:u>|��@>����]�x�����������i����A�R�j�*&L�@�.]X�bm���d���I�J��a���L���������4��ff��
��eee�T*�F#m���M�6����e�m����999���1j�(�����v���k��&��W�*���\I���v��s�n+�{i��
�f��"
���5��L���
�=��1�W�[��w�LV��oM�N��byU������4s��[�wk��(�����No=v���J��wy���*��t:�z=���w��^�����888T��())�g���=�l��8m��?Mii���y�@ �@P'F&���-[�p�B�O�����;w~,�������w�}���~J�.]��u+wt+�����������5kC����J2{��z�~�:III4m�Tr�u?�W��a4����k�^�^=����Vj�%����n!��s�{�7��]����o��L&����3g�v[���d���8;;����H}�L�V�%55���k���v������������2��^�?�@AA'N�k~�J%^^^�+++�r|i��-���,K������|����������W �@ �sJ������+�3����K���'(����?��N�7�|#�����n>g���3q�D8����O�:u�]�R����+QQQU������t��
ggg�z�c1�6����{��~���J��&�O����y�����a��M�vO���q��K�����W)��\�����RT�_��W�^E.����)����Y�z5=z��M`���������}�v�T�_�A�?���c�)?��F����k�D�4+��vg0pww���I���������z���<���Obb"g��E��1x�`a�7eg2�x���Y�f
�����_�V4���*�f����z����;��g�}F�N���G�ye�U�V�X��d���W����0��O�>��=���w��m[|||puu}������y����)S8p 666��L&j�����K�$>��s�h��5���DDDP�vm�����k�k�&##�N�:���IJJ�q����A>Lzz:��u����s��q��a��m�L&c�����[�:���K\\�w�&44TZ�7�Y���Dll,�6m��_~a��q��������HMM%,,��G���sg�r9k��!++���T�������9}�4=z���������j���///O��dK���\��&--�f��Q�^�{js2����RSSi�����B 5�P)���3gZ���_�����_?���+B{�aRh690`J����bbbn�7}�uP�~}�/_�������?S�Ne��I����6���W��=����S^^N�.]����1�����~c05j/��2M�6��6$��ppp���4o���k�RPP��A����/�����|�I�&�������^���E�7n���#))�����n�:�J%`���L�8�~���^{�;v��Olllh��%��7�����s����-�}:v��w�}��S�8�<z�������}{6n���5k�3g�Z�b��=h�Z�O�����	

����g�}��7r��i^x������u�ns�$��\.'99|||0��r�Z�)��e�h4"��Q��R��\.��4��0��|���%K������a�9r$�f�"22�o���q#��m����f���|��G�������@ �@��)����H�<���'i���(�*�y��1m�4^}�U����J|u�������'<<�A��w�^�/_^�a�����������)S�7o���c�������F�������i			���{4l����)�J�z=*����x���qtt$,,��������F���Uzxx`gg��}����111����f���z�j���qww�����<y�#G�0b�������������1r�H�/��L���+	�n����U+++��9����:������B���),,d����_[i,--Q(�����7��7�BV>I(
RRRHLL���ooo���O���9r$���dff������{	���K|��G�Y���W�����s�=G�-��o)))���K�L���t��������i�&�/��k�����z���;���J���_~���C�����������Tu��=|������M��]=z4������+,^��u�����?���[Y�v�Sm�$�@ <����p�����)//���K8p���?����O�<�;�����'��e�d
_��;f�C�����1���P����w�.y�~W�L&vvv|���>}���xrss9v��p����W@@nnnt���i��1`��5k��a�h�����R���Sn�d24��{B.����%]�����U���%Kptt$22���;��M�O��W_}ERR���]���r9���R?��?V����gV����T*Q��O\=���8z�(��Q�8p ��]�^�z\�v
;;;^z�%�����u��t����G.�����K@@vvv������c�6m�{��m��>�_��^�z��Y3���������g��=l��	�V���c=z4�;w����5�p��5���IMM%++�_|���h�{�=���#)�&O����7IJJ���b0�@ �_}TDGGs��)����-[��C�X�r%/��Ou��d2���IHH��/��e��$$$T*�{
_v?�4_��������_|��)SX�nS�L!<<��|���0�
4`��9b��Ah4>��3V�Z��q�����m���k����WZ)��mk4���U��_�>����i���:u���/���CFF��]�������������������6m���=e�]� IDAT�����y��S���_?T*���

�`0������YYY�9s������D:���%�������={�p��.]����W�j�������Mff&yyy\�r���,���h��1�������>}��3g>���`0�����$&��.]��a�rss���7������b4Q*����SXX���G����W�^h4������|��
������d��E�_JU[[[JKK9t�����3�F#�[5[pl���e�����h���:u"??kkk����p��/&77��/J�U]]]1�LB))�@ <�����SdeeU�_]��r������+���:t������T��V�e�������={��ys6n�X��U��������4m���C*V��|�M��k�������?C�e�����r7E���?j&�	KKK������#33���d�m���)S����}������6�#s����2�L���m��h4�k����(����`0��o_���899a0�����z&N����[����`0�����7�r�
�V�B.�3x�`


�����������V+��[�.S�L!77�j5qqq��zJKK	�V�Z����h�"��������7�������X������t������_���1c		y"{f_���'((www:w���)Sh��5����d2�\����;�v��?�<���(
rss���G�Pp��Y����H}���rv�����i������h�{{{.]�DNN666��]��~����|�J%III�<y���6l���5S�La������������%%%xzz������gqvv���Tj�����@��{��D0]�@��O�e2����\����H|}}���yd�C�\��` //�F����S]F����ti��h��~�����'yyy9r���
T�mA�V�c��N�
�_|A���J� ������r�^�JJJ
+W����C3j�(F��B�`���$%%1i�$j����/�{Qt]�~��k��J�7n��������l2�(**���OOO,--���e����?��_��s�4h�___���%A���	'''���(--�������z=aaaRG�"��G�n�����p��
4
���xxx������
���������������OOO�j5����T*ppp ==GGG�F#*�
+++����]��tO�*�:v�X�BLL���a ��I���~����;w.VVV�U������d�w��������5���~[����������[�nt���3f��];�
F||��9\ �[[6�+kkk����O�>\�~�%K�0m�4����A�())a��i�z��^�2_����8cii���~JXX^^^�F���������`�t
��O���;;��2v�������e��`ooO�z�*�cccCHHH�������\��*�S�K�{k��@ x����o)//g��qh�Z�(�0�7;[�z5���L�0��&�W��=��a����">>��]�J��1Z��fs���a�.\����U���w�{��4j�T**����%���R�����(�$�^ 9s�'��
C%�'��nEX�#,�S;��o���L�<YJ[�`����S!���H�D���o1�L����/�����Dz��Q-��+�!!!����h�"&O���e�x���������'AM�V���={��gOrrrHLL$11�W^y���3�<C��ui��!���8;;cgg���-666XZZ�R�$�nU�����N�C����W�����1�*�L&C�PHa���������GG��,~g4G*x��F#��,���?���A�Z������iD��3u�Tf���\.�&%�>�,��o*������7o���;88PXXXi�?z�h>��S�����Y���_~����`^{�5:w�,:��_EYY'O������={���tn��!	�
��B���5���XYYaee%y�7�L&�Z-j����2�����t�L&����oUSQ��+��+�/���]�6�<����'""�J����;Y���Uc�����U�V��%,�����d���4o����G�-�Q��}{���8�<����X���B�[o��'�|@�:u>|8�}��#�x��1��W�o���[��!C�T��*�����e��Y<�5k�0v�XBBB�:u*��5�Ma �$�m������Ih��t������Oaa��`������b���P����j�F#����d2T*������YIP�cN����,	
�A�h4JKK)**"//�s��q��I��_O^^��������}�J������@qq�S�0oIB 5������*���D������`��U�����_�?��#F`ee��%K�j����2q�D�����i���8::��o_���X�re�-s�5i�����?�g��
��!C��������}��,X�������
������[��R���������gU\��x�L&��W�^^^�Z�&++�_~��0i�$��3���~d�P��SRRrW3|KKK�Z-�kh�T*�g�S��������/����oM��sj�x*�@ <!
ooo4hP�'�������J{i/^�����a0��cm��a��=h4����V�%  ���`V�Z�o��R���~��eq��M��9�X�
������`>��3��������5j3f����W���4�����|�rn��IJJ�$���1 ((��i�����7��\������P($�777"##y�����{7��O�����^{��3gboo�H���J��B��A�G}���#quu��������[����C���������q'���s��7���0�|���CYY�C�_2��s��1u�T����S�c�������|>��c����h4,Z��c����7�p��M�x�
��k':�@ �@ ���4m��I�&��������=z�����:u��6Q����^�x���l�?����(�L&�_���G����o��Q#������������Dy��L&����|���8::2�|lllD��v������<x0���(��������m������}��1i�$�y��y�^x�����(,?��
���������D\\�O����~����V�Z��3������k����'::�������h4���'N������~~~�����G1u�TN�<����qss#;;���������c���'N���������C�Vs�����h��)��q��{�"��h��%>>>�Z������e��4i����w���x��	c��a���xzz2~�x.]�T�g������q����_?~��WN�:E�����-[���������\�@ �\,--9|�0�1�'O&77�+Vp��E��]����t�yo�Y`'���������������u�����w�����l������*��'M����?����x����4i��k;vd���:tH��y����+��[�����������?��[76l� E�.��
����t~��g�4i��+W�r�
QQQxzz��_?���)((��?�$22�y��������������rZ�l�L&�Q�F4h��N�:�R�$11�JEvv6�O�����l�������s�N��?_i+�L&����8p�~��q��
._�����)**�c��|���l�����l\\\�x�":���C����H�>}$�	s�����3�{�n<==���������ckk��#G�_�>�������\����e�@��!,������V���������/z��u�����Jnn.�-�O�>������b��9�F�����5�����0�m���M�68p�_~���S�booO�~�:t(NNN��'AH3�������7��|l��]���������}�������SY�x1?��|j�O���c���t��I
��y�f������c����`����^�zq���Z-�����z�F#Z��� �J4�L�i{{{����H�P������r�,��P(�]�67o��^�z�� ??,,,3f���$%%��I�y��^�
@�v�8|�0���#**
�L�F���O�^O��=1��������
�VK�
��gO%�tE����P��]���EEExzzT{d�@(�@Pc��s�m���.]���'7o������3�y�����Nnn.��~����R�s�G$��h��f��q��Ev����E��;w.���c��q��^��B������4���@)-11�/�����;�^_#��L&���O��%��/���y��������:;;��;���S'��O���IHH ""��pr����|��?���y������?�[�.&�	�F�N�#??�'N��kWI���dRx��	&����R����W�\����d2
���G��s��%�u�&��|���;������2�|��kG@@��������� .^����-2��c��!	����X�{{{:w�|��}��!!!�������Add$M�6���#����s�N�r9��og���l����W��c��{�9�r�a�)5���rJJJ*���z����h4�V��h4deeQ^^��h���XZ��8�T�"���[�.�F�"99�o���#G��s�=�����k��4�A�{��q���*��������2[[��w����`�$*
�{�9��Y�T�Cs�j��1;w�$..��M��d�i;���;��������/���������3f{�����K��]���8.\���	8w�DEE���%	�r��n�����Azz:j������q�FBBB���F����������������b@�P ������C��^����(������������d�y�5jDii)F����{�P(���a��Al���Z��d�V�ZxxxTR4�+�g�����U�V����Kqqq�9;v�S�N,\��e�����E�~�ptt$--���x�R�a ��0����*�,��ku����]�r��If��ATT���L�0�g�}+++T*�c���c�h���my���!&����z�����e*�
�B�V�������{����q�HNNF��I��5YeccCqq�Q�Z�����y^�4�\���i��9/��"���������`0M�f�0�L�B&44�
H��v�Z)/&��V�ZI!��^y��F#:����p"##1�L�T*%!�h4r��i����*��V�ZAxx��'kkk���$��vvv���_�&�	�RI�=$�^�'::�K�|?uc�?��
�-m�����Wll,����9���<��u*�@ www|||�j�x�������[���e��aC��[Gff&_~�%S�La��������={J������K��v��h�?>�Z�����#--�=z��j�v����'  ��#G"�����[�l����F�@ZZ[�l���`0���{,����}�^Oaa!���UW����ji����|/�>��'O��M�J��d21p�@���0`z��?�++���f!���T���j���v��P�^��t:���D��b2�

�}3z��Nw���<T�cU�=l�����~w�@ 
�@ �6^~�e�u���N6�r9���O�S�b����f�����9s�0}�t6m���
x��7pqq!66��;S����P��j�����X�R��qcbccIKK���[[[.\�����Jzz:�O�&%%�V+	�r����V�\���	���`�O������n��������m{LOO����c���U��y3�f�������r�r9���������4�3**��k���o_|}}3f�}�+����V�x{{WZ����w�����RN 
�@ ������T��[XXZ#B��t��[W�lmm���?�������Z�353���H!$$� ���M#WEATD.
zQib�ZQ���""��.%�J��I�>��s�	��r��f%s��=����}�����d���9x� �6m��o�����>}�0d�������tm���c��)..&%%�S�NA`` �w�����bVq�RYcT�T���FAA�?�2��>�?[������=����O��+��r����t7��;��2�����������~���
5�6m��?��#F���Dtt�M][��<��b6���=&$$$$�������{�4]]��A�w�\:
��J��')�W�������A�(..
3f��e���9���_5)F��x�p�.\�X����$''���0���L��$j��\�\.�Kc�d2f����`�h4����N�#))�s��1k�,����8q"�~�->>><��S����_�����y���es��%11���,X@ZZ�����3G,7{�l�����5kX�b�������f������3v�X�z�))**B�P0c�V�\��#GHOOg��y���K�6m�={6J�R��INN�[�n���K���Y�l���:k����qd�ZEO����h8����{!U������|�^J����t����kJ����v��w�������dl�����w����RUU%���t��6�LF�v��s�������SRR"��x�����z�puu%,,���G�w�^�=J||</����!C��s�N�����������5�/Z��#G���Y3f��)*n�}�eee8P|_ZZ��je��Y���g�N�<��o���A�X�j���b���;������6����'c�ZY�|9}����,]��n��Q\\�����������`������0s�L���Y�f
�z�"33'''���i��
s��e��y�T*,:t`����9s�C���cG�y���i���+�S�			<�����wo�t����[�;���9�u��q�������f3�������+7,x�����WR���d����x�����6n�Hjj*�W��b��o�>�\��J�b�����fv������Y�z5UUU�L&~��WV�ZEZZ����������q�1�^q��1��f��y�f>��C~��'�F#���|�����7���6l���C����O���@�T^��*77�o���?����,�v;���|�K�.�����������a�V�K>L���0����)))��~�j���_?bbb��cz�^���:���\�dAz���(}�k��e���������Jf������X�p!eee�l6������['O���u:f��O�	��f����g�}FFF����gBH���222

 66��'O��x�T�k���W�3g���������k�
���ip=e2**�����l��[�Q�y��<���\.��_uu5&���6a�R����Y�j��9Z���F���]�6���q^)++C�P\slm��z����[�������sNYYz�����I
�+,,������/�������/_&77���j��IBB2HHHH<�8��n��O>�$r����\233������s�d2����������������i�&bbb����)**������/w�JE||<;w�D���o�>�L�B�N�X�p!)))l���%K���GRSS),,d���l6^~�e���M{�����������d2����g�}��������#������h��
6l ##��5$9
��<�+W����K��9�+W����/��^z�%.\����,�W�wT]��K�
HOO ??�B��������f����J%-Z�����g���L�4��L�deep��)bcc����'��bA.��P(j$������vN�>�������C�b9=�L��l�5)������
�1���8�Z�;v�����;vL<Wqq1����j�"�����,^���7b0P*����Euu56����H�y���Ys���RIyy9�������T*������q��q��l6��������w�^f��I^^�X��������;V�KJJ�>}:S�L�j�R^^���SY�r%S�L��#C`������O���[���kTVV��[o������_�g�i�JH�!R			�{��	��m6&�	�ZMdd$�������'�|���N�����z���������^�z8;;��c�����L&#99����`��+��|� IDAT!Z����h�,YBLLkB?��S������������a����
�W�������R���KTT����l6�������Y�f�<y�����l�$?���O	��L&������3x�`�z=G�����Y���>��VK�f�����������������:u*M�6���6���+�]��U:t���#GX�f
%%%����I�&��w����K`` �?�<����C�6��@�&M���%..�^O``��|���������k�R�N�������?���8{�,qqqddd���O���1�Lh�Z~��W��?O�n�HJJ"77�'N�����K�P*����s��q�������O����777�F#NNN���'N����� $$��J�YTTT�������s'����8q��}�b0���������4v��IBBG��g�������fG�HNN��N�:���$''S\\���g�j������wo���Cyy9���DGG���@EE%%%�F�v;r���~����@�w�~G�f�LF�F�DC�B��s��4�7�|����Z�4��
�d2q��^|�E��=KQQ�?�8���DDDH�]BB2HHHH<�(
�����l��v7n��E�8�<TUUQVVFqq1�O�&>>�N��?�HHH;w��E���v-ZDDD-[��n���Euu5QQQ��v222?~<���
			8p���`������b������+t���
����n�f���������!##�JE��mQ(��������w/]�t�n�c08�<J�R��.q�{�L&#00�>}���O������#55�-[����oRXXH��-			a���;v��^{�#F\7����>K���na�!��A���??�;>����������V������S�RPP�N�#..��$�+���������l���������~*�P���F�IQQ�z�B����iS�6m�J�b��Y����_~�Z��j���Q#4h@pp0r��a��QZZ���eeeh4�Jii)NNN,_��JE���E���
p��Q�\����qwwG��b6�����������j������'!!����={����G�<��S���C�'66777BCC	#==���T1q�����<x��L�������������aCZ�lIrr2���#++�3g�0`�"""���4j���[�#�:w��Z�������N�#((���L\\\0`�-����<��s����o���j%>>����SXX���6l ;;[�� !!!$$$$H�f3;v�����������L&����n���n�������!*�V����W��U+����S�:���������'0j�(���HLLd�����5���x���Q������|�r��O�
�����3g�&""�������\.�w���3�5k������f�T*���>K�,�k�����C&O�:������.�%dx{{���Mll,�h4������+��q#YYY�����9s����Z�__��r����-Z������wr���B����~��h		�#@�,�/����O?������+����������&aE����[�nb(��9��...7��d2F���k�����^�G��#���4i���{'��ouu5��������`��l6
��c���{�n��Caa�M)�B��h���)++�l6��jqss���
�B���C���d����o����{�mp�C7�$B8�@EE?��3�<�����X�B�}������2z�h��Mtt4��7g����@BB2HHHH<��l6���:t��PX,�z�h�?�Z�jE�F�D��E��j�J���m{���`���1cv����$q{�V�h��U���|���q%Z��W_���>�l�������)S�m��NW�<R��[Se2*�
�ZM���i��k����v�{�=t:����n���b��T>�������j����n��}5B(������f*����=M&V���y�\�*����F���G]w����v�///<X��}���Vk�Wuu5iii;v���L��=��={pvv&>>���\�r9�;w���������{����F��l6SRR���3M�6e��������� >g�FCII	����
t:�����������F���Z���l6bbb8|�0EEE��3�'�|���H���0t������M�P���i�F4B(
T*EEE�����S�Np�ek������������&33�:��~>��V�^-w��!��i@������O������V���{!!!$$$$��LH�%���8V��F��k������Xm�-�������������y���\��������>��O�����T*���qvvF��q��!JJJ��R��hX�h�G����Z�xV�EA���l5������Q�h4�z�ji������zFG�}�]l6o��V��.$77���y�Z��s�NN�:��q�nh����n��?3TTTPQQAyy9������Nzz:999dgg����F�������pZ�h�������������1y�df��-�S���{l���_�>UUU?~\,M��h������^B�T�T*������G����G�j5eee<��sh4v����+W7n��-#<<����7@.���Q#<==��k�G�&22���o��Fii)���*v��^�z�w�^
m��E&����Grr2��#!!��F��]�j�w^����^�'66�E����/�����n�:���i��=������+5��x�|���|����i�����������t5�U$$$$�����5���p����B&��B�B� ::��Vk��������r��H��wQ�n���5F��������G�P*9y�$+V��C����Ftt4nnnddd��j)**�b�PVVF��u	

����a��h��r����L*++i���=�f����S�n]�.]����IIIWp[�j�F�a��]�����j���3�����������#��L&���^b���dee����/���B��f���#�p��%***h��%�������Q�T�����gO���O��������2������K�]�t���l�>��,400���P�u�F�z���� <<�VO���P�7oN�:u������r����D�7o��h�5n���"�������>��l�j���[�!��������3g�\*�
'''"""����j�b2�Do2�*����{��b?����%$��_��{�	��&l��t�x}������#>{��Nrrr��'''F�q�m����~C$$$����D�����P

v��Ry�����$����h2�����Q�2�L����V���������;�j�*^x�RRR�n����?�i�����B��}Y�r%NNN�i����"������������7RXX(*)G�������^#((����3l�0V�^MFF���b�E�U�VQ�n]�����j�Z�-[FAA]�ta������S�NN�<��;h�����,[��=zp��Q*++y���QJ��n';;�.p��y��?��s�����)..���
�N���'�����K����������b������(�z}��DFFRPP����M)����q��[�6o.G7��sm8�G� ^c��fCj�����ry\�������g�l������ov�����N��H�)!!$$$$�"���)))yh
j��� ���j��L&#22���r�������i������l6���t����S�RYY����EC��$%&&����h�Z��kG�~����+W��p�B>,�>�;��^{���x��f#""�������SZZZC�Q(����A���I���9p�������p��q_�NG�
������sK%�j������s����$++���L222(,,���
777���	#,,�6m�P�~}���qrrB��������S��Go�������@�<�p��/����;��S�|�+��s�<(��A��;v��A�xzzJ����d���������d���[��*7�[���U����_m������J�p �3������xzz���������\.������b���P*����2h� N�<���'v�����SQQ!�1�K
����l�^����L���#�w�NGJJ
�����c��/|���I�X�v-&�	WWW����<z���={�F�q���A�KO��/r�����������'���#22���h���Kll,����k��	7��n������(��
0`^^^�m����7�������������<��������d�����5EE*�v;F��]�v��w�k�>�����f���ddd��}{Q�{!���s��4_����W����hX�f
�{����������������Ox���k��f��-[����Nbb"�;w&;;���7c2�HNN&  @�p��n����W_��kW���y���5j����l6�T*9s��f��1��aC������7n2����


h���=5���u�"�����+~�!
4 55���x�z=c��!,,���XN�:%V����j���[o1m�4\\\���qqq|���:uJ�|X�r%[�n�����s���E���Q��������u�`a��Z�X,����l6c2�((( 77���\������C��s��e�z=%%%b�������DDD������H"""�W��
K��o�`����7oz�����?e��>}�����WWW��k�F�y��W<�����Y�`��
���%$$�������eeedggc��C��q��IV�ZEBB������PQQ�L&#((ooo����R���b6�3g�$�hR��������B��9s�2����r5jt�K������R�����:u�p��)Q��W�r��3g��T*1��4l����b�-[Fdd�'[TTDAAw$�fgg�}�v,XP�����'55������eK.\��+HHH **���G�n�:��=D�L&f��!*�������1|�p,
����J���h��=f�������2|���X,�������{*����������;a�}�����S�N��m��Q����M <<���;��}||������y�N�����SE�j�RVV��j�`0`00�5������������(++�`0P]]MUU��������	777�@��	

"((���@n���z���J��n'  ///N�<I```
o��c���W_���M��uqssC�P�q�<�;G�P �����D��s��Q^|�E���%�_BB2HHHH��0�y�fJJJ���B�fA���f��]���q��E8��q���o������_��|���V+(�J�m����111L�>�;v�f�6l����1�L�i�����Z�f��y4l��LFaa!&��+V��o_RSS�dUK�,����&--���,UUU�������\.'//����z���NTTQQQL�2����>}���hv��I�.]���_���u��a���R�{���dTUU����f�r���o�����;����~����������/x��������P(��os���R�D.��V�qwwG��������www<<<��N����ww�u�o4O�����&��pww'11������jx[���3q�D���Gvv6z����"�,���V����A�R�����9s��0&!!$$$$$�cccY�n���2��N�&Mpss�a��\]]9x� v����Q�����y���j5����l6�6m��bA�R�R�j\�����
�������i��]��O*����i��QQQ��ng��-�����m[�f3d��Q�����w��V�����FCBB*�
��Bdd$u���a���U<���8i��J�
���_�h4�1����oo�k����es�{�����J�N��cf��-Z���)������f#44�a������Z�F�R����D��u3������Gy�i����K/��� �e�[��u��X,���������{�V�k�%��		� !!!q�h�ZF�Ijj*��o'<<\�/��dh4-Z��U���o�/_�V[Cyb�I��_@pq�������Va����+W�`0������ULf0pss�h4��uk4h��y�8v��<�H�|2����brss����#���6�d2�������		����;F��}),,�������v��I�E�V�����~��G�MHH�
��1�0*QB�_|��3���W��RY�<-����������d�����S�F#��/G�V��O�r9NNNxxx�t�R���C������/	

B������Y��Z�����m�6�.]����i���6m�n������f�b����BNNS�L�����f�����3777�4iBRRG����>�j���O��h���8~�8NNN4j���@����OIJJ�Q�F��z����d2G����~B�P��7���W/�>}�hx����;w.���
M�6�e���]��O>����g�}&u�WW�k�T>LX���u���]����<���1y�d}�Q����
���?��KH<4��.�.IHH<������l��F�'���')**Kv	��&�I\�wvvW�5M�l���J�L&�h4�+�
��F��b�h4�T*Q��X,4
���;�/&))����S]]��+D7\�nz�f�P��bj���V��PM&��� (m�A�&�VJ�R�c��v;NNN4h�@,sv3sm��f�
�&���2�������k�^�Z����w�}GNN�&M��=##�K�.�P�v,�w+(�J,�_������W�X,�i�WW�[R$o������[eC333�7o}��������~��o���?�(z(IF		��������u�Z����5��k>�:!�������f�'''�6m����l6�zM{��\��Bmm���W�'��F���p=a�F	���]�L�Dq�32n���V+/^+^���g���J%	�V+Z��-[���G�o
c��T���z���\�B��� \K0�)�J1�B�������"����6���%>o���L&�����[���}{�������vV�\Ill,�7���e����!11Q��&L�`00h� ������Ck�pIHHHH			��c�Z��S�N�l6Q�V��W�ngW��APzN�:Enn.���C�P��~6m�D���y��'pvv���#���������3v������R����4l������}�j5111�������qss�����Jvv�x����\.����={��-[����\.g������'z������� �������Y�b����Y�f����-Z���Z�r%;v� 00�V��-[X�~=���4n��LFff&s��e����������pT�_�u����<y2YYYL�6��������
�t$$$$j*�Z��/y	�����k�Z4��6���=�rv���o��F��u�2e
Z����@���i��Z�����#G���jY�v-UUU(
f��Myy9!!!�L&Z�hAEE-[�������t�m���;���`�������J��9sDGe����l�����f����l����/V����,�m����/��2���?~������quu�^�z4l������3����J�^�z|CE�S�N��������N�n���8���w����y��7{������,Yr���`2d+V���o�%99�����KHHH���<$$$$��������\�rH%�$��Z�f��=h4�y�L&�'''�����lt���m���}�v�X.����V�Za6����b�	���1���L&����Jee%���t�����~�JuM���}�����~����1'''6m�$�l��?���(�J���[���CLL���S�T�����`�����~���Cc�����h45��;vJii�5���D&������/���%K

���A���S'��{�����2����B��y�{�9z��q��S�L!00�����~���L���+�v�z��D�f�HIIa���DGG�q�F�4ir�'�@BBB��.^ IDATo����),,��@'�)_o�-�F+D&�	�����S���w[���U*!	����5+�W�W��{;��ne��2z�����9o�5�~��z�l6	c���<�������b;�v;J����W������>���k�A�V[#���?	q���'�1��*&���?��j�F#6����bprr�`0`6�����Ff����X�d	���'99Y��J�^������P[���b�J%�����{�n���9{�,
��G}�����2|}}�0a>>>��N�F#...��jF�IDD6����r1W���v����
1��F��wwwG�P`4����������
pww�s���L&\]]��d<���bH��n�!�����������;�0x�`1�jUU����j������l��������M�K6v�ihh(�v�b����k���c�2a�������������
L&�m�����J�
9>�P		� !!!��G&����k��v;���4l�P\�t��/��:t����������e2���l��???���s�dyr�\TRj�����n��	����())!""Bl�R�����c;o�>���s��E�F#u��%88����={h������WQQ���Gqqq!<<ooo:�B�@&�W\�o�y��f
	�+��L&���������5��L//�;6�
ljj*6�M�#���rN�:Ejj*���4n������3:��s��Q�N���)..F���} 88����j���qc�?Npp0���:t���,�V+...b|���M�^�hh��-)))>|����3n�8���������q��xxx�����^�z��M����Z���[�'N���C`` ...�;��k����$��8q�/^$!!�V���NHHO=�2��s��a6����$77�7�x�o��������d���s��I�6mJAA[�lA�R��h���;�������KBBt�����8�}�]bccqrr"""����������{�f��5X,BBB���f��Et�����@f���k����-[DIhh(�V��`0PPP@�N���a����K�.�T*	

b���L�:�m����aC�v�Jzz:�.]���E�l��Y�K�~Ks��7���s���?��M#))�^x���������(����r^^999������(�J"""���%((��-[JI%$$�����?�\��M�X�~='N$,,�;��`�Q�Fh�Z�;�o�����	������4����DcQQQ\�xQT������I�
pwwG�T��o�!����a�������t4h����"��[��s�x���i��)v����T����8�X&�QUU���qrr"**�g�y�_~����4^}�U�{�=�u�V�����.����������y�x��g����(,,�{������={�I�&��?�5Av��
���0a��Z�)F���I�����	�������������g���O��0.|||(,,d��)�L&t:={�$77��B����������0����Z����k5*h�L&�x�
�z=6����p���)//��g�E���u�V���OPP]�v����������;v������\���R�$99�S�N���LXX&����������iSBCC1��m�OOO�jFee%�f��++�UUU<��cTWWc0�j�>\,-
���G�^���l��?�q��C���yyy�F&N��+��B���3g?��...;v�a��QUU�Z�&44�
6��ukL&���<�q��1q�D:w��O<��ba�����������������{��4i��5k����o��#��n�:rrrP*�|��7���/�;w�BA��uQ�Tt���~����73d���[���)..��O>!))���x���0`���~~~<���8����[
p��j��-[�la���,Y���������O>)>�Gx�����W_a2��S��;w���E�Hs�~��v;iii���o����������$$$$�����?�
�j������/G�T��e�6laaa������k��������@�y�f����b�f�]wJ&������j�*z���_|�����������F�Pp��
����y���IKK#++���{c�����'$$�����+3g�d���5��E�R����JAA���A�4l�����g�}FAA���#55�+W�������;&����������7o�]`���KEE�u����s������8g�>��"""������m�\8_�:u		��:��������8����
��9-z��}||����f�a6�			-�RIll,���#**
�����/...5���j�����6���
���'�m/�LF\\�X.����{����v������a�����C��b%U*G��M�6DDDp��ibbbDO#�J%V[p�����'22���<�=��S��_�>
6d��aL�8��]�2v�X���^M�5`��U��j���/��n���d2,�&"��qqq��~a�X0�\�|��-[��U+:t[���Z�f��������7���_2�|����c��3t<��y�

�{���
/�[��C:��	���O��3�T�� p�R��������e����G���(--]���g�RIRRr��'N�{�n1~�F(
����J\\/��2���,_��^�z���)//�����k�F���Q�T������&*e���|��w%�� xGDDp��z������n*�AII	r����*���0`.\��7�d��Mw�@q+�����S'�v;���G������y��'1�l���&M��`��BAA/���G���?����'�x�^x�Q�F���/��{�Q]]��'x���x��WX�x1eee���[,]���G�2p�@>��S��m��S�����O�>���[8���wc4�3g�x~����?�����y3F����\���k�w�NAA�]�wA��m���;���-o���;�Kxo��1��������pQ!���$88��� �%����c��p�mr�(���(��m�U�>W�w��Z�DGGs��E�\�B``�j$���P!a���St���_|�7�|���`�����>}��j\�\(�5j��#G�yV��B;?�!|�P(prr���O�'O��
w:���1l�0RRR���/���_	g���=z��|w�M�6������h�h����|%$$�^H�!�;*��gm���+���`��!|���7(�'�;��:^����O>����4V�^MLL�?�|
aS��n����x�"&L���?�e��b��r�U;�>""��@LL�������q�F�J%7n���S���#��w���o����c���A*++���+S�L����c��TTT�c�,_~�%�>�,/^�I�&X�V^�uV�^����h42�={������#h��M�6������ ������>Juu5���g���DGG����2a��5k��3g8p ������SZZJRR>>>����u�����#9{�,��og���w�y�U�!o�`u���rY������
/^��)S�j�����4�������	����C�q��:��f�o��|���L�0���h���Gxx8��oG����o�P(����������WWW��]KRR�����������[�2r�H������>J���5j��������9s�={���j�������������<N�8���9~�8�=��1�w�������{������r��VK��=���'���w��e����_�#F��������R��f.����d2._�Lnn.�
�3,���TUU����T*�W��������]�h���� !!$$$$����R���/^����'�x���7���;!!!X,"##������777���9x� aaaa2�����n�����N��ct���+Vp��i��Y��1cx��'��iJ����0�8q"��S�N���a�Z	������z�mz��!,^������F�.]��		����b��B����Dt���{7��-c��L�:����HLL����Q�F1k�,�=��O?}W�4��<^����%^@�P���N~~>�|�
%%%h4�!���X�V�r9�O�K�	^�u�Ura_������FVV��c������Z����~7W=<<��b�0`�Z���1e2yyy���\]]qww���U\���!MK�.�q�y����o��M����l��U����+k��c�����/�M�6����1����w��k�	���X����>���G}Tc���{-������q�F���Y�d	��-�����a��t���N�:������nnn�T��������f����c�\�B��}E���F�a��
<��#�d2�J%����������K����d����xp�EowwwF��^������C�r��a�f3O>�$
����jf�����gqwwg��A�8q����O�N^^W�\���]����jE�XA�KLL���������=WWW���C�P�����b4y���8t�t�����*:t� &F��������S��T�����Grss��?v����0RSS8p��L����qc����3��g�T*-Z���> 55�1c����s[+I���S^^^C��3aZ&�a2�D�f!.�l6_�M�?n��1����1�#F\#�
��j%!!�3g�P�N�kJ��;+���hHKK�$������|����qB�����[1��eee���{>&�m�y<(X,�Y��{}O���7nZ��F���+���b����`X�|9M�6%66�O��w_��Wm�������I��4i��g�������U�V���B@@M�4!&&�����������}����4�������8��������3���->>��d����:�f���wQ(xyyQTT$�gB	EGt:Z�V4�JHHH			�!��v�������h�I�&�{AP���'  @L,��El6��R^C�������6�
��F@@AAA����b+	�S(�k�N\I�����PZ���oX�f���899��p�.$�r��������5������ ""�������#Gh��=;v��'��U�V74�d2222����7oF�V����i��
'N�@.���m[N�>M\\�N���G���K,^�OOO:u�$&���K�UWW�`�RRRprrb��!h4L&v����,d2����F�V+���TTT�a�������/Q��4�;v��KN�<I���<x0��o����������l�}7��z�l�2��J%&���x��\r��^���'�j��m�������D����t_�R�73.��c���)�Wo�[
��j�m�����k�������9{�,����������������i��	��m������@����7>>>�x���w����qc7n��q��p�������s���m�F~~>
����p7nL��
���!**
gggf��AQQ��M�s���d2233ILL�a;�-[Vk����O��8���'zn��7������2� !!$$$$\�5k��;h���-�W+&������q�P�( Y���]�\���|�m�~W��������LB����[5H�d26o�������d|���������P^x�����s���`�Q�MHH@�T2�|Qi����Q*���5�\�F�a��Q\�r�R���c���n���h������I�����bA��a��7n�G����h�Z-����<nnn�i����1������ �R��o�-n������L�2�Z}�����0�����I|}}�l�
�����jE�Tr��a���������(�J�.��jE����}{����k�t;r��R)���E�O�T���m6j���3g2}�t���k�l�(����C�L���{y��g8s�W�\a���xyy��S'1���3j�(&O�L�-��gK�,���������Z�&<<\4�	F
��@uu�hp��������z���8u�yyy\�|���R�r���S�D`` ~~~����G���P��WZ�IIITVVR^^NUU���g��}?~�u������J�������R
9|�0`����L&�F�
�]��p��_~������];z��!���X��a����O�����i�n�{X^^~Ov�@BBB��������u��^����`X�5�w;��n�{�������n���G
�����9s&���*�f���������...������R�Tb�oOOON�:�o��o����+��@@p���N��v�?����JLL��Q!��jm�p~G]������ba��ml������������g+,QJQ�*��%�%����$�h�Xx5��Xb�	������b�(��(�"(*b���ew��� ����<�������9��9��{��3�7�F���g��������f���={��k���h�������C�K�z�����`0`iiIff�C��L&#>>�#G�P�Z5�6mJAA�������k��
*PPP��;����M�6�����pww���{{{��9�\.�~���l��d2.^����)�.] ++���\����P�v�G���W���~�94|�p��?��c��~�����b�F0��J������v��w���ILL���[��}�����c$&&���HJJJ�v4�L����"�����acc���
������y�*�\���R�w�W�N�6m�����%**���p�O��oI��u���y3M�6����_�}q9

������
4�������#��t9r��+�p���v
��R��i����OY�p!���l�����&����NaE�`00i�$���S�!P�|y�O�����	g��E4n�������{� %_|R�Q9���Sb���54h �?{V��E+�J�������������_�_������l�2����'N��F�4m���G���#����Q���c�Q\�v���F��?����	yyy�8q�~���d�������[IMM�~��������#��};�&55�\��K�P(xyy=��`0<0�ZPP�L&c��m�����={R�J��MMM%""ooo�`�������9r�5j<���I��QQ8����U�R�j�=�V�%))��w����LJJ��JMM%99�������T���IOOG��J�"��4
�sss���033���333���111���SSS)*���q���)�Fz����V����2��Z�J����T��Y"C�;RJJ�YXV�Z-���K��655%55������W#,`��I�1����"���}�@8����`0`ggG������/4h���Eff���}�����i��U�V-R��0����]�v��q�_~��5k��h�"������^^^���q*<��"��>�f�E��j����:u�&M�P�jU���������u:������q��
>�Z����{�u�Fc�|����=���\���[������'�n�B��R�n]�m���[����A�RI�h0���c���O��q�S���0`���\�p�v��I��������c888p��EZ�h���W�y�&IIIR��W���)�R����O*G��������,������"33���,����Mnn�����"�����e�?�2���[�r�L���a�<�j��9Y��+<����{��r�e����Q���S�R%�z��FJ�������F�!!!A����dT�V���\j����M�X�z56l ((���,����_�>G�?:�pA�7 
��5C��������T�T�Te!/�r��H����))))�8q��w����S$l�Q����3S�Ne���>|���p���HOO����N�:��}���.�N��]rb4��z=...;v����Je%77W�p��a��������<�}MLL���G��y���
������WWW����v�7o��\�r��rT*��5����l���Q�Fabb"�z��J��C����4i��I[� IDATH��m����P(�y�&��U���Z�����9s�:H��}��e���$''#���5k�-����"<<���~��*���eDO�@)�f
�kk������]��Ga�@aG�^�db��N��Q8�lq�����q��e4��OLL�f����S���[������[�l�W��I��\�2
����LLLLppp��O>�Z�j$&&���7VVV���;\�x���������coj�G�@8���8����^�:/^���KDDDp��e�@O`���y������yslll�5�Y0���������[o�����H��f�BA�V�h��w��!66���P�����)S���#G�,�=�uWjMLL�(�Q�/_OOO�;���#�7���������cG�������l��#G���?���A�^���c�$���'�v��[����~������[K�d���m[������R������C����a��abb���'O�����:H��}��a��4n�[[[���J���������9x� ���c���4k��r����o�
@^^�����zm�� 11�V�Z0v�X6n��R�d��!O�@�P��'�I��!��������)���Qe	�B����������J%%���j6K�,y`[tt4,����E�����m���6�JE||<����O�>���<0�>��H � �� 2L	�D~~�4$x|t:��u#;;�-[�`gg����8+�V���h(~L~~>YYYDDD��7�p��A<<<�0a�~���e������>|x���/_�����l_�����6���T�"�-�Z-
��R)E�3���s��-8 ��\.�i����Q���\�{���t�"2a,�h�V�~�5��j%��j���},C�X�x>c{�gI������2h��5���"����yR�]���
�:u��y�f�7o�@u��%==������g�?�r�
����3�i������#G���+���e�o�dD�t:BBB�R�J�������n������~*T`����m�V������Y���k���T�P����v�J�v�P��� �2D�@ ���"x2Cz�������L�8�+VP�\��6k�4�(~�Z�F�V��sg:w���[�

b���|������q�����.%{�3�,��A��_�T�c�a-��)nT������N��o��wuu} qZ�u��P���/�/��_�c��s��(
c����[R�A�k��d��}R��?�=��1c_}�]�ty.ms��%f���P��]����?�P\F��_�vMZ�����c�
%]�����h��i����^�%�������+W���������m����o_���i��	;v�S�N��UK����K,^��""�@����n��k����_���T'���#;w�d���=z777�w�N���T��T��,+����8q"��O�B�
����Xn�����vAA~~~OJ�����5k�2�Oz����R��������"99WWWt:7n�������T\\\�h4��������`�F����r��-�����5k���7^g�j��w�899���=h4�t�R�D��UIJJ"33���j������Y�t)M�6�S�N(
����q�*T(��kY&>>����3f�)&33��s�������)kkk��������;p����%:v"##��k{������X[[��IZ�nM�
�P�*T(�K3��p�d�����wo����������.��������m�6v�������V�m���y��E��������W_}���.��'$$�a�O�N��������4�����9~�8�'O~�����x��w����}����5������w�1v�Xj����~�����������	`��y���s��A��Gvv6��w'00gggz����`�����]����[�}�vf������7n�/_������s��u�o���A������?VVV����n�:���O�����eC��n���;���;3~�x�J%�O�f��U���2a���N6CCC����C�/}\�����_~���>�����}III;v���N�>MZZ�����Y___<==�S��IEd�@��K�@�\����J�^����7!!!����IE�x��*U�0~�xF��_���c���w/AAAT�V�n����W���n�e?;{{{:v������)S�h4888���yrP����:���8u��|��t����2&�l��j�{{{������QQQ�l��Z�j�����{��p�-[�d���|��W��������g���R����w��Iz��M\\����=ZZ����@��
	����/���4i�ooo�;��}�h��9�N����������M<==i���d ��_���[����
��6m��|�r���h���5��Y�z�*��-c��q���<��q���=��u�[�n���p��Ubcc9{�,[�ne���h46lH�h��
����59�@ �@ <g#�XJ����?���^�z��S'������{-��T*>>>�������������[����6m���c��	�h��D�4?���[�P(����3fu���w�Q�V�g�}���-�&M�����7obgg'��&�������y�Z�T����XF�X��b��t����
bjjJ^^�9)A$���)���E@6Ha��m��\w�������U�V���I�e<�0�k|�[[[[>��-ZDxx8���/���w���DEE1m�4)S��Ncn�:u�P�N�w�����;w���w3u�T���K�&M���/}����������p���t���F������6lx-f�������`cc�'�|����9{�,.�]�v8::����3r�Hi���+�2���-[R�vm������������B�.�������@vv6����q��(
222�2e
[�la���L�<�j��1�6c�o��kmmM�58u�M�4!++��y
��}{��]K���	��o�E��I���40:8���9r����g��E���������%r��V�@�����:����r��	�X���";;��J%
���7o2x�`/^��	&Kjw�BA�r�(W���W�{���t:���/����1c#F����������gO����3@ x��y�@ /�b���F��=���b��T�X��P������5kX�|9�o��C��9///����$�*m�Q�zn����k�^�Y�����(�f,�����9y�$m�������i��XZZJF\aC���[l��
�J���+g���E��={��@�V�������X���1bYYY������C�=�p��/_�����/Orr2����O��~�v�����W�&//���+������-J��7n��Kf�����-U�Ta��!X[[s��N�<���'N�`��aDGGs��)�V�Jll,...dff���K�.]^�D�%�Y�NGtt4���n��R������$�<{�,������p��=�5kF�~�h��-VVVXXX'�@ �@ (MJiRR�������+VP�r���	P���?��?���}�077�y��t�����kS�r�2��-�+����a��U���KKKz��I�V��U��5�SRR���g���:t����}���;����?�l
�.;�BI�9~�8�7o�����w������C5j���k�x��p��*�w��e���$&&���?���Qf��?�������	����(
|}}���#����f�_�v�|9,,Ow��e��]������-m���C�xyy=w*!!���Hi��������M���������(���V�%22�?���#G�p�����h��5o��6���� �@ ^����������{��i���o��[\���\�v���(�m����133�G����{��QC(��NVVW�^���l�������+��W/����\�S�-*�I���DZZ���=z�;vp��y�����!C���_�D�B���KV�rss�3gk��e���������knn.YYY����j�*�?���/}�=z������ �����KRR��m��$&&�F�1n�8z��-e�r((�c�N�#77���V�Z��u����b���L�2GG��_ �@ ^0Z����g���?F������o�RV���^���E�F�V3t�PF�E�j����E���1&xQrMPP��������gO�N�&MP((
!{�R-�z�����3w�\��=K@@�1���(
��J �@ �LM��3m�4~��BBB���Fm!t:���AAA���?4h��w�y�f��Q�re��J����w������#XYY��}{�������FS�XaL	J��={�o���]�vQ�jU�J�V�pvv���\�����e)gs��e��e|��w���[(a�<��Azz:�j��������777!P��"��������?���s��!������e��xyyQ�N�"(u2��!�����


%--��u�@�-�X�b��� �s6.��Y�����>}:�&M��C���L��=���Ixx8���4h��>}���[���*���0x^�w��u�������"""HHH�����m���cG�������0���������S����={����G�:t(�j���@8�@ x������0`���J�#�W�^Orr2qqql���-[�������?c���������FNdd$g��!>>^�_+�����@�*Uh��-���/Uu:���$&&��~�m����g�X�"}�����xxx�y���uGEEq��q�������^1j�{{{4h@��M)g��7�NGRR�N�"((��G���iS�O�N�f��#@ �@ �(��`0p��I�v���#�={6J�R(]�0D�?�yyy����t�R�?���?�|�	;vD�T�x��%]��o?��-Z��Q�F����gQJ177'==��[��������Q��/�h)i6\��#��HLL$$$���`N�8���+�f���T�R�LU�����3��7___�6m�V�%77W��W�R�D����?���1c�����Fl�4&�����_���'�}��:uB.���p�@�"8u���u�o��|��g�����1W�\a��El��kkk����qrr���\����������6??�
6p��f��!��
8�O?��_|A��_��]�|����[����`�������k��t��������h055}�w�j�z=7n$**��3g>p�����e�HLLd����T���������2o�<V�^M��?~<}�����
�����yF#4**��}�����w�}'2�	��
l^^�4M�:u���-Z��Q�F�X��^�zIN�L����IJJ��> %%�������J���*����D	������W�^���g������bgg���m������j��aeeUj��1'<<������L&#++���D1�"�z=�������LFxx8����5�����LV�^��?���{�x������'���XZZ�r�@ ��{��
��CBBk���n��B�zBG�������}��s��������!C�0s�L\\\����c����.���~{#�<//�Z]���`0P�zu�,Y������U�V1w��R��Odd$�����3���bkkK�������I�&����rg@ZZ�/f���!y��>���"�_�1����L-����a��	:�B��`��_~���E��,�hAA{��!44���H*W�L�=����$��I-�@ ��`HMM���>c��-I�$xr����{\�~�n��'m�U�AAA�[��o��SSS����������h����s��q�Zm��vWWW����W�.=���0T*o��v������_������8{�,�����W���:u�$�h{�����Ki��
u����u��M������j�WWW�^�JNNN���Y�f1s�L
2��;w�����,y�qT��q��%v����
HMM�_�~L�0���
���W �c��r��1o�<������kW�����o���emm�Z�&99��~���t������"�?�B�(s�}��]>��cV�X����C�k��	c������3������g]x����N�:���_�����b��4n��a���r�J�=��5k�^�:,�r��x{{���_r��ed2Y��E���;###�����[����7���|���,[��Hu��I}������{GG��e��_~��qtt$!!����g����[�PP�V->��C������K9p�...�5����*��p���wh4�M���Y�`��ME[�d=�[�R%.^�Hzz:z����V�e���t���L8������q�F�w���������M�q�����f��I�n�����d@��_�������V���R���8��gZ��d2�kkkZ�h�������!::�����Y���U�Ve��IDDD���MAAz���F��\���Y�}����DEE1o�<~��w&M����c�����?���-[��gO>��3|}}��t(
z���|�Z�.�m��h(((x���P(����K�.;v�={�������.111�>��*�p�@��N�?���+W2l�0>��3�����<��������X[[i�+W�������	�*U"11�6m�������[�2e
nnnDGGs��av�����������b���l�����C~~>�.]*SK
��e������@bbb�y�&�~�)/^�G���[�w�}�����(n��Mnn���#���-�������+�����+W���O�t�'N����:t���Tf������Q(8;;s�����5jT�m��7or�������Y3"""8z�(��������}��o�>RSS������j��	�@PV����.�����������x�b���E#=A[>l�\.�Bh��r�T��}{�����i999������G^^��X�T�9611����$$$`mm�Z��q=tY�W������Q�5j���>|�C��q�F���[��+G��5����v�����coo��wo������>���qrr�y��(�J������������lmm�����	Z��\���7�{�.���evY��x���z___�o������U��8q"NNN����:P�j�"�������N��@�V���e�'O�g���Y�WW��V���*��G���g3\�+�o�R)����c��~��a���������[7� 0��Q��(�J�Je�{~]�i�>aaaA�����#������r��%��=������U��j���S�7oN��u��
�5�CR��\�|���i���3Y�`���+"�J�)����	r��2��U��Qv������K�|�2�v�"88�����.]�0z�h�W�.��+C,A�Q������k���v���k����O��7t:���#++��u�.\���K%�+~VC��^�'::��/�h�6����9q��Cg�e2�/����J%��?y�������g��
������BA����e�����z��[':]p��Z��N�:������@��]��
X�x1������/�j��j����{��q�F������A�������N�<Yd�g�}��������S�Z5>��#�
������9r����s����C�x���5k2~�xBBBX�x1����������s�����A �2����
j���y�f��`0��z�^��1YYYwww��s�J�|�����?������\�133�]d[NN�a��	�y��=��S�N�a���~��=t������Sz?�����
,x`��q�@�z�����d2�U|{��J�����U��!..������5�����V�F�%�}�^o(((0���kX�~�a����
*������O?58p����
!!!��`HLL4�j����l���L�DqY/.��?+,�����������*�� IDAT?�p���W*����j����HC���
r��0p�@C|||��/
�@ e��
��y�pqqa����1����	�.i6O�Vs��9
z�����r9:�+++f���N�C�T���"�W��������*�������)������L�Z-*�
�FCpp0����������F�!''����J�2��������jbbb��a���|���������INN������<�J%��������������{��I�j\��&E����h������lF�)
�����w���w� ::�m�����~@RR}��!00�������5�U6�v�����313�|eR�P��qc�����'�6m0��'R�F
LMM�����<o�@ eV�2��>www�Jll,_}����
s��-F��G}D�r���q#����?��}�Edd$��/�����_�\���)S�La���T�P�������f������E����������'�7o�����
��U+�,YBHH���������3qrr"??SSS���8w����'//����s��94h�w�}��3g���e���\�|���h6n�H�6m����������c��;W
�}t:��2@AA�0��3��j��V�ZL�:��M�r��1i���@���+����Oiw�_��qc�������Y�`]�t�U�V����xyyacc#���a
U�f�����7n���c�����W��$y�*U���333���&N����7��s��a���\�z�F���5k�����~��\�������?����S�Jj����M���m���h47n���>>>4m��z��amm�����G�!99��G��������HKK#""�w�NBB�����-Z��K�.T�^�z�������#���/h��������d��-L�4�������7Z�t:]�6���W�f��0��Q#���111���SSS222��g���/_oo�7��Kc�����J�*e�H.U�����-[���$88�?�'''H�=���(��@ �@ 
��)Ennn�_���3g��E�����)`L������t�d2rrr$E�������"3I:��N'��2Ef[e2nnn8880o�<�T��^�g����=���SPP@AA���i�Z,,,��LKK���A:���-Z�V�����"��V�%??��?���7dgg������
			����:u�n��o�l�t:�W����I��N�JE�
�`���z/^�@��{��q�����Z�j1o��76;������e��&����T���#�I�&4n����h���.\��=z4c���^� AqP&�agg�������b��A�>}������8i�Z:u����[�]�6����{��h�Z�d��@P\�l��g���G��T*�^����78p _~��t���d���,�r����<:w����~JLL����V�IJJ����R)9�Z-
��B!�(�P�k������}�v����l��^����J�*ann^����v=�V�Y��aFc^^^���
��Z��:t:�����k�����A��}�v�������	d��� xf������@��(QF������'N���S���[�L�N�c���8;;��_?�Z-�������^�zq��I233Q��$$$��hP(������L\\*�����������6l 66��u�r��u�m������P�����;w���T<<<�p����g�����������Q���y3��\�r����������p�5j� 99��5k������Wqww������2220�l�~��'F����W��S���(222�OMM-�T�y]F���������>+��E�$�t:*W��Z�~ ��p����aF������@Z�jU�>999����z�j<==���zh?HMM����t�������d2�\���%Kh������~�L��}�X�r%���a�Fa�����iC�y`{bb�s5��2���x���'^��B�
Rh�^����N�C.�?V��S�{.��cI�J�����k�.���G�����o�L&���///&L��J�b��i�X����+���Z���3@�D�f�L�@�bT����fff|�����W���6n����Ci���s9��~^Z���a7n�`���E�_�|��7o>W�R&�������#Y�z��`jj�\.'??_Z�a0�������L�V��������Ka��
	/bM�V����233���>>>4o����yyy���bmm����O�f��9l��A�-NIIA��cgg�\.';;�JEZZ����d2������o�1c�t���TLLL��`���g��1�h����~��e�,Y���KKtT<�~�o4o��5k�P�f�'����ld2�F��yVy������(����������= 33����h�J%-�1F%egg��h�h4�t:�����������SS���>xzzJ�����Chh(��U#""���WS�\9RSS%g����� ��������S��3///�����3�����I�r�P(�����Llll�h4���b0$'���K��	&0p�@�4iR������?����S�re�L�B��Mqtt|)�A�� �����h(888�w�^>��C�����y�����������y����r��D�PEBBQQQ���s������T���z�����?(
rrr����y��=z�NGrr2�;w����3g����B��]_x��*U������3g�mK�.������T���-�&&&�s�������'������:w����{IHH���___�j5'O�$22���\~��w233�u�����?����~�����s�pvv�������S�N.]��Z����SSSbbbHOO�n���_��B� 55��u�bjjJzz:W�\���www���	

����a���P(���&..777i9��0^%$$p��Y*W�Lzz:w��%..��]�CJJ
fff\�pgggn��M�^�8u�999dffR�zu���������t���������qttd��q����h�Z��9�_�EAAU�T�u���Y�;;;�������9t�NNN����;w�R���#u��%$$>|8�N����c���s��)>�����^���������3fAAA��;sss@����V��0���\4�@ ^w'���%AAA|����?^��3*V"����ji����:`ggG�r�8v�
��={���������d�o��������LHH2��={�p��
NNN��Q��<�
*���\D�����������s��-���K�
���C�V3z�h�����;wX�lw�����<x�=z������o��6;v������>����K��3f���#""kkk&M�Dvv6���R
�LFVV)))L�6
�B!���������'���g��:t���<���)�L&����������	�^O��5�^�:>>>899Q�fMv��I~~>�/_F�������+Wh��qqq>|��;wr��=����?>�;;;���_���#F`ii��9sX�|9����^��.���K��=���g���������������T��&Mb������0d��u�F������C�P`mm�^�g������_���p���t���;w8r���[fo�M�������a���i��5��w�J���5�p���v�T*F�����9t�>>>���I�'xy����������|Z�j��s�����j��R�q;;;������ //������qc���+Z�l�V��f��4h�������N�:8PZ��s�N�������TA����H\\�F�b��A�[�N
�vuu}@a7�����r��	,,,���%++�T>��7r��]�t�������r������aC��kGZZ���'=={{{��iCvv6����o���={����������������kK�������R����'t:z�^��affF�����{7w������^O����d���r��m���i����uc��%ddd���D�F�^x�HNNYYY4�I�&q��-���133�m��4������������B�����BAdd$3f����?f���$$$G�J�����i��R�T///��������#�����#//��7��*Ub���l������s�������9s����/�@ �8'@�:u8t�~~~4m��]�vQ�/���Z�&==]*���eK���C�>}���C�TKdd$���X[[ciiIVV��/��1����b��^��`0������...�Az��LMMINN����Q�����INNf���R����x����$%%acc��K����y�A�����d���t����C������d��r��+GZZr�\�����7n�r�J��������2R�w��n(�J����N�#??�=z�u�V���077G.�K3�qqq�j�����������f��XXX����_�q,��X�j������r��%5j���#�o�&66��c�biiI��9{�,����T*��]���Q�T���!�����?�7o���#��9����c0077'&&Fr�.��&������t���������v�Z��+���_��	�p�@�J�&�F�����;w.}��e���EfW�������c���l��U2`�������J�*����h���e��y�/_�A�q��!:w�L��
�j�xxx��Q�`bbB��=�Y�%K� �����8v�AAA����+����q�F���

�����2}�tLLLh��;v��3<<�9s��d�������{?~<���c���899�����3���������3��;�222X�b...\�rsss����j����T*���&##�k����A�z=999���C������a��	t�����j���+0/��,������r9��w'==�k��!��P���������V�E�������={2d5j�`�����������3����r������pG���)��9_�5k���q���;"##��i�����=���T*�T�"//�����������u����&::��'��{���}{:DPPr�������[7�v�J��
������s��U,X���_�����i����y�(;�
�@ �4
���������z��1�|�����M�eV0��J�B.�SPP@^^��o��������T*���o������G���P(P*�EJ�)
iY�����UJ�����G�3{T�'�����EW�����V�*����G����G��mY�l��/g��ddd���K��U������|�����cgg��!C������������8f���o��Fbb"m��a��E\\��M{��<�s.�,�eW0��Z���.\���CL�8�VKxx8�o�f���R��\�R��2#P�r�q�����|���.]��f�*T����=m�2R��<�XPPP��E�X�j�;�-ZP�R��2��@ �2�(�����3s�L"""d���o��e;�=���������.5�n������x��P�|�2_�5��-+�r<p�@&O��\�q<++W�D����eK<==HII����,@a
'N��a��R����4����|���e����������������HLL��_~a��
��r
������}�~��C��I���*U��b�
BBB�={6���g��e�������1!�����
)�[��Q�bE��0�U����t�l~~>iii(��Rs2����tlll��cU�Ty�%
�����};���;�����S���;��E�"�
�/C.


���F��I}���J��,�	��@�z���K����4i}��e���,_���������3z����
g�����@ E���sGGG3f������c�T^�uW����Avv����z��/_&��_�v
���_���0#2??��:�W-_���E]J��J���;g��-�onn.���ot����A����k:����

e�������p�B)��Q�MMMEd�k���Oa%�v�����3~�xj�������a�JT�����o"Z�??�gr<������>���t:��k���SKU@i���L**��)_�<}����w�a��Y<������?��:���B�������������{a�>��7�r��1l�0
��y����/
6����������[K�0���@ ��^Q2&�

�m���?���w�p�B�T��D��^'��a�k0�j�(�'6����077���V��������'1�333111y�y`�\��s��]�����������l��/�B�x&Y3XZZ���!��f��t����#GJ��)))R���'����������"e�y��_U���` 77�����{h�Z��������L&#''������$gUFFZ�����}�������_&N���)S������\�v
???N�:E�j���5D���'��`�O�>�>}�NG�n�F��?�f�M���T*T*��U>//���H222$�H�V�R�$���`����R)��U�VI���r�d��3�a��j�.~M��$���k0����J�B&��T*�r�
���R���`��V��w/�-"66��J��u���w/�����}���/�������k��Q�Q)x4_~�%;v�(
�o�VX��J���������0rss%@a�3b|o�'r������J�������R�D�P�V������5�;F9*�|j�ZrTe�X���}��>i���d�����O?�{�n�o���Ln���?��C�]��%~��W~��W�?.������a���,[��[�n���III!  ���x���!"@ �G(G�*Ub��
�^��/�����w���_R�R�7���L&�����9s���,������������7o��W/222��w/��Q�Z�j!��	

���
'''���9t�aaa4k�WWW����u�-Z�`���8::r���Z-�����S��u�>`�����s�N�Z-*T����7np��q4
>>>T�\�?��SZo\�u�Vrss����A��T*����'�|"��>-���\�t����?�t�[�la���l��������w|TU����>��� �A  
����T�����*�,��WE����X@��   �A�	��Bz�$�����{�3$`A���u_3s����9w�������A��3f��?��u	�~'���`p3t5�O�l66m��R�����{�������]�J��K�.����q�Fjjj�W�^��vv����f#((�:�����U�

%((���X^}�U�N���c�(,,$88�S�N���MUUC�u��9������
���>|8���l����L�N�������������A�n�h���~�-���#))���8�����u+�����F'|��y��'���;������;n�|��w���2u�T���N���8t�������p����c�!����Nzf���SPP����y���X�d	����b5�����=�@ ��i4&L������������+�g�������?��R��C�8y�$���c������K����}{�Z-�m����w���?_}����#$$��Fbb�\NL��r���?NZZ���(
�9Bll,]�ta��,Y����j���k�.JJJ���;��u+J��Y�f��3��������y��x����;w.���������*����8�v;���I������[/�Nzz:��r�����
c���������l6���?~\~g%�1�X�Rq��qv���������),,$22		�d2�R�2d��;~��G���
����P������#  �Z��u��6myyydffb�Z���������'�|B���i���[�����IOO��{�����={�S�Na�X���'�g�����/�}�j��=zPQQ����}��r�C�{��p\�W�����.��U IDAT�'o��6���dee�1�?������K�t���;�Z����1x��:IodEm����Y����"rrr��j�8JKK��lxzzb�X�Z�l�����$����"h��Fdd$���c�����(�@ 4p��U+V�X�_|������a|��\��f�]�v%##�g�}�{�������`��{}}}�3g�����f������S]]��n'((�BAPP&�IV�$c�4�'11����z�g��!>>���P��V���_~�c��TUUq���F#�&Mb���2a��z=��Z���&����Z&O�|�F�BQ�T��5�ZMmm-O<����=��s,^��O>�������N�������o����D�L�B\\�{�����VK`` �����c����&''G�������H|||������uBQ\���!���CQQ			n���"""<x06��������;�����3g0`s��e��}<���V�����h4b�����/pu��j5V��	&��+���	���R������~�_|�F��l�o��xzz�����XUU��	HNNf���xzz��A�P*���v��]��!Cx���h���U�@ �(t��x���4F�M���������������UUU����	&0t�PF�)�����T*��m���t���5k��J���ZrQ�VSSS#�0��r�5i�SZZJnn�[��+QQQ\�x�����k:t(-[������������V�����w�y�����k�.���eE�l6�P(������������<���X,jjjdZ�n�����K.\Hmm-����[oe��=t������3d�&M�$:_3.�����eK����o�����:t�l��BX
�4i�7o�j��V��M$�R�0�L�rh0(++��J}�����H@@@Y�����<x������)**���sDGG�2�������lv��!g}W(�L&����w���A��]m���?����m��TVV����s�=��Y��_0�:u���Z�=���3��w/�������0������L�L���y��\�o����?�Q�F1l�0&M���!C����=��@ ����]��>}:�G�������U�V7m��^��={8t��>��3��������o���X����0���.]�`���kb��1b�W��w��t������}�v���	@�P���GNNO?�4yyyTTT�]�~���j�*/^Lxx8�����������CZZ:�-Z������X,RRRX�b���'55�RIfff�$y����p8����[n����p��������HF��'�|"{�:u��K�������>��������q:����p��)������ 55�����]�HII!<<�6m��y�fn��6��9Cbb"���������T*IJJb��}$$$��U+���W_}�^�'..����l��d������-��R��M�6�����7�PVVF���	f���|��W���������1����Z�N��[�nl������Z-%%%xyy]�������1����s�}����?x�`����3gw�}7�������|�r>��S��������P(8�<}��-�����FNN�����^�(^^^r���3x���	�C����
�(
+�U�������������'�d��q�t���,]��s��������gffr��y���Ii���t�3�Z��B��lF�T�����l�T*�f�<p1�n	
�\�O��o����/��$--
�����')**r8���[vv8rIB)���j�n�����cKmR&u����j�s�V�����ZAce����&��V�?33���~�9s��
������G��?��q��1�J%
��N���D�Tb2�d��B!��N��e�b�`���j���v7��Z�v[��D�F�a�����������P(8{�,���rP�T����vNR?�cJU�N'6�M�:�U�sw:�X,9�`�

��~ �����o�������x@N��{b��X�`={�$11�����g����>���#���R(�%�C�_p�4s#b�Z���+[�l�
r�N�b����=�Q�Q��@ ���u��{��|��|�����1�e��1g�y�w3��Ju��f�[��=�u�U[[+X�����������@�V�1��KHH���w�[��n�����6��.�[:�K��j�����e^�����'.'o�lK}�����g��&��dTs]�G�t��Q64����I��p8d��U���<��.��_����������~���V��Q���_��trh�t,N���k�g��[n�����g�6��===���{(((`��]7t	_���v�m��a��5��������~"|O�@ �F��t�����Q�X�v-�����������nD\c���n���U+|}}��$�UQ���"��/~���pLLL�,���N���LD�c�����,ndc��/������������~�(o���9��J���w�u���'����a��19r�7�x��={���Z����;Z������_W���[8u�T��#<�@ hBC@dd$s��a��a<��C|��,Y����;�)7� P��5���fCr�\�
oo�?�\8R�����<>nT���X�b�}��g�f����Z�����///>��S�F#����5������
��M#!!���B��]��lf��	\�x�������/��J�b��5�1�
F�v���y3���>���b���~��G�.]����3gr���Ann.��=C�a������/����f��v������k��o���>>>�8q�����$��@ ���U��[o���s<�������G}�'�|����*I��������!��`��o�2d��G��������>�p8�����p��
�F���uBAn�����O�v�h���1/����f��M��������w�^��i�_����[�{����?��+�����[������t�x�
�O�N�=8~�8���g��e����?������{����:uj��!����p&L��w�����i��
7n$55UN���cG�}�]����1c��
6�����rNC�@ ���P(�={6��?/��2��
��Ge��1r9��n(++��^���T*��z\*�JN V�>�F#���h�ZZ�ly�}]-R���`�����hT��K�iC��]ND��Gmm-g����aH�P�V���lW4f��j9��R�J%eee���Ettt��	�<;Km���������7�A}������L��ntl6��r��
c���dee��h�����G���?�����s������g�k?�rJH�����_���G���p�����m�[��������$��F�np����n�:�V+/^$**��s4V��O�@ �y��������y������/�������/���sl�R�D�T�R��]?��3�����jT*Z�4�������'1r���Z�V����jy��W����s�<4
����x��U*z��^�Z�F�T������+������Z�|�������U(\�x���z��D���8f����m�d#��X�d	~��M�D�l\NV�j5f���P(d��JQJ��V���� ??�N'W�p�7���9s&^^^����%�xz�^^��OHmV��m�����-�i�Z��M�'
�����l?�Z��^���>���K��P(���b������;����~�����?�����O��}IJJ"//�C�q���;���r��$''3|�p��^�-r9���u��Q9��������3�V�fP�h4�A@�C���uIf8@����������OyO�@ ������t:���>V�^��>�������?���-�7Z�"������Y�`.����B��3gX�|9/^D���������Y�d	���`0p��q���+233�j�x{{��sg���/�`�T*���X�b?��3*�
����c�X�jF�Qtn���
6PSS�V�e���,\��u��QVV�Z�����n%���%K�p��	���.�����������#���;��fn��6�=���kE���~����_��E��p�B�_9r���WS]]�R�����|���,Z����<�z=`��\�p�J���?�:u������Q�VKVV��-����ri�={��n�:9t�b��a��m�&�}��g,X��-[�P[[�R������;w�I��B� ==���2��U��=������/����c�X���@�~��2e��?�]�vQXX��n��_$))�y����E���~:@AA���<x�e��p��	���4h�\����?����m[�|�I�j5			�9�7�|�z�)���)**����c���������������?����[�n�y�f��������{�p���[>��S�~�i�����M����T��@p����P(���g���L�:�n�����O�����5�o��.�JEBB����y��xzzr��>��#�z�)-Z�<@��m����E�t���={��i�&�~�i�|�M|�AZ�n}Eg�BA^^�V�b���|���TWW�����ew�u���.�?�<����h4��EV�^��#:t(K�,��;�����J��]�P���m��������c�*�c����`���h�Z���8q�'N��`0O~~>��
��tr��A������y��wx���i��-111�����M�8x� =���9c��%44��qYe\�Rq��:����y��W;v,���TWW����y���X�l���RYY��A���_�BFF��v&�	�R�?�@TT-[�l���v�����x�g���'	�����m��e����	

�c���[�N���E�d����'9}�4v���>��-����#?~�-�����7�|@n{��g�}gdd���)�����E�Tb���c/[��J%��Y�����Z.��p8����'�r�K�.u���b�������@ ~GC��>00�?��m����w���U+-ZT��os�
���%��]�v��kW��kGEEna���]������+�������AF���"*++������^�g��rb�n�������j%88���wc2������j�r�r�Z-�W��G;v�u��}i����S�Z�����6m�Z��E������k�>�t:�������=z� ==��!���T*l6��z+III�Y����2*++tIy�����w�%>>���,�������w�F�V�����
����_�~n}�5?�O<�]w��d���y\K�r���[�Vs�]w�x�b>��Q����p�=�$E^*����f���BR�]�q����zRy�K���m���V���K��������gU��@ �?� ������G�����W_}��j�*9��� ��8�N���)--�]�%EXti4������+3f�����v�@ )&J�����h4�;���')))������
��������t��C&N�HFF�~����K3>�������s��\�p:������P(��������-����Y�fa������Eg�A��B������TVVb0���n���j��q#�6mb��1����3������_��jkk�P���^�������|||P(�����{��7�r�Jy{�?H���������O����B�P(��e�[����
��o�/��B�����f����9�=z�t�!\
MUVR��@��A�B�`��	�=�y����o������2j�(4�����KgI������A�>}X�l�7o&99���P�N'���dff���Kdd$���?~���P�v;YYY�����m[v�����7���n����n��v����'8p }��a���l���{���NGNN����M�6nI�z����}������������V����m�r]
����7�t:9z�(�������v�Z"""=z4
���Q.�t��i�����s'DGG������W��S��MXX������O����^�z�}�v6n���#d�i��}������������G�Pp��1jkki��
��m#<<���B��ez���:t�{�����~��6m���	�Z�dffr��9�t�BLL^^^���r��Z�j�N�c������1`��kV6
���ddd���������7q�D9y\������oX�f
m��%--�5k�����R��?���5���$����n�MNh�\^���N��-�DnN�� A�P6$������X��������>���#�]����i.\`��qn�����������R���P���F���	C����������������555��v*++�����f���d@�v�����y?���r����*"""����/b�Z	��VTTP]]MHHZ����Jy��rX�VRRR��N}=z�^��b�e��xzzRZZ*�c�:uJVP111R\\Ltt4����t�srrX�xq�����a�Xx������/�����8v������`4ee[����HY�M&/^$$$OOO����h4��z���bA��a�X(,,���P��NG��]��t���v����b,QQQ�!����RIXX�l*--�n��J�����Z���p)6��:���������|�z=6����h����l�R����
������G��`�����A��q����W^��$..�w������K1�<��cnJ�T����zQ*�$%%�[�R��p
����q#�f��)
6��@ ���4�m��'N������>���3f�`�������m��"..��~�������rMp�����'����@~u���!��FHH���dSpp�����eK��(�K�����������y��_:O����97��t:�t���N[@@���M�6u�			���)��zT8����jek����m@@����^��E���.�;�0n�����l6�mR]t�Z-�����r�Q�|������:�_PP���K����=)$����N���K�}}}����?�T*Z�j��|��g�����E�����b������$�Bi�Z���7�����\*M�%��@ ���:(`��Idee��o_���L�M�,0..N.GW�����.�k�t�K���vR���$���K6&xzz����]�;�k��~���������������s/((���	GLL�����mh���Vq����>��h����`��[*�
�'M�'.'�����BS��������;�\����V�9s���9�z��������,���J�_*��3j5���l63a�����'|��R����7�����j�9������;���_jl
��@ ���t:���f���L�4�_|�^�z1`��y�:v�(]�W3`5j+W�d����>�[��5@�Q����hd��5���k�3]���?y���y������?��is�-���w�}G�.]�x 4��XRR"+���������S'>���?�����#���`�Z���������B�������
�v;�???jjj�����Q���l6
����WU(�Y�����xPH�����n��RR����$""�N�������3eO���"9��N�������|�HF^^�[XT*����5������b6��X,DFFb���p�z��FCPP�
�V�	D��p�����t:�x�"��FC``���Q(���PUU%���������89D�������:�4
���Daa!�OOO|||(..��'��=pjkk)))����NEa��O��J����,X����/��}��O||<�F�b��DDD���P�U�f��a���������W/BCC��.��p:�r�Bs?O�����s<x�<C|#1��5
'66�u��1d�YQk������:��F�����@zz:����3�Y�'�BAYY|����\�x�����o����h4�q�F������x���Q���\������b�
�j5}��e��t�����]�gR�IDATr������	

"''�^�z��[7�����s����sNF���_~���d���i��-#F��s�G���?$99�>}��o�A||<��mc���$''c2��i��9���b��i��hd��1,\����$���{������c4h�}�=��O��s���T*9g�/������������g�����q�����O�u�V���K�z�-��o��]�x��g		a���8��������a�9gMFF���J�>�<����.]���+a2��2e
-[�$##�A�1v��:�n��Y�L&��m��I��������q�<��S,^��'N���*�@ �Y���v����p��)��Y�G}�{������y���b���M�2������<F���/h�2�����_~I��]IKK��5^S�B��������Y�`��_�j���L�����9x� ��w!!!��h4v��MPP#G������\���J�����V�N�#==�n�����Q(r�H���)))!,,�����k�6m�<�,�Z�<y2�������]�P�T<��#8�Nrss�Y�p�J�C=���YYY�]����{���\N�>Mrrr��{yy��Q�x���1��xzz��j��������l6����1y�d��G���Q��������+�j�DGGs��y1TVV��uk&L�������������s�())a����j��Gy���r����5k��OG�Ra0(,,�cP���'���>������[o�S�N�����k����SSS���g�={6YYY�u�]>|X����y���HJJ��G�@ �!���D�6m�<y2c��e��=��?��s�2`��N�J�� �����O<���ky��'���/]�t����^Oyy9���C��3b�:t� ��5�l������u+����g������p8��.�������8q�o�����4�qY����q5���Guu5J����J���	

E���P(���������\RSS�������t:�F#������c��)�q�����H�g��j%''Gv��OOO�3�l6s��)bcc9s����$%%�����'WP*���S'4�������Z�^�w{^Y,�Z-{��������T�-[V'�����
 ;v$<<����N')))��{��~�zz��!P���������C,Y��R���/����!�Z�"**
__�z=����IJJ��MJ�Z�,*�J�v�&SVV�O?�D�~��_K��l6�|���#�Bh�Zl6F���eM�@ �	
aaa6�;���S�N1m�4:w�L�>}x�������R���/��wC�e���,_����L�%��All,�>�(111n�Sb��i�<OOO���N�������o)((���B\�?�NGDD�:u��w������B]�����3L�8���3d����Q*�W<��j��������������0z�h���k9��w�!$$������i��?��#w�uV���RTT���V��;v����B�`��q��;�������_K���?�~���)�}����o���^���������;w���!$��t����>|8/��yyy����l���o����{�RYY��Q���N���L�X�x1��/'((�����.��n���Ez����E�8w�C�A�T�g���;Gff&�<����dee��������T*i��5���.���8p���~�
60i�$,�&M��O>a�������R�dE����V�����j��p`��e��s�x�����.X��������RSS���b���l��	///4
�f��Y���WAkJ9V8�yX ��FQ�	���L�>�/������{�9�
����[V������+B��V<�m;I�����L@qq1��l�_�����HIIa��q��6����L.\� ���*���@�V�
�k��R��b��J��v;j�Z���Z��T*�e]R�����K�IJ�B����u�o�?����c8p�3f�r��k>���M�u�����u�VN�>�c�=��}�@ n\��[�l�����5k�������c���0�{���v��}���Prn\�k+�S��:�;��Fmm��������;w���
)..���TWW��)**b���DGG��z�KCH$�zW�|��v��BQ���k�d�4���biP������}�}||HLLl��j���[��Z�G�����?� �������p�i�&���<�J��W�^�v�m���[��l�@Y ����JX�VJJJ(..����m����������t�3���RI`` !!!����V�����/��������#F��h����1b�\�f�q��i.\��lB��J%iii7���3����7�|�1c������@ 7)�� �R��A�4h��������_��_|��N�~�1biii�{���U�n�c	n������������b
���#77���\���(--����Z-�v{yy�����������������"��ZT�

b��DFF��m�X8}�4�:u��W�T���fe�����L��#G�Fppp�������9������������p�B6o����'C�a������G(^�F�������c��_
�n�����N9�Y������J


�p�.\ //���|������#//���r�V+V��BA`` ���ELL�Z�"..4
j�Z~u]#�RV{I��d�����S������������s4'��5/���x����������#G��uka�@�x���d�������?g��Mx{{3d�F������6�%��}���O�6���H���Njkk���T����,]�����3u��:���y��o�I��/\�@AA��r��Y�������H�N�TDTTDDDY�500��I.?~<���111B^���*++�2e
>� �z�j�L	�@ �:�����kY�|9��o�j����J������[	���//�+f������?�`�f��EPP�u?��;X�d	/��QQQ�f\c_o�v6�M.qV�b�Z�X,�����/k_VVFMM
��V�V�%00���0���'""���py	����������V����z���[s��w���1��5L�P4
J��;v�~�z�O�N�-�J��@ �����Q����-[��w�^��?���?111$''��}{bcc����wp.7��a�v���k��������|��WL�0����B��X�Vjkk1�L����e�w}_]]Mii)eee���QUU��l�d2a6���&�	���^����OOO|}}	���� �W��u���j������l�����2����U(����p8

"$$���n���k��� ��Q�Evv6������>|���|�F#~~~�k����$:u��-���6 7�Ldgg�t�R^x��;i�z/�J%:�N��m��Q\\�=��#�@�3+�F����**++������B^\?WVVRUUEuu5UUU����P(�u���^�������������O}I��Dy���r��@�|�� ��A�
�;�V]]MII	����8q���w���Nff&����W�^����������/7��s��Y�}���n�Zn[�~=���*F��I�i�Z���.tS�_z�%��y|||��]�\WTT�3��"���.EEETTT`2��X,��f�B~i�{����f��z���/-�����F���z�@��e�@ �&�����|cbb���##G��f�a2�8v�[�ne��]��5���j"##����{�&%%����z�$ah��PUU�F�����M>���IOO������+eQ�*
Z�lIFF��wov���5����:�����/++�f��5��N'z�^v�wU�;t� �Dpp0�������E�T��.�@ ��A��E[�T�V���� --���4����Lv����;x������ !!���d:w�LRR���C����#_i�Q~������C�����^��z�~�if����N�6m�={6C�������h���7o�W���qqq���4���\7��������m�]Jh'��K��\g��F#*�J�J�RV�%%>((��m���I�����p!�@ ������������#���u9r��~�����t�R���Cmm-���DEEE\\m��!((Hva�b�5���]***����f�]v�N��	����8�N�q7e����BA^^����5�V�Zq���p�RZZ���'����l6�Y��Z��{����*9������
������������>h�Zt:Z����d%=!!9������__��V��V���a�@�,p:�h4�u�F�n�����rrr8s��������w�^V�Z���@���V��j����EHH����4���jS	��_���+�oa6��>���0x�`�*g�^�|9}�J��3g�p��A��m���'m����@���q�F�;��hts���K?k�Z<==1r���!!!uL�~���j����2*�@ �
��r
��kG�v����\�%����Rrss9{�,'O��gu+++1�L��kdd$111DDD���CCC			�g���GR�2�J�$�*##��������������d�����oF����t�����{���p8		���x{{�����t�t:���~�f���k
�@ �@ �k4H���]@@n����z���F#���dee�����S���};/^�����L&9�ypp0���DGG.BCCe�����&Q�ne��Y���'�}�v
D�~����?^^^
��p8�=�k{vv6���.��{/=�S�LA�������l6z����	���
�0�@ 4�r%%tMD')������v����;w���\��?Onn.���c��������X���_c����	���???����W��R�tW�rOOOT*7B�e��$/����>�����>}:����:t��v��S�cbb����E@@�����)S$>>�W^y�9s�.W�X�f
��o��������|���B	a�@ h�2(|||HLL$11�����l�Kaa!������SVVFyy9YYYr����rL&v������p{�j�77t�J%��K^	j��N�����*H�K�������b��]����n�_�V���;�f�[�x����b�d2���T*�[�?�JEDD-[�$..��.����x{{��M�6��z3f���v��RRRt��@ �@ ������j����p���},)+}mm-&�I~���q�Xo��0�L�l6Y	����L&
������pS�]��%���F�q+�(UK��+^/��K��Z��V������.���*:t`��A<��ch�Z��Y��+�����`!��@ �@ ��Pp���u[�L������NTT��v111���c��d���p���k�5'�d�)((�m��Bh�@�@ ����F!99�����)�~~~�����������T��1X,|}}��3##�A�	���_9o�l4�@ �����{�����l�����zJn��l�������5��B�������6Lq���@ �zqU�����m���^��M�61p��_��������#�����s'C�A���%
}��@ ��*��?�<��w���n#((��7==�
6��cG�f�0�@ ��~�X�p!��������no�0�V��h������Bz��Ijjj����@ �@ �u2H�wnn.g���l6�������Z�Hhh(����d�P��@�@ $����d�s:��T*�X��/W�����G��N�IEND�B`�
#2Gregory Stark
stark@enterprisedb.com
In reply to: Adriano Lange (#1)
Re: graph representation of data structures in optimizer

Adriano Lange <adriano@c3sl.ufpr.br> writes:

Hi,

I'm interested in data representation and debug of optimizer routines. Thus,
I've changed the debug functions of allpaths.c to make a graphviz-like output
of RelOptInfo structure.

Any idea about this?
Is there some project or improvement like this?

Several people have asked about ways to see what possible plans were
considered and why the were rejected, it was one of the repeat offenders in
the recent Postgres Pet Peeves thread so this is a very interesting area to
explore.

However I have to say this graph you've generated is amazingly hard to
decipher :) It took me a while to even figure out what information it was
presenting.

Worse, it's not useful unless you add a lot more information to it such as
what relations are actually being scanned or joined at each path which is
going to make it a hell of a lot harder to read.

I'm not sure how to do any better but I would be fascinated to see any new
images you generate :)

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com
Ask me about EnterpriseDB's PostGIS support!

#3Robert Haas
robertmhaas@gmail.com
In reply to: Adriano Lange (#1)
Re: graph representation of data structures in optimizer

On Wed, Feb 18, 2009 at 10:22 AM, Adriano Lange <adriano@c3sl.ufpr.br> wrote:

Hi,

I'm interested in data representation and debug of optimizer routines. Thus,
I've changed the debug functions of allpaths.c to make a graphviz-like
output of RelOptInfo structure.

Any idea about this?
Is there some project or improvement like this?

That is pretty cool.

It would help a lot to label the baserels with their names.

You might also want to move the RestrictInfo out of line so that it's
easier to see where the inner and outer joinpath arrows are going.

It would be really sweet if there were some compact way to see the pathkeys.

...Robert

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gregory Stark (#2)
Re: graph representation of data structures in optimizer

Gregory Stark <stark@enterprisedb.com> writes:

Adriano Lange <adriano@c3sl.ufpr.br> writes:

I've changed the debug functions of allpaths.c to make a graphviz-like output
of RelOptInfo structure.

However I have to say this graph you've generated is amazingly hard to
decipher :) It took me a while to even figure out what information it was
presenting.

Worse, it's not useful unless you add a lot more information to it such as
what relations are actually being scanned or joined at each path which is
going to make it a hell of a lot harder to read.

Labeling the bottom-level scan paths with their relations would help a
lot. The label at the top level isn't real helpful.

But really I think the problem with this approach is that the
information density is too low --- imagine what it would look like in a
six-or-more-way join. I don't think the graphical approach is helpful
at all here.

Also, showing the final Path data structure has the problem that a lot
of the information someone might want is already gone, because we throw
away Paths that are determined to be dominated by other paths. The
question someone usually wants answered is "was a path of this structure
considered at all, and if so what was the estimated cost?". In a large
fraction of cases, that's not answerable from the paths that remain at
the end of the search. I think some sort of on-the-fly tracing of all
add_path calls might be a more useful approach.

regards, tom lane

#5Adriano Lange
adriano@c3sl.ufpr.br
In reply to: Tom Lane (#4)
Re: graph representation of data structures in optimizer

Tom Lane escreveu:

Gregory Stark <stark@enterprisedb.com> writes:

Adriano Lange <adriano@c3sl.ufpr.br> writes:

I've changed the debug functions of allpaths.c to make a graphviz-like output
of RelOptInfo structure.

However I have to say this graph you've generated is amazingly hard to
decipher :) It took me a while to even figure out what information it was
presenting.

Worse, it's not useful unless you add a lot more information to it such as
what relations are actually being scanned or joined at each path which is
going to make it a hell of a lot harder to read.

Labeling the bottom-level scan paths with their relations would help a
lot. The label at the top level isn't real helpful.

But really I think the problem with this approach is that the
information density is too low --- imagine what it would look like in a
six-or-more-way join. I don't think the graphical approach is helpful
at all here.

Certainly. That example had only three relations. Six relations in a
RelOptInfo will make a big graph and too hard to understand.

So, I will think about this for a while. A interesting thing for me is
to identify the in-degree pointers of each structure.

Also, showing the final Path data structure has the problem that a lot
of the information someone might want is already gone, because we throw
away Paths that are determined to be dominated by other paths. The
question someone usually wants answered is "was a path of this structure
considered at all, and if so what was the estimated cost?". In a large
fraction of cases, that's not answerable from the paths that remain at
the end of the search. I think some sort of on-the-fly tracing of all
add_path calls might be a more useful approach.

regards, tom lane

Humm. This temporal approach may be dificult to represent in this
graphical mode. I guess that the text-like pretty_format_node_dump()
representation and diff are yet more usefull for this.

--
Adriano Lange
C3SL/UFPR - www.c3sl.ufpr.br

#6Adriano Lange
adriano@c3sl.ufpr.br
In reply to: Robert Haas (#3)
1 attachment(s)
Re: graph representation of data structures in optimizer

Robert Haas escreveu:

That is pretty cool.

It would help a lot to label the baserels with their names.

You might also want to move the RestrictInfo out of line so that it's
easier to see where the inner and outer joinpath arrows are going.

Humm. Maybe this is not easy to do in dot command line graph generator.
Perhaps I should to try this in other application. The output generated
by debug is only a text plain description of vertex and edges, without
any information about position or path. See the attached file.

It would be really sweet if there were some compact way to see the pathkeys.

Several attributes and objects are missing yet, but I will add them.

Thanks,

Adriano Lange
C3SL/UFPR - www.c3sl.ufpr.br

Attachments:

RelOptInfo_graph.dotapplication/x-crossover-dot; name=RelOptInfo_graph.dotDownload
#7Adriano Lange
adriano@c3sl.ufpr.br
In reply to: Tom Lane (#4)
Re: graph representation of data structures in optimizer

Tom Lane escreveu:

But really I think the problem with this approach is that the
information density is too low --- imagine what it would look like in a
six-or-more-way join. I don't think the graphical approach is helpful
at all here.

I was thinking about the hard visualization and navigability in the
graph. I think that a good solution for this would be a dynamic
navigability in their nodes and a rearrange their positions by focused
node. I'm not remembering now, but I've saw a tool like this.

Thanks

--
Adriano Lange
C3SL/UFPR - www.c3sl.ufpr.br

#8Peter Eisentraut
peter_e@gmx.net
In reply to: Adriano Lange (#7)
Re: graph representation of data structures in optimizer

On Thursday 19 February 2009 22:17:54 Adriano Lange wrote:

Tom Lane escreveu:

But really I think the problem with this approach is that the
information density is too low --- imagine what it would look like in a
six-or-more-way join. I don't think the graphical approach is helpful
at all here.

I was thinking about the hard visualization and navigability in the
graph. I think that a good solution for this would be a dynamic
navigability in their nodes and a rearrange their positions by focused
node. I'm not remembering now, but I've saw a tool like this.

http://prefuse.org could be useful for that.

#9Adriano Lange
adriano@c3sl.ufpr.br
In reply to: Adriano Lange (#1)
1 attachment(s)
Re: graph representation of data structures in optimizer

Hi,

The patch attached is an implementation for graph generation of data
structures in postgres. The file debuggraph.c is a simple library that
generate graphs in the format supported by graphviz. Example:

#include "nodes/debuggraph.h"
...
DebugGraph *graph;
DebugNode *node;

graph = createDebugGraph();
node = newDebugNode( graph, "node1", "Node 1" );
addDebugNodeAttribute( node, "Attribute 1", "Value 1" );
newDebugNode( graph, "node2", "Node 2" );
newDebugEdge( graph, "node1", "node2", "Edge 1" );

printGraphvizToFile( graph, stderr );
destroyDebugGraph( graph );

I've also made a reimplementation of outfuncs.c to outfuncs_graph.c for
an entire node output support.

#include "nodes/outfuncs_graph.h"
...
printGraphNodes( node, stderr );

I hope that this may be useful for somebody.

--
Adriano Lange
C3SL/UFPR - www.c3sl.ufpr.br

Attachments:

postgresql-8.3.5-debuggraph-20090222.patchtext/x-diff; name=postgresql-8.3.5-debuggraph-20090222.patchDownload
Index: src/include/nodes/print.h
===================================================================
--- src/include/nodes/print.h	(revision 11)
+++ src/include/nodes/print.h	(working copy)
@@ -28,6 +28,7 @@
 extern char *pretty_format_node_dump(const char *dump);
 extern void print_rt(List *rtable);
 extern void print_expr(Node *expr, List *rtable);
+extern int  print_expr_str(char *output, Node *expr, List *rtable);
 extern void print_pathkeys(List *pathkeys, List *rtable);
 extern void print_tl(List *tlist, List *rtable);
 extern void print_slot(TupleTableSlot *slot);
Index: src/include/nodes/debuggraph.h
===================================================================
--- src/include/nodes/debuggraph.h	(revision 0)
+++ src/include/nodes/debuggraph.h	(revision 0)
@@ -0,0 +1,80 @@
+/*-------------------------------------------------------------------------
+ *
+ * debuggraph.h
+ *
+ * Copyright (c) 2009, Adriano Lange <alange0001@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without  modifi-
+ * cation, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of  source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above copyright noti-
+ *     ce,  this list of conditions and the following disclaimer in the  docu-
+ *     mentation and/or other materials provided with the distribution.
+ *
+ *  3. Neither the name of the UNIVERSIDADE FEDERAL DO PARANÁ nor the names of
+ *     its  contributors may be  used to endorse or  promote  products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT LIMITED TO,  THE
+ * IMPLIED  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE  DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT  OWNER OR CONTRIBUTORS BE
+ * LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
+ * CONSEQUENTIAL DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
+ * SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
+2 * INTERRUPTION)  HOWEVER CAUSED AND ON ANY  THEORY OF  LIABILITY,  WHETHER IN
+ * CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE OR  OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PRINT_GRAPH_H
+#define PRINT_GRAPH_H
+
+typedef struct DebugNode {
+	char* internal_name;
+	char* name;
+	int attributeCount;
+	int attributeMemorySpace;
+	char** attributeNames;
+	char** attributeValues;
+} DebugNode;
+
+typedef struct DebugEdge {
+	char* source;
+	char* destination;
+	char* label;
+} DebugEdge;
+
+typedef struct DebugGraph {
+	DebugNode**   nodes;
+	DebugEdge**   edges;
+	int           nodeCount;
+	int           nodeMemorySpace;
+	int           edgeCount;
+	int           edgeMemorySpace;
+} DebugGraph;
+
+extern DebugGraph* createDebugGraph();
+extern void destroyDebugGraph(DebugGraph* graph);
+extern DebugNode* newDebugNode(DebugGraph* graph, const char* internal_name,
+		const char* name);
+extern void addDebugNodeAttribute(DebugNode* node, const char* name,
+		const char* value);
+extern void addDebugNodeAttributeArgs(DebugNode* node, const char* name,
+		const char* value,...);
+extern void newDebugEdge(DebugGraph* graph, const char* source,
+		const char* destination, const char* label);
+extern void printGraphvizToFile( DebugGraph* graph, FILE* file );
+extern char* addressToName( char* destination, void* address );
+extern DebugNode* findDebugNodeByInternalName( DebugGraph *graph,
+		const char *internal_name );
+extern DebugEdge* findDebugEdge( DebugGraph *graph, const char *source,
+		const char *destination, const char *label );
+
+
+#endif
Index: src/include/nodes/outfuncs_graph.h
===================================================================
--- src/include/nodes/outfuncs_graph.h	(revision 0)
+++ src/include/nodes/outfuncs_graph.h	(revision 0)
@@ -0,0 +1,14 @@
+/*-------------------------------------------------------------------------
+ *
+ * outfuncs_graph.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef NODEGRAPH_H
+#define NODEGRAPH_H
+
+extern DebugGraph *createGraphNodes(void *obj);
+extern void printGraphNodes(void *obj, FILE *file);
+
+#endif
+
Index: src/backend/optimizer/path/allpaths.c
===================================================================
--- src/backend/optimizer/path/allpaths.c	(revision 11)
+++ src/backend/optimizer/path/allpaths.c	(working copy)
@@ -15,8 +15,11 @@
 
 #include "postgres.h"
 
+#define OPTIMIZER_DEBUG
 #ifdef OPTIMIZER_DEBUG
 #include "nodes/print.h"
+#include "nodes/debuggraph.h"
+#include "nodes/outfuncs_graph.h"
 #endif
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
@@ -671,6 +674,7 @@
 	}
 	else
 	{
+		RelOptInfo *ret;
 		/*
 		 * Consider the different orders in which we could join the rels,
 		 * using a plugin, GEQO, or the regular join search code.
@@ -681,11 +685,16 @@
 		root->initial_rels = initial_rels;
 
 		if (join_search_hook)
-			return (*join_search_hook) (root, levels_needed, initial_rels);
+			ret = (*join_search_hook) (root, levels_needed, initial_rels);
 		else if (enable_geqo && levels_needed >= geqo_threshold)
-			return geqo(root, levels_needed, initial_rels);
+			ret = geqo(root, levels_needed, initial_rels);
 		else
-			return standard_join_search(root, levels_needed, initial_rels);
+			ret = standard_join_search(root, levels_needed, initial_rels);
+
+#		ifdef OPTIMIZER_DEBUG
+		//printGraphNodes( ret, stderr );
+#		endif
+		return ret;
 	}
 }
 
@@ -1108,47 +1117,95 @@
 
 #ifdef OPTIMIZER_DEBUG
 
+static const char*
+get_renation_name(PlannerInfo *root, int relid)
+{
+	RangeTblEntry *rte;
+
+	Assert(relid <= list_length(root->parse->rtable));
+	rte = rt_fetch(relid, root->parse->rtable);
+	return rte->eref->aliasname;
+}
+
 static void
-print_relids(Relids relids)
+print_relids(DebugNode *node, PlannerInfo *root, Relids relids)
 {
 	Relids		tmprelids;
 	int			x;
-	bool		first = true;
+	char        aux[30];
 
 	tmprelids = bms_copy(relids);
 	while ((x = bms_first_member(tmprelids)) >= 0)
 	{
-		if (!first)
-			printf(" ");
-		printf("%d", x);
-		first = false;
+		sprintf(aux, "relids[%d]", x);
+		addDebugNodeAttribute(node, aux, get_renation_name(root, x));
 	}
 	bms_free(tmprelids);
 }
 
 static void
-print_restrictclauses(PlannerInfo *root, List *clauses)
+print_restrictclauses(DebugGraph *graph, DebugNode *parent, PlannerInfo *root,
+		List *clauses)
 {
+	DebugNode  *node;
 	ListCell   *l;
+	char        aux[500];
 
 	foreach(l, clauses)
 	{
 		RestrictInfo *c = lfirst(l);
 
-		print_expr((Node *) c->clause, root->parse->rtable);
-		if (lnext(l))
-			printf(", ");
+		node = newDebugNode( graph, addressToName(aux, c), "RestrictInfo" );
+		print_expr_str(aux, (Node *) c->clause, root->parse->rtable);
+		addDebugNodeAttribute( node, "clause", aux );
+		newDebugEdge( graph, parent->internal_name, node->internal_name, "" );
 	}
 }
 
 static void
-print_path(PlannerInfo *root, Path *path, int indent)
+print_pathkeys_node(DebugGraph *graph, DebugNode *parent, List *pathkeys,
+		List *rtable)
 {
+	ListCell   *i;
+
+	foreach(i, pathkeys)
+	{
+		PathKey    *pathkey = (PathKey *) lfirst(i);
+		EquivalenceClass *eclass;
+		ListCell   *k;
+		DebugNode  *node;
+		char        aux[500];
+
+		node = newDebugNode(graph, addressToName(aux, pathkey), "PathKey");
+		newDebugEdge(graph, parent->internal_name, node->internal_name, "");
+
+		eclass = pathkey->pk_eclass;
+		/* chase up, in case pathkey is non-canonical */
+		while (eclass->ec_merged)
+			eclass = eclass->ec_merged;
+
+		foreach(k, eclass->ec_members)
+		{
+			EquivalenceMember *mem = (EquivalenceMember *) lfirst(k);
+
+			print_expr_str(aux,(Node *) mem->em_expr, rtable);
+			addDebugNodeAttribute(node, "eclass", aux);
+		}
+	}
+}
+
+
+static DebugNode*
+print_path(DebugGraph *graph, PlannerInfo *root, Path *path)
+{
+	DebugNode  *node;
+	char        aux[500];
 	const char *ptype;
 	bool		join = false;
 	Path	   *subpath = NULL;
-	int			i;
 
+	node = newDebugNode( graph, addressToName(aux, path), "Path" );
+
 	switch (nodeTag(path))
 	{
 		case T_Path:
@@ -1200,90 +1257,123 @@
 			break;
 	}
 
-	for (i = 0; i < indent; i++)
-		printf("\t");
-	printf("%s", ptype);
+	addDebugNodeAttribute(node, "type", ptype );
 
-	if (path->parent)
-	{
-		printf("(");
-		print_relids(path->parent->relids);
-		printf(") rows=%.0f", path->parent->rows);
-	}
-	printf(" cost=%.2f..%.2f\n", path->startup_cost, path->total_cost);
+	print_relids(node, root, path->parent->relids);
 
+	addDebugNodeAttributeArgs(node, "rows", "%.0f", path->parent->rows);
+	addDebugNodeAttributeArgs(node, "startup_cost", "%.2f", path->startup_cost);
+	addDebugNodeAttributeArgs(node, "total_cost", "%.2f", path->total_cost);
+
 	if (path->pathkeys)
 	{
-		for (i = 0; i < indent; i++)
-			printf("\t");
-		printf("  pathkeys: ");
-		print_pathkeys(path->pathkeys, root->parse->rtable);
+		DebugNode *node2;
+		node2 = newDebugNode( graph, addressToName(aux, path->pathkeys),
+				"List");
+		newDebugEdge( graph, node->internal_name, node2->internal_name,
+				"pathkeys" );
+		print_pathkeys_node(graph, node2, path->pathkeys, root->parse->rtable);
 	}
 
 	if (join)
 	{
+		DebugNode *node2;
 		JoinPath   *jp = (JoinPath *) path;
 
-		for (i = 0; i < indent; i++)
-			printf("\t");
-		printf("  clauses: ");
-		print_restrictclauses(root, jp->joinrestrictinfo);
-		printf("\n");
+		node2 = newDebugNode( graph, addressToName(aux, jp->joinrestrictinfo),
+				"List");
+		newDebugEdge( graph, node->internal_name, node2->internal_name,
+				"joinrestrictinfo" );
 
+		print_restrictclauses(graph, node2, root, jp->joinrestrictinfo);
+
 		if (IsA(path, MergePath))
 		{
 			MergePath  *mp = (MergePath *) path;
 
 			if (mp->outersortkeys || mp->innersortkeys)
 			{
-				for (i = 0; i < indent; i++)
-					printf("\t");
-				printf("  sortouter=%d sortinner=%d\n",
-					   ((mp->outersortkeys) ? 1 : 0),
-					   ((mp->innersortkeys) ? 1 : 0));
+				addDebugNodeAttributeArgs(node, "sortouter", "%d",
+						((mp->outersortkeys) ? 1 : 0));
+				addDebugNodeAttributeArgs(node, "sortinner", "%d",
+						((mp->innersortkeys) ? 1 : 0));
 			}
 		}
 
-		print_path(root, jp->outerjoinpath, indent + 1);
-		print_path(root, jp->innerjoinpath, indent + 1);
+		node2 = print_path(graph, root, jp->outerjoinpath);
+		newDebugEdge(graph, node->internal_name, node2->internal_name,
+				"outerjoinpath");
+		node2 = print_path(graph, root, jp->innerjoinpath);
+		newDebugEdge(graph, node->internal_name, node2->internal_name,
+				"innerjoinpath");
 	}
 
-	if (subpath)
-		print_path(root, subpath, indent + 1);
+	if (subpath) {
+		DebugNode *node2;
+		node2 = print_path(graph, root, subpath);
+		newDebugEdge(graph, node->internal_name, node2->internal_name,
+				"subpath");
+	}
+
+	return node;
 }
 
 void
 debug_print_rel(PlannerInfo *root, RelOptInfo *rel)
 {
-	ListCell   *l;
+	DebugGraph  *graph;
+	DebugNode   *node,
+	            *node2;
+	char         aux[500];
+	ListCell    *l;
 
-	printf("RELOPTINFO (");
-	print_relids(rel->relids);
-	printf("): rows=%.0f width=%d\n", rel->rows, rel->width);
+	graph = createDebugGraph();
 
+	node = newDebugNode(graph, addressToName(aux,rel), "RelOptInfo" );
+
+	print_relids(node, root, rel->relids);
+
+	addDebugNodeAttributeArgs(node, "rows", "%.0f", rel->rows);
+
+	addDebugNodeAttributeArgs(node, "width", "%d", rel->width);
+
 	if (rel->baserestrictinfo)
 	{
-		printf("\tbaserestrictinfo: ");
-		print_restrictclauses(root, rel->baserestrictinfo);
-		printf("\n");
+		node2 = newDebugNode( graph, addressToName(aux,rel->baserestrictinfo),
+				"List" );
+		newDebugEdge( graph, node->internal_name, node2->internal_name,
+				"baserestrictinfo" );
+		print_restrictclauses(graph, node2, root, rel->baserestrictinfo);
 	}
 
 	if (rel->joininfo)
 	{
-		printf("\tjoininfo: ");
-		print_restrictclauses(root, rel->joininfo);
-		printf("\n");
+		node2 = newDebugNode( graph, addressToName(aux,rel->joininfo),
+				"List" );
+		newDebugEdge( graph, node->internal_name, node2->internal_name,
+				"joininfo" );
+		print_restrictclauses(graph, node2, root, rel->joininfo);
 	}
 
-	printf("\tpath list:\n");
-	foreach(l, rel->pathlist)
-		print_path(root, lfirst(l), 1);
-	printf("\n\tcheapest startup path:\n");
-	print_path(root, rel->cheapest_startup_path, 1);
-	printf("\n\tcheapest total path:\n");
-	print_path(root, rel->cheapest_total_path, 1);
-	printf("\n");
-	fflush(stdout);
+
+	node2 = newDebugNode( graph, addressToName(aux,rel->pathlist),
+				"List" );
+	newDebugEdge( graph, node->internal_name, node2->internal_name,
+				"pathlist" );
+	foreach(l, rel->pathlist) {
+		DebugNode *node3;
+		node3 = print_path(graph, root, lfirst(l));
+		newDebugEdge( graph, node2->internal_name, node3->internal_name, "");
+	}
+	newDebugEdge( graph, node->internal_name,
+			addressToName(aux, rel->cheapest_startup_path),
+			"cheapest_startup_path");
+	newDebugEdge( graph, node->internal_name,
+			addressToName(aux, rel->cheapest_total_path),
+			"cheapest_total_path");
+
+	printGraphvizToFile( graph, stderr );
+	destroyDebugGraph( graph );
 }
 
 #endif   /* OPTIMIZER_DEBUG */
Index: src/backend/nodes/debuggraph.c
===================================================================
--- src/backend/nodes/debuggraph.c	(revision 0)
+++ src/backend/nodes/debuggraph.c	(revision 0)
@@ -0,0 +1,415 @@
+/*-------------------------------------------------------------------------
+ *
+ * debuggraph.c
+ *
+ * Copyright (c) 2009, Adriano Lange <alange0001@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without  modifi-
+ * cation, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of  source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above copyright noti-
+ *     ce,  this list of conditions and the following disclaimer in the  docu-
+ *     mentation and/or other materials provided with the distribution.
+ *
+ *  3. Neither the name of the UNIVERSIDADE FEDERAL DO PARANÁ nor the names of
+ *     its  contributors may be  used to endorse or  promote  products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT LIMITED TO,  THE
+ * IMPLIED  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE  DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT  OWNER OR CONTRIBUTORS BE
+ * LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
+ * CONSEQUENTIAL DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
+ * SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
+ * INTERRUPTION)  HOWEVER CAUSED AND ON ANY  THEORY OF  LIABILITY,  WHETHER IN
+ * CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE OR  OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "postgres.h"
+
+#include "nodes/debuggraph.h"
+
+#define INITIAL_LIST_SIZE 100
+
+#define ALLOC_FUNC  palloc
+#define ALLOC_FUNC0 palloc0
+#define FREE_FUNC   pfree
+
+static void addDebugNode(DebugGraph* graph, DebugNode* node);
+static void addDebugEdge(DebugGraph* graph, DebugEdge* edge);
+static DebugNode* createDebugNode( const char* internal_name,
+		const char* name );
+static void destroyDebugNode(DebugNode* node);
+static DebugEdge* createDebugEdge( const char* source, const char* destination,
+		const char* label );
+static void destroyDebugEdge(DebugEdge* edge);
+static char* copyString( const char* source );
+
+
+DebugGraph*
+createDebugGraph()
+{
+	DebugGraph* graph;
+
+	graph = (DebugGraph*) ALLOC_FUNC0(sizeof(DebugGraph));
+
+	return graph;
+}
+
+void
+destroyDebugGraph(DebugGraph* graph)
+{
+	if( graph ){
+		int i;
+
+		if( graph->nodeMemorySpace ){
+			for( i=0; i<graph->nodeCount; i++ ){
+				if( graph->nodes[i] )
+					destroyDebugNode( graph->nodes[i] );
+			}
+			FREE_FUNC( graph->nodes );
+		}
+
+		if( graph->edgeMemorySpace ){
+			for( i=0; i<graph->edgeCount; i++ ){
+				if( graph->edges[i] )
+					destroyDebugEdge( graph->edges[i] );
+			}
+			FREE_FUNC( graph->edges );
+		}
+
+		FREE_FUNC(graph);
+	}
+}
+
+DebugNode*
+newDebugNode(DebugGraph* graph, const char* internal_name, const char* name)
+{
+	DebugNode* node;
+
+	if( ! graph )
+		return NULL;
+
+	node = findDebugNodeByInternalName(graph, internal_name);
+	if( node )
+		return node;
+
+	node = createDebugNode( internal_name, name );
+	addDebugNode(graph, node);
+
+	return node;
+}
+
+void
+newDebugEdge(DebugGraph* graph, const char* source, const char* destination,
+		const char* label)
+{
+	DebugEdge* edge;
+
+	if( !graph )
+		return;
+
+	edge = findDebugEdge(graph, source, destination, label);
+	if( edge )
+		return;
+
+	edge = createDebugEdge( source, destination, label );
+	addDebugEdge( graph, edge );
+}
+
+void
+addDebugNodeAttributeArgs(DebugNode* node, const char* name,
+		const char* value,...)
+{
+	char  *str_value;
+	va_list va;
+	int len = 100;
+	int print_return;
+
+	if( !node || !name || !value )
+		return;
+
+	va_start(va, value);
+	for(;;){
+		str_value = (char*) ALLOC_FUNC( sizeof(char) * len );
+
+		print_return = vsnprintf(str_value, len, value, va);
+
+		if( print_return >= 0 && print_return < len - 1 ) {
+			break;
+		} else {
+			FREE_FUNC(str_value);
+			len *= 2;
+		}
+	}
+	va_end(va);
+
+	addDebugNodeAttribute(node, name, str_value);
+
+	FREE_FUNC(str_value);
+}
+
+void
+addDebugNodeAttribute(DebugNode* node, const char* name, const char* value)
+{
+	int    index;
+
+	if( !node || !name || !value )
+		return;
+	for( index=0; index<node->attributeCount; index++ ){
+		if( (!strcmp(node->attributeNames[index], name))
+		&&	(!strcmp(node->attributeValues[index], value)) )
+			return;
+	}
+
+	if( node->attributeCount >= node->attributeMemorySpace ){
+		int i;
+		int new_size;
+		char** new_names;
+		char** new_values;
+
+		if( node->attributeMemorySpace )
+			new_size = node->attributeMemorySpace *2;
+		else
+			new_size = INITIAL_LIST_SIZE;
+
+		new_names = (char**) ALLOC_FUNC( sizeof(char*) * new_size );
+		new_values = (char**) ALLOC_FUNC( sizeof(char*) * new_size );
+
+		for( i=0; i<node->attributeCount; i++ ){
+			new_names[i] = node->attributeNames[i];
+			new_values[i] = node->attributeValues[i];
+		}
+		if( node->attributeMemorySpace ){
+			FREE_FUNC( node->attributeNames );
+			FREE_FUNC( node->attributeValues );
+		}
+		node->attributeNames = new_names;
+		node->attributeValues = new_values;
+		node->attributeMemorySpace = new_size;
+	}
+
+	index = node->attributeCount++;
+
+	node->attributeNames[index] = copyString(name);
+	node->attributeValues[index] = copyString(value);
+}
+
+void
+printGraphvizToFile( DebugGraph* graph, FILE* file )
+{
+	int i,j;
+
+	if( !graph )
+		return;
+
+	fprintf(file, "digraph g {\n");
+	fprintf(file, "\tgraph [fontsize=30 labelloc=\"t\" label=\"\" splines=true overlap=false rankdir = \"LR\"];\n");
+	fprintf(file, "\tnode  [style = \"filled\" penwidth = 1 fillcolor = \"white\" fontname = \"Courier New\" shape = \"Mrecord\"];\n");
+	fprintf(file, "\tedge [ penwidth = 2 fontsize = 18 fontcolor = \"black\" ];\n");
+	fprintf(file, "\tratio = auto;\n");
+	for( i=0; i<graph->nodeCount; i++ ){
+		fprintf(file, "\t\"%s\" [ label =<\\\n", graph->nodes[i]->internal_name);
+		fprintf(file, "\t\t<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">\\\n");
+		fprintf(file, "\t\t\t<tr><td bgcolor=\"black\" align=\"center\" colspan=\"2\"><font color=\"white\">%s</font></td></tr>\\\n",
+				graph->nodes[i]->name);
+		for( j=0; j<graph->nodes[i]->attributeCount; j++ ){
+			fprintf(file, "\t\t\t<tr><td bgcolor=\"grey\" align=\"left\">%s:</td><td align=\"left\">%s</td></tr>\n",
+					graph->nodes[i]->attributeNames[j],
+					graph->nodes[i]->attributeValues[j]);
+		}
+		fprintf(file, "\t\t</table>> ];\n");
+	}
+	for( i=0; i<graph->edgeCount; i++ ){
+		fprintf(file, "\t\"%s\" -> \"%s\" [ label = \"%s\" ];\n",
+				graph->edges[i]->source,
+				graph->edges[i]->destination,
+				graph->edges[i]->label);
+	}
+	fprintf(file, "}\n");
+}
+
+char*
+addressToName( char* destination, void* address )
+{
+	sprintf(destination, "a%p", address );
+	return destination;
+}
+
+DebugNode*
+findDebugNodeByInternalName( DebugGraph *graph, const char *internal_name )
+{
+	int i;
+	if( !graph )
+		return NULL;
+
+	for( i=0; i<graph->nodeCount; i++ ){
+		if( !strcmp( graph->nodes[i]->internal_name, internal_name ) )
+			return graph->nodes[i];
+	}
+	return NULL;
+}
+
+DebugEdge*
+findDebugEdge( DebugGraph *graph, const char *source, const char *destination,
+		const char *label )
+{
+	int i;
+	if( !graph )
+		return NULL;
+
+	for( i=0; i<graph->edgeCount; i++ ){
+		if( (!strcmp( graph->edges[i]->source, source ))
+		&&  (!strcmp( graph->edges[i]->destination, destination ))
+		&&  (!strcmp( graph->edges[i]->label, label )))
+			return graph->edges[i];
+	}
+	return NULL;
+}
+
+static void
+addDebugNode(DebugGraph* graph, DebugNode* node)
+{
+	if( (!graph) || (!node) )
+		return;
+
+	if( graph->nodeCount >= graph->nodeMemorySpace ){
+		int new_size;
+		DebugNode** new_list;
+
+		if( graph->nodeMemorySpace )
+			new_size = graph->nodeMemorySpace * 2;
+		else
+			new_size = INITIAL_LIST_SIZE;
+		new_list = (DebugNode**) ALLOC_FUNC( sizeof(DebugNode*) * new_size );
+
+		if( graph->nodeMemorySpace ){
+			int i;
+			for( i=0; i<graph->nodeCount; i++ ){
+				new_list[i] = graph->nodes[i];
+			}
+			FREE_FUNC( graph->nodes );
+		}
+		graph->nodeMemorySpace = new_size;
+		graph->nodes = new_list;
+	}
+
+	graph->nodes[ graph->nodeCount++ ] = node;
+}
+
+static void
+addDebugEdge(DebugGraph* graph, DebugEdge* edge)
+{
+	if( (!graph) || (!edge) )
+		return;
+
+	if( graph->edgeCount >= graph->edgeMemorySpace ){
+		int new_size;
+		DebugEdge** new_list;
+
+		if( graph->edgeMemorySpace )
+			new_size = graph->edgeMemorySpace *2;
+		else
+			new_size = INITIAL_LIST_SIZE;
+
+		new_list = (DebugEdge**) ALLOC_FUNC( sizeof(DebugEdge*) * new_size );
+
+		if( graph->edgeMemorySpace ){
+			int i;
+			for( i=0; i<graph->edgeCount; i++ ){
+				new_list[i] = graph->edges[i];
+			}
+			FREE_FUNC( graph->edges );
+		}
+		graph->edges = new_list;
+		graph->edgeMemorySpace = new_size;
+	}
+
+	graph->edges[ graph->edgeCount++ ] = edge;
+}
+
+static DebugNode*
+createDebugNode( const char* internal_name, const char* name )
+{
+	DebugNode* node;
+
+	node = (DebugNode*) ALLOC_FUNC0( sizeof(DebugNode) );
+
+	node->internal_name = copyString( internal_name );
+	node->name = copyString( name );
+
+	return node;
+}
+
+static void
+destroyDebugNode(DebugNode* node)
+{
+	if( node ) {
+		int i;
+
+		if( node->internal_name )
+			FREE_FUNC( node->internal_name );
+		if( node->name )
+			FREE_FUNC( node->name );
+
+		if( node->attributeMemorySpace ) {
+			for( i=0; i<node->attributeCount; i++ ){
+				FREE_FUNC( node->attributeNames[i] );
+				FREE_FUNC( node->attributeValues[i] );
+			}
+			FREE_FUNC( node->attributeNames );
+			FREE_FUNC( node->attributeValues );
+		}
+
+		FREE_FUNC(node);
+	}
+}
+
+static DebugEdge*
+createDebugEdge( const char* source, const char* destination,
+		const char* label )
+{
+	DebugEdge* edge;
+
+	edge = (DebugEdge*) ALLOC_FUNC( sizeof(DebugEdge) );
+
+	edge->source = copyString( source );
+	edge->destination = copyString( destination );
+	edge->label = copyString( label );
+
+	return edge;
+}
+
+static void
+destroyDebugEdge(DebugEdge* edge)
+{
+	if( edge ){
+		if( edge->source )
+			FREE_FUNC( edge->source );
+		if( edge->destination )
+			FREE_FUNC( edge->destination );
+		if( edge->label )
+			FREE_FUNC( edge->label );
+		FREE_FUNC( edge );
+	}
+}
+
+static char*
+copyString( const char* source )
+{
+	char* str;
+	int len;
+
+	len = strlen( source );
+	str = (char*) ALLOC_FUNC( sizeof(char) * (len+1) );
+	strcpy(str,source);
+
+	return str;
+}
Index: src/backend/nodes/outfuncs_graph.c
===================================================================
--- src/backend/nodes/outfuncs_graph.c	(revision 0)
+++ src/backend/nodes/outfuncs_graph.c	(revision 0)
@@ -0,0 +1,2529 @@
+/*-------------------------------------------------------------------------
+ *
+ * outfuncs_graph.c
+ *
+ * Portions Copyright (c) 2009, Adriano Lange <alange0001@gmail.com>.
+ * This file was changed from original src/backend/nodes/outfuncs.c file
+ * at PostgreSQL version 8.3. These portions of code follow the same BSD
+ * license adopted by the PostgreSQL Global Development Group.
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include <ctype.h>
+
+#include "lib/stringinfo.h"
+#include "nodes/plannodes.h"
+#include "nodes/relation.h"
+#include "nodes/debuggraph.h"
+#include "nodes/outfuncs_graph.h"
+#include "utils/datum.h"
+
+
+/*
+ * Macros to simplify output of different kinds of fields.	Use these
+ * wherever possible to reduce the chance for silly typos.	Note that these
+ * hard-wire conventions about the names of the local variables in an Out
+ * routine.
+ */
+
+/* Write the label for the node type */
+#define WRITE_NODE_TYPE(nodetitle) \
+	DebugNode *graphnode; \
+	graphnode = _newDebugNode(graph, parent, nodetitle, label, node)
+
+
+#define WRITE_FORMATED_FIELD(fldname, format) \
+	addDebugNodeAttributeArgs(graphnode, CppAsString(fldname), \
+			format,node->fldname)
+
+/* Write an integer field (anything written as ":fldname %d") */
+#define WRITE_INT_FIELD(fldname) WRITE_FORMATED_FIELD(fldname, "%d")
+
+/* Write an unsigned integer field (anything written as ":fldname %u") */
+#define WRITE_UINT_FIELD(fldname) WRITE_FORMATED_FIELD(fldname, "%u")
+
+/* Write an OID field (don't hard-wire assumption that OID is same as uint) */
+#define WRITE_OID_FIELD(fldname) WRITE_FORMATED_FIELD(fldname, "%u")
+
+/* Write a long-integer field */
+#define WRITE_LONG_FIELD(fldname) WRITE_FORMATED_FIELD(fldname, "%ld")
+
+/* Write a char field (ie, one ascii character) */
+#define WRITE_CHAR_FIELD(fldname) WRITE_FORMATED_FIELD(fldname, "%c")
+
+/* Write an enumerated-type field as an integer code */
+#define WRITE_ENUM_FIELD(fldname, enumtype) \
+	addDebugNodeAttributeArgs(graphnode, CppAsString(fldname), \
+			"%d", (int) node->fldname)
+
+/* Write a float field --- caller must give format to define precision */
+#define WRITE_FLOAT_FIELD(fldname,format) WRITE_FORMATED_FIELD(fldname, format)
+
+/* Write a boolean field */
+#define WRITE_BOOL_FIELD(fldname) \
+	addDebugNodeAttributeArgs(graphnode, CppAsString(fldname), \
+			"%s",booltostr(node->fldname))
+
+/* Write a character-string (possibly NULL) field */
+#define WRITE_STRING_FIELD(fldname) \
+	_outToken(graph, graphnode, CppAsString(fldname), node->fldname)
+
+/* Write a Node field */
+#define WRITE_NODE_FIELD(fldname) \
+	 _outNode(graph, graphnode, CppAsString(fldname), node->fldname)
+
+/* Write a bitmapset field */
+#define WRITE_BITMAPSET_FIELD(fldname) \
+	 _outBitmapset(graph, graphnode, CppAsString(fldname), node->fldname)
+
+#define WRITE_LIST_VALUES(countvalue, fieldname, format) \
+	{ \
+		int   i; \
+		char  str[500]; \
+		char *aux = str; \
+		\
+		for (i = 0; i < countvalue; i++) { \
+			if( i ) \
+				aux += sprintf(aux, " "); \
+			aux += sprintf(aux, format, node->fieldname[i]); \
+		} \
+		addDebugNodeAttribute(graphnode, CppAsString(fieldname), str); \
+	}
+
+
+#define booltostr(x)  ((x) ? "true" : "false")
+
+static void _outNode(DebugGraph *graph, DebugNode *parent, const char *label,
+		void *obj);
+
+
+static DebugNode *
+_newDebugNode(DebugGraph *graph, DebugNode *parent, const char *node_title,
+		const char *edge_label, void *node)
+{
+	DebugNode *graphnode;
+	char aux[50];
+	graphnode = newDebugNode(graph, addressToName(aux, node), node_title);
+	if( parent )
+		newDebugEdge(graph, parent->internal_name, graphnode->internal_name,
+				edge_label);
+	return graphnode;
+}
+
+/*
+ * _outToken
+ *	  Convert an ordinary string (eg, an identifier) into a form that
+ *	  will be decoded back to a plain token by read.c's functions.
+ *
+ *	  If a null or empty string is given, it is encoded as "<>".
+ */
+static void
+_outToken(DebugGraph *graph, DebugNode *parent, const char *label, char *s)
+{
+	if (s == NULL)
+	{
+		addDebugNodeAttribute(parent,label,"NULL");
+		return;
+	}
+	if (*s == '\0')
+		return;
+
+#	ifdef corrigir__out_Token
+	/*
+	 * Look for characters or patterns that are treated specially by read.c
+	 * (either in pg_strtok() or in nodeRead()), and therefore need a
+	 * protective backslash.
+	 */
+	/* These characters only need to be quoted at the start of the string */
+	if (*s == '<' ||
+		*s == '\"' ||
+		isdigit((unsigned char) *s) ||
+		((*s == '+' || *s == '-') &&
+		 (isdigit((unsigned char) s[1]) || s[1] == '.')))
+		appendStringInfoChar(str, '\\');
+	while (*s)
+	{
+		/* These chars must be backslashed anywhere in the string */
+		if (*s == ' ' || *s == '\n' || *s == '\t' ||
+			*s == '(' || *s == ')' || *s == '{' || *s == '}' ||
+			*s == '\\')
+			appendStringInfoChar(str, '\\');
+		appendStringInfoChar(str, *s++);
+	}
+#	else
+	// TODO: Replace HTML special characters
+	addDebugNodeAttribute(parent,label,s);
+#	endif
+}
+
+static void
+_outList(DebugGraph *graph, DebugNode *parent, const char *label, List *node)
+{
+	ListCell   *lc;
+	DebugNode  *graphnode;
+	const char *object_name;
+	char        aux[100];
+	int         count = 0;
+
+	if (IsA(node, List))
+		object_name = "List";
+	else if (IsA(node, IntList))
+		object_name = "IntList";
+	else if (IsA(node, OidList))
+		object_name = "OidList";
+	else {
+		sprintf(aux, "List (unrecognized: %d)",
+			 (int) node->type);
+		object_name = aux;
+	}
+
+	graphnode = newDebugNode(graph, addressToName(aux, node), object_name);
+	if( parent )
+		newDebugEdge(graph, parent->internal_name, graphnode->internal_name,
+				label);
+
+	foreach(lc, node)
+	{
+		sprintf(aux, "[%d]", count++);
+		/*
+		 * For the sake of backward compatibility, we emit a slightly
+		 * different whitespace format for lists of nodes vs. other types of
+		 * lists. XXX: is this necessary?
+		 */
+		if (IsA(node, List))
+		{
+			_outNode(graph, graphnode, "", lfirst(lc));
+		}
+		else if (IsA(node, IntList))
+			addDebugNodeAttributeArgs(graphnode, aux, "%d", lfirst_int(lc));
+		else if (IsA(node, OidList))
+			addDebugNodeAttributeArgs(graphnode, aux, "%u", lfirst_oid(lc));
+	}
+}
+
+/*
+ * _outBitmapset -
+ *	   converts a bitmap set of integers
+ *
+ * Note: the output format is "(b int int ...)", similar to an integer List.
+ * Currently bitmapsets do not appear in any node type that is stored in
+ * rules, so there is no support in readfuncs.c for reading this format.
+ */
+static void
+_outBitmapset(DebugGraph *graph, DebugNode *parent, const char *label,
+		Bitmapset *bms)
+{
+	StringInfo  str = makeStringInfo();
+	Bitmapset  *tmpset;
+	int			x;
+	bool        first = true;
+
+	tmpset = bms_copy(bms);
+	while ((x = bms_first_member(tmpset)) >= 0){
+		if( !first )
+			appendStringInfo(str, ", ");
+		appendStringInfo(str, "%d", x);
+		first = false;
+	}
+	bms_free(tmpset);
+
+	if( parent ){
+		addDebugNodeAttribute(parent, label, str->data);
+	} else {
+		char aux[50];
+		DebugNode *graphnode = newDebugNode(graph, addressToName(aux, bms),
+				"Bitmapset");
+		addDebugNodeAttribute(graphnode, "", str->data);
+	}
+}
+
+/*
+ * Print the value of a Datum given its type.
+ */
+static void
+_outDatum(DebugGraph *graph, DebugNode *parent, const char *label,
+		Datum value, int typlen, bool typbyval)
+{
+	Size		length,
+				i;
+	char	   *s;
+	StringInfo  str = makeStringInfo();
+
+	length = datumGetSize(value, typbyval, typlen);
+
+	if (typbyval)
+	{
+		s = (char *) (&value);
+		appendStringInfo(str, "%u [ ", (unsigned int) length);
+		for (i = 0; i < (Size) sizeof(Datum); i++)
+			appendStringInfo(str, "%d ", (int) (s[i]));
+		appendStringInfo(str, "]");
+	}
+	else
+	{
+		s = (char *) DatumGetPointer(value);
+		if (!PointerIsValid(s))
+			appendStringInfo(str, "0 [ ]");
+		else
+		{
+			appendStringInfo(str, "%u [ ", (unsigned int) length);
+			for (i = 0; i < length; i++)
+				appendStringInfo(str, "%d ", (int) (s[i]));
+			appendStringInfo(str, "]");
+		}
+	}
+
+	if( parent ){
+		addDebugNodeAttribute(parent, label, str->data);
+	} else {
+		char aux[50];
+		DebugNode *graphnode = newDebugNode(graph,
+				addressToName(aux, &value), "Datum");
+		addDebugNodeAttribute(graphnode, "", str->data);
+	}
+}
+
+/*
+ *	Stuff from plannodes.h
+ */
+
+static void
+_outPlannedStmt(DebugGraph *graph, DebugNode *parent, const char *label,
+		PlannedStmt *node)
+{
+	WRITE_NODE_TYPE("PlannedStmt");
+
+	WRITE_ENUM_FIELD(commandType, CmdType);
+	WRITE_BOOL_FIELD(canSetTag);
+	WRITE_NODE_FIELD(planTree);
+	WRITE_NODE_FIELD(rtable);
+	WRITE_NODE_FIELD(resultRelations);
+	WRITE_NODE_FIELD(utilityStmt);
+	WRITE_NODE_FIELD(intoClause);
+	WRITE_NODE_FIELD(subplans);
+	WRITE_BITMAPSET_FIELD(rewindPlanIDs);
+	WRITE_NODE_FIELD(returningLists);
+	WRITE_NODE_FIELD(rowMarks);
+	WRITE_NODE_FIELD(relationOids);
+	WRITE_INT_FIELD(nParamExec);
+}
+
+/*
+ * print the basic stuff of all nodes that inherit from Plan
+ */
+static void
+_outPlanInfo(DebugGraph *graph, DebugNode *graphnode, Plan *node)
+{
+	WRITE_FLOAT_FIELD(startup_cost, "%.2f");
+	WRITE_FLOAT_FIELD(total_cost, "%.2f");
+	WRITE_FLOAT_FIELD(plan_rows, "%.0f");
+	WRITE_INT_FIELD(plan_width);
+	WRITE_NODE_FIELD(targetlist);
+	WRITE_NODE_FIELD(qual);
+	WRITE_NODE_FIELD(lefttree);
+	WRITE_NODE_FIELD(righttree);
+	WRITE_NODE_FIELD(initPlan);
+	WRITE_BITMAPSET_FIELD(extParam);
+	WRITE_BITMAPSET_FIELD(allParam);
+}
+
+/*
+ * print the basic stuff of all nodes that inherit from Scan
+ */
+static void
+_outScanInfo(DebugGraph *graph, DebugNode *graphnode, Scan *node)
+{
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_UINT_FIELD(scanrelid);
+}
+
+/*
+ * print the basic stuff of all nodes that inherit from Join
+ */
+static void
+_outJoinPlanInfo(DebugGraph *graph, DebugNode *graphnode, Join *node)
+{
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_ENUM_FIELD(jointype, JoinType);
+	WRITE_NODE_FIELD(joinqual);
+}
+
+
+static void
+_outPlan(DebugGraph *graph, DebugNode *parent, const char *label, Plan *node)
+{
+	WRITE_NODE_TYPE("Plan");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+}
+
+static void
+_outResult(DebugGraph *graph, DebugNode *parent, const char *label, Result *node)
+{
+	WRITE_NODE_TYPE("Result");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_NODE_FIELD(resconstantqual);
+}
+
+static void
+_outAppend(DebugGraph *graph, DebugNode *parent, const char *label, Append *node)
+{
+	WRITE_NODE_TYPE("Append");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_NODE_FIELD(appendplans);
+	WRITE_BOOL_FIELD(isTarget);
+}
+
+static void
+_outBitmapAnd(DebugGraph *graph, DebugNode *parent, const char *label, BitmapAnd *node)
+{
+	WRITE_NODE_TYPE("BitmapAnd");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_NODE_FIELD(bitmapplans);
+}
+
+static void
+_outBitmapOr(DebugGraph *graph, DebugNode *parent, const char *label, BitmapOr *node)
+{
+	WRITE_NODE_TYPE("BitmapOr");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_NODE_FIELD(bitmapplans);
+}
+
+static void
+_outScan(DebugGraph *graph, DebugNode *parent, const char *label, Scan *node)
+{
+	WRITE_NODE_TYPE("Scan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+}
+
+static void
+_outSeqScan(DebugGraph *graph, DebugNode *parent, const char *label, SeqScan *node)
+{
+	WRITE_NODE_TYPE("SeqScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+}
+
+static void
+_outIndexScan(DebugGraph *graph, DebugNode *parent, const char *label, IndexScan *node)
+{
+	WRITE_NODE_TYPE("IndexScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_OID_FIELD(indexid);
+	WRITE_NODE_FIELD(indexqual);
+	WRITE_NODE_FIELD(indexqualorig);
+	WRITE_NODE_FIELD(indexstrategy);
+	WRITE_NODE_FIELD(indexsubtype);
+	WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
+}
+
+static void
+_outBitmapIndexScan(DebugGraph *graph, DebugNode *parent, const char *label, BitmapIndexScan *node)
+{
+	WRITE_NODE_TYPE("BitmapIndexScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_OID_FIELD(indexid);
+	WRITE_NODE_FIELD(indexqual);
+	WRITE_NODE_FIELD(indexqualorig);
+	WRITE_NODE_FIELD(indexstrategy);
+	WRITE_NODE_FIELD(indexsubtype);
+}
+
+static void
+_outBitmapHeapScan(DebugGraph *graph, DebugNode *parent, const char *label, BitmapHeapScan *node)
+{
+	WRITE_NODE_TYPE("BitmapHeapScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_NODE_FIELD(bitmapqualorig);
+}
+
+static void
+_outTidScan(DebugGraph *graph, DebugNode *parent, const char *label, TidScan *node)
+{
+	WRITE_NODE_TYPE("TidScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_NODE_FIELD(tidquals);
+}
+
+static void
+_outSubqueryScan(DebugGraph *graph, DebugNode *parent, const char *label, SubqueryScan *node)
+{
+	WRITE_NODE_TYPE("SubqueryScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_NODE_FIELD(subplan);
+	WRITE_NODE_FIELD(subrtable);
+}
+
+static void
+_outFunctionScan(DebugGraph *graph, DebugNode *parent, const char *label, FunctionScan *node)
+{
+	WRITE_NODE_TYPE("FunctionScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_NODE_FIELD(funcexpr);
+	WRITE_NODE_FIELD(funccolnames);
+	WRITE_NODE_FIELD(funccoltypes);
+	WRITE_NODE_FIELD(funccoltypmods);
+}
+
+static void
+_outValuesScan(DebugGraph *graph, DebugNode *parent, const char *label, ValuesScan *node)
+{
+	WRITE_NODE_TYPE("ValuesScan");
+
+	_outScanInfo(graph, graphnode, (Scan *) node);
+
+	WRITE_NODE_FIELD(values_lists);
+}
+
+static void
+_outJoin(DebugGraph *graph, DebugNode *parent, const char *label, Join *node)
+{
+	WRITE_NODE_TYPE("Join");
+
+	_outJoinPlanInfo(graph, graphnode, (Join *) node);
+}
+
+static void
+_outNestLoop(DebugGraph *graph, DebugNode *parent, const char *label, NestLoop *node)
+{
+	WRITE_NODE_TYPE("NestLoop");
+
+	_outJoinPlanInfo(graph, graphnode, (Join *) node);
+}
+
+static void
+_outMergeJoin(DebugGraph *graph, DebugNode *parent, const char *label, MergeJoin *node)
+{
+	int			numCols;
+
+	WRITE_NODE_TYPE("MergeJoin");
+
+	_outJoinPlanInfo(graph, graphnode, (Join *) node);
+
+	WRITE_NODE_FIELD(mergeclauses);
+
+	numCols = list_length(node->mergeclauses);
+
+	WRITE_LIST_VALUES(numCols, mergeFamilies, "%u");
+	WRITE_LIST_VALUES(numCols, mergeStrategies, "%d");
+	WRITE_LIST_VALUES(numCols, mergeNullsFirst, "%d");
+}
+
+static void
+_outHashJoin(DebugGraph *graph, DebugNode *parent, const char *label, HashJoin *node)
+{
+	WRITE_NODE_TYPE("MergeJoin");
+
+	_outJoinPlanInfo(graph, graphnode, (Join *) node);
+
+	WRITE_NODE_FIELD(hashclauses);
+}
+
+static void
+_outAgg(DebugGraph *graph, DebugNode *parent, const char *label, Agg *node)
+{
+	WRITE_NODE_TYPE("Agg");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
+	WRITE_INT_FIELD(numCols);
+
+	WRITE_LIST_VALUES(node->numCols, grpColIdx, "%d");
+	WRITE_LIST_VALUES(node->numCols, grpOperators, "%u");
+
+	WRITE_LONG_FIELD(numGroups);
+}
+
+static void
+_outGroup(DebugGraph *graph, DebugNode *parent, const char *label, Group *node)
+{
+	WRITE_NODE_TYPE("Group");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_INT_FIELD(numCols);
+
+	WRITE_LIST_VALUES(node->numCols, grpColIdx, "%d");
+	WRITE_LIST_VALUES(node->numCols, grpOperators, "%u");
+}
+
+static void
+_outMaterial(DebugGraph *graph, DebugNode *parent, const char *label, Material *node)
+{
+	WRITE_NODE_TYPE("Material");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+}
+
+static void
+_outSort(DebugGraph *graph, DebugNode *parent, const char *label, Sort *node)
+{
+	WRITE_NODE_TYPE("Sort");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_INT_FIELD(numCols);
+
+	WRITE_LIST_VALUES(node->numCols, sortColIdx, "%d");
+	WRITE_LIST_VALUES(node->numCols, sortOperators, "%u");
+
+	{
+		int   i;
+		char  str[500];
+		char *aux = str;
+		for (i = 0; i < node->numCols; i++){
+			if( i )
+				aux += sprintf(aux, " ");
+			aux += sprintf(aux, " %s", booltostr(node->nullsFirst[i]));
+		}
+		addDebugNodeAttribute(graphnode, "nullsFirst", str);
+	}
+}
+
+static void
+_outUnique(DebugGraph *graph, DebugNode *parent, const char *label, Unique *node)
+{
+	WRITE_NODE_TYPE("Unique");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_INT_FIELD(numCols);
+
+	WRITE_LIST_VALUES(node->numCols, uniqColIdx, "%d");
+	WRITE_LIST_VALUES(node->numCols, uniqOperators, "%u");
+}
+
+static void
+_outSetOp(DebugGraph *graph, DebugNode *parent, const char *label, SetOp *node)
+{
+	WRITE_NODE_TYPE("SetOp");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_ENUM_FIELD(cmd, SetOpCmd);
+	WRITE_INT_FIELD(numCols);
+
+	WRITE_LIST_VALUES(node->numCols, dupColIdx, "%d");
+	WRITE_LIST_VALUES(node->numCols, dupOperators, "%u");
+
+	WRITE_INT_FIELD(flagColIdx);
+}
+
+static void
+_outLimit(DebugGraph *graph, DebugNode *parent, const char *label, Limit *node)
+{
+	WRITE_NODE_TYPE("Limit");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+
+	WRITE_NODE_FIELD(limitOffset);
+	WRITE_NODE_FIELD(limitCount);
+}
+
+static void
+_outHash(DebugGraph *graph, DebugNode *parent, const char *label, Hash *node)
+{
+	WRITE_NODE_TYPE("Hash");
+
+	_outPlanInfo(graph, graphnode, (Plan *) node);
+}
+
+/*****************************************************************************
+ *
+ *	Stuff from primnodes.h.
+ *
+ *****************************************************************************/
+
+static void
+_outAlias(DebugGraph *graph, DebugNode *parent, const char *label, Alias *node)
+{
+	WRITE_NODE_TYPE("Alias");
+
+	WRITE_STRING_FIELD(aliasname);
+	WRITE_NODE_FIELD(colnames);
+}
+
+static void
+_outRangeVar(DebugGraph *graph, DebugNode *parent, const char *label, RangeVar *node)
+{
+	WRITE_NODE_TYPE("RangeVar");
+
+	/*
+	 * we deliberately ignore catalogname here, since it is presently not
+	 * semantically meaningful
+	 */
+	WRITE_STRING_FIELD(schemaname);
+	WRITE_STRING_FIELD(relname);
+	WRITE_ENUM_FIELD(inhOpt, InhOption);
+	WRITE_BOOL_FIELD(istemp);
+	WRITE_NODE_FIELD(alias);
+}
+
+static void
+_outIntoClause(DebugGraph *graph, DebugNode *parent, const char *label, IntoClause *node)
+{
+	WRITE_NODE_TYPE("IntoClause");
+
+	WRITE_NODE_FIELD(rel);
+	WRITE_NODE_FIELD(colNames);
+	WRITE_NODE_FIELD(options);
+	WRITE_ENUM_FIELD(onCommit, OnCommitAction);
+	WRITE_STRING_FIELD(tableSpaceName);
+}
+
+static void
+_outVar(DebugGraph *graph, DebugNode *parent, const char *label, Var *node)
+{
+	WRITE_NODE_TYPE("Var");
+
+	WRITE_UINT_FIELD(varno);
+	WRITE_INT_FIELD(varattno);
+	WRITE_OID_FIELD(vartype);
+	WRITE_INT_FIELD(vartypmod);
+	WRITE_UINT_FIELD(varlevelsup);
+	WRITE_UINT_FIELD(varnoold);
+	WRITE_INT_FIELD(varoattno);
+}
+
+static void
+_outConst(DebugGraph *graph, DebugNode *parent, const char *label, Const *node)
+{
+	WRITE_NODE_TYPE("Const");
+
+	WRITE_OID_FIELD(consttype);
+	WRITE_INT_FIELD(consttypmod);
+	WRITE_INT_FIELD(constlen);
+	WRITE_BOOL_FIELD(constbyval);
+	WRITE_BOOL_FIELD(constisnull);
+
+	if (node->constisnull)
+		addDebugNodeAttribute(graphnode, "constvalue", "");
+	else
+		_outDatum(graph, graphnode, "constvalue", node->constvalue,
+				node->constlen, node->constbyval);
+}
+
+static void
+_outParam(DebugGraph *graph, DebugNode *parent, const char *label, Param *node)
+{
+	WRITE_NODE_TYPE("Param");
+
+	WRITE_ENUM_FIELD(paramkind, ParamKind);
+	WRITE_INT_FIELD(paramid);
+	WRITE_OID_FIELD(paramtype);
+	WRITE_INT_FIELD(paramtypmod);
+}
+
+static void
+_outAggref(DebugGraph *graph, DebugNode *parent, const char *label, Aggref *node)
+{
+	WRITE_NODE_TYPE("Aggref");
+
+	WRITE_OID_FIELD(aggfnoid);
+	WRITE_OID_FIELD(aggtype);
+	WRITE_NODE_FIELD(args);
+	WRITE_UINT_FIELD(agglevelsup);
+	WRITE_BOOL_FIELD(aggstar);
+	WRITE_BOOL_FIELD(aggdistinct);
+}
+
+static void
+_outArrayRef(DebugGraph *graph, DebugNode *parent, const char *label, ArrayRef *node)
+{
+	WRITE_NODE_TYPE("ArrayRef");
+
+	WRITE_OID_FIELD(refarraytype);
+	WRITE_OID_FIELD(refelemtype);
+	WRITE_INT_FIELD(reftypmod);
+	WRITE_NODE_FIELD(refupperindexpr);
+	WRITE_NODE_FIELD(reflowerindexpr);
+	WRITE_NODE_FIELD(refexpr);
+	WRITE_NODE_FIELD(refassgnexpr);
+}
+
+static void
+_outFuncExpr(DebugGraph *graph, DebugNode *parent, const char *label, FuncExpr *node)
+{
+	WRITE_NODE_TYPE("FuncExpr");
+
+	WRITE_OID_FIELD(funcid);
+	WRITE_OID_FIELD(funcresulttype);
+	WRITE_BOOL_FIELD(funcretset);
+	WRITE_ENUM_FIELD(funcformat, CoercionForm);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outOpExpr(DebugGraph *graph, DebugNode *parent, const char *label, OpExpr *node)
+{
+	WRITE_NODE_TYPE("OpExpr");
+
+	WRITE_OID_FIELD(opno);
+	WRITE_OID_FIELD(opfuncid);
+	WRITE_OID_FIELD(opresulttype);
+	WRITE_BOOL_FIELD(opretset);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outDistinctExpr(DebugGraph *graph, DebugNode *parent, const char *label, DistinctExpr *node)
+{
+	WRITE_NODE_TYPE("DistinctExpr");
+
+	WRITE_OID_FIELD(opno);
+	WRITE_OID_FIELD(opfuncid);
+	WRITE_OID_FIELD(opresulttype);
+	WRITE_BOOL_FIELD(opretset);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outScalarArrayOpExpr(DebugGraph *graph, DebugNode *parent, const char *label,
+		ScalarArrayOpExpr *node)
+{
+	WRITE_NODE_TYPE("ScalarArrayOpExpr");
+
+	WRITE_OID_FIELD(opno);
+	WRITE_OID_FIELD(opfuncid);
+	WRITE_BOOL_FIELD(useOr);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outBoolExpr(DebugGraph *graph, DebugNode *parent, const char *label,
+		BoolExpr *node)
+{
+	char	   *opstr = "NULL";
+
+	WRITE_NODE_TYPE("BoolExpr");
+
+	/* do-it-yourself enum representation */
+	switch (node->boolop)
+	{
+		case AND_EXPR:
+			opstr = "and";
+			break;
+		case OR_EXPR:
+			opstr = "or";
+			break;
+		case NOT_EXPR:
+			opstr = "not";
+			break;
+	}
+	addDebugNodeAttribute(graphnode, "boolop", opstr);
+
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outSubLink(DebugGraph *graph, DebugNode *parent, const char *label,
+		SubLink *node)
+{
+	WRITE_NODE_TYPE("SubLink");
+
+	WRITE_ENUM_FIELD(subLinkType, SubLinkType);
+	WRITE_NODE_FIELD(testexpr);
+	WRITE_NODE_FIELD(operName);
+	WRITE_NODE_FIELD(subselect);
+}
+
+static void
+_outSubPlan(DebugGraph *graph, DebugNode *parent, const char *label,
+		SubPlan *node)
+{
+	WRITE_NODE_TYPE("SubPlan");
+
+	WRITE_ENUM_FIELD(subLinkType, SubLinkType);
+	WRITE_NODE_FIELD(testexpr);
+	WRITE_NODE_FIELD(paramIds);
+	WRITE_INT_FIELD(plan_id);
+	WRITE_OID_FIELD(firstColType);
+	WRITE_BOOL_FIELD(useHashTable);
+	WRITE_BOOL_FIELD(unknownEqFalse);
+	WRITE_NODE_FIELD(setParam);
+	WRITE_NODE_FIELD(parParam);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outFieldSelect(DebugGraph *graph, DebugNode *parent, const char *label,
+		FieldSelect *node)
+{
+	WRITE_NODE_TYPE("FieldSelect");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_INT_FIELD(fieldnum);
+	WRITE_OID_FIELD(resulttype);
+	WRITE_INT_FIELD(resulttypmod);
+}
+
+static void
+_outFieldStore(DebugGraph *graph, DebugNode *parent, const char *label, FieldStore *node)
+{
+	WRITE_NODE_TYPE("FieldStore");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_NODE_FIELD(newvals);
+	WRITE_NODE_FIELD(fieldnums);
+	WRITE_OID_FIELD(resulttype);
+}
+
+static void
+_outRelabelType(DebugGraph *graph, DebugNode *parent, const char *label, RelabelType *node)
+{
+	WRITE_NODE_TYPE("RelabelType");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_OID_FIELD(resulttype);
+	WRITE_INT_FIELD(resulttypmod);
+	WRITE_ENUM_FIELD(relabelformat, CoercionForm);
+}
+
+static void
+_outCoerceViaIO(DebugGraph *graph, DebugNode *parent, const char *label, CoerceViaIO *node)
+{
+	WRITE_NODE_TYPE("CoerceViaIO");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_OID_FIELD(resulttype);
+	WRITE_ENUM_FIELD(coerceformat, CoercionForm);
+}
+
+static void
+_outArrayCoerceExpr(DebugGraph *graph, DebugNode *parent, const char *label,
+		ArrayCoerceExpr *node)
+{
+	WRITE_NODE_TYPE("ArrayCoerceExpr");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_OID_FIELD(elemfuncid);
+	WRITE_OID_FIELD(resulttype);
+	WRITE_INT_FIELD(resulttypmod);
+	WRITE_BOOL_FIELD(isExplicit);
+	WRITE_ENUM_FIELD(coerceformat, CoercionForm);
+}
+
+static void
+_outConvertRowtypeExpr(DebugGraph *graph, DebugNode *parent, const char *label,
+		ConvertRowtypeExpr *node)
+{
+	WRITE_NODE_TYPE("ConvertRowtypeExpr");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_OID_FIELD(resulttype);
+	WRITE_ENUM_FIELD(convertformat, CoercionForm);
+}
+
+static void
+_outCaseExpr(DebugGraph *graph, DebugNode *parent, const char *label, CaseExpr *node)
+{
+	WRITE_NODE_TYPE("CaseExpr");
+
+	WRITE_OID_FIELD(casetype);
+	WRITE_NODE_FIELD(arg);
+	WRITE_NODE_FIELD(args);
+	WRITE_NODE_FIELD(defresult);
+}
+
+static void
+_outCaseWhen(DebugGraph *graph, DebugNode *parent, const char *label, CaseWhen *node)
+{
+	WRITE_NODE_TYPE("CaseExpr");
+
+	WRITE_NODE_FIELD(expr);
+	WRITE_NODE_FIELD(result);
+}
+
+static void
+_outCaseTestExpr(DebugGraph *graph, DebugNode *parent, const char *label, CaseTestExpr *node)
+{
+	WRITE_NODE_TYPE("CaseTestExpr");
+
+	WRITE_OID_FIELD(typeId);
+	WRITE_INT_FIELD(typeMod);
+}
+
+static void
+_outArrayExpr(DebugGraph *graph, DebugNode *parent, const char *label, ArrayExpr *node)
+{
+	WRITE_NODE_TYPE("ArrayExpr");
+
+	WRITE_OID_FIELD(array_typeid);
+	WRITE_OID_FIELD(element_typeid);
+	WRITE_NODE_FIELD(elements);
+	WRITE_BOOL_FIELD(multidims);
+}
+
+static void
+_outRowExpr(DebugGraph *graph, DebugNode *parent, const char *label, RowExpr *node)
+{
+	WRITE_NODE_TYPE("RowExpr");
+
+	WRITE_NODE_FIELD(args);
+	WRITE_OID_FIELD(row_typeid);
+	WRITE_ENUM_FIELD(row_format, CoercionForm);
+}
+
+static void
+_outRowCompareExpr(DebugGraph *graph, DebugNode *parent, const char *label, RowCompareExpr *node)
+{
+	WRITE_NODE_TYPE("RowCompareExpr");
+
+	WRITE_ENUM_FIELD(rctype, RowCompareType);
+	WRITE_NODE_FIELD(opnos);
+	WRITE_NODE_FIELD(opfamilies);
+	WRITE_NODE_FIELD(largs);
+	WRITE_NODE_FIELD(rargs);
+}
+
+static void
+_outCoalesceExpr(DebugGraph *graph, DebugNode *parent, const char *label, CoalesceExpr *node)
+{
+	WRITE_NODE_TYPE("CoalesceExpr");
+
+	WRITE_OID_FIELD(coalescetype);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outMinMaxExpr(DebugGraph *graph, DebugNode *parent, const char *label, MinMaxExpr *node)
+{
+	WRITE_NODE_TYPE("MinMaxExpr");
+
+	WRITE_OID_FIELD(minmaxtype);
+	WRITE_ENUM_FIELD(op, MinMaxOp);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outXmlExpr(DebugGraph *graph, DebugNode *parent, const char *label, XmlExpr *node)
+{
+	WRITE_NODE_TYPE("XmlExpr");
+
+	WRITE_ENUM_FIELD(op, XmlExprOp);
+	WRITE_STRING_FIELD(name);
+	WRITE_NODE_FIELD(named_args);
+	WRITE_NODE_FIELD(arg_names);
+	WRITE_NODE_FIELD(args);
+	WRITE_ENUM_FIELD(xmloption, XmlOptionType);
+	WRITE_OID_FIELD(type);
+	WRITE_INT_FIELD(typmod);
+}
+
+static void
+_outNullIfExpr(DebugGraph *graph, DebugNode *parent, const char *label, NullIfExpr *node)
+{
+	WRITE_NODE_TYPE("NullIfExpr");
+
+	WRITE_OID_FIELD(opno);
+	WRITE_OID_FIELD(opfuncid);
+	WRITE_OID_FIELD(opresulttype);
+	WRITE_BOOL_FIELD(opretset);
+	WRITE_NODE_FIELD(args);
+}
+
+static void
+_outNullTest(DebugGraph *graph, DebugNode *parent, const char *label, NullTest *node)
+{
+	WRITE_NODE_TYPE("NullTest");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_ENUM_FIELD(nulltesttype, NullTestType);
+}
+
+static void
+_outBooleanTest(DebugGraph *graph, DebugNode *parent, const char *label, BooleanTest *node)
+{
+	WRITE_NODE_TYPE("BooleanTest");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_ENUM_FIELD(booltesttype, BoolTestType);
+}
+
+static void
+_outCoerceToDomain(DebugGraph *graph, DebugNode *parent, const char *label, CoerceToDomain *node)
+{
+	WRITE_NODE_TYPE("CoerceToDomain");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_OID_FIELD(resulttype);
+	WRITE_INT_FIELD(resulttypmod);
+	WRITE_ENUM_FIELD(coercionformat, CoercionForm);
+}
+
+static void
+_outCoerceToDomainValue(DebugGraph *graph, DebugNode *parent, const char *label,
+		CoerceToDomainValue *node)
+{
+	WRITE_NODE_TYPE("CoerceToDomainValue");
+
+	WRITE_OID_FIELD(typeId);
+	WRITE_INT_FIELD(typeMod);
+}
+
+static void
+_outSetToDefault(DebugGraph *graph, DebugNode *parent, const char *label,
+		SetToDefault *node)
+{
+	WRITE_NODE_TYPE("SetToDefault");
+
+	WRITE_OID_FIELD(typeId);
+	WRITE_INT_FIELD(typeMod);
+}
+
+static void
+_outCurrentOfExpr(DebugGraph *graph, DebugNode *parent, const char *label,
+		CurrentOfExpr *node)
+{
+	WRITE_NODE_TYPE("CurrentOfExpr");
+
+	WRITE_UINT_FIELD(cvarno);
+	WRITE_STRING_FIELD(cursor_name);
+	WRITE_INT_FIELD(cursor_param);
+}
+
+static void
+_outTargetEntry(DebugGraph *graph, DebugNode *parent, const char *label, TargetEntry *node)
+{
+	WRITE_NODE_TYPE("TargetEntry");
+
+	WRITE_NODE_FIELD(expr);
+	WRITE_INT_FIELD(resno);
+	WRITE_STRING_FIELD(resname);
+	WRITE_UINT_FIELD(ressortgroupref);
+	WRITE_OID_FIELD(resorigtbl);
+	WRITE_INT_FIELD(resorigcol);
+	WRITE_BOOL_FIELD(resjunk);
+}
+
+static void
+_outRangeTblRef(DebugGraph *graph, DebugNode *parent, const char *label, RangeTblRef *node)
+{
+	WRITE_NODE_TYPE("RangeTblRef");
+
+	WRITE_INT_FIELD(rtindex);
+}
+
+static void
+_outJoinExpr(DebugGraph *graph, DebugNode *parent, const char *label, JoinExpr *node)
+{
+	WRITE_NODE_TYPE("JoinExpr");
+
+	WRITE_ENUM_FIELD(jointype, JoinType);
+	WRITE_BOOL_FIELD(isNatural);
+	WRITE_NODE_FIELD(larg);
+	WRITE_NODE_FIELD(rarg);
+	WRITE_NODE_FIELD(using);
+	WRITE_NODE_FIELD(quals);
+	WRITE_NODE_FIELD(alias);
+	WRITE_INT_FIELD(rtindex);
+}
+
+static void
+_outFromExpr(DebugGraph *graph, DebugNode *parent, const char *label, FromExpr *node)
+{
+	WRITE_NODE_TYPE("FromExpr");
+
+	WRITE_NODE_FIELD(fromlist);
+	WRITE_NODE_FIELD(quals);
+}
+
+/*****************************************************************************
+ *
+ *	Stuff from relation.h.
+ *
+ *****************************************************************************/
+
+/*
+ * print the basic stuff of all nodes that inherit from Path
+ *
+ * Note we do NOT print the parent, else we'd be in infinite recursion
+ */
+static void
+_outPathInfo(DebugGraph *graph, DebugNode *graphnode, Path *node)
+{
+	WRITE_ENUM_FIELD(pathtype, NodeTag);
+	WRITE_FLOAT_FIELD(startup_cost, "%.2f");
+	WRITE_FLOAT_FIELD(total_cost, "%.2f");
+	WRITE_NODE_FIELD(pathkeys);
+}
+
+/*
+ * print the basic stuff of all nodes that inherit from JoinPath
+ */
+static void
+_outJoinPathInfo(DebugGraph *graph, DebugNode *graphnode, JoinPath *node)
+{
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_ENUM_FIELD(jointype, JoinType);
+	WRITE_NODE_FIELD(outerjoinpath);
+	WRITE_NODE_FIELD(innerjoinpath);
+	WRITE_NODE_FIELD(joinrestrictinfo);
+}
+
+static void
+_outPath(DebugGraph *graph, DebugNode *parent, const char *label, Path *node)
+{
+	WRITE_NODE_TYPE("Path");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+}
+
+static void
+_outIndexPath(DebugGraph *graph, DebugNode *parent, const char *label, IndexPath *node)
+{
+	WRITE_NODE_TYPE("IndexPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(indexinfo);
+	WRITE_NODE_FIELD(indexclauses);
+	WRITE_NODE_FIELD(indexquals);
+	WRITE_BOOL_FIELD(isjoininner);
+	WRITE_ENUM_FIELD(indexscandir, ScanDirection);
+	WRITE_FLOAT_FIELD(indextotalcost, "%.2f");
+	WRITE_FLOAT_FIELD(indexselectivity, "%.4f");
+	WRITE_FLOAT_FIELD(rows, "%.0f");
+}
+
+static void
+_outBitmapHeapPath(DebugGraph *graph, DebugNode *parent, const char *label, BitmapHeapPath *node)
+{
+	WRITE_NODE_TYPE("BitmapHeapPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(bitmapqual);
+	WRITE_BOOL_FIELD(isjoininner);
+	WRITE_FLOAT_FIELD(rows, "%.0f");
+}
+
+static void
+_outBitmapAndPath(DebugGraph *graph, DebugNode *parent, const char *label, BitmapAndPath *node)
+{
+	WRITE_NODE_TYPE("BitmapAndPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(bitmapquals);
+	WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
+}
+
+static void
+_outBitmapOrPath(DebugGraph *graph, DebugNode *parent, const char *label, BitmapOrPath *node)
+{
+	WRITE_NODE_TYPE("BitmapOrPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(bitmapquals);
+	WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
+}
+
+static void
+_outTidPath(DebugGraph *graph, DebugNode *parent, const char *label, TidPath *node)
+{
+	WRITE_NODE_TYPE("TidPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(tidquals);
+}
+
+static void
+_outAppendPath(DebugGraph *graph, DebugNode *parent, const char *label, AppendPath *node)
+{
+	WRITE_NODE_TYPE("AppendPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(subpaths);
+}
+
+static void
+_outResultPath(DebugGraph *graph, DebugNode *parent, const char *label, ResultPath *node)
+{
+	WRITE_NODE_TYPE("ResultPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(quals);
+}
+
+static void
+_outMaterialPath(DebugGraph *graph, DebugNode *parent, const char *label, MaterialPath *node)
+{
+	WRITE_NODE_TYPE("MaterialPath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(subpath);
+}
+
+static void
+_outUniquePath(DebugGraph *graph, DebugNode *parent, const char *label, UniquePath *node)
+{
+	WRITE_NODE_TYPE("UniquePath");
+
+	_outPathInfo(graph, graphnode, (Path *) node);
+
+	WRITE_NODE_FIELD(subpath);
+	WRITE_ENUM_FIELD(umethod, UniquePathMethod);
+	WRITE_FLOAT_FIELD(rows, "%.0f");
+}
+
+static void
+_outNestPath(DebugGraph *graph, DebugNode *parent, const char *label, NestPath *node)
+{
+	WRITE_NODE_TYPE("NestPath");
+
+	_outJoinPathInfo(graph, graphnode, (JoinPath *) node);
+}
+
+static void
+_outMergePath(DebugGraph *graph, DebugNode *parent, const char *label, MergePath *node)
+{
+	WRITE_NODE_TYPE("MergePath");
+
+	_outJoinPathInfo(graph, graphnode, (JoinPath *) node);
+
+	WRITE_NODE_FIELD(path_mergeclauses);
+	WRITE_NODE_FIELD(outersortkeys);
+	WRITE_NODE_FIELD(innersortkeys);
+}
+
+static void
+_outHashPath(DebugGraph *graph, DebugNode *parent, const char *label, HashPath *node)
+{
+	WRITE_NODE_TYPE("HashPath");
+
+	_outJoinPathInfo(graph, graphnode, (JoinPath *) node);
+
+	WRITE_NODE_FIELD(path_hashclauses);
+}
+
+static void
+_outPlannerGlobal(DebugGraph *graph, DebugNode *parent, const char *label, PlannerGlobal *node)
+{
+	WRITE_NODE_TYPE("PlannerGlobal");
+
+	/* NB: this isn't a complete set of fields */
+	WRITE_NODE_FIELD(paramlist);
+	WRITE_NODE_FIELD(subplans);
+	WRITE_NODE_FIELD(subrtables);
+	WRITE_BITMAPSET_FIELD(rewindPlanIDs);
+	WRITE_NODE_FIELD(finalrtable);
+	WRITE_NODE_FIELD(relationOids);
+}
+
+static void
+_outPlannerInfo(DebugGraph *graph, DebugNode *parent, const char *label, PlannerInfo *node)
+{
+	WRITE_NODE_TYPE("PlannerInfo");
+
+	/* NB: this isn't a complete set of fields */
+	WRITE_NODE_FIELD(parse);
+	WRITE_NODE_FIELD(glob);
+	WRITE_UINT_FIELD(query_level);
+	WRITE_NODE_FIELD(join_rel_list);
+	WRITE_NODE_FIELD(resultRelations);
+	WRITE_NODE_FIELD(returningLists);
+	WRITE_NODE_FIELD(init_plans);
+	WRITE_NODE_FIELD(eq_classes);
+	WRITE_NODE_FIELD(canon_pathkeys);
+	WRITE_NODE_FIELD(left_join_clauses);
+	WRITE_NODE_FIELD(right_join_clauses);
+	WRITE_NODE_FIELD(full_join_clauses);
+	WRITE_NODE_FIELD(oj_info_list);
+	WRITE_NODE_FIELD(in_info_list);
+	WRITE_NODE_FIELD(append_rel_list);
+	WRITE_NODE_FIELD(query_pathkeys);
+	WRITE_NODE_FIELD(group_pathkeys);
+	WRITE_NODE_FIELD(sort_pathkeys);
+	WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
+	WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
+	WRITE_BOOL_FIELD(hasJoinRTEs);
+	WRITE_BOOL_FIELD(hasOuterJoins);
+	WRITE_BOOL_FIELD(hasHavingQual);
+	WRITE_BOOL_FIELD(hasPseudoConstantQuals);
+}
+
+static void
+_outRelOptInfo(DebugGraph *graph, DebugNode *parent, const char *label, RelOptInfo *node)
+{
+	WRITE_NODE_TYPE("RelOptInfo");
+
+	/* NB: this isn't a complete set of fields */
+	WRITE_ENUM_FIELD(reloptkind, RelOptKind);
+	WRITE_BITMAPSET_FIELD(relids);
+	WRITE_FLOAT_FIELD(rows, "%.0f");
+	WRITE_INT_FIELD(width);
+	WRITE_NODE_FIELD(reltargetlist);
+	WRITE_NODE_FIELD(pathlist);
+	WRITE_NODE_FIELD(cheapest_startup_path);
+	WRITE_NODE_FIELD(cheapest_total_path);
+	WRITE_NODE_FIELD(cheapest_unique_path);
+	WRITE_UINT_FIELD(relid);
+	WRITE_ENUM_FIELD(rtekind, RTEKind);
+	WRITE_INT_FIELD(min_attr);
+	WRITE_INT_FIELD(max_attr);
+	WRITE_NODE_FIELD(indexlist);
+	WRITE_UINT_FIELD(pages);
+	WRITE_FLOAT_FIELD(tuples, "%.0f");
+	WRITE_NODE_FIELD(subplan);
+	WRITE_NODE_FIELD(subrtable);
+	WRITE_NODE_FIELD(baserestrictinfo);
+	WRITE_NODE_FIELD(joininfo);
+	WRITE_BOOL_FIELD(has_eclass_joins);
+	WRITE_BITMAPSET_FIELD(index_outer_relids);
+	WRITE_NODE_FIELD(index_inner_paths);
+}
+
+static void
+_outIndexOptInfo(DebugGraph *graph, DebugNode *parent, const char *label, IndexOptInfo *node)
+{
+	WRITE_NODE_TYPE("IndexOptInfo");
+
+	/* NB: this isn't a complete set of fields */
+	WRITE_OID_FIELD(indexoid);
+	/* Do NOT print rel field, else infinite recursion */
+	WRITE_UINT_FIELD(pages);
+	WRITE_FLOAT_FIELD(tuples, "%.0f");
+	WRITE_INT_FIELD(ncolumns);
+	WRITE_NODE_FIELD(indexprs);
+	WRITE_NODE_FIELD(indpred);
+	WRITE_BOOL_FIELD(predOK);
+	WRITE_BOOL_FIELD(unique);
+}
+
+static void
+_outEquivalenceClass(DebugGraph *graph, DebugNode *parent, const char *label, EquivalenceClass *node)
+{
+	/*
+	 * To simplify reading, we just chase up to the topmost merged EC and
+	 * print that, without bothering to show the merge-ees separately.
+	 */
+	while (node->ec_merged)
+		node = node->ec_merged;
+
+	WRITE_NODE_TYPE("EquivalenceClass");
+
+	WRITE_NODE_FIELD(ec_opfamilies);
+	WRITE_NODE_FIELD(ec_members);
+	WRITE_NODE_FIELD(ec_sources);
+	WRITE_NODE_FIELD(ec_derives);
+	WRITE_BITMAPSET_FIELD(ec_relids);
+	WRITE_BOOL_FIELD(ec_has_const);
+	WRITE_BOOL_FIELD(ec_has_volatile);
+	WRITE_BOOL_FIELD(ec_below_outer_join);
+	WRITE_BOOL_FIELD(ec_broken);
+	WRITE_UINT_FIELD(ec_sortref);
+}
+
+static void
+_outEquivalenceMember(DebugGraph *graph, DebugNode *parent, const char *label, EquivalenceMember *node)
+{
+	WRITE_NODE_TYPE("EquivalenceMember");
+
+	WRITE_NODE_FIELD(em_expr);
+	WRITE_BITMAPSET_FIELD(em_relids);
+	WRITE_BOOL_FIELD(em_is_const);
+	WRITE_BOOL_FIELD(em_is_child);
+	WRITE_OID_FIELD(em_datatype);
+}
+
+static void
+_outPathKey(DebugGraph *graph, DebugNode *parent, const char *label, PathKey *node)
+{
+	WRITE_NODE_TYPE("PathKey");
+
+	WRITE_NODE_FIELD(pk_eclass);
+	WRITE_OID_FIELD(pk_opfamily);
+	WRITE_INT_FIELD(pk_strategy);
+	WRITE_BOOL_FIELD(pk_nulls_first);
+}
+
+static void
+_outRestrictInfo(DebugGraph *graph, DebugNode *parent, const char *label, RestrictInfo *node)
+{
+	WRITE_NODE_TYPE("RestrictInfo");
+
+	/* NB: this isn't a complete set of fields */
+	WRITE_NODE_FIELD(clause);
+	WRITE_BOOL_FIELD(is_pushed_down);
+	WRITE_BOOL_FIELD(outerjoin_delayed);
+	WRITE_BOOL_FIELD(can_join);
+	WRITE_BOOL_FIELD(pseudoconstant);
+	WRITE_BITMAPSET_FIELD(clause_relids);
+	WRITE_BITMAPSET_FIELD(required_relids);
+	WRITE_BITMAPSET_FIELD(left_relids);
+	WRITE_BITMAPSET_FIELD(right_relids);
+	WRITE_NODE_FIELD(orclause);
+	/* don't write parent_ec, leads to infinite recursion in plan tree dump */
+	WRITE_NODE_FIELD(mergeopfamilies);
+	/* don't write left_ec, leads to infinite recursion in plan tree dump */
+	/* don't write right_ec, leads to infinite recursion in plan tree dump */
+	WRITE_NODE_FIELD(left_em);
+	WRITE_NODE_FIELD(right_em);
+	WRITE_BOOL_FIELD(outer_is_left);
+	WRITE_OID_FIELD(hashjoinoperator);
+}
+
+static void
+_outInnerIndexscanInfo(DebugGraph *graph, DebugNode *parent, const char *label, InnerIndexscanInfo *node)
+{
+	WRITE_NODE_TYPE("InnerIndexscanInfo");
+	WRITE_BITMAPSET_FIELD(other_relids);
+	WRITE_BOOL_FIELD(isouterjoin);
+	WRITE_NODE_FIELD(cheapest_startup_innerpath);
+	WRITE_NODE_FIELD(cheapest_total_innerpath);
+}
+
+static void
+_outOuterJoinInfo(DebugGraph *graph, DebugNode *parent, const char *label, OuterJoinInfo *node)
+{
+	WRITE_NODE_TYPE("OuterJoinInfo");
+
+	WRITE_BITMAPSET_FIELD(min_lefthand);
+	WRITE_BITMAPSET_FIELD(min_righthand);
+	WRITE_BITMAPSET_FIELD(syn_lefthand);
+	WRITE_BITMAPSET_FIELD(syn_righthand);
+	WRITE_BOOL_FIELD(is_full_join);
+	WRITE_BOOL_FIELD(lhs_strict);
+	WRITE_BOOL_FIELD(delay_upper_joins);
+}
+
+static void
+_outInClauseInfo(DebugGraph *graph, DebugNode *parent, const char *label, InClauseInfo *node)
+{
+	WRITE_NODE_TYPE("InClauseInfo");
+
+	WRITE_BITMAPSET_FIELD(lefthand);
+	WRITE_BITMAPSET_FIELD(righthand);
+	WRITE_NODE_FIELD(sub_targetlist);
+	WRITE_NODE_FIELD(in_operators);
+}
+
+static void
+_outAppendRelInfo(DebugGraph *graph, DebugNode *parent, const char *label, AppendRelInfo *node)
+{
+	WRITE_NODE_TYPE("AppendRelInfo");
+
+	WRITE_UINT_FIELD(parent_relid);
+	WRITE_UINT_FIELD(child_relid);
+	WRITE_OID_FIELD(parent_reltype);
+	WRITE_OID_FIELD(child_reltype);
+	WRITE_NODE_FIELD(col_mappings);
+	WRITE_NODE_FIELD(translated_vars);
+	WRITE_OID_FIELD(parent_reloid);
+}
+
+static void
+_outPlannerParamItem(DebugGraph *graph, DebugNode *parent, const char *label, PlannerParamItem *node)
+{
+	WRITE_NODE_TYPE("PlannerParamItem");
+
+	WRITE_NODE_FIELD(item);
+	WRITE_UINT_FIELD(abslevel);
+}
+
+/*****************************************************************************
+ *
+ *	Stuff from parsenodes.h.
+ *
+ *****************************************************************************/
+
+static void
+_outCreateStmt(DebugGraph *graph, DebugNode *parent, const char *label, CreateStmt *node)
+{
+	WRITE_NODE_TYPE("CreateStmt");
+
+	WRITE_NODE_FIELD(relation);
+	WRITE_NODE_FIELD(tableElts);
+	WRITE_NODE_FIELD(inhRelations);
+	WRITE_NODE_FIELD(constraints);
+	WRITE_NODE_FIELD(options);
+	WRITE_ENUM_FIELD(oncommit, OnCommitAction);
+	WRITE_STRING_FIELD(tablespacename);
+}
+
+static void
+_outIndexStmt(DebugGraph *graph, DebugNode *parent, const char *label, IndexStmt *node)
+{
+	WRITE_NODE_TYPE("IndexStmt");
+
+	WRITE_STRING_FIELD(idxname);
+	WRITE_NODE_FIELD(relation);
+	WRITE_STRING_FIELD(accessMethod);
+	WRITE_STRING_FIELD(tableSpace);
+	WRITE_NODE_FIELD(indexParams);
+	WRITE_NODE_FIELD(options);
+	WRITE_NODE_FIELD(whereClause);
+	WRITE_BOOL_FIELD(unique);
+	WRITE_BOOL_FIELD(primary);
+	WRITE_BOOL_FIELD(isconstraint);
+	WRITE_BOOL_FIELD(concurrent);
+}
+
+static void
+_outNotifyStmt(DebugGraph *graph, DebugNode *parent, const char *label, NotifyStmt *node)
+{
+	WRITE_NODE_TYPE("NotifyStmt");
+
+	WRITE_NODE_FIELD(relation);
+}
+
+static void
+_outDeclareCursorStmt(DebugGraph *graph, DebugNode *parent, const char *label, DeclareCursorStmt *node)
+{
+	WRITE_NODE_TYPE("DeclareCursorStmt");
+
+	WRITE_STRING_FIELD(portalname);
+	WRITE_INT_FIELD(options);
+	WRITE_NODE_FIELD(query);
+}
+
+static void
+_outSelectStmt(DebugGraph *graph, DebugNode *parent, const char *label, SelectStmt *node)
+{
+	WRITE_NODE_TYPE("SelectStmt");
+
+	WRITE_NODE_FIELD(distinctClause);
+	WRITE_NODE_FIELD(intoClause);
+	WRITE_NODE_FIELD(targetList);
+	WRITE_NODE_FIELD(fromClause);
+	WRITE_NODE_FIELD(whereClause);
+	WRITE_NODE_FIELD(groupClause);
+	WRITE_NODE_FIELD(havingClause);
+	WRITE_NODE_FIELD(valuesLists);
+	WRITE_NODE_FIELD(sortClause);
+	WRITE_NODE_FIELD(limitOffset);
+	WRITE_NODE_FIELD(limitCount);
+	WRITE_NODE_FIELD(lockingClause);
+	WRITE_ENUM_FIELD(op, SetOperation);
+	WRITE_BOOL_FIELD(all);
+	WRITE_NODE_FIELD(larg);
+	WRITE_NODE_FIELD(rarg);
+}
+
+static void
+_outFuncCall(DebugGraph *graph, DebugNode *parent, const char *label, FuncCall *node)
+{
+	WRITE_NODE_TYPE("FuncCall");
+
+	WRITE_NODE_FIELD(funcname);
+	WRITE_NODE_FIELD(args);
+	WRITE_BOOL_FIELD(agg_star);
+	WRITE_BOOL_FIELD(agg_distinct);
+	WRITE_INT_FIELD(location);
+}
+
+static void
+_outDefElem(DebugGraph *graph, DebugNode *parent, const char *label, DefElem *node)
+{
+	WRITE_NODE_TYPE("DefElem");
+
+	WRITE_STRING_FIELD(defname);
+	WRITE_NODE_FIELD(arg);
+}
+
+static void
+_outLockingClause(DebugGraph *graph, DebugNode *parent, const char *label, LockingClause *node)
+{
+	WRITE_NODE_TYPE("LockingClause");
+
+	WRITE_NODE_FIELD(lockedRels);
+	WRITE_BOOL_FIELD(forUpdate);
+	WRITE_BOOL_FIELD(noWait);
+}
+
+static void
+_outXmlSerialize(DebugGraph *graph, DebugNode *parent, const char *label, XmlSerialize *node)
+{
+	WRITE_NODE_TYPE("XmlSerialize");
+
+	WRITE_ENUM_FIELD(xmloption, XmlOptionType);
+	WRITE_NODE_FIELD(expr);
+	WRITE_NODE_FIELD(typename);
+}
+
+static void
+_outColumnDef(DebugGraph *graph, DebugNode *parent, const char *label, ColumnDef *node)
+{
+	WRITE_NODE_TYPE("ColumnDef");
+
+	WRITE_STRING_FIELD(colname);
+	WRITE_NODE_FIELD(typename);
+	WRITE_INT_FIELD(inhcount);
+	WRITE_BOOL_FIELD(is_local);
+	WRITE_BOOL_FIELD(is_not_null);
+	WRITE_NODE_FIELD(raw_default);
+	WRITE_STRING_FIELD(cooked_default);
+	WRITE_NODE_FIELD(constraints);
+}
+
+static void
+_outTypeName(DebugGraph *graph, DebugNode *parent, const char *label, TypeName *node)
+{
+	WRITE_NODE_TYPE("TypeName");
+
+	WRITE_NODE_FIELD(names);
+	WRITE_OID_FIELD(typeid);
+	WRITE_BOOL_FIELD(timezone);
+	WRITE_BOOL_FIELD(setof);
+	WRITE_BOOL_FIELD(pct_type);
+	WRITE_NODE_FIELD(typmods);
+	WRITE_INT_FIELD(typemod);
+	WRITE_NODE_FIELD(arrayBounds);
+	WRITE_INT_FIELD(location);
+}
+
+static void
+_outTypeCast(DebugGraph *graph, DebugNode *parent, const char *label, TypeCast *node)
+{
+	WRITE_NODE_TYPE("TypeCast");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_NODE_FIELD(typename);
+}
+
+static void
+_outIndexElem(DebugGraph *graph, DebugNode *parent, const char *label, IndexElem *node)
+{
+	WRITE_NODE_TYPE("IndexElem");
+
+	WRITE_STRING_FIELD(name);
+	WRITE_NODE_FIELD(expr);
+	WRITE_NODE_FIELD(opclass);
+	WRITE_ENUM_FIELD(ordering, SortByDir);
+	WRITE_ENUM_FIELD(nulls_ordering, SortByNulls);
+}
+
+static void
+_outQuery(DebugGraph *graph, DebugNode *parent, const char *label, Query *node)
+{
+	WRITE_NODE_TYPE("Query");
+
+	WRITE_ENUM_FIELD(commandType, CmdType);
+	WRITE_ENUM_FIELD(querySource, QuerySource);
+	WRITE_BOOL_FIELD(canSetTag);
+
+	/*
+	 * Hack to work around missing outfuncs routines for a lot of the
+	 * utility-statement node types.  (The only one we actually *need* for
+	 * rules support is NotifyStmt.)  Someday we ought to support 'em all, but
+	 * for the meantime do this to avoid getting lots of warnings when running
+	 * with debug_print_parse on.
+	 */
+	if (node->utilityStmt)
+	{
+		switch (nodeTag(node->utilityStmt))
+		{
+			case T_CreateStmt:
+			case T_IndexStmt:
+			case T_NotifyStmt:
+			case T_DeclareCursorStmt:
+				WRITE_NODE_FIELD(utilityStmt);
+				break;
+			default:
+				addDebugNodeAttribute(graphnode, "utilityStmt", "?");
+				break;
+		}
+	}
+	else
+		addDebugNodeAttribute(graphnode, "utilityStmt", "NULL");
+
+	WRITE_INT_FIELD(resultRelation);
+	WRITE_NODE_FIELD(intoClause);
+	WRITE_BOOL_FIELD(hasAggs);
+	WRITE_BOOL_FIELD(hasSubLinks);
+	WRITE_NODE_FIELD(rtable);
+	WRITE_NODE_FIELD(jointree);
+	WRITE_NODE_FIELD(targetList);
+	WRITE_NODE_FIELD(returningList);
+	WRITE_NODE_FIELD(groupClause);
+	WRITE_NODE_FIELD(havingQual);
+	WRITE_NODE_FIELD(distinctClause);
+	WRITE_NODE_FIELD(sortClause);
+	WRITE_NODE_FIELD(limitOffset);
+	WRITE_NODE_FIELD(limitCount);
+	WRITE_NODE_FIELD(rowMarks);
+	WRITE_NODE_FIELD(setOperations);
+}
+
+static void
+_outSortClause(DebugGraph *graph, DebugNode *parent, const char *label, SortClause *node)
+{
+	WRITE_NODE_TYPE("SortClause");
+
+	WRITE_UINT_FIELD(tleSortGroupRef);
+	WRITE_OID_FIELD(sortop);
+	WRITE_BOOL_FIELD(nulls_first);
+}
+
+static void
+_outGroupClause(DebugGraph *graph, DebugNode *parent, const char *label, GroupClause *node)
+{
+	WRITE_NODE_TYPE("GroupClause");
+
+	WRITE_UINT_FIELD(tleSortGroupRef);
+	WRITE_OID_FIELD(sortop);
+	WRITE_BOOL_FIELD(nulls_first);
+}
+
+static void
+_outRowMarkClause(DebugGraph *graph, DebugNode *parent, const char *label, RowMarkClause *node)
+{
+	WRITE_NODE_TYPE("RowMarkClause");
+
+	WRITE_UINT_FIELD(rti);
+	WRITE_BOOL_FIELD(forUpdate);
+	WRITE_BOOL_FIELD(noWait);
+}
+
+static void
+_outSetOperationStmt(DebugGraph *graph, DebugNode *parent, const char *label, SetOperationStmt *node)
+{
+	WRITE_NODE_TYPE("SetOperationStmt");
+
+	WRITE_ENUM_FIELD(op, SetOperation);
+	WRITE_BOOL_FIELD(all);
+	WRITE_NODE_FIELD(larg);
+	WRITE_NODE_FIELD(rarg);
+	WRITE_NODE_FIELD(colTypes);
+	WRITE_NODE_FIELD(colTypmods);
+}
+
+static void
+_outRangeTblEntry(DebugGraph *graph, DebugNode *parent, const char *label, RangeTblEntry *node)
+{
+	WRITE_NODE_TYPE("RangeTblEntry");
+
+	/* put alias + eref first to make dump more legible */
+	WRITE_NODE_FIELD(alias);
+	WRITE_NODE_FIELD(eref);
+	WRITE_ENUM_FIELD(rtekind, RTEKind);
+
+	switch (node->rtekind)
+	{
+		case RTE_RELATION:
+		case RTE_SPECIAL:
+			WRITE_OID_FIELD(relid);
+			break;
+		case RTE_SUBQUERY:
+			WRITE_NODE_FIELD(subquery);
+			break;
+		case RTE_FUNCTION:
+			WRITE_NODE_FIELD(funcexpr);
+			WRITE_NODE_FIELD(funccoltypes);
+			WRITE_NODE_FIELD(funccoltypmods);
+			break;
+		case RTE_VALUES:
+			WRITE_NODE_FIELD(values_lists);
+			break;
+		case RTE_JOIN:
+			WRITE_ENUM_FIELD(jointype, JoinType);
+			WRITE_NODE_FIELD(joinaliasvars);
+			break;
+		default:
+			addDebugNodeAttributeArgs(graphnode, "rtekind",
+					"unrecognized RTE kind: %d",
+					(int) node->rtekind);
+			break;
+	}
+
+	WRITE_BOOL_FIELD(inh);
+	WRITE_BOOL_FIELD(inFromCl);
+	WRITE_UINT_FIELD(requiredPerms);
+	WRITE_OID_FIELD(checkAsUser);
+}
+
+static void
+_outAExpr(DebugGraph *graph, DebugNode *parent, const char *label, A_Expr *node)
+{
+	WRITE_NODE_TYPE("A_Expr");
+
+	switch (node->kind)
+	{
+		case AEXPR_OP:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_OP");
+			WRITE_NODE_FIELD(name);
+			break;
+		case AEXPR_AND:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_AND");
+			break;
+		case AEXPR_OR:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_OR");
+			break;
+		case AEXPR_NOT:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_NOT");
+			break;
+		case AEXPR_OP_ANY:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_OP_ANY");
+			WRITE_NODE_FIELD(name);
+			break;
+		case AEXPR_OP_ALL:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_OP_ALL");
+			WRITE_NODE_FIELD(name);
+			break;
+		case AEXPR_DISTINCT:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_DISTINCT");
+			WRITE_NODE_FIELD(name);
+			break;
+		case AEXPR_NULLIF:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_NULLIF");
+			WRITE_NODE_FIELD(name);
+			break;
+		case AEXPR_OF:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_OF");
+			WRITE_NODE_FIELD(name);
+			break;
+		case AEXPR_IN:
+			addDebugNodeAttribute(graphnode, "kind", "AEXPR_IN");
+			WRITE_NODE_FIELD(name);
+			break;
+		default:
+			addDebugNodeAttribute(graphnode, "kind", "??");
+			break;
+	}
+
+	WRITE_NODE_FIELD(lexpr);
+	WRITE_NODE_FIELD(rexpr);
+	WRITE_INT_FIELD(location);
+}
+
+static void
+_outValue(DebugGraph *graph, DebugNode *parent, const char *label, Value *value)
+{
+	DebugNode *graphnode;
+	if( parent ){
+		graphnode = parent;
+	} else {
+		char aux[100];
+		graphnode = newDebugNode(graph, addressToName(aux, value), "Value");
+	}
+
+	switch (value->type)
+	{
+		case T_Integer:
+			addDebugNodeAttributeArgs(graphnode, label, "%ld", value->val.ival);
+			break;
+		case T_Float:
+
+			/*
+			 * We assume the value is a valid numeric literal and so does not
+			 * need quoting.
+			 */
+			addDebugNodeAttribute(graphnode, label, value->val.str);
+			break;
+		case T_String:
+			_outToken(graph, graphnode, label, value->val.str);
+			break;
+		case T_BitString:
+			/* internal representation already has leading 'b' */
+			addDebugNodeAttribute(graphnode, label, value->val.str);
+			break;
+		case T_Null:
+			/* this is seen only within A_Const, not in transformed trees */
+			addDebugNodeAttribute(graphnode, label, "NULL");
+			break;
+		default:
+			addDebugNodeAttributeArgs(graphnode, label,
+					"unrecognized node type: %d", (int) value->type);
+			break;
+	}
+}
+
+static void
+_outColumnRef(DebugGraph *graph, DebugNode *parent, const char *label,
+		ColumnRef *node)
+{
+	WRITE_NODE_TYPE("ColumnRef");
+
+	WRITE_NODE_FIELD(fields);
+	WRITE_INT_FIELD(location);
+}
+
+static void
+_outParamRef(DebugGraph *graph, DebugNode *parent, const char *label,
+		ParamRef *node)
+{
+	WRITE_NODE_TYPE("ParamRef");
+
+	WRITE_INT_FIELD(number);
+}
+
+static void
+_outAConst(DebugGraph *graph, DebugNode *parent, const char *label, A_Const *node)
+{
+	WRITE_NODE_TYPE("A_Const");
+
+	_outValue(graph, graphnode, "val", &(node->val));
+	WRITE_NODE_FIELD(typename);
+}
+
+static void
+_outA_Indices(DebugGraph *graph, DebugNode *parent, const char *label,
+		A_Indices *node)
+{
+	WRITE_NODE_TYPE("A_Indices");
+
+	WRITE_NODE_FIELD(lidx);
+	WRITE_NODE_FIELD(uidx);
+}
+
+static void
+_outA_Indirection(DebugGraph *graph, DebugNode *parent, const char *label,
+		A_Indirection *node)
+{
+	WRITE_NODE_TYPE("A_Indirection");
+
+	WRITE_NODE_FIELD(arg);
+	WRITE_NODE_FIELD(indirection);
+}
+
+static void
+_outResTarget(DebugGraph *graph, DebugNode *parent, const char *label, ResTarget *node)
+{
+	WRITE_NODE_TYPE("ResTarget");
+
+	WRITE_STRING_FIELD(name);
+	WRITE_NODE_FIELD(indirection);
+	WRITE_NODE_FIELD(val);
+	WRITE_INT_FIELD(location);
+}
+
+static void
+_outConstraint(DebugGraph *graph, DebugNode *parent, const char *label,
+		Constraint *node)
+{
+	WRITE_NODE_TYPE("Constraint");
+
+	WRITE_STRING_FIELD(name);
+
+	switch (node->contype)
+	{
+		case CONSTR_PRIMARY:
+			addDebugNodeAttribute(graphnode, "contype", "PRIMARY_KEY");
+			WRITE_NODE_FIELD(keys);
+			WRITE_NODE_FIELD(options);
+			WRITE_STRING_FIELD(indexspace);
+			break;
+
+		case CONSTR_UNIQUE:
+			addDebugNodeAttribute(graphnode, "contype", "UNIQUE");
+			WRITE_NODE_FIELD(keys);
+			WRITE_NODE_FIELD(options);
+			WRITE_STRING_FIELD(indexspace);
+			break;
+
+		case CONSTR_CHECK:
+			addDebugNodeAttribute(graphnode, "contype", "CHECK");
+			WRITE_NODE_FIELD(raw_expr);
+			WRITE_STRING_FIELD(cooked_expr);
+			break;
+
+		case CONSTR_DEFAULT:
+			addDebugNodeAttribute(graphnode, "contype", "DEFAULT");
+			WRITE_NODE_FIELD(raw_expr);
+			WRITE_STRING_FIELD(cooked_expr);
+			break;
+
+		case CONSTR_NOTNULL:
+			addDebugNodeAttribute(graphnode, "contype", "NOT_NULL");
+			break;
+
+		default:
+			addDebugNodeAttribute(graphnode, "contype",
+					"<unrecognized_constraint>");
+			break;
+	}
+}
+
+static void
+_outFkConstraint(DebugGraph *graph, DebugNode *parent, const char *label,
+		FkConstraint *node)
+{
+	WRITE_NODE_TYPE("FkConstraint");
+
+	WRITE_STRING_FIELD(constr_name);
+	WRITE_NODE_FIELD(pktable);
+	WRITE_NODE_FIELD(fk_attrs);
+	WRITE_NODE_FIELD(pk_attrs);
+	WRITE_CHAR_FIELD(fk_matchtype);
+	WRITE_CHAR_FIELD(fk_upd_action);
+	WRITE_CHAR_FIELD(fk_del_action);
+	WRITE_BOOL_FIELD(deferrable);
+	WRITE_BOOL_FIELD(initdeferred);
+	WRITE_BOOL_FIELD(skip_validation);
+}
+
+
+/*
+ * _outNode -
+ *	  converts a Node into ascii string and append it to 'str'
+ */
+static void
+_outNode(DebugGraph *graph, DebugNode *parent, const char *label, void *obj)
+{
+	if (obj == NULL)
+		return;
+	else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
+		_outList(graph, parent, label, obj);
+	else if (IsA(obj, Integer) ||
+			 IsA(obj, Float) ||
+			 IsA(obj, String) ||
+			 IsA(obj, BitString))
+	{
+		/* nodeRead does not want to see { } around these! */
+		 _outValue(graph, parent, label, obj);
+	}
+	else
+	{
+		switch (nodeTag(obj))
+		{
+			case T_PlannedStmt:
+				_outPlannedStmt(graph, parent, label, obj);
+				break;
+			case T_Plan:
+				_outPlan(graph, parent, label, obj);
+				break;
+			case T_Result:
+				_outResult(graph, parent, label, obj);
+				break;
+			case T_Append:
+				_outAppend(graph, parent, label, obj);
+				break;
+			case T_BitmapAnd:
+				_outBitmapAnd(graph, parent, label, obj);
+				break;
+			case T_BitmapOr:
+				_outBitmapOr(graph, parent, label, obj);
+				break;
+			case T_Scan:
+				_outScan(graph, parent, label, obj);
+				break;
+			case T_SeqScan:
+				_outSeqScan(graph, parent, label, obj);
+				break;
+			case T_IndexScan:
+				_outIndexScan(graph, parent, label, obj);
+				break;
+			case T_BitmapIndexScan:
+				_outBitmapIndexScan(graph, parent, label, obj);
+				break;
+			case T_BitmapHeapScan:
+				_outBitmapHeapScan(graph, parent, label, obj);
+				break;
+			case T_TidScan:
+				_outTidScan(graph, parent, label, obj);
+				break;
+			case T_SubqueryScan:
+				_outSubqueryScan(graph, parent, label, obj);
+				break;
+			case T_FunctionScan:
+				_outFunctionScan(graph, parent, label, obj);
+				break;
+			case T_ValuesScan:
+				_outValuesScan(graph, parent, label, obj);
+				break;
+			case T_Join:
+				_outJoin(graph, parent, label, obj);
+				break;
+			case T_NestLoop:
+				_outNestLoop(graph, parent, label, obj);
+				break;
+			case T_MergeJoin:
+				_outMergeJoin(graph, parent, label, obj);
+				break;
+			case T_HashJoin:
+				_outHashJoin(graph, parent, label, obj);
+				break;
+			case T_Agg:
+				_outAgg(graph, parent, label, obj);
+				break;
+			case T_Group:
+				_outGroup(graph, parent, label, obj);
+				break;
+			case T_Material:
+				_outMaterial(graph, parent, label, obj);
+				break;
+			case T_Sort:
+				_outSort(graph, parent, label, obj);
+				break;
+			case T_Unique:
+				_outUnique(graph, parent, label, obj);
+				break;
+			case T_SetOp:
+				_outSetOp(graph, parent, label, obj);
+				break;
+			case T_Limit:
+				_outLimit(graph, parent, label, obj);
+				break;
+			case T_Hash:
+				_outHash(graph, parent, label, obj);
+				break;
+			case T_Alias:
+				_outAlias(graph, parent, label, obj);
+				break;
+			case T_RangeVar:
+				_outRangeVar(graph, parent, label, obj);
+				break;
+			case T_IntoClause:
+				_outIntoClause(graph, parent, label, obj);
+				break;
+			case T_Var:
+				_outVar(graph, parent, label, obj);
+				break;
+			case T_Const:
+				_outConst(graph, parent, label, obj);
+				break;
+			case T_Param:
+				_outParam(graph, parent, label, obj);
+				break;
+			case T_Aggref:
+				_outAggref(graph, parent, label, obj);
+				break;
+			case T_ArrayRef:
+				_outArrayRef(graph, parent, label, obj);
+				break;
+			case T_FuncExpr:
+				_outFuncExpr(graph, parent, label, obj);
+				break;
+			case T_OpExpr:
+				_outOpExpr(graph, parent, label, obj);
+				break;
+			case T_DistinctExpr:
+				_outDistinctExpr(graph, parent, label, obj);
+				break;
+			case T_ScalarArrayOpExpr:
+				_outScalarArrayOpExpr(graph, parent, label, obj);
+				break;
+			case T_BoolExpr:
+				_outBoolExpr(graph, parent, label, obj);
+				break;
+			case T_SubLink:
+				_outSubLink(graph, parent, label, obj);
+				break;
+			case T_SubPlan:
+				_outSubPlan(graph, parent, label, obj);
+				break;
+			case T_FieldSelect:
+				_outFieldSelect(graph, parent, label, obj);
+				break;
+			case T_FieldStore:
+				_outFieldStore(graph, parent, label, obj);
+				break;
+			case T_RelabelType:
+				_outRelabelType(graph, parent, label, obj);
+				break;
+			case T_CoerceViaIO:
+				_outCoerceViaIO(graph, parent, label, obj);
+				break;
+			case T_ArrayCoerceExpr:
+				_outArrayCoerceExpr(graph, parent, label, obj);
+				break;
+			case T_ConvertRowtypeExpr:
+				_outConvertRowtypeExpr(graph, parent, label, obj);
+				break;
+			case T_CaseExpr:
+				_outCaseExpr(graph, parent, label, obj);
+				break;
+			case T_CaseWhen:
+				_outCaseWhen(graph, parent, label, obj);
+				break;
+			case T_CaseTestExpr:
+				_outCaseTestExpr(graph, parent, label, obj);
+				break;
+			case T_ArrayExpr:
+				_outArrayExpr(graph, parent, label, obj);
+				break;
+			case T_RowExpr:
+				_outRowExpr(graph, parent, label, obj);
+				break;
+			case T_RowCompareExpr:
+				_outRowCompareExpr(graph, parent, label, obj);
+				break;
+			case T_CoalesceExpr:
+				_outCoalesceExpr(graph, parent, label, obj);
+				break;
+			case T_MinMaxExpr:
+				_outMinMaxExpr(graph, parent, label, obj);
+				break;
+			case T_XmlExpr:
+				_outXmlExpr(graph, parent, label, obj);
+				break;
+			case T_NullIfExpr:
+				_outNullIfExpr(graph, parent, label, obj);
+				break;
+			case T_NullTest:
+				_outNullTest(graph, parent, label, obj);
+				break;
+			case T_BooleanTest:
+				_outBooleanTest(graph, parent, label, obj);
+				break;
+			case T_CoerceToDomain:
+				_outCoerceToDomain(graph, parent, label, obj);
+				break;
+			case T_CoerceToDomainValue:
+				_outCoerceToDomainValue(graph, parent, label, obj);
+				break;
+			case T_SetToDefault:
+				_outSetToDefault(graph, parent, label, obj);
+				break;
+			case T_CurrentOfExpr:
+				_outCurrentOfExpr(graph, parent, label, obj);
+				break;
+			case T_TargetEntry:
+				_outTargetEntry(graph, parent, label, obj);
+				break;
+			case T_RangeTblRef:
+				_outRangeTblRef(graph, parent, label, obj);
+				break;
+			case T_JoinExpr:
+				_outJoinExpr(graph, parent, label, obj);
+				break;
+			case T_FromExpr:
+				_outFromExpr(graph, parent, label, obj);
+				break;
+
+			case T_Path:
+				_outPath(graph, parent, label, obj);
+				break;
+			case T_IndexPath:
+				_outIndexPath(graph, parent, label, obj);
+				break;
+			case T_BitmapHeapPath:
+				_outBitmapHeapPath(graph, parent, label, obj);
+				break;
+			case T_BitmapAndPath:
+				_outBitmapAndPath(graph, parent, label, obj);
+				break;
+			case T_BitmapOrPath:
+				_outBitmapOrPath(graph, parent, label, obj);
+				break;
+			case T_TidPath:
+				_outTidPath(graph, parent, label, obj);
+				break;
+			case T_AppendPath:
+				_outAppendPath(graph, parent, label, obj);
+				break;
+			case T_ResultPath:
+				_outResultPath(graph, parent, label, obj);
+				break;
+			case T_MaterialPath:
+				_outMaterialPath(graph, parent, label, obj);
+				break;
+			case T_UniquePath:
+				_outUniquePath(graph, parent, label, obj);
+				break;
+			case T_NestPath:
+				_outNestPath(graph, parent, label, obj);
+				break;
+			case T_MergePath:
+				_outMergePath(graph, parent, label, obj);
+				break;
+			case T_HashPath:
+				_outHashPath(graph, parent, label, obj);
+				break;
+			case T_PlannerGlobal:
+				_outPlannerGlobal(graph, parent, label, obj);
+				break;
+			case T_PlannerInfo:
+				_outPlannerInfo(graph, parent, label, obj);
+				break;
+			case T_RelOptInfo:
+				_outRelOptInfo(graph, parent, label, obj);
+				break;
+			case T_IndexOptInfo:
+				_outIndexOptInfo(graph, parent, label, obj);
+				break;
+			case T_EquivalenceClass:
+				_outEquivalenceClass(graph, parent, label, obj);
+				break;
+			case T_EquivalenceMember:
+				_outEquivalenceMember(graph, parent, label, obj);
+				break;
+			case T_PathKey:
+				_outPathKey(graph, parent, label, obj);
+				break;
+			case T_RestrictInfo:
+				_outRestrictInfo(graph, parent, label, obj);
+				break;
+			case T_InnerIndexscanInfo:
+				_outInnerIndexscanInfo(graph, parent, label, obj);
+				break;
+			case T_OuterJoinInfo:
+				_outOuterJoinInfo(graph, parent, label, obj);
+				break;
+			case T_InClauseInfo:
+				_outInClauseInfo(graph, parent, label, obj);
+				break;
+			case T_AppendRelInfo:
+				_outAppendRelInfo(graph, parent, label, obj);
+				break;
+			case T_PlannerParamItem:
+				_outPlannerParamItem(graph, parent, label, obj);
+				break;
+
+			case T_CreateStmt:
+				_outCreateStmt(graph, parent, label, obj);
+				break;
+			case T_IndexStmt:
+				_outIndexStmt(graph, parent, label, obj);
+				break;
+			case T_NotifyStmt:
+				_outNotifyStmt(graph, parent, label, obj);
+				break;
+			case T_DeclareCursorStmt:
+				_outDeclareCursorStmt(graph, parent, label, obj);
+				break;
+			case T_SelectStmt:
+				_outSelectStmt(graph, parent, label, obj);
+				break;
+			case T_ColumnDef:
+				_outColumnDef(graph, parent, label, obj);
+				break;
+			case T_TypeName:
+				_outTypeName(graph, parent, label, obj);
+				break;
+			case T_TypeCast:
+				_outTypeCast(graph, parent, label, obj);
+				break;
+			case T_IndexElem:
+				_outIndexElem(graph, parent, label, obj);
+				break;
+			case T_Query:
+				_outQuery(graph, parent, label, obj);
+				break;
+			case T_SortClause:
+				_outSortClause(graph, parent, label, obj);
+				break;
+			case T_GroupClause:
+				_outGroupClause(graph, parent, label, obj);
+				break;
+			case T_RowMarkClause:
+				_outRowMarkClause(graph, parent, label, obj);
+				break;
+			case T_SetOperationStmt:
+				_outSetOperationStmt(graph, parent, label, obj);
+				break;
+			case T_RangeTblEntry:
+				_outRangeTblEntry(graph, parent, label, obj);
+				break;
+			case T_A_Expr:
+				_outAExpr(graph, parent, label, obj);
+				break;
+			case T_ColumnRef:
+				_outColumnRef(graph, parent, label, obj);
+				break;
+			case T_ParamRef:
+				_outParamRef(graph, parent, label, obj);
+				break;
+			case T_A_Const:
+				_outAConst(graph, parent, label, obj);
+				break;
+			case T_A_Indices:
+				_outA_Indices(graph, parent, label, obj);
+				break;
+			case T_A_Indirection:
+				_outA_Indirection(graph, parent, label, obj);
+				break;
+			case T_ResTarget:
+				_outResTarget(graph, parent, label, obj);
+				break;
+			case T_Constraint:
+				_outConstraint(graph, parent, label, obj);
+				break;
+			case T_FkConstraint:
+				_outFkConstraint(graph, parent, label, obj);
+				break;
+			case T_FuncCall:
+				_outFuncCall(graph, parent, label, obj);
+				break;
+			case T_DefElem:
+				_outDefElem(graph, parent, label, obj);
+				break;
+			case T_LockingClause:
+				_outLockingClause(graph, parent, label, obj);
+				break;
+			case T_XmlSerialize:
+				_outXmlSerialize(graph, parent, label, obj);
+				break;
+
+			default:
+
+				/*
+				 * This should be an ERROR, but it's too useful to be able to
+				 * dump structures that _outNode only understands part of.
+				 */
+				{
+					char name[100];
+					char aux[100];
+					DebugNode *graphnode;
+					sprintf(aux, "unrecognized node type: %d",
+							(int) nodeTag(obj));
+					graphnode = newDebugNode(graph, addressToName(name, obj), aux);
+					if( parent )
+						newDebugEdge(graph, parent->internal_name,
+								graphnode->internal_name, label);
+				}
+				break;
+		}
+	}
+}
+
+DebugGraph *
+createGraphNodes(void *obj)
+{
+	DebugGraph *graph;
+
+	graph = createDebugGraph();
+	_outNode(graph, NULL, "", obj);
+	return graph;
+}
+
+void
+printGraphNodes(void *obj, FILE *file)
+{
+	DebugGraph *graph;
+
+	if( !file && !obj )
+		return;
+
+	graph = createGraphNodes( obj );
+	printGraphvizToFile( graph, file );
+	destroyDebugGraph( graph );
+}
Index: src/backend/nodes/Makefile
===================================================================
--- src/backend/nodes/Makefile	(revision 11)
+++ src/backend/nodes/Makefile	(working copy)
@@ -14,7 +14,8 @@
 
 OBJS = nodeFuncs.o nodes.o list.o bitmapset.o tidbitmap.o \
        copyfuncs.o equalfuncs.o makefuncs.o \
-       outfuncs.o readfuncs.o print.o read.o params.o value.o
+       outfuncs.o readfuncs.o print.o read.o params.o value.o \
+       debuggraph.o outfuncs_graph.o
 
 all: SUBSYS.o
 
Index: src/backend/nodes/print.c
===================================================================
--- src/backend/nodes/print.c	(revision 11)
+++ src/backend/nodes/print.c	(working copy)
@@ -401,6 +401,111 @@
 		printf("unknown expr");
 }
 
+int
+print_expr_str(char *output, Node *expr, List *rtable)
+{
+	char *aux = output;
+
+	if (expr == NULL)
+	{
+		aux += sprintf(aux, "<>");
+		return aux - output;
+	}
+
+	if (IsA(expr, Var))
+	{
+		Var		   *var = (Var *) expr;
+		char	   *relname,
+				   *attname;
+
+		switch (var->varno)
+		{
+			case INNER:
+				relname = "INNER";
+				attname = "?";
+				break;
+			case OUTER:
+				relname = "OUTER";
+				attname = "?";
+				break;
+			default:
+				{
+					RangeTblEntry *rte;
+
+					Assert(var->varno > 0 &&
+						   (int) var->varno <= list_length(rtable));
+					rte = rt_fetch(var->varno, rtable);
+					relname = rte->eref->aliasname;
+					attname = get_rte_attribute_name(rte, var->varattno);
+				}
+				break;
+		}
+		aux = aux + sprintf(aux, "%s.%s", relname, attname);
+	}
+	else if (IsA(expr, Const))
+	{
+		Const	   *c = (Const *) expr;
+		Oid			typoutput;
+		bool		typIsVarlena;
+		char	   *outputstr;
+
+		if (c->constisnull)
+		{
+			aux = aux + sprintf(aux, "NULL");
+			return;
+		}
+
+		getTypeOutputInfo(c->consttype,
+						  &typoutput, &typIsVarlena);
+
+		outputstr = OidOutputFunctionCall(typoutput, c->constvalue);
+		aux = aux + sprintf(aux, "%s", outputstr);
+		pfree(outputstr);
+	}
+	else if (IsA(expr, OpExpr))
+	{
+		OpExpr	   *e = (OpExpr *) expr;
+		char	   *opname;
+
+		opname = get_opname(e->opno);
+		if (list_length(e->args) > 1)
+		{
+			aux += print_expr_str(aux, get_leftop((Expr *) e), rtable);
+			aux = aux + sprintf(aux, " %s ",
+					((opname != NULL) ? opname : "(invalid operator)"));
+			aux += print_expr_str(aux, get_rightop((Expr *) e), rtable);
+		}
+		else
+		{
+			/* we print prefix and postfix ops the same... */
+			aux = aux + sprintf(aux, "%s ",
+					((opname != NULL) ? opname : "(invalid operator)"));
+			aux += print_expr_str(aux, get_leftop((Expr *) e), rtable);
+		}
+	}
+	else if (IsA(expr, FuncExpr))
+	{
+		FuncExpr   *e = (FuncExpr *) expr;
+		char	   *funcname;
+		ListCell   *l;
+
+		funcname = get_func_name(e->funcid);
+		aux = aux + sprintf(aux, "%s(",
+				((funcname != NULL) ? funcname : "(invalid function)"));
+		foreach(l, e->args)
+		{
+			aux += print_expr_str(aux, lfirst(l), rtable);
+			if (lnext(l))
+				aux= aux + sprintf(aux, ",");
+		}
+		aux = aux + sprintf(aux, ")");
+	}
+	else
+		aux = aux + sprintf(aux, "unknown expr");
+
+	return aux - output;
+}
+
 /*
  * print_pathkeys -
  *	  pathkeys list of PathKeys
#10ITAGAKI Takahiro
itagaki.takahiro@oss.ntt.co.jp
In reply to: Adriano Lange (#9)
Re: graph representation of data structures in optimizer

Adriano Lange <adriano@c3sl.ufpr.br> wrote:

The patch attached is an implementation for graph generation of data
structures in postgres. The file debuggraph.c is a simple library that
generate graphs in the format supported by graphviz.

It's interesting, but I don't think it is suitable for a core feature.
Could you split the patch into a core-patch and an extension module?
The extension module would be put in contrib or in a pgFoundry project.
XML might be good for communications between the core and the module;
XML-explain was ongoingly discussed, but had not been completed yet.

Regards,
---
ITAGAKI Takahiro
NTT Open Source Software Center