monopyly 1.6.1__py3-none-any.whl → 1.6.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
monopyly/CHANGELOG.md CHANGED
@@ -244,4 +244,12 @@
244
244
  - Bump dependencies
245
245
 
246
246
 
247
+ ### 1.6.2
248
+
249
+ - Fix bug in the transaction tag tree template preventing new subtags in the same subtag subtree
250
+ - Refactor JavaScript used to manage the transaction tag tree
251
+ - Add specificity to the reconciliation tool when parsing payment columns (when otherwise unidentified, payment transactions are determined by the presence of the isolated word "payment" in the description field)
252
+ - Bump dependencies
253
+
254
+
247
255
  <a name="bottom" id="bottom"></a>
monopyly/_version.py CHANGED
@@ -1,16 +1,34 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
3
13
  TYPE_CHECKING = False
4
14
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
15
+ from typing import Tuple
16
+ from typing import Union
17
+
6
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
7
20
  else:
8
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
9
23
 
10
24
  version: str
11
25
  __version__: str
12
26
  __version_tuple__: VERSION_TUPLE
13
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '1.6.2'
32
+ __version_tuple__ = version_tuple = (1, 6, 2)
14
33
 
15
- __version__ = version = '1.6.1'
16
- __version_tuple__ = version_tuple = (1, 6, 1)
34
+ __commit_id__ = commit_id = None
@@ -213,7 +213,7 @@ class _TransactionActivityParser:
213
213
  def _infer_payment_row(row):
214
214
  # Infer whether the row constitutes a payment transaction
215
215
  contextual_info = [row[i].lower() for i in contextual_column_indices]
216
- return any("payment" in element for element in contextual_info)
216
+ return any("payment" in element.split() for element in contextual_info)
217
217
 
218
218
  payment_rows = list(filter(_infer_payment_row, raw_data))
219
219
  return self._extrapolate_payments_positive(payment_rows, raw_data)
@@ -13,111 +13,199 @@ import { executeAjaxRequest } from './modules/ajax.js';
13
13
 
14
14
 
15
15
  (function() {
16
-
17
- const endpointAddTag = ADD_TAG_ENDPOINT;
18
- const endpointRemoveTag = REMOVE_TAG_ENDPOINT;
19
- // Set animation parameters
20
- const slideTime = 300;
21
16
  // Identify the buttons
22
- const $buttonsAddTag = $('#transaction-tags .new-tag.button');
23
- const $buttonsDelete = $('#transaction-tags .action.button.delete');
24
-
25
- bindTagCreator($buttonsAddTag, $buttonsDelete);
26
-
27
- function bindTagCreator($buttonsAddTag, $buttonsDelete) {
28
- // Bind add tag buttons
29
- $buttonsAddTag.on('click', function() {
30
- const $container = $(this).closest('.tag-container');
31
- const $tags = $container.children('ul.tags');
32
- const $input = $tags.children('input.new-tag');
33
- // Reveal the input
34
- showInput($input);
35
- // Perform actions when focus is lost
36
- $input.on('blur', function() {
37
- if ($input.val()) {
38
- addNewTag($input, $container);
39
- } else {
40
- hideEmptyInput($input);
41
- }
42
- clearInput($input);
43
- });
44
- $input.on('keydown', function() {
45
- if (event.which == 27) {
46
- clearInput($input);
47
- hideEmptyInput($input);
48
- }
49
- });
17
+ const $createTagButtons = $('#transaction-tags .new-tag.button');
18
+ const $deleteTagButtons = $('#transaction-tags .action.button.delete');
19
+ bindTagButtonBehavior($createTagButtons, $deleteTagButtons);
20
+
21
+ })();
22
+
23
+
24
+ /**
25
+ * Create the tag manager.
26
+ *
27
+ * @param {JQuery} $createTagButtons - Buttons for adding subtags to one or
28
+ * more tags.
29
+ * @param {JQuery} $deleteTagButtons - Buttons for removing tags.
30
+ */
31
+ function bindTagButtonBehavior($createTagButtons, $deleteTagButtons) {
32
+ console.log('bind create buttons', $createTagButtons);
33
+ console.log('bind delete buttons', $deleteTagButtons);
34
+ $createTagButtons.on('click', function() {
35
+ const $button = $(this);
36
+ const behavior = new TagCreation($button);
37
+ behavior.perform();
38
+ });
39
+ $deleteTagButtons.on('click', function() {
40
+ const $button = $(this);
41
+ const behavior = new TagDeletion($button);
42
+ behavior.perform();
43
+ });
44
+ }
45
+
46
+
47
+ /**
48
+ * A class for managing transaction tags and the behavior of their buttons.
49
+ */
50
+ class TagButtonBehavior {
51
+
52
+ /**
53
+ * Create the tag manager.
54
+ *
55
+ * @param {JQuery} $button - A button belonging to a tag.
56
+ */
57
+ constructor($button) {
58
+ this.$container = $button.closest('.tag-container');
59
+ this.$tag = this.$container.children('.tag-area').find('.tag');
60
+ this.$tags = this.$container.children('ul.tags');
61
+ this.$input = this.$tags.children('input.new-tag');
62
+ // Set animation parameters
63
+ this.slideTime = 300;
64
+ }
65
+
66
+ }
67
+
68
+ /**
69
+ * A class for managing transaction tags creation behavior.
70
+ */
71
+ class TagCreation extends TagButtonBehavior {
72
+
73
+ #endpoint = ADD_TAG_ENDPOINT;
74
+
75
+ /**
76
+ * Create the tag creator.
77
+ *
78
+ * @param {JQuery} $button - A button belonging to a tag.
79
+ */
80
+ constructor($button) {
81
+ super($button);
82
+ self = this;
83
+ this.$input.on('blur', function() {
84
+ self.#dropInputFocus();
50
85
  });
51
- // Bind remove tag buttons
52
- $buttonsDelete.on('click', function() {
53
- if (confirmDelete()) {
54
- const $container = $(this).closest('.tag-container');
55
- const $tag = $container.find('.tag').first();
56
- // Remove the tag from the database
57
- removeTag($tag);
58
- // Remove the tag from the display
59
- const $tagContainer = $tag.closest('.tag-area');
60
- $tagContainer.slideUp(300, function() {
61
- $(this).remove()
62
- });
86
+ this.$input.on('keydown', function() {
87
+ if (event.key == 'Escape') {
88
+ self.#clearInput();
89
+ this.blur();
90
+ } else if (event.key == 'Enter') {
91
+ this.blur();
63
92
  }
64
93
  });
65
94
  }
66
95
 
67
- function addNewTag($input, $container) {
68
- // Add the input value to the database as a tag
69
- const parentTag = $container.children('.tag-area').find('.tag').text()
96
+ /**
97
+ * Perform the behavior.
98
+ */
99
+ perform() {
100
+ this.#showInput();
101
+ }
102
+
103
+ /**
104
+ * Show the input box to collect new tag information.
105
+ */
106
+ #showInput() {
107
+ console.log('showing input', this.$input);
108
+ self = this;
109
+ this.$input.slideDown(this.slideTime, function() {
110
+ self.$input.addClass('visible');
111
+ self.$input.focus();
112
+ console.log('focus', self.$input);
113
+ });
114
+ }
115
+
116
+ /**
117
+ * Perform a specific action when the input loses focus.
118
+ */
119
+ #dropInputFocus() {
120
+ if (this.$input.val()) {
121
+ this.#createTag();
122
+ this.#hideFilledInput();
123
+ } else {
124
+ this.#hideEmptyInput();
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Create the new tag in the database.
130
+ */
131
+ #createTag() {
70
132
  const rawData = {
71
- 'tag_name': $input.val(),
72
- 'parent': parentTag
133
+ 'tag_name': this.$input.val(),
134
+ 'parent': this.$tag.text()
73
135
  };
74
- // Execute the AJAX request and display update
75
- function addTag(response) {
76
- // Add the AJAX request response to the DOM before the input
77
- $input.before(response);
78
- hideFilledInput($input);
79
- // Bind the buttons for the newly added tag
80
- const $buttonAddTag = $input.prev().find('.new-tag.button');
81
- const $buttonRemoveTag = $input.prev().find('.action.button.delete');
82
- bindTagCreator($buttonAddTag, $buttonRemoveTag);
83
- }
84
- executeAjaxRequest(endpointAddTag, rawData, addTag);
136
+ // Execute the AJAX request and place the new tag
137
+ executeAjaxRequest(this.#endpoint, rawData, this.#placeNewTag.bind(this));
85
138
  }
86
139
 
87
- function showInput($input) {
88
- $input.slideDown(slideTime, function() {
89
- $input.addClass('visible');
90
- $input.focus();
91
- });
140
+ /**
141
+ * Add the new tag to the DOM before the input.
142
+ */
143
+ #placeNewTag(newTagHTML) {
144
+ const $newTag = $(newTagHTML);
145
+ this.$input.before($newTag);
146
+ // Bind behavior functionality to the newly created/placed tag buttons
147
+ bindTagButtonBehavior(
148
+ $newTag.find('.new-tag.button'), $newTag.find('.action.button.delete')
149
+ );
92
150
  }
93
151
 
94
- function hideFilledInput($input) {
95
- // Hide the input immediately
96
- $input.hide();
97
- $input.removeClass('visible');
152
+ /**
153
+ * Hide the input immediately.
154
+ */
155
+ #hideFilledInput() {
156
+ this.$input.hide();
157
+ this.$input.removeClass('visible');
158
+ this.#clearInput();
98
159
  }
99
160
 
100
- function hideEmptyInput($input) {
101
- // Hide the input gracefully
102
- $input.removeClass('visible');
103
- $input.slideUp(slideTime);
161
+ /**
162
+ * Hide the (empty) input gracefully.
163
+ */
164
+ #hideEmptyInput() {
165
+ this.$input.removeClass('visible');
166
+ this.$input.slideUp(this.slideTime);
167
+ console.log('hiding empty input', this.$input);
104
168
  }
105
169
 
106
- function clearInput($input) {
107
- // Clear the input
108
- $input.val('');
170
+ /**
171
+ * Clear the input.
172
+ */
173
+ #clearInput() {
174
+ this.$input.val('');
109
175
  }
110
176
 
111
- function confirmDelete() {
112
- return confirm('Are you sure you want to delete this tag?');
177
+ }
178
+
179
+
180
+ /**
181
+ * A class for managing transaction tags deletion behavior.
182
+ */
183
+ class TagDeletion extends TagButtonBehavior {
184
+
185
+ #endpoint = REMOVE_TAG_ENDPOINT;
186
+
187
+ /**
188
+ * Perform the behavior.
189
+ */
190
+ perform() {
191
+ if (this.#confirmDelete()) {
192
+ this.#removeTag();
193
+ }
113
194
  }
114
195
 
115
- function removeTag($tag) {
116
- // Get the name of the tag
117
- const tagName = $tag.html();
118
- const rawData = {'tag_name': tagName};
119
- // Execute the AJAX request
120
- executeAjaxRequest(endpointRemoveTag, rawData);
196
+ /**
197
+ * Remove the tag from the database.
198
+ */
199
+ #removeTag() {
200
+ const rawData = {'tag_name': this.$tag.html()};
201
+ // Execute the AJAX request to delete the tag
202
+ executeAjaxRequest(this.#endpoint, rawData);
203
+ // Remove the tag from the display
204
+ this.$container.slideUp(this.slideTime, function() {this.remove()});
121
205
  }
122
206
 
123
- })();
207
+ #confirmDelete() {
208
+ return confirm('Are you sure you want to delete this tag?');
209
+ }
210
+
211
+ }
@@ -114,6 +114,7 @@ class DiscrepancyHighlighter {
114
114
  this.removeHighlight($(activity), $matchingTransactionRow);
115
115
  }
116
116
  }
117
+
117
118
  }
118
119
 
119
120
 
@@ -18,7 +18,10 @@
18
18
  </li>
19
19
 
20
20
  {% if loop.last %}
21
- <input class="new-tag" type="text" />
21
+ {# Do not create a new input for a tag when its subtree is updated #}
22
+ {% if new_tree or loop.depth0 != 0 %}
23
+ <input class="new-tag" type="text" />
24
+ {% endif %}
22
25
  {% endif %}
23
26
  {% else %}
24
27
  <input class="new-tag" type="text" />
@@ -33,7 +33,9 @@
33
33
  <div id="tags-container" class="tag-container">
34
34
 
35
35
  <ul class="tags">
36
- {% include 'common/tag_tree.html' %}
36
+ {% with new_tree = True %}
37
+ {% include 'common/tag_tree.html' %}
38
+ {% endwith %}
37
39
  </ul>
38
40
 
39
41
  <img class="root new-tag button" src="{{ url_for('static', filename='img/icons/plus-thick.png') }}" />
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: monopyly
3
- Version: 1.6.1
3
+ Version: 1.6.2
4
4
  Summary: A homemade personal finance manager.
5
5
  Project-URL: Download, https://pypi.org/project/monopyly
6
6
  Project-URL: Homepage, http://monopyly.com
@@ -23,15 +23,15 @@ Classifier: Topic :: Office/Business :: Financial
23
23
  Classifier: Topic :: Office/Business :: Financial :: Accounting
24
24
  Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
25
25
  Requires-Python: >=3.10
26
- Requires-Dist: dry-foundation==1.6.0
26
+ Requires-Dist: dry-foundation==1.6.2
27
27
  Requires-Dist: flask-wtf==1.2.2
28
28
  Requires-Dist: flask==3.1.2
29
- Requires-Dist: gunicorn==23.0.0
30
- Requires-Dist: markdown==3.10
29
+ Requires-Dist: gunicorn==25.0.1
30
+ Requires-Dist: markdown==3.10.1
31
31
  Requires-Dist: nltk==3.9.2
32
32
  Requires-Dist: python-dateutil==2.9.0
33
- Requires-Dist: rich==14.2.0
34
- Requires-Dist: sqlalchemy==2.0.45
33
+ Requires-Dist: rich==14.3.2
34
+ Requires-Dist: sqlalchemy==2.0.46
35
35
  Description-Content-Type: text/markdown
36
36
 
37
37
  <div id="header">
@@ -1,7 +1,7 @@
1
- monopyly/CHANGELOG.md,sha256=Vnw4KMwtRmyZB90oD4eWHnhZgo3vG69hGpI280a5wjo,9702
1
+ monopyly/CHANGELOG.md,sha256=ageIgsoNIn4S7g64zhNHpp7LVkxX3XtXL1uQvcRnup8,10107
2
2
  monopyly/README.md,sha256=TBuObVJnYFYIiSvYUrcAsCtXCUz7D9ZpIHmhDzdPD9k,9045
3
3
  monopyly/__init__.py,sha256=fC8Z7V4uGJMPfA4MeC94EPA8Tq5qgUE33vLngYg2ut8,2046
4
- monopyly/_version.py,sha256=edFVVa8HpVPfLqL2y6CKtViSqJREfmXxInA-HCy-134,411
4
+ monopyly/_version.py,sha256=pmw-c24rp71yAW3-J78udTUvsycSgeO_KbRTgXpqRGA,704
5
5
  monopyly/auth/actions.py,sha256=uwXg0LVz3QVJxKkiI-YCJMT8OSjUK7R-aEy-XTM0Ghs,702
6
6
  monopyly/auth/blueprint.py,sha256=xA2vC10uu0ekFYPj0q0z2er1-v0G7juVI35RKNN0GQw,266
7
7
  monopyly/auth/routes.py,sha256=V9c0omnvLKOp-B5EL14waUF-4QrkoriFVKMjPaRph2w,3345
@@ -39,7 +39,7 @@ monopyly/credit/transactions/__init__.py,sha256=LnixNzeUV3jzZqxB2xdxBBRu94F1oZh9
39
39
  monopyly/credit/transactions/_transactions.py,sha256=4K1_QUYUMAikaYicXsm5GsojUL5UjA6x8Jjemf2rbwY,9621
40
40
  monopyly/credit/transactions/activity/__init__.py,sha256=hT1VaqPQQz0qxpgJyy46kSHbiBE5crg4pxW2Xvg_2KE,248
41
41
  monopyly/credit/transactions/activity/data.py,sha256=6ND7fz5L1aH2g_2drGz2Xf7maUaJ6RyItLdBeWXBIlA,5849
42
- monopyly/credit/transactions/activity/parser.py,sha256=bwJF-Z3kDJnUTQT5iAf88SNsITMnf3dwpA3hE_fKC9M,11581
42
+ monopyly/credit/transactions/activity/parser.py,sha256=7NWmEyTOxeKIinBKZLhtbUKHnykUhhh_rPxxigSw3XQ,11589
43
43
  monopyly/credit/transactions/activity/reconciliation.py,sha256=1CIeaVBhJ-2wufyk7OBo40X6Ql627_I-rZ8axOFeFpM,19449
44
44
  monopyly/database/__init__.py,sha256=GMbtb8FQM_gdvClzVLue7g1dkQIOfc0YnA_vRK-9edI,1582
45
45
  monopyly/database/models.py,sha256=9QCZZNXfe0JWtX33Jtk94m0cEBd-Lxk1SUWeawWgbDw,14667
@@ -110,7 +110,7 @@ monopyly/static/img/icons/x-thick.png,sha256=Fs9bVUFDVUCjWZQbicFGYZMcsUwerxf6KlX
110
110
  monopyly/static/js/add-subtransaction.js,sha256=BoLvpahd__YHOwodqJXg10OCY7CJJX0k7yJpYAVW9iw,1465
111
111
  monopyly/static/js/add-transfer.js,sha256=3ve8v-7g-LIVi9Mij68CGCLnIesjhR0vtmsnkVbtNzE,1496
112
112
  monopyly/static/js/autocomplete-transaction.js,sha256=pZQ7v04WEHcJ7riPparhdF70W3ZDSz9Z0j0N_OVgZ9k,2753
113
- monopyly/static/js/bind-tag-actions.js,sha256=ev0WMvkatJFlvvTyMuGAcstYJ2cziOKXZzXLmhDdqr0,3776
113
+ monopyly/static/js/bind-tag-actions.js,sha256=WK0jNuxUG2sVp4VOi4JPANfT1SyS2PsPc99LtX2BfFI,5075
114
114
  monopyly/static/js/create-balance-chart.js,sha256=LX4mbEPf1b6QayEkAj1L1b-zPE4Pxr84V4rQ_Es2OqA,2452
115
115
  monopyly/static/js/create-category-chart.js,sha256=SfWQrs4c0QT4whr7KvrvWVdyYfeGu-ENscpoPjEYcqc,519
116
116
  monopyly/static/js/define-filter.js,sha256=nz64sha6G9QXOyVEqxd_xYK0F_fXxzXxIHiQfpvUo7A,1133
@@ -122,7 +122,7 @@ monopyly/static/js/expand-bank.js,sha256=vb1DTCOidQgQzX0FC-7Zwk-Poc-e38mpORgWG_L
122
122
  monopyly/static/js/expand-transaction.js,sha256=wfql6MjA6LP1bSob4MUUREkHLhAFbcbH0pQAdbouObE,984
123
123
  monopyly/static/js/flip-card.js,sha256=4a65JFO7kf4qzZ-8wvWiiO_BwZpiWO2cHHzZugXRoAQ,720
124
124
  monopyly/static/js/hide-homepage-block.js,sha256=Yw3m5sc5dO6pDh2VUzJu1re4NXZcuSLSMs6Acou_rHo,495
125
- monopyly/static/js/highlight-discrepant-transactions.js,sha256=jnbs6HSh4Byq46xJuDNseGHOnf_KuVH-wYRr_dsj_Y8,4188
125
+ monopyly/static/js/highlight-discrepant-transactions.js,sha256=lQg7S6BqjWiMlMvqaiEDt6zlSvObQaA4G5SGh2CshYw,4189
126
126
  monopyly/static/js/infer-card.js,sha256=WIDXWhfF4gXdlRCo2OA0IpSsszxDTkV7ZSb6Qo7pheA,1790
127
127
  monopyly/static/js/infer-statement.js,sha256=ufcYJ2z6halVXpiZHviI_4JN48jOBAM4NbSDtWH9BoU,1896
128
128
  monopyly/static/js/load-more-transactions.js,sha256=PhhYVW3mDQo_hYz5vhbLK-BtB1k6NluGAxPFY44rqf0,671
@@ -171,8 +171,8 @@ monopyly/templates/banking/transactions_table/table.html,sha256=1zxNJOOXmc6RkMkB
171
171
  monopyly/templates/banking/transactions_table/transaction_field_titles.html,sha256=WvjcRAByg1xSHqfNEkcJYB1eFnNfm4-qfHZben_YApI,600
172
172
  monopyly/templates/banking/transactions_table/transactions.html,sha256=UuBCMXwDqKlHdxUy07O_hVQjJ8V5nhM4O5trfF4zJYg,394
173
173
  monopyly/templates/common/form_page.html,sha256=Sx2Y6dhNsjkDQBaepTBPBvVeIe7N730llhgbcAQOrCk,107
174
- monopyly/templates/common/tag_tree.html,sha256=sCmyVNGJBaBtfuvl9PepYhfV9HPYn5aL79reGhpl6H4,644
175
- monopyly/templates/common/tags_page.html,sha256=hBG1777lXotxAljoWGDZ15gVa1o_I9vyZN9Po5QePx8,803
174
+ monopyly/templates/common/tag_tree.html,sha256=STdQI84sehxWIKjkr6bt6kIYzM3KhKd6f3658j_GyKM,778
175
+ monopyly/templates/common/tags_page.html,sha256=-L8LyKpzGJE-nOOQrAa_PlOfM8ig0QPg7ei7XWijHa4,862
176
176
  monopyly/templates/common/transaction_form/subform.html,sha256=BjwJA0-ZOeBhrLdZAkddl5F5ElMN2MSykD2hZu8PNEA,370
177
177
  monopyly/templates/common/transaction_form/subtransaction_subform.html,sha256=WBCGnkKNGC0x7KSJeKA1g8Xbm5sO9N3jY5Nt2WiWpUk,827
178
178
  monopyly/templates/common/transaction_form/transaction_form_page.html,sha256=gZ7uWIgaVo67m4F9cgXnrjwQ3_nEk_F2E1jT_C1yy8s,294
@@ -227,9 +227,9 @@ monopyly/templates/credit/transactions_table/expanded_row_content.html,sha256=Ui
227
227
  monopyly/templates/credit/transactions_table/table.html,sha256=S2xjvUyWnsKDIux2kt_sV2DRzKov-TfPuACBYrh9HDw,224
228
228
  monopyly/templates/credit/transactions_table/transaction_field_titles.html,sha256=km-3YEDJaygwcKV-rwYnrE7xF8u4Z7jCBsk0Ia-LO-M,758
229
229
  monopyly/templates/credit/transactions_table/transactions.html,sha256=83zHx5Oa1KH1bMrKk2mlBmMiYKwa1t5lBq_JSAgslgc,390
230
- monopyly-1.6.1.dist-info/METADATA,sha256=9Pb68wIyAxWEnIN37V6c4dH08nmTyv03QtL-fNGM4Y8,10969
231
- monopyly-1.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
232
- monopyly-1.6.1.dist-info/entry_points.txt,sha256=VMqyRA0VRpTc0-5Z-VB-wX1AuyezoKKPhcf4bIUKz9g,110
233
- monopyly-1.6.1.dist-info/licenses/COPYING,sha256=5X8cMguM-HmKfS_4Om-eBqM6A1hfbgZf6pfx2G24QFI,35150
234
- monopyly-1.6.1.dist-info/licenses/LICENSE,sha256=94rIicMccmTPhqXiRLV9JsU8P2ocMuEUUtUpp6LPKiE,253
235
- monopyly-1.6.1.dist-info/RECORD,,
230
+ monopyly-1.6.2.dist-info/METADATA,sha256=6_yb0zSwwJlc832fqs8fjfUykRdC0w2rDCfp8UO1qXE,10971
231
+ monopyly-1.6.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
232
+ monopyly-1.6.2.dist-info/entry_points.txt,sha256=VMqyRA0VRpTc0-5Z-VB-wX1AuyezoKKPhcf4bIUKz9g,110
233
+ monopyly-1.6.2.dist-info/licenses/COPYING,sha256=5X8cMguM-HmKfS_4Om-eBqM6A1hfbgZf6pfx2G24QFI,35150
234
+ monopyly-1.6.2.dist-info/licenses/LICENSE,sha256=94rIicMccmTPhqXiRLV9JsU8P2ocMuEUUtUpp6LPKiE,253
235
+ monopyly-1.6.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any