)]}'
{"nova/scheduler/client/report.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"baafe10c8f6fb366b2067825d30b8d7115836c03","unresolved":false,"context_lines":[{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"},{"line_number":723,"context_line":"                    # part of a tree."},{"line_number":724,"context_line":"                    self._provider_tree.new_root("},{"line_number":725,"context_line":"                        rp[\u0027name\u0027], rp[\u0027uuid\u0027], rp[\u0027generation\u0027])"},{"line_number":726,"context_line":"                    # Now we have to populate that guy\u0027s traits and aggregates"}],"source_content_type":"text/x-python","patch_set":6,"id":"9f91af0f_85a96b7c","line":723,"updated":"2018-01-03 12:02:50.000000000","message":"I sincerely hope we have no plans to ever change this constraint.","commit_id":"e0203fe6156931e0556241b587538c07e6d962c2"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3fe9a063115c9f58b9f717673b11d80fb80f70a6","unresolved":false,"context_lines":[{"line_number":715,"context_line":""},{"line_number":716,"context_line":"            if refresh_sharing:"},{"line_number":717,"context_line":"                # Refresh providers associated by aggregate"},{"line_number":718,"context_line":"                for rp in (rp for rp in self._get_providers_in_aggregates(aggs)"},{"line_number":719,"context_line":"                           if not self._provider_tree.exists(rp[\u0027uuid\u0027])):"},{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_abb50e80","line":718,"range":{"start_line":718,"start_character":19,"end_line":718,"end_character":36},"updated":"2018-01-16 15:10:48.000000000","message":"ouch","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1243a4e68a4ab6407e1a4c1821298753f1c1740a","unresolved":false,"context_lines":[{"line_number":715,"context_line":""},{"line_number":716,"context_line":"            if refresh_sharing:"},{"line_number":717,"context_line":"                # Refresh providers associated by aggregate"},{"line_number":718,"context_line":"                for rp in (rp for rp in self._get_providers_in_aggregates(aggs)"},{"line_number":719,"context_line":"                           if not self._provider_tree.exists(rp[\u0027uuid\u0027])):"},{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_efb39e4c","line":718,"range":{"start_line":718,"start_character":19,"end_line":718,"end_character":36},"in_reply_to":"7f96bb07_a31c47c1","updated":"2018-01-19 16:24:55.000000000","message":"It was two separate variables named \u0027rp\u0027 that hurt my brain a bit.","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a48015093aaafbcdbc319880e143ea98223c2d64","unresolved":false,"context_lines":[{"line_number":715,"context_line":""},{"line_number":716,"context_line":"            if refresh_sharing:"},{"line_number":717,"context_line":"                # Refresh providers associated by aggregate"},{"line_number":718,"context_line":"                for rp in (rp for rp in self._get_providers_in_aggregates(aggs)"},{"line_number":719,"context_line":"                           if not self._provider_tree.exists(rp[\u0027uuid\u0027])):"},{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_a31c47c1","line":718,"range":{"start_line":718,"start_character":19,"end_line":718,"end_character":36},"in_reply_to":"7f96bb07_abb50e80","updated":"2018-01-16 15:37:22.000000000","message":"Is there a nicer way to do this?  (Assuming the conditional stays.)  I could do\n\n for rp in self._get...:\n     if self._provider_tree.exists(rp[\u0027uuid\u0027]):\n         continue\n\nbut I don\u0027t think that\u0027s any more efficient in terms of processing or memory, since the existing is using a generator anyway, nah?","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3fe9a063115c9f58b9f717673b11d80fb80f70a6","unresolved":false,"context_lines":[{"line_number":716,"context_line":"            if refresh_sharing:"},{"line_number":717,"context_line":"                # Refresh providers associated by aggregate"},{"line_number":718,"context_line":"                for rp in (rp for rp in self._get_providers_in_aggregates(aggs)"},{"line_number":719,"context_line":"                           if not self._provider_tree.exists(rp[\u0027uuid\u0027])):"},{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_eb647624","line":719,"range":{"start_line":719,"start_character":27,"end_line":719,"end_character":74},"updated":"2018-01-16 15:10:48.000000000","message":"Why we skip those that are already exists in our cache? I think even if we cached a shared RP in the past it is possible that the traits on that RP has been changed and needs to be refreshed.","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5a16bf6098543a0b928a0cef9449cf09819269e2","unresolved":false,"context_lines":[{"line_number":716,"context_line":"            if refresh_sharing:"},{"line_number":717,"context_line":"                # Refresh providers associated by aggregate"},{"line_number":718,"context_line":"                for rp in (rp for rp in self._get_providers_in_aggregates(aggs)"},{"line_number":719,"context_line":"                           if not self._provider_tree.exists(rp[\u0027uuid\u0027])):"},{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_9b860066","line":719,"range":{"start_line":719,"start_character":27,"end_line":719,"end_character":74},"in_reply_to":"7f96bb07_83902bef","updated":"2018-01-18 17:47:33.000000000","message":"Done","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a48015093aaafbcdbc319880e143ea98223c2d64","unresolved":false,"context_lines":[{"line_number":716,"context_line":"            if refresh_sharing:"},{"line_number":717,"context_line":"                # Refresh providers associated by aggregate"},{"line_number":718,"context_line":"                for rp in (rp for rp in self._get_providers_in_aggregates(aggs)"},{"line_number":719,"context_line":"                           if not self._provider_tree.exists(rp[\u0027uuid\u0027])):"},{"line_number":720,"context_line":"                    # NOTE(efried): Right now sharing providers are always"},{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_83902bef","line":719,"range":{"start_line":719,"start_character":27,"end_line":719,"end_character":74},"in_reply_to":"7f96bb07_eb647624","updated":"2018-01-16 15:37:22.000000000","message":"Yes, that\u0027s a good point.  Will fix.","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3fe9a063115c9f58b9f717673b11d80fb80f70a6","unresolved":false,"context_lines":[{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"},{"line_number":723,"context_line":"                    # part of a tree."},{"line_number":724,"context_line":"                    self._provider_tree.new_root("},{"line_number":725,"context_line":"                        rp[\u0027name\u0027], rp[\u0027uuid\u0027], rp[\u0027generation\u0027])"},{"line_number":726,"context_line":"                    # Now we have to populate that guy\u0027s traits and aggregates"},{"line_number":727,"context_line":"                    # (but not *his* aggregate-associated providers)."}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_2b7edeae","line":724,"range":{"start_line":724,"start_character":25,"end_line":724,"end_character":48},"updated":"2018-01-16 15:10:48.000000000","message":"Bit unrelated but the naming is misleading here. If we have a single provider_tree then I would assume that tree has only one root node. By this call we are not overwriting that root but adding a new root to the list of roots in the provider_tree. This changes the tree to a forest data structure.","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1243a4e68a4ab6407e1a4c1821298753f1c1740a","unresolved":false,"context_lines":[{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"},{"line_number":723,"context_line":"                    # part of a tree."},{"line_number":724,"context_line":"                    self._provider_tree.new_root("},{"line_number":725,"context_line":"                        rp[\u0027name\u0027], rp[\u0027uuid\u0027], rp[\u0027generation\u0027])"},{"line_number":726,"context_line":"                    # Now we have to populate that guy\u0027s traits and aggregates"},{"line_number":727,"context_line":"                    # (but not *his* aggregate-associated providers)."}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_6fcf8eb0","line":724,"range":{"start_line":724,"start_character":25,"end_line":724,"end_character":48},"in_reply_to":"7f96bb07_03cf3b29","updated":"2018-01-19 16:24:55.000000000","message":"It is well commented here and there is no accessor giving back a single root for the ProviderTree so this is just for later discussion.","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"a48015093aaafbcdbc319880e143ea98223c2d64","unresolved":false,"context_lines":[{"line_number":721,"context_line":"                    # treated as roots. This is deliberate. From the context of"},{"line_number":722,"context_line":"                    # this compute\u0027s RP, it doesn\u0027t matter if a sharing RP is"},{"line_number":723,"context_line":"                    # part of a tree."},{"line_number":724,"context_line":"                    self._provider_tree.new_root("},{"line_number":725,"context_line":"                        rp[\u0027name\u0027], rp[\u0027uuid\u0027], rp[\u0027generation\u0027])"},{"line_number":726,"context_line":"                    # Now we have to populate that guy\u0027s traits and aggregates"},{"line_number":727,"context_line":"                    # (but not *his* aggregate-associated providers)."}],"source_content_type":"text/x-python","patch_set":12,"id":"7f96bb07_03cf3b29","line":724,"range":{"start_line":724,"start_character":25,"end_line":724,"end_character":48},"in_reply_to":"7f96bb07_2b7edeae","updated":"2018-01-16 15:37:22.000000000","message":"Well, yes, the point is that we\u0027re treating associated shared providers as roots (NB: even if they happen to be children in a tree of their own).  I suppose technically we could create a new semantic in ProviderTree for these, since they\u0027ll never have a tree structure (that we track here).  But that would be a fair bit of extra overhead for relatively little value.  Jay, thoughts?","commit_id":"61277734848dab72703fc6913c86bb1c2101cebf"}],"nova/tests/unit/scheduler/client/test_report.py":[{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"50b3948a2f8abd0f8e8f8987db5b339758412c7d","unresolved":false,"context_lines":[{"line_number":1840,"context_line":"        self.client._provider_tree.new_root(\u0027compute\u0027, uuid, 1)"},{"line_number":1841,"context_line":"        mock_agg_get.return_value \u003d set([uuids.agg1])"},{"line_number":1842,"context_line":"        mock_trait_get.return_value \u003d set([\u0027CUSTOM_GOLD\u0027])"},{"line_number":1843,"context_line":"        self.client._refresh_associations(uuid, refresh_sharing\u003dFalse)"},{"line_number":1844,"context_line":"        mock_agg_get.assert_called_once_with(uuid)"},{"line_number":1845,"context_line":"        mock_trait_get.assert_called_once_with(uuid)"},{"line_number":1846,"context_line":"        mock_pia_get.assert_not_called()"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf8cb3f7_7e5dd1e7","line":1843,"range":{"start_line":1843,"start_character":8,"end_line":1843,"end_character":70},"updated":"2017-12-25 00:18:21.000000000","message":"I prefer to keep using the same arguments between test_refresh_associations_no_last() and test_refresh_associations_not_stale().\n\nIf you just intend to add the test case for refresh_sharing\u003dFalse, I prefer adding a new test for that.","commit_id":"76cfe91177269e733d55724c965a019d4270f0c0"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"afbf52003eddc9b18884ad34fdce96533f57593a","unresolved":false,"context_lines":[{"line_number":1840,"context_line":"        self.client._provider_tree.new_root(\u0027compute\u0027, uuid, 1)"},{"line_number":1841,"context_line":"        mock_agg_get.return_value \u003d set([uuids.agg1])"},{"line_number":1842,"context_line":"        mock_trait_get.return_value \u003d set([\u0027CUSTOM_GOLD\u0027])"},{"line_number":1843,"context_line":"        self.client._refresh_associations(uuid, refresh_sharing\u003dFalse)"},{"line_number":1844,"context_line":"        mock_agg_get.assert_called_once_with(uuid)"},{"line_number":1845,"context_line":"        mock_trait_get.assert_called_once_with(uuid)"},{"line_number":1846,"context_line":"        mock_pia_get.assert_not_called()"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f91af0f_3dd28101","line":1843,"range":{"start_line":1843,"start_character":8,"end_line":1843,"end_character":70},"in_reply_to":"9f91af0f_538a561b","updated":"2018-01-09 10:03:54.000000000","message":"Thanks for the update.","commit_id":"76cfe91177269e733d55724c965a019d4270f0c0"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"95c7eb6ecbd1e49cf7b42a04e0a0f780d73727ba","unresolved":false,"context_lines":[{"line_number":1840,"context_line":"        self.client._provider_tree.new_root(\u0027compute\u0027, uuid, 1)"},{"line_number":1841,"context_line":"        mock_agg_get.return_value \u003d set([uuids.agg1])"},{"line_number":1842,"context_line":"        mock_trait_get.return_value \u003d set([\u0027CUSTOM_GOLD\u0027])"},{"line_number":1843,"context_line":"        self.client._refresh_associations(uuid, refresh_sharing\u003dFalse)"},{"line_number":1844,"context_line":"        mock_agg_get.assert_called_once_with(uuid)"},{"line_number":1845,"context_line":"        mock_trait_get.assert_called_once_with(uuid)"},{"line_number":1846,"context_line":"        mock_pia_get.assert_not_called()"}],"source_content_type":"text/x-python","patch_set":5,"id":"9f91af0f_538a561b","line":1843,"range":{"start_line":1843,"start_character":8,"end_line":1843,"end_character":70},"in_reply_to":"bf8cb3f7_7e5dd1e7","updated":"2018-01-04 23:11:32.000000000","message":"Done","commit_id":"76cfe91177269e733d55724c965a019d4270f0c0"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"62bf78ab5b15d2a24eeb5402e3bcdbf2d516a56e","unresolved":false,"context_lines":[{"line_number":1202,"context_line":"    @mock.patch(\u0027nova.scheduler.client.report.SchedulerReportClient.\u0027"},{"line_number":1203,"context_line":"                \u0027_get_resource_provider\u0027)"},{"line_number":1204,"context_line":"    def test_ensure_resource_provider_exists_in_cache(self, get_rp_mock,"},{"line_number":1205,"context_line":"            get_pia_mock, get_trait_mock, get_agg_mock, create_rp_mock):"},{"line_number":1206,"context_line":"        # Override the client object\u0027s cache to contain a resource provider"},{"line_number":1207,"context_line":"        # object for the compute host and check that"},{"line_number":1208,"context_line":"        # _ensure_resource_provider() doesn\u0027t call _get_resource_provider() or"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f96bb07_54d029ca","line":1205,"range":{"start_line":1205,"start_character":16,"end_line":1205,"end_character":19},"updated":"2018-01-11 01:52:57.000000000","message":"pain in (the) ass? I see what you did there... good.","commit_id":"ac0cb4dcc3ce7f180e353f768367dcbcb859bc97"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3fe9a063115c9f58b9f717673b11d80fb80f70a6","unresolved":false,"context_lines":[{"line_number":1202,"context_line":"    @mock.patch(\u0027nova.scheduler.client.report.SchedulerReportClient.\u0027"},{"line_number":1203,"context_line":"                \u0027_get_resource_provider\u0027)"},{"line_number":1204,"context_line":"    def test_ensure_resource_provider_exists_in_cache(self, get_rp_mock,"},{"line_number":1205,"context_line":"            get_pia_mock, get_trait_mock, get_agg_mock, create_rp_mock):"},{"line_number":1206,"context_line":"        # Override the client object\u0027s cache to contain a resource provider"},{"line_number":1207,"context_line":"        # object for the compute host and check that"},{"line_number":1208,"context_line":"        # _ensure_resource_provider() doesn\u0027t call _get_resource_provider() or"}],"source_content_type":"text/x-python","patch_set":7,"id":"7f96bb07_6221d5b4","line":1205,"range":{"start_line":1205,"start_character":16,"end_line":1205,"end_character":19},"in_reply_to":"7f96bb07_54d029ca","updated":"2018-01-16 15:10:48.000000000","message":"In Hungarian pia means booze... so mocking get_pia is a way to control my abuse","commit_id":"ac0cb4dcc3ce7f180e353f768367dcbcb859bc97"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"62bf78ab5b15d2a24eeb5402e3bcdbf2d516a56e","unresolved":false,"context_lines":[{"line_number":1264,"context_line":"        # The second has bronze"},{"line_number":1265,"context_line":"        self.assertFalse(self.client._provider_tree.have_traits_changed("},{"line_number":1266,"context_line":"            uuids.shr2, [\u0027CUSTOM_BRONZE\u0027]))"},{"line_number":1267,"context_line":"        # These were not called because we had the root provider in the cache."},{"line_number":1268,"context_line":"        self.assertFalse(get_rp_mock.called)"},{"line_number":1269,"context_line":"        self.assertFalse(create_rp_mock.called)"},{"line_number":1270,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7f96bb07_d4e3d9a3","line":1267,"updated":"2018-01-11 01:52:57.000000000","message":"good test assertions and excellent code comments. ++","commit_id":"ac0cb4dcc3ce7f180e353f768367dcbcb859bc97"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"356025d4247ba97115044c71f6a65ce92c9f1c9f","unresolved":false,"context_lines":[{"line_number":1231,"context_line":"        get_pia_mock.assert_called_once_with(set([uuids.agg1, uuids.agg2]))"},{"line_number":1232,"context_line":"        self.assertTrue(self.client._provider_tree.exists(uuids.shr1))"},{"line_number":1233,"context_line":"        self.assertTrue(self.client._provider_tree.exists(uuids.shr2))"},{"line_number":1234,"context_line":"        # _get_provider_aggregates and _traits were called thrice: one for the"},{"line_number":1235,"context_line":"        # compute RP and once for each of the sharing RPs."},{"line_number":1236,"context_line":"        expected_calls \u003d [mock.call(uuid)"},{"line_number":1237,"context_line":"                          for uuid in (cn.uuid, uuids.shr1, uuids.shr2)]"}],"source_content_type":"text/x-python","patch_set":16,"id":"7f96bb07_94db1120","line":1234,"range":{"start_line":1234,"start_character":59,"end_line":1234,"end_character":65},"updated":"2018-01-19 16:09:32.000000000","message":"Three shall be the number of the counting and the number of the counting shall be three. Four shalt thou not count, neither shalt thou count two, excepting that thou then proceedeth to three. Five is right out.","commit_id":"f0d830d56d20c7f34372cd3c68d13a94bdf645a6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1243a4e68a4ab6407e1a4c1821298753f1c1740a","unresolved":false,"context_lines":[{"line_number":1231,"context_line":"        get_pia_mock.assert_called_once_with(set([uuids.agg1, uuids.agg2]))"},{"line_number":1232,"context_line":"        self.assertTrue(self.client._provider_tree.exists(uuids.shr1))"},{"line_number":1233,"context_line":"        self.assertTrue(self.client._provider_tree.exists(uuids.shr2))"},{"line_number":1234,"context_line":"        # _get_provider_aggregates and _traits were called thrice: one for the"},{"line_number":1235,"context_line":"        # compute RP and once for each of the sharing RPs."},{"line_number":1236,"context_line":"        expected_calls \u003d [mock.call(uuid)"},{"line_number":1237,"context_line":"                          for uuid in (cn.uuid, uuids.shr1, uuids.shr2)]"}],"source_content_type":"text/x-python","patch_set":16,"id":"7f96bb07_d42c39ae","line":1234,"range":{"start_line":1234,"start_character":59,"end_line":1234,"end_character":65},"in_reply_to":"7f96bb07_94db1120","updated":"2018-01-19 16:24:55.000000000","message":"\"Ni!\"","commit_id":"f0d830d56d20c7f34372cd3c68d13a94bdf645a6"}]}
