From 6831f90ddf0ed894009371e8da31c6526f0aec35 Mon Sep 17 00:00:00 2001 From: VinzentRisch Date: Tue, 12 May 2026 13:47:26 +0200 Subject: [PATCH 1/3] moved importance formats --- q2_types/feature_data/__init__.py | 9 +- .../feature_data/_deferred_setup/__init__.py | 15 +- .../_deferred_setup/_transformers.py | 36 +- q2_types/feature_data/_formats.py | 56 + q2_types/feature_data/_types.py | 2 + .../tests/data/chardonnay.map.txt | 22 + .../feature_data/tests/data/empty_file.txt | 1 + q2_types/feature_data/tests/data/garbage.txt | 6 + .../feature_data/tests/data/importance.tsv | 1057 +++++++++++++++++ q2_types/feature_data/tests/test_formats.py | 37 +- .../feature_data/tests/test_transformer.py | 45 +- q2_types/feature_data/tests/test_type.py | 10 +- 12 files changed, 1286 insertions(+), 10 deletions(-) create mode 100644 q2_types/feature_data/tests/data/chardonnay.map.txt create mode 100644 q2_types/feature_data/tests/data/empty_file.txt create mode 100644 q2_types/feature_data/tests/data/garbage.txt create mode 100644 q2_types/feature_data/tests/data/importance.tsv diff --git a/q2_types/feature_data/__init__.py b/q2_types/feature_data/__init__.py index d0b70179..b7b4e7b3 100644 --- a/q2_types/feature_data/__init__.py +++ b/q2_types/feature_data/__init__.py @@ -27,11 +27,13 @@ MixedCaseAlignedRNAFASTAFormat, MixedCaseAlignedRNASequencesDirectoryFormat, SequenceCharacteristicsDirectoryFormat, - SequenceCharacteristicsFormat) + SequenceCharacteristicsFormat, ImportanceFormat, + ImportanceDirectoryFormat) from ._types import ( FeatureData, Taxonomy, Sequence, PairedEndSequence, AlignedSequence, Differential, ProteinSequence, AlignedProteinSequence, RNASequence, - AlignedRNASequence, PairedEndRNASequence, BLAST6, SequenceCharacteristics) + AlignedRNASequence, PairedEndRNASequence, BLAST6, + SequenceCharacteristics, Importance) from ._objects import ( NucleicAcidIterator, DNAIterator, PairedDNAIterator, AlignedDNAIterator, ProteinIterator, AlignedProteinIterator, RNAIterator, AlignedRNAIterator, @@ -68,5 +70,6 @@ 'MixedCaseProteinSequencesDirectoryFormat', 'MixedCaseAlignedProteinSequencesDirectoryFormat', 'SequenceCharacteristics', 'SequenceCharacteristicsDirectoryFormat', - 'SequenceCharacteristicsFormat', + 'SequenceCharacteristicsFormat', 'Importance', 'ImportanceFormat', + 'ImportanceDirectoryFormat', ] diff --git a/q2_types/feature_data/_deferred_setup/__init__.py b/q2_types/feature_data/_deferred_setup/__init__.py index 6d20c0c0..d2d781ca 100644 --- a/q2_types/feature_data/_deferred_setup/__init__.py +++ b/q2_types/feature_data/_deferred_setup/__init__.py @@ -30,9 +30,11 @@ MixedCaseAlignedRNASequencesDirectoryFormat, SequenceCharacteristicsDirectoryFormat, SequenceCharacteristicsFormat, + ImportanceFormat, ImportanceDirectoryFormat, FeatureData, Taxonomy, Sequence, PairedEndSequence, AlignedSequence, Differential, ProteinSequence, AlignedProteinSequence, RNASequence, - AlignedRNASequence, PairedEndRNASequence, BLAST6, SequenceCharacteristics) + AlignedRNASequence, PairedEndRNASequence, BLAST6, + SequenceCharacteristics, Importance) from ...plugin_setup import plugin @@ -57,7 +59,8 @@ MixedCaseAlignedDNASequencesDirectoryFormat, MixedCaseAlignedRNAFASTAFormat, MixedCaseAlignedRNASequencesDirectoryFormat, SequenceCharacteristicsFormat, - SequenceCharacteristicsDirectoryFormat + SequenceCharacteristicsDirectoryFormat, ImportanceFormat, + ImportanceDirectoryFormat ) plugin.register_semantic_types(FeatureData, Taxonomy, Sequence, @@ -65,7 +68,7 @@ Differential, ProteinSequence, AlignedProteinSequence, RNASequence, AlignedRNASequence, PairedEndRNASequence, - BLAST6, SequenceCharacteristics) + BLAST6, SequenceCharacteristics, Importance) plugin.register_artifact_class( FeatureData[Taxonomy], @@ -144,5 +147,11 @@ description=("Characteristics of sequences (e.g., the length of a gene " "in basepairs).")) +plugin.register_artifact_class( + FeatureData[Importance], + directory_format=ImportanceDirectoryFormat, + description=("Numeric importance scores associated with a set of feature " + "identifiers.")) + importlib.import_module('._transformers', __name__) importlib.import_module('._validators', __name__) diff --git a/q2_types/feature_data/_deferred_setup/_transformers.py b/q2_types/feature_data/_deferred_setup/_transformers.py index 10e45bf8..ba7d52a7 100644 --- a/q2_types/feature_data/_deferred_setup/_transformers.py +++ b/q2_types/feature_data/_deferred_setup/_transformers.py @@ -11,6 +11,7 @@ import pandas as pd import biom import skbio +import numpy as np import qiime2 @@ -25,7 +26,7 @@ AlignedRNAFASTAFormat, PairedRNASequencesDirectoryFormat, BLAST6Format, MixedCaseDNAFASTAFormat, MixedCaseRNAFASTAFormat, MixedCaseAlignedDNAFASTAFormat, MixedCaseAlignedRNAFASTAFormat, - SequenceCharacteristicsFormat, + SequenceCharacteristicsFormat, ImportanceFormat, DNAIterator, PairedDNAIterator, AlignedDNAIterator, ProteinIterator, AlignedProteinIterator, RNAIterator, AlignedRNAIterator, PairedRNAIterator @@ -110,6 +111,14 @@ def _has_expected_header(df): return df.iloc[0].tolist()[:2] == TSVTaxonomyFormat.HEADER +def _read_dataframe(fh): + """Read a TSV file into a dataframe with the first column as the index.""" + df = pd.read_csv(fh, sep='\t', header=0, dtype='str') + df.set_index(df.columns[0], drop=True, append=False, inplace=True) + df.index.name = 'id' + return df + + def _dataframe_to_tsv_taxonomy_format(df): if len(df.index) < 1: raise ValueError("Taxonomy format requires at least one row of data.") @@ -242,6 +251,31 @@ def _29(ff: TSVTaxonomyFormat) -> qiime2.Metadata: return qiime2.Metadata(df) +@plugin.register_transformer +def _dataframe_to_importance_format(data: pd.DataFrame) -> ImportanceFormat: + """Write feature importance values from a dataframe to TSV format.""" + ff = ImportanceFormat() + with ff.open() as fh: + data.to_csv(fh, sep='\t', header=True, na_rep=np.nan) + return ff + + +@plugin.register_transformer +def _importance_format_to_dataframe(ff: ImportanceFormat) -> pd.DataFrame: + """Read feature importance TSV values into a numeric dataframe.""" + with ff.open() as fh: + return _read_dataframe(fh).apply( + lambda x: pd.to_numeric(x, errors='raise')) + + +@plugin.register_transformer +def _importance_format_to_metadata(ff: ImportanceFormat) -> qiime2.Metadata: + """Read feature importance TSV values into QIIME 2 metadata.""" + with ff.open() as fh: + return qiime2.Metadata(_read_dataframe(fh).apply( + lambda x: pd.to_numeric(x, errors='raise'))) + + @plugin.register_transformer def _24(df: pd.DataFrame) -> TSVTaxonomyFormat: return _dataframe_to_tsv_taxonomy_format(df) diff --git a/q2_types/feature_data/_formats.py b/q2_types/feature_data/_formats.py index eceb31bc..71d5a5f5 100644 --- a/q2_types/feature_data/_formats.py +++ b/q2_types/feature_data/_formats.py @@ -505,3 +505,59 @@ def validate(self, n_records=None): "SequenceCharacteristicsDirectoryFormat", "sequence_characteristics.tsv", SequenceCharacteristicsFormat ) + + +def _validate_file_not_empty(has_data): + """Validate that a delimited text format contains at least one record.""" + if not has_data: + raise ValidationError( + "There must be at least one data record present in the " + "file in addition to the header line.") + + +class _MultiColumnNumericFormat(model.TextFileFormat): + def _validate(self, n_records=None): + """Validate rows with an identifier followed by numeric values.""" + with self.open() as fh: + # The header is intentionally flexible because column names and + # counts can vary by estimator. + fh.readline() + + has_data = False + for line_number, line in enumerate(fh, start=2): + # Strip each cell rather than the full line so empty cells are + # preserved and fail numeric validation. + cells = [c.strip() for c in line.split('\t')] + if len(cells) < 2: + raise ValidationError( + "Expected data record to be TSV with two or more " + "fields. Detected {0} fields at line {1}:\n\n{2!r}" + .format(len(cells), line_number, cells)) + + try: + [float(c) for c in cells[1:]] + except ValueError: + raise ValidationError( + "Columns must contain only numeric values. " + "A non-numeric value ({0!r}) was detected at line " + "{1}.".format(cells[1], line_number)) + + has_data = True + if n_records is not None and (line_number - 1) >= n_records: + break + + _validate_file_not_empty(has_data) + + def _validate_(self, level): + """Validate this format using QIIME 2's min or max validation level.""" + record_count_map = {'min': 5, 'max': None} + self._validate(record_count_map[level]) + + +class ImportanceFormat(_MultiColumnNumericFormat): + pass + + +ImportanceDirectoryFormat = model.SingleFileDirectoryFormat( + 'ImportanceDirectoryFormat', 'importance.tsv', + ImportanceFormat) diff --git a/q2_types/feature_data/_types.py b/q2_types/feature_data/_types.py index 80a69212..8c3e6961 100644 --- a/q2_types/feature_data/_types.py +++ b/q2_types/feature_data/_types.py @@ -42,3 +42,5 @@ SequenceCharacteristics = SemanticType('SequenceCharacteristics', variant_of=FeatureData.field['type']) + +Importance = SemanticType('Importance', variant_of=FeatureData.field['type']) diff --git a/q2_types/feature_data/tests/data/chardonnay.map.txt b/q2_types/feature_data/tests/data/chardonnay.map.txt new file mode 100644 index 00000000..5feab16e --- /dev/null +++ b/q2_types/feature_data/tests/data/chardonnay.map.txt @@ -0,0 +1,22 @@ +#SampleID Vineyard Region latitude longitude +v4.3.618 1 Coombsville 38.306 -122.228 +v4.3.642 1 Coombsville 38.306 -122.228 +v4.3.687 1 Coombsville 38.306 -122.228 +v4.3.412 2 Coombsville 38.306 -122.227 +v4.3.637 2 Coombsville 38.306 -122.227 +v4.3.643 2 Coombsville 38.306 -122.227 +v4.3.350 3 Carneros 38.212 -122.213 +v4.3.353 3 Carneros 38.212 -122.213 +v4.3.355 3 Carneros 38.212 -122.213 +v4.3.415 8 Oakville 38.418 -122.412 +v4.3.416 8 Oakville 38.418 -122.412 +v4.3.417 8 Oakville 38.418 -122.412 +v4.3.692 9 Carneros 38.285 -122.322 +v4.3.693 9 Carneros 38.285 -122.322 +v4.3.694 9 Carneros 38.285 -122.322 +v4.3.600 10 Russian_River 38.424 -122.895 +v4.3.657 10 Russian_River 38.424 -122.895 +v4.3.659 10 Russian_River 38.424 -122.895 +v4.3.587 11 Russian_River 38.455 -122.862 +v4.3.588 11 Russian_River 38.455 -122.862 +v4.3.589 11 Russian_River 38.455 -122.862 diff --git a/q2_types/feature_data/tests/data/empty_file.txt b/q2_types/feature_data/tests/data/empty_file.txt new file mode 100644 index 00000000..302fb4ec --- /dev/null +++ b/q2_types/feature_data/tests/data/empty_file.txt @@ -0,0 +1 @@ +#SampleID Garbage \ No newline at end of file diff --git a/q2_types/feature_data/tests/data/garbage.txt b/q2_types/feature_data/tests/data/garbage.txt new file mode 100644 index 00000000..fa43564d --- /dev/null +++ b/q2_types/feature_data/tests/data/garbage.txt @@ -0,0 +1,6 @@ +#SampleID +one +two +buckle +my +shoe diff --git a/q2_types/feature_data/tests/data/importance.tsv b/q2_types/feature_data/tests/data/importance.tsv new file mode 100644 index 00000000..5281c005 --- /dev/null +++ b/q2_types/feature_data/tests/data/importance.tsv @@ -0,0 +1,1057 @@ + importance +74ec9fe6ffab4ecff6d5def74298a825 0.44469828320835586 +c82032c40c98975f71892e4be561c87a 0.07760118417569697 +79280cea51a6fe8a3432b2f266dd34db 0.06570251750505914 +f7686a74ca2d3729eb66305e8a26309b 0.061718558716901406 +4d04d759f5a6615dac43060726239891 0.028086160290024458 +04195686f2b70585790ec75320de0d6f 0.02610253907515516 +ea3433f2c148c6fae4cc2e9ae197f5b8 0.025273854068462408 +8ce931b0c99ad5ed648c25483c1ca492 0.02029344879308132 +370829fece3190f1a8efccf50b7d0921 0.017580266040786597 +8720f9ecd2331ce68e2896df1bf2d977 0.017034058634807364 +e2c3ff4f647112723741aa72087f1bfa 0.016776104364241963 +a650f349bbdffb95b3624519d1ba72b8 0.013283768202156983 +2ae8a432208b85a14e86eb821c86ce2b 0.010909411591413926 +cae14798faeabb8e1b8840e712839921 0.010685797620545407 +5d62137a2d05df0be8d6b7e163a3ef08 0.010020841856182077 +596c1c5efe777a8d8aafbca19fe37e1d 0.009651091043216155 +48d9883fd871b82d9bbc89cb0447be8c 0.008982921060244274 +8937656c16c20701c107e715bad86732 0.008214293017642144 +c1b636001e0773f9cca8096d70e8b5de 0.006950690004962161 +77ad88eed91eef009bf64f101c96baa6 0.00665688537920522 +5ee1da6b8eb2e1149af74254c8c07736 0.006601399203235563 +eea6b86c0c75e740670ccc50613b1b23 0.006479475209726379 +3128e057b1d4f320961e4da677724613 0.005645919539722557 +be17b29b03ed02bed133932284568d16 0.004989948679963887 +a66dd8d31584930c2b0f811f572dddcf 0.0048124059283415396 +ea2b0e4a93c24c6c3661cbe347f93b74 0.004810025669591898 +07bfddb8e62098a85afc8fd68ebc308c 0.004140136921392747 +4b548f1f6fc22f32237396b7d4ffee6e 0.0038498233115332368 +d75b7080930e7a77ef3de8c6154895b9 0.0033346270477890225 +9099a7f671b923c7b07c12508f17270a 0.0033074689234597054 +0c70bdd5631104dd3d818561c9166f6c 0.00324330648569082 +47ad35356a9bfec68416d32e4f039021 0.0022404365031278746 +ee084a976fc8028a3fdc50c9555b2a08 0.0022298514655499533 +c162a4f3943238810eba8a25f0563cca 0.0021855014795936893 +c4f9ef34bd2919511069f409c25de6f1 0.002166099280415516 +94b000e59b7ac160b0416c9ab45ff0bf 0.0021550588496877933 +148c7eb0139bbc1b8c87dd31464742e4 0.0021365496990399203 +0cc2420a6a4698f8bf664d50b17d26b4 0.0021008032637668066 +d56536a97c18adccf18eb08958d93345 0.002021901283310038 +25def15fb42bed6855ede4893d27a21d 0.0020017444379080624 +c18afe570abfe82d2f746ecc6e291bab 0.001972967397047078 +a9387e76477da8688775569cf540191b 0.0018074625819242743 +6c83fec6e8d03fad51eabc871853c991 0.0017508229418444995 +8a261f382a739bbc5f9494b2c64c2744 0.0017232389271744585 +3e93fd55a231bb99b67a666bad8446a8 0.0015688191643981873 +d996e8d86e152c0a3c5852a2d8c4c52c 0.0014605617822782211 +bae0d49b5eb22b0dfaecbcbf39a52265 0.0014360435703925205 +74923f4bbde849e27fc4eda25d757e2a 0.0013332140948707867 +aebf2a74a3aa9e5876c479b1db88985f 0.0013164588291310188 +8e6e925baa81466352ff781a289e188d 0.001305557690975839 +d1b7d3ea1db807e9352522d92e403246 0.0012130802121359668 +90c2b51afe404951ec89bd52c7ae1f58 0.0012032892974370578 +9d4e16844252e2dfbaf80a4a6fc4d55d 0.0011721920358687048 +dafe809740d0545dc25c6939a84a1820 0.0010598552486115634 +df6a1dbd34417b068878c043bd7a6bcc 0.0010397960283382362 +4311a44a7d56ce4086afad3e75bedd6e 0.000943488403386402 +61795ee8e60f4a0f66080ab812573fb8 0.0008962861766715468 +a24dae6b87885a55d81df1ea6d1abaf5 0.0008721132528209371 +7667b07b46f3d78c76f13781337cd218 0.0007996665724943059 +3f1ed51e954b35a8108c12dd882b696b 0.0007869337305015549 +29bb5fa7f45e47bbabab8cc1b1b3d18e 0.0007471894961390048 +ad52a0f6646c574417ce0b13b84acfa9 0.0007379284165598606 +59b17c1cd2e1fa86064869f5bdbea8c4 0.0006810720140934703 +2fee36ac3b841b7c63b377f87cd57634 0.0006184580387951528 +ad7bc2bb6e1ec90a9bc3c8949bce80d6 0.00061784619277928 +d9b76ee51ff2b6961430bf352cc578f2 0.0006143795451714199 +877f27b47c85f6b2d3cf8a6aa86def40 0.000579939824065776 +1986030e3c5cd5df6d869054bc96e536 0.0005571839389159251 +e91f1c5b67ffecb5ca3ca3b393a50f00 0.0005367673621172981 +f83bc32e60e9c7bddf53a52937cc7ab6 0.0005354610613922348 +059c8f8bb468064b134ea6d3661761ea 0.0005301713126190168 +1243750138937650754b619370565800 0.0004890847692921625 +9ac5fec396208e598ab2e2d26985d0df 0.0004198438160258734 +d43642bb228b6bd084483d2e5b48c3ca 0.0004196113785368746 +147e08753c0c32354e69746256220ca8 0.00040094057274993046 +b9024a1f377b62508864cfea59b16a31 0.0003872820865898205 +3b092a59cd0e2d57483420cc994ec49c 0.0003753321093973754 +5e4405e37412f415c47c112a0cbc487a 0.0003630769561779562 +6c7fa77831ae630967a6fbfc8ee47901 0.0003620100294304884 +e7e74960c5ee1984f2e60f99081a368b 0.00035092992275626917 +b75d05e361f46e33b39ef21d05334744 0.0003429082395799726 +0d357d84911ef4a089c6ae3c6deb39b9 0.000321837484901028 +bca0b81a0b8d59e90c25a323c2f62f31 0.00032148902937567593 +ece1af985b63ebccd2833e9b5f0432e3 0.00031620424482054 +dff37b3a4d27b9220b9af1459162a48b 0.00031297752477390487 +78eecb7cd2176d3a2ed21ce8154ba1b3 0.0002897361736257693 +0021d135d4ac12982cc8abdf2b38e23f 0.00028687561969616186 +1ad289cd8f44e109fd95de0382c5b252 0.0002614751742022106 +b7fe67097e773cb42109cefc45628173 0.0002592864600918602 +82585d0d14cc315f9da0257c3a2875a4 0.0002544671856237352 +ac5402de1ddf427ab8d2b0a8a0a44f19 0.00020068725358655715 +c123ec846a7e3837d1247386a6060ad9 0.0001854681628289824 +2a13ecb6c618ddf8154298c69336dd8e 0.0001810963201993466 +7ce470a3f833253f6d667fa6830abe07 0.0001808688941675811 +588a23811b3e98af68f4f0fb24a0daa8 0.00017377450975371653 +447b9d6a5c17543a456c597e65b37139 0.00016726377442023347 +82c890da8759fa9477cd991a1f214b3c 0.00016594333445879174 +ea3af29626a95b6c7b89d631bf1a739c 0.00015564865018761215 +ed5952d1e022067b212146b9b3bc6812 0.0001490369165590016 +010f0ac2691bc0be12d0633d4b5d2cc4 0.0001427705331111527 +a590ab40dc8a6b5cbffa347e8e32e63d 0.00013477008207658987 +86deb5cf8d6f29d383136e0d09863b69 0.00013383226709210312 +d0f1985c2b919dcbd0bf4664c844a900 0.00012362381132402674 +124c75409b4ecd0bf23a84e28593567d 0.0001205792627783874 +a186bb74dfce512f83043f7b366c60c4 0.00011304305885473818 +62cb0ed0f2cba6fd1ab5d2a374c15bb1 0.00010757469651420703 +1aab913302590e21a7be28b1494a3320 0.00010706581367368249 +c8d7e00fbcfbd34e1c85a8040155ecb3 0.00010371458403674598 +fcc915000295812eecfa7245a74346e9 0.00010216080211401838 +5b6a30b5a900999d91448bc79c5e14d4 9.716320058704939e-05 +c5b4c6b372dbc13b6a7f2d466fc7335f 9.489811410385969e-05 +c04879d53b5b084096c5f2bdcc38d55a 9.334312563306969e-05 +de08a70ee5e3336d2c494d20206e650e 9.043444708379022e-05 +7281d8476d29dd24b3e674ce9cd9e3b0 8.785266881993596e-05 +9b2d42844c99887e67257a377f7b193b 8.74479052197794e-05 +4e1758e81adcb1107024ee52c0113a6f 8.098909104258687e-05 +0189d0173c07f11e7586ff20eb33f5ba 7.858913280228686e-05 +539ca948741b9a713eb781d4281b23fc 7.821268709252524e-05 +b3fef1e26b7b6ac20847ede4da68547a 7.701147547233651e-05 +ee02d6d3506da57909d5e603709a295f 7.427114488130107e-05 +b45c9784d674879d68d54362419a1d70 7.171890492404162e-05 +105d5959bed2c9399522aba4291031fd 6.810720140934897e-05 +3baa56d5f42b81f2817aa34412e36439 6.782583531284291e-05 +bc4177a5fd330e9c23138dac2d6c69e0 6.723418532137901e-05 +de61860db8d93da85692dffb5cf32ab9 6.60098361191445e-05 +6a66cd42df39f678f4bb2f3e840b011e 6.028963138919508e-05 +b7a041d2927c03859714fcdd60b9dc7e 5.378917869303054e-05 +04c8be5a3a6ba2d70446812e99318905 5.134352337296379e-05 +328d5b7cdad033d7b3ed419b720ba2d3 5.108040105701027e-05 +4c731267e801c2afe253b5cbb58bdd24 5.0241359490998746e-05 +b835514e2678e3c7ba13bfe0a0d79bb4 5.0241359490996184e-05 +2480f3aa1e7784b461d9b5b83a6bfc81 4.604372766711962e-05 +237135dc8b20f922cabee934f7d410a1 4.460367317873236e-05 +5cf5895a231b0a52d5859c74c74aada7 4.139914348861156e-05 +764bb70efe70ec930379806d178319cb 4.0341884019772904e-05 +40c85a458df8d5a935122ba778d4f334 3.7337250253227875e-05 +34c133377349d1b57072aaab4f781fd9 3.580564835875417e-05 +2364e23d05750415070f8df3ccb0c95b 3.568860455789974e-05 +ede423f2b32cfcbc0815db2435994947 3.3617092660689695e-05 +424613c7d3d2daf5c715d1356a972381 3.3188666891759055e-05 +59196a586276f0be745d0e334fc071c6 3.3188666891756934e-05 +954f244280781f0339631a6eee679e1e 3.0255383394620722e-05 +30fc8af207d17abc37394fbf3d1793f7 2.5212819495517268e-05 +b8315874f4341a59e8e3ed317406ab09 2.4891500168818583e-05 +b0574dba26050e54cf5efd672c2f58ee 2.4453423469918827e-05 +52b25decd37eb58a3bd46167d1c46354 2.128350044041883e-05 +68c83aae1babce28612ba404b1096cc1 2.1077191628870952e-05 +c5adecb440a6bac201ab573ccd2d6dda 2.098349859690685e-05 +ff5c02a6c8a80d8898f37b7dc71f4c10 1.897042303767303e-05 +5a0df24ab3d9c2d78a043cd477a54b4f 1.8243000377503335e-05 +df1bc3956db29b2cded9d3925999f6e7 1.6809118341572044e-05 +4bdc8766a80671911353b96f2d702ffc 1.344683706427589e-05 +22b9160be22106587cc68893686c44c1 1.3446837064275873e-05 +f8000a94d405169f38df61e7cf1cd286 1.3427118134532813e-05 +df3f8cdac76c62baa98469c33b82d8df 1.2770100264252568e-05 +1ba09da532a0f9985b3caf72a47b42e3 1.2376844272339594e-05 +cca22a273fa140d50cc3cdce9f539f73 1.1787784859310052e-05 +0c17cef318a9e1c8895c0961c5ed2193 1.0706581367368972e-05 +3ee072a59b45057a86369a7c80ad90e4 1.0371458403674174e-05 +ed1c3370c86ae00e0062a3498ef06cf4 1.0085471004943226e-05 +1a389bf765c8ff0f92600f684fbe7ad7 8.9648631155042e-06 +276c5b1d00e091a197a9ed8753beebc7 8.951412089688543e-06 +ebd14a21e990e0266b2b985be4cb3c44 6.6916133546051555e-06 +0064e2a432a2756eabdb6288a368eaef 0.0 +009a4919860d6d1fddec5d3771d37351 0.0 +00bb7a84ce1fa6f7411597672ff1b09d 0.0 +00ecdfa98a302087bca221884a535f55 0.0 +01241d7b0a1f219f5a68bf78b9f3b294 0.0 +0209f9868a22059c659df474a746d8f4 0.0 +021899b8a2f4157d54475a024303ad5c 0.0 +0233fed56365db96e625e92c4dfb9cd0 0.0 +026598f1d03fa900cc03cf9a32dc17d8 0.0 +03569e3fd843f501355f7853b0ec9361 0.0 +03fdbec0c9b63a05ae79f92c6d3a4cfc 0.0 +041d6dba3af0b8c9c1a422ed942ee16c 0.0 +04cf55ca51883bf19bca35e8ab225def 0.0 +052ad6076dacb9cca0dbb762a466404c 0.0 +053c4d5b8717b60387f777efae437b40 0.0 +0540bf08e9a1eb8691a9b1be2afe577a 0.0 +0550a92d2e1e15136084e85881efbdea 0.0 +05736395b184324b94bf557984b36834 0.0 +0584be58049c7828c032b2171aa00a4b 0.0 +0590c29091ff2b3affd966ed57773407 0.0 +05992d2befeb4bd87b626698a9694ccc 0.0 +0615dc8ff9d74b14531dde03da40bc47 0.0 +06c0aa8ad0fa418a4236c6914fb420e1 0.0 +07465ac96a07454a7c155d9c674bbd5c 0.0 +075eb451ed18cc7fa554e88c2726e7ed 0.0 +075f8821bc5c57034fb74afc07233d97 0.0 +08091b93dffe421f648aac3eb7e192c5 0.0 +0820b82d14921828dfa20b56242a48c3 0.0 +08a1598eb1ea4dca23db1135552cd5a7 0.0 +08a62d972f6bf2ca4dd9291bc2cc9f63 0.0 +08be83d0a527ddd1da0861135192e593 0.0 +091e6e4ffe1252fd657f19e42e04e859 0.0 +0a5225695ff3a449ad8ce395d75c3799 0.0 +0a99bccbf1bd2e4f728514ba8c4cf6b5 0.0 +0ae0be308568d07e0434434b14b8d565 0.0 +0b05a2e48cdc5f9e766bb0f4c209d4b4 0.0 +0b3c20a64187d28e11a68f342081c17c 0.0 +0c336b876b379dc729ffcc2a1340f670 0.0 +0c3a02ffb054a07b355c1649433fc699 0.0 +0c3f267cef317f7d71015849370f1f6d 0.0 +0c4204a0e15fccc22a7456685898cd5c 0.0 +0cc26190e976fc496119a5eb4cd0fee7 0.0 +0cdc26df2e337ea78808c32c8f52c94b 0.0 +0cf86462b45382da531327e4186091da 0.0 +0d188e3528ce4d674680de129470f7bc 0.0 +0d3b942348cade7e1c41ac52df03e63e 0.0 +0d69754929eb3dd1a5b256b43f1c05d7 0.0 +0e637c81e25ffbf7b7e68a8fbcc4f2ea 0.0 +0e7be154d128e3ce2b9b05e3e64a679e 0.0 +0eb15dc6ca644533da15764998436274 0.0 +0f0a1f8c92368be6e8d3145bd4e94cd1 0.0 +0f0c741eeebdb89289460115e9430f1a 0.0 +0f42bfd00e871207c3e2bc92a79f3456 0.0 +0f6200a5b77099113b52eea9a8645181 0.0 +0f8aa0e4c4ccd80c090db7c72be4d264 0.0 +0f92fcc184a951ff8b0914467ad2f8f9 0.0 +0f9411ed14b5b3aa1a9655523fa33004 0.0 +0fcd8cec2c4190fb7703e87f3c04a0a9 0.0 +10155b2834300619ce0102110a37b057 0.0 +10a9a0887483597b71cffa08dcda40de 0.0 +10cd502b01abafc87e2ecbad86389286 0.0 +113ce005a880987438bdbe19ee22add8 0.0 +1141f30eddb626a3a1151a19445eadfe 0.0 +1142fa8636688cdac86a8bdcbc8bee05 0.0 +114a94e972186d56504069f1bacf505a 0.0 +11764b0405507198175fe590debb40b4 0.0 +1182d94e2fd82a9b44657970e252736d 0.0 +11b21c7f71591dd1570f9717990ea4c7 0.0 +1264ac914d010d7c663fadca9c5904f4 0.0 +131d3b899e72f19fcae1b0f9f8f3a009 0.0 +138daeaeee1211d2a3d8502b8fe23b2a 0.0 +1407e963207002430eaebcae4b500708 0.0 +1442af5b43d77ad0cd6b73feea01af87 0.0 +145ebc1f8ab3b2896eb631008973c0b4 0.0 +149e7d5e484d157f2ac6140a2111618e 0.0 +14ea2e862193001ceb4322087eca9f4d 0.0 +1516918080ce0a63f2e1ac6251ba1282 0.0 +1527fd8b14037f53b8edb26b111e1f72 0.0 +157a9e8a83fb37615cabb48c14d919f5 0.0 +15dd83460074717cb57171578115cb49 0.0 +161d27a7363501e838efa59628353a65 0.0 +16306acecd104a4f12ec62522e1bf751 0.0 +1634bc38311d3c868d1077602dc439f2 0.0 +1661c49d1dc41645c0bf242b2064f1f3 0.0 +16c36bcee25e65305630899e962804ca 0.0 +17824e221f06eecf126ea102c3a2c289 0.0 +17c24a9e01ee9569cd8f4a4b0e9b1b33 0.0 +17dd8d3d133442253a1d51601ca5a192 0.0 +180b74e94caf35fac5e1f0f4b7ad9d9f 0.0 +185e45802a5c7674f89b5d0dd66d7912 0.0 +192522c9b7c41f7a761f8a2ba792268a 0.0 +19cb3add28813b2bf3e1f40a000d33c2 0.0 +1a0bea5ccf9d532d75136168ddb54654 0.0 +1a5526b9f7147b6893f1a034a107cc65 0.0 +1a962bffebb20d79245326ada6fa9b4a 0.0 +1aaeb592fcca5013db99a4f629c55062 0.0 +1bb5836797e9a89a2de9b96bbe206524 0.0 +1bf05d12bfd387888facafd52c07a37b 0.0 +1c4344ff805fe2e4a760b5d01eb57eca 0.0 +1c85fe6e01899c1b9575734197172ab7 0.0 +1c86153e1b13ab5322c96f2602b73513 0.0 +1c94105978b1aa2095e3c0096774f240 0.0 +1c9f7427ad9eef9581c32e490d0f3e35 0.0 +1caec778d70d2d387717d1d1bc248bb6 0.0 +1cba52a9db0c46eaa9148953a6983f1d 0.0 +1d1d606cff1c8bab0027fdd1e2ede36d 0.0 +1ec95834f03c9606f9433e59443e5bf3 0.0 +1ef782a559e3e0a4ab42516e0a2c828f 0.0 +1ef9d7dc5f8c93a8a43bd84e55f9a08e 0.0 +1f4c8ba04bcab2849c9ddfbd7fa3d1ea 0.0 +1f982b62b3d278f92eb3007e366fbe14 0.0 +1fa555f9a74d47a6ca7a65a347bc885f 0.0 +1fc9389433a5ed33af26e3985bdcda26 0.0 +200f25968eccba0fac01ab0385952acb 0.0 +2086666afdd5de098b04a94247040c11 0.0 +218a6324d16b842a38c70f1088a7c8b0 0.0 +219d2ac2e47968bb839bfa948559ebcd 0.0 +219fca301444ebadab34c1a35847fca8 0.0 +21ce8465657612a85e2f89e74d285ce1 0.0 +21d92a1e71eeadaeec2fd51f41249446 0.0 +22026223740aa4b6376f724986d7bf12 0.0 +226d7503ab3d1ea0ae84d97fbd804323 0.0 +228592b44e6a4d192af2d0732ec64a51 0.0 +2290e92733707772a839abf72e7981f9 0.0 +239b4f4f6c5fc459a1c95c4bf704de3c 0.0 +23bf5f7fe3d1ff8167bf3901fdb0685a 0.0 +23c05ffd2b0ba1534717ee52a81b589e 0.0 +23dece0aa961e717a81e1118455253d1 0.0 +23f4c333bc50c5cf2c0f20855d049cc4 0.0 +2403a466dd6d1e4f551d80394c2aa994 0.0 +24ef07664cfa04a819d7797a89e653b6 0.0 +251429848560a80abcb96640ceb102db 0.0 +252d0fd6601d9776290e142e5bfd744b 0.0 +2594fcf48955bec7b61a5ce4aefa3868 0.0 +2732bd972ea75eaae442f937cb39253e 0.0 +29568b810d7a4e985424b9037aaeab9e 0.0 +29784e17460e4faa8e4eb6576e85f22d 0.0 +29ccf8b234ac00b114fb2c8e1c44f932 0.0 +29e53aaab03b86749d3941da8ea5b59c 0.0 +2a8a90cd5770804a5f23f425004de7e5 0.0 +2a99ec1157a90661db7ff643b82f1914 0.0 +2aa7a8ef7c70b5f684c856e6c21b6635 0.0 +2b982979f2401a8bc447d7141879e9b2 0.0 +2be34a58b64107daf7b5426302feeff7 0.0 +2c0fa4f09b72e538e3c6acead5b987cb 0.0 +2c1dcc76478dfbb19fa59690738202c6 0.0 +2c61ba77eb8ea89ea85728bd0022ac09 0.0 +2cca9e3bd17f06418ac623fb0017c4cc 0.0 +2cdea72aa7fe332d3e0a891d49d22c1e 0.0 +2cf53730a41137e7ad95ed3680541d80 0.0 +2d273dee370721d368ed3534c76100ce 0.0 +2d5957484a1289ca13b12328802dfaec 0.0 +2ea79eaaa0b23b2a7d2cf470cbaf72ea 0.0 +2eb7bab7b0af702e4f18358968a8f7ff 0.0 +2f3b51e3f7acc3c9f66f1552b67a0209 0.0 +2f75b02cd4d3ddebf390d17a120f419a 0.0 +2f9d067d5ea9cc1b1289e9de830b326e 0.0 +2fad39e365933a7f925040cb3c2a5ef8 0.0 +3017f87a3b0f5200ed54eca17eef3cbb 0.0 +30207d209491dfb7de83344e77fd6fbd 0.0 +306d425d43fecaddb4ea5af1cc34ef98 0.0 +3098ee4e595175076514b00a8a20c291 0.0 +3127220258419507743dc5f2bba69d86 0.0 +31ebb433ebf0b3e83259d826875b4438 0.0 +31f493208054aa0fea8a26d72ee670dd 0.0 +31fe7997ddfef193110db377890f9520 0.0 +320c03afc417b829a51ecad3dea2e065 0.0 +320fd62cdcfb66cfcc1438371751c4af 0.0 +3233034b11dfc584717d9264882a4fce 0.0 +32382a0f5831da5faee464d011b5616c 0.0 +3255b196d8b70893d9124239bcd46782 0.0 +32a21601ca89d1f2629c1a9fc2de4359 0.0 +32afbeb5f76a69e47f6cf6a1870e95d6 0.0 +32d9ab84e859d48f487b790c58e98234 0.0 +32ebb69544acaf3162b5e828d05a5f84 0.0 +330b6fa220b88e87ac7c5ed39ec276dc 0.0 +33206a2306ca96922fed904661eff421 0.0 +334af877a390268de17839f80e212fd0 0.0 +33852dc244bb69590e8e756a83bb2f4c 0.0 +33902c26956acf7efa69413cfea6326e 0.0 +33950a5fa4d8ee86e10778182fae6714 0.0 +33b58b0709e9c05ba8404c47e6a7ea2e 0.0 +340a5698fe78713b785c3bcce89df73b 0.0 +34cddd9fe152c24d78924ef25927d67c 0.0 +35513c8de34a49ef37dde85737e6aef9 0.0 +362b97b08074732371b6e76cd1a894e1 0.0 +363c1c39d58bce4fc3218659d0944258 0.0 +36402f6154239da8ce422da64a0bd247 0.0 +36be43c248f8e4a7b60a4739cd8dd932 0.0 +3781803fe3eeb8e5bc50a5308f4516a6 0.0 +3788b1d514737976689f4ed1dee8b52f 0.0 +37bdb470cfb64ad4594c5968cd95e312 0.0 +37ff76f02e76dd8fc629cb05575defb1 0.0 +387e36ab394fd347fd94d8762016779f 0.0 +38c80ed971960fd1e878080f767a4765 0.0 +38e3b7abf4e08699d7a1d1965f177086 0.0 +3902e1865aa0a0863687793a7891f8f7 0.0 +3950fe55c9d109b986e327da3ab3653f 0.0 +399bcf0feb12a20ca0731d8d65268dae 0.0 +39bb3fb5b2257fd2eacca408dc42c5d1 0.0 +3a0e00761e8113458ccd7d13af71b4b0 0.0 +3a1461e8439091ad6b93af0ddb3849eb 0.0 +3a3e562a61e57ea1ff4f24857a1e79da 0.0 +3a8731148bda5325db164e3729754abd 0.0 +3ad7da49c52ec79eb228067d25d2f2a7 0.0 +3af2ddaf4af4b5ae4100439a9c3d4099 0.0 +3bfae16068c7a0b87db6a711c01eadc7 0.0 +3bff9ab82e7f2a76cc22e687ac7b72fd 0.0 +3c5496fdcfbdd5b2e4f620d44f83414c 0.0 +3cb3514dd7db8d7720477ab5759b970e 0.0 +3cc53c481fdae6358e4d2d5c9f95a1f0 0.0 +3cc657dfb41c68faa70508afc63f4222 0.0 +3d52122a218f9c70126d51d42996a1a7 0.0 +3d6469bbfb14a86abdaa602a89753ec9 0.0 +3d766867c97f511431bf97e059d6498f 0.0 +3dca01142e22e42b989fe5a513e103c7 0.0 +3df77157a242066dfb4eb9c19062436a 0.0 +3e2716bec0426995af52846a88864c6c 0.0 +3e9c062471302ac0ef352264490d1b3f 0.0 +3ee56b6c4d038d4b8d26f63fc337cd02 0.0 +3f11f9f226ab63cc1ff6bfeee9699b79 0.0 +3f2fd56fd1ec26b86eed89795fe014cc 0.0 +3f54618710e03bf1e78b57e14ca8775f 0.0 +3f55a8ca784ae7190790023a30cd859c 0.0 +3f56d7b61bdc82e4d12c6f58617f5103 0.0 +3f6c45001fd40e8b6f9d0558539fd820 0.0 +3fe55dd5e59267f275e972017302459f 0.0 +4060be28072a120ebefbef199c09187f 0.0 +40787e473f59ede4ad561b4e4079d97b 0.0 +40a6b537d995aeb12b0100e2cb6ad879 0.0 +41239266f2952a56a313fc4798f28a1c 0.0 +419242e308e14800b26a10a4bf82831f 0.0 +41b518f17927240fdfd1465cd351afc4 0.0 +41df3b4c55182503ecd97c6dbe47966a 0.0 +4261b78dbd18dd66cbbc7a7f0f2a51a8 0.0 +426bd7119a31b73ef734771a071a216c 0.0 +42ac6d34b293d442987af367e2eb4f51 0.0 +42ce63585eaa407ee53b568bdc648be8 0.0 +42ef609ea1f85d92d08a416be896e309 0.0 +431c53fa5c895a6e6f5951578f6dca8b 0.0 +433d8ad01fdf6ed57d8f509a7d6bfe2a 0.0 +4346c337f6760bd0f8e574277524165e 0.0 +4355c3f086c69fffe013ed0a3fdc8b66 0.0 +438eb58eedcd45e1eedb5889431ebe2a 0.0 +444d635c03299c7b88a3a0c236831bad 0.0 +44620cd517e481b3b2b27ff6d6611d53 0.0 +446ec4331e4894b14be920825fc962a5 0.0 +44a36b6738e227582e14a58b9d92a5f5 0.0 +454aceb66125863a02ea9d46c0b23136 0.0 +457d3865cf0a4bc602a07d8d5324388f 0.0 +467201ebcbdb17a73c8dbe98f8bbdafc 0.0 +467fa58ad637f123633ecf3cd389ed36 0.0 +4687677f9674fec6aca4275f36063b4d 0.0 +470aabeb5aab36d5ddc9d1995b087843 0.0 +4786895e195caa90723aa4bcb25b8b03 0.0 +4790a2be4d1288d94177213af8380f12 0.0 +47c98abffb77eb5999855b75594356cb 0.0 +47d0d6c4ca012181585fabd306fe7026 0.0 +49a130e2f6d8bdeddd170945a75a6783 0.0 +49dd84930ff914f17216bbbef0c6ef0f 0.0 +4a86baaa7e5adb00842830155d3c7fd0 0.0 +4ab7cc7f5969573696f5cc3b1ea0f4bc 0.0 +4acc36d268585bc3834e627756313b21 0.0 +4b3f3f0ecac9b4026751b7549559c9c3 0.0 +4bec204a5986223b16143ad5db1c8433 0.0 +4c1afcf47b47fc2850fae19210e27117 0.0 +4c2189b6b5ced3cb80093414e9449de9 0.0 +4c855814a58f4f324e8f0cfaab222e1f 0.0 +4c954887a7bd1f32382dbbade7b91aaa 0.0 +4ca53113aeac7afa697e8cae58f69855 0.0 +4cc94d6f0ba7a2a174fa668ef5966bae 0.0 +4d7f3a8e908cb29809ed118acf40d513 0.0 +4db47b583b03cc6706e28a2fe2731080 0.0 +4e3406627aa545813116167826c24a46 0.0 +4eb0fadd9ccb6cd253273f89be164175 0.0 +4eb2c50a69efefc9d10540928ce08822 0.0 +4f5e90e831377b98f5f6e569d6d8f64f 0.0 +4f6f2afb7adf1bb487b6a86b13022445 0.0 +4fd1b92e9814b1bc6d1f7b1117daf660 0.0 +4fdbeac7d6cea1fef876d607636f189b 0.0 +4feb634e0ed63566c64710659b17a2ad 0.0 +4fed36b0643aa2ddcecf381c1f487a85 0.0 +50f328ff0b5c3003ce220fbd7aaa2ef7 0.0 +50f8db74e965cdba7ae86014644a3137 0.0 +516549c565407769125e3e8f3ca298cd 0.0 +517eed6e97dd2846dae1553b8c7c9464 0.0 +51a63d18809e04591820c7e3f3acf0b4 0.0 +51c999131379511e8950fed0550134f7 0.0 +51e4182fc25b356d52164f3de0d5d4b6 0.0 +51e77f4577d36c8bd3627a3d0229dd37 0.0 +5226eb5e70712d3425df4b0e57d5a406 0.0 +5350db19ba80799a8c5ee886143dd940 0.0 +536018032c5d0d65e6d25d3988f87421 0.0 +53609d8db4e52b4f03beab3bc44ad5ba 0.0 +53668ab088d92c4856914e433447af5a 0.0 +539c656b9710b0099a96a678b3023299 0.0 +53a3eb7f49d8d6857ba7c50dd5bda866 0.0 +53f6fd6e785c7fb9d72f94a6ea343a15 0.0 +5406f4862e6c5e04e925b8f0a501958d 0.0 +5494f5c56e0875a35b62e234cc67ffa1 0.0 +552e00cb506f739acaf08aa5641f9d84 0.0 +55993950ca597b6dc821765327bbf3b9 0.0 +55af0326535a408ef56415f2952e2896 0.0 +55d4d3011e1f3bb8e4e5089b801b61a4 0.0 +56c3d1a8e4dc5c2aa7afbc1563559448 0.0 +576c2135e8ddf9d0a3674a5937d2466d 0.0 +580e8927be639c5ab7fa8731a72c76d2 0.0 +5844d8e76e12fb8526d7fede1c425670 0.0 +58464ec27209abed9698e88ab974e84f 0.0 +585f01cd625ddb45fa4eebbc072fecd1 0.0 +5860dac317300b1fe6094e958240cc7f 0.0 +58df89090206b56c52bfffa4b97f4d5d 0.0 +59597cd430deea6d8e0908dcd6db7e50 0.0 +597966c93921ecc2907ad15121cbcd2c 0.0 +599ba6458e91e2527f358f547ea39261 0.0 +59c4a678634e50b3fda861310820aadd 0.0 +59c6ed04d2faf081cecca31f1eb2e42d 0.0 +59d031b8ba709e8da78b4c1f63c74f09 0.0 +5a21785c07d7cc123256f09d00deec29 0.0 +5aa1c4b839946b713b450ff38e7d5bf8 0.0 +5ae365ca527c17c22171f54421e75197 0.0 +5b31527f1b28c37035a08b3642d61ece 0.0 +5ba339813ae7235641d2f1ff581ff2d7 0.0 +5bfef4e7e21aee58609421e4f24b5dc8 0.0 +5c3e4422374120cd00d41557946e5c6f 0.0 +5c6ba6ec99b516d0d9cba8e4730ea1fe 0.0 +5c78e7010bae7392c680c7ee9a1ed076 0.0 +5ca5ea401c8d3569e69626d2f81d5578 0.0 +5cad0c3ca2db85210a2d320bbe783fbd 0.0 +5d141d74c8bd046171ec64835c4864b2 0.0 +5d20f93c621d95608e5b8473d56d5b52 0.0 +5e151aa3f416a2fa6f0a1d8985282783 0.0 +5e32dea22765b73ed60b1d78a9d4d574 0.0 +5e99c84d99dca9630c51c5fb88000143 0.0 +5eb9520307f1836913cc5937f1c9f64d 0.0 +5f1d2db99a41906b5ca2800149e0c385 0.0 +5f8c4f83215d666e801e21278b17fb45 0.0 +5ff2bac04b0e8ba06ff7e0293588c308 0.0 +5ff715b26c5f3632a12da2d4dbd758bd 0.0 +6007bf22076e2e3d0030e38442149c54 0.0 +602510f333bda9666e551383f7ebaf82 0.0 +60746d8928422234eb34fff42f4cca47 0.0 +60c57911662a9159dfdd0fc05d975a55 0.0 +60ce43bfcf795e997e3c969938262dab 0.0 +60e681703dcab859a8e336be27fd6cf0 0.0 +61602441fe4b6f2b36be40c311fa9cb3 0.0 +6240207fd3edd24bf0799b5f427423a0 0.0 +628a44c637e99429e3ac4c39227c6c9d 0.0 +62ada1b9706d5e11072e7d78ecb0a4bb 0.0 +62f043c2aed6f033879b83ca519fde32 0.0 +630bffb8b9a197b3a6359f42828b4de3 0.0 +639a2c1d7ae3f6700506aba8baeec034 0.0 +640f0d7bcadfc07ac9f3a4d0b440d859 0.0 +64618afa3a07dcab19ba87629333ab84 0.0 +6474f5ab8c91efe951ad41f60fb4218b 0.0 +64b3028e870c12fc7d39287219f7af67 0.0 +64dc86ad2807b50d91f4938a5bb31a87 0.0 +651794369aeb3db83839b81fe49c8b4e 0.0 +66127b1730c816b3e022c01fcaf024ea 0.0 +6677fe5ca3b81ce606eac5d76b0a0ece 0.0 +6689cc067754fa14964e70c77ae9ce0a 0.0 +6694ca246e895a4f1d7e1d077cc27f5d 0.0 +6700772469767941a3992c3e2c65c3bb 0.0 +67cd78854a06d6e3867c28745e509ad9 0.0 +67ec5c8d397bcd64b2e336a60eef437c 0.0 +686d42b9552375c3b61301ae5605e3a2 0.0 +68bb0065fa02ba7b52acf3f4d833895b 0.0 +68db566a60ba7167b024b4c5032d9400 0.0 +690754306aeed53ec9ffe767151681cb 0.0 +691656f33e727f8857f5c9ee40ed05b1 0.0 +69536042153447ceb692aa53159ce0c2 0.0 +6961c6244fb505547380d15bfee162a9 0.0 +697b3fb29268cba4b2a9eef0eab2de7e 0.0 +698862fbff78c7fc3cd7a9f4958bdadb 0.0 +699d4b4de178e2d52195830debfc3b1f 0.0 +69d052e452e79d571cba042af265d50c 0.0 +69f46a090420a7f596df5d450ef67e66 0.0 +6a129e8ae637c96e7bb56223913911f7 0.0 +6a17479edbe461431433bddb084f731e 0.0 +6a5f9d9d0fbc066a57bb7798f9f371ff 0.0 +6a6880faba39965be0e4b7d88966d1c9 0.0 +6a6d8054e2a7052fb8fd458dccb2f88b 0.0 +6a75fd73efa64af9c36a4435bae0f920 0.0 +6a83401c3ea3089bf7d3c3051a709ef9 0.0 +6b90b86f5da836f13c0ee2f67132e12a 0.0 +6bbaf2d026d54c61f24b5c5483e56842 0.0 +6c1f3bf3e2186d0faf5325be92f4c974 0.0 +6c4de756c45fa6e7e5adfe196f9f0039 0.0 +6c84b0ea6103c2ad5f4c3b7f5dd5e1d2 0.0 +6d0013cae9b331ee166821cb124dbca1 0.0 +6d34445f3adb296a5642fcb5f81e5219 0.0 +6e8986f8088b452f964e7968bb8bca87 0.0 +6eae8918e5425723c03d19afa8ca0356 0.0 +6ed7152332889b69d2d2f33c53b68934 0.0 +6fa149c798c4251f1ca8cd356f0568ee 0.0 +7029eddc845e01d613a3bbc113ebeaba 0.0 +704d0070549f26fe1f99eb736cdc4c34 0.0 +704e8a1acf77dcc1bc06251a34ba2132 0.0 +7069d1ba735fd4d5199050b4c100bea7 0.0 +71a713c5aa69a8e46efa23a2437010b8 0.0 +71d32936afbf6c7745a6083e7b09dff3 0.0 +7201d53bd647437ec3de879774eba498 0.0 +7212fe837f6f09bd16ed2c9b2c58e557 0.0 +740c97e7b2eddae8044cf27859a86b7b 0.0 +7412af58f3daee6101db082fd334144b 0.0 +744b8cd51857478bda77a9f3ab5e1d5a 0.0 +74b7dc5aa537fcaf4d0046dc7715b9bf 0.0 +74f2fa20e0ed1f74fbe4857f249e3a28 0.0 +758cd34d30d7af60445b5f0f932d21b9 0.0 +75a5999048000b7e178036f0e75e4dd4 0.0 +75c5f35120584c258c8ffa734a94ea8b 0.0 +76075eede2e2c9cf276a8394c7cca293 0.0 +764ce1e6cf32606d676870bd6ab3e21d 0.0 +76cee9663ccd2b6160d3dfcc88df3c38 0.0 +76f7f30b434c8deb5e2a0fd50baa1496 0.0 +7769cac4c6bfbe7e3cddd33636c22519 0.0 +77c18841a3a2296268d30a71c26a5cec 0.0 +78266846787de98cf89a724cb5586858 0.0 +7839f352a2bbf8261351db78a9bf3bd8 0.0 +78d8e6cbe439685d63e01561094d1736 0.0 +797ebe05936131bb058c0ab04c171a26 0.0 +7a1144e3e5689e67eb04e1a00e49c45c 0.0 +7a629c748d0205443ef1e8e26ee09543 0.0 +7a8d29c59b803baaed9cc1f04ce0dc33 0.0 +7a9469ff27dc7afffdb7238976da0a6e 0.0 +7ae7a28e3e35f8669d62a551beedaf7b 0.0 +7b2ff5940de11da4dc3bb208805dff11 0.0 +7b6f8858b481821ad1aae2e8d796fae6 0.0 +7b9a7ec76bd5dd38a2964e80934bc632 0.0 +7bb3a2f7b1bab185035b2e361b4fa760 0.0 +7be9bac1b13acbd8acf0de464d7c20e6 0.0 +7bfa7582156c882bb0c1de44aaaf7a3c 0.0 +7c99906fc47555e0b2df4cb90c47a3c9 0.0 +7cb7753109015ae718a1a0201d081e99 0.0 +7cc8273fa6f3c9f55f426c3765741834 0.0 +7d2f0f34f2ea4ce7030a589e76c0d06a 0.0 +7d4bc1c15b975e6ffe247f13716e5f53 0.0 +7db357a4adb452de8504d8ca1ddb3f99 0.0 +7df3c653a9ad469d0de18261ee771eac 0.0 +7dfa96abfa7484bb6c9cfa90dc9b606f 0.0 +7e17a5137fd9dab8c02617a186088c4d 0.0 +7e3f4a0767fe59521a6db1862056798d 0.0 +7e54570d21f03dfcefff07151a8c2d54 0.0 +7e57bf1306ddc4beb5aa7a1084d8c845 0.0 +7e86e84e054d9c5a6d485c9ef762c5c2 0.0 +7e907df30e0739c3bf57f18729659005 0.0 +7e9ed2c841e64976eace4b578ff56a26 0.0 +7ead39abbaa90f90242247c455393162 0.0 +7eb58843a058a3dcc0c051e0762de977 0.0 +7ebc04cb539befd9f2e7faa131628c66 0.0 +7f323d6db23992932ec6e097ae09c4c4 0.0 +7fa68c46b87cb8fc334456fc14dfdf23 0.0 +8042eb376d870b471cadeab735dee5a5 0.0 +80fd14aea177425eb5d6a4b388a08a07 0.0 +812aac97abf11d6d64a00496e070e266 0.0 +8139d4cc5e4e5d44bad494a295a3e7d6 0.0 +8183f1e3f9806994e125b1d5c6932498 0.0 +81a1e88c8e85192aecbcb517cb0bf1ba 0.0 +81f1b22052c8eb3dfb1e6b45ab7c8530 0.0 +82168325f126cecd669b2d0e030c9eae 0.0 +825e1e1d675a615bb3e6914499939c93 0.0 +830932289444e28d4ab0ac9cdabfe977 0.0 +832e6210c0410af8e0356bea5ec39c80 0.0 +832fd777a62ea50c5c34a8c2efb5c5e2 0.0 +83420377ed17df2c16abaf3a72e05633 0.0 +846b433f433cbb20d6208bd54067f911 0.0 +84853bd31e74a04290e47c542c8d293d 0.0 +84d6422c401698d91e646b9b4fe4774e 0.0 +8507091bac6b1be88f3d360d6d535d0e 0.0 +855e8b78c6f45f9a2e3d5afb75c4f5bb 0.0 +85d8ef495cd58b08a300a623a3718ba9 0.0 +862f918acd63eeace039314ff2263a39 0.0 +86f04c5c81713db61f97bb53835f9189 0.0 +8731860c790449910b7955d1bde836f2 0.0 +87bb02a4196dc0430e4ad2a975a345c8 0.0 +8833ed97ab90d2af80eb7c7f7921f139 0.0 +88c180a637696e987712b40ac9089f8c 0.0 +890bfce6cfa2575db09fc1ba0909d3bd 0.0 +8919944cb4b67e5abb04cc8afad9045d 0.0 +894f46d021396ebbbc4041b65e198bd4 0.0 +8951cc9103140b71bd50c0932e096502 0.0 +89aabf43d24dd5bd0fd0f5aca189d341 0.0 +8a20667bca2eaf2a0687995af876a84c 0.0 +8a658263f5f46e9b06ce187893565b47 0.0 +8a83cfd5eb074b5dbc6118eb03ef915e 0.0 +8a974c19d04562e710612ca049799942 0.0 +8a9f7499cdb85b8efa497bb56256cb43 0.0 +8aa70d0c06e8da0b4c0ea2eba6308983 0.0 +8ad30192adf51cd7b03105a1acdea794 0.0 +8b0fef40cdee88fe61bf6c86ea5b8d41 0.0 +8b159e3b7ba334383b185c1926d9b9c3 0.0 +8b78fe0639a5308fb6f33a8eaafcdfd9 0.0 +8b86b84549e5940744c30df2a573b55e 0.0 +8bb5ff097e0707dca3fe5860af20f4a6 0.0 +8bd6fae62d450bdf768bfc6464d36d38 0.0 +8d89ee75fdeac54f5ebb1ef3edf80e73 0.0 +8d99d70a19898e91e9d7dd54dbd5881c 0.0 +8db257dc277d4e84ef974e07dc449820 0.0 +8dba41073e8e2650e099cda3fd3a0630 0.0 +8dccd839cf4868a3343e411c063932a6 0.0 +8dcd5864b11c06837480c727198cded4 0.0 +8df5a666d571bcb1b2a44aaf978fab49 0.0 +8e1c69dc9a692ce4b7e93c8cb728b7a6 0.0 +8f1c11c7b732265cbfc1bb7dbd0241e7 0.0 +8f4a3341ccda8d1b45f286cb686a3aec 0.0 +8f5b5babdbe9847334e115160088b371 0.0 +8fd6bffb88d374f38c6bf35cc8a4a221 0.0 +902c0a7dd5a911a8fbf9e34e49f72297 0.0 +904ad13c7b8512200836d5cd9fb09e1b 0.0 +904d063813394e9a3cd5a23fef870ec8 0.0 +904f7b1ae29e6a78ff83eacd9ef9cda7 0.0 +906138f305d5b85ac761fc50bbb6ca87 0.0 +907ceab78e867d765fa360527608efa1 0.0 +90949bb38f58e92949ab8504aff01df1 0.0 +90a0937762431acf0f8f3643e08d3180 0.0 +90a685caa7eac21daa8a8f56df52eb29 0.0 +90b56798a9abd8360a79627ec3c332d3 0.0 +90dd37137cfac54abcaebc7048fe77c9 0.0 +90e427df120ab07ffbd57703f11c1a4f 0.0 +9122e867c908301e783c5ce0c3bf12e0 0.0 +919db619ad90cc6b09b31c83d5719da9 0.0 +91b88aa295fe09a255b2f321d9d2b12b 0.0 +91d7d1256be7c1797cd45c2296095521 0.0 +926708e33d1ebf1a9da757f78c673190 0.0 +92ae272884c88aa3be9a5800f2836740 0.0 +92f000f936d3f349c5e7719a5edc5078 0.0 +93029132afec86c495769fbd8dd65ff2 0.0 +932e1f2d3f75eaba13d2b2be2f2f7cb3 0.0 +9394eec407745afeb6370fb2a0ee1a98 0.0 +9394fd89106163be8a11cd4dc46bc8a3 0.0 +93a9affe525a4ddda933fce27518d7ce 0.0 +94035fd1b8dabc1d79586ff8b52846b3 0.0 +94650d81f3f14b948edfadca3ca7b166 0.0 +94738eca8f0e714dac0390e647565488 0.0 +94a699e62982fe59b7725f1b7271972a 0.0 +95348b8c18227b458056472fc9eeafd3 0.0 +957a16edeead7722188be53d05fbf001 0.0 +959d48a11e3b26c9268f0bd1dae6ec40 0.0 +95f77f9e6df255cf93ec17c1a48bc194 0.0 +965d7a58f59ea6445b32afede05a4012 0.0 +96794c2d601e0082c9b66552dce42e4e 0.0 +97951199cbbcc765ccde49fbcbff09b1 0.0 +979578981da3916b394bf24c32bace21 0.0 +97cfaa815d9e25d41d6698f790b7ad0a 0.0 +9828f58eaf910927264c204ace9caeed 0.0 +984ef97167ec7b42d7a3650716d6a2ed 0.0 +988b0b7321184cfc2c53e0966dcab560 0.0 +992072d045462445dc239b35300af2cc 0.0 +9938c8f22908861f780f8719b75dc0b2 0.0 +993ea35e8ad7ff6894e32247dc507e9b 0.0 +99dda7b5337bc09a69e9e27bab56fd79 0.0 +9a75764782a384ce3b83e019c8b2dd94 0.0 +9aa7314d56b3b3db2253ec2763414be7 0.0 +9acc238746a1f2aa7745a0b5720c4eac 0.0 +9bbe5054cf0bc376baf895f0638705f1 0.0 +9bbff59b3c1084173c4917e136b496fa 0.0 +9c25197937d1f54e2634026fbca6b55f 0.0 +9c58ab3805d06ed6f1ff2a2de766458d 0.0 +9c61dd9fc1208289eefdccd5ad281288 0.0 +9caa12440830e96456250882ad25f89b 0.0 +9cb1cfaea33aafcffe7c261eb104ca56 0.0 +9d2176c908640e85287b95f9cd17bf64 0.0 +9d650084364f31c59068a17261e13dc8 0.0 +9dc78fd8f2f7cb10e190e77af61c7ecd 0.0 +9dd9cefe38347b087dd318d82962cc03 0.0 +9e033e0a6e420a9d407f908d59aa31eb 0.0 +9e644716572f5930cb56186d75a6bb84 0.0 +9e8e56f06c0615130e1e2f459bd4052a 0.0 +9ecd25659ebff6a840c089b93515c5b7 0.0 +9f48f7b79ed6f3dcde8b25e0cf244d5d 0.0 +9f4d14b114e7499772a797790d81c1db 0.0 +9f74473636e6874853d88dfcbcecff49 0.0 +9f8119029c8b972ae0375c8b968c14e6 0.0 +a02c286e5afe7220b1fdf83dadea939f 0.0 +a1999b4f10c91d6f8efa3c9d73f77fa4 0.0 +a1a22b2e460e6454dca7805f1cde48d8 0.0 +a1f75692d5fc417ae9461aa66e0ed7ef 0.0 +a220d7daecd7de9a9560ac2a5a64e2a5 0.0 +a2e0f228d7110587954e13405f98f003 0.0 +a2e3ac6b18daba602b14d93882f3663a 0.0 +a33859e0fe8e20bd783ad918ac192884 0.0 +a36d070ba91e6c48d0c79036200d0b20 0.0 +a42ad1956d801cce5e0109dc0e987ceb 0.0 +a4c61d535793417f6f6ab9eae2463f12 0.0 +a4dbf71f32a016e120fe6cf253dfa6c0 0.0 +a4e2a4e1321a599651edf92f6999e78e 0.0 +a4ecfb2e708863a17978a0942358ffc3 0.0 +a51b62113b7c9d4febf6956e86e5dfd0 0.0 +a544abd909afc727c4418e4e19eed417 0.0 +a5676561cb37d21b8c485040ca3ebe96 0.0 +a607665fc01df970cb3f1c4002a00bab 0.0 +a6099802840e60febef8e896967b7747 0.0 +a66a33da056496a076f57ec22a435dc9 0.0 +a6bd74dcea0ad6299a4cd2937e192151 0.0 +a6fa2de5f4576d1d77b1616786e3dd52 0.0 +a75b0438ad19fb4e31f4d58c2d49ea02 0.0 +a765441df9f96c9e8a1baf9645528616 0.0 +a7e74b8756d98ed147f70628144245cc 0.0 +a7fad69a900f747d777bf13f8c1ffd83 0.0 +a837426344372de1e6d07876dd214a5b 0.0 +a898fafd80c4c90cdcde401ca2332e05 0.0 +a8aca6d9fcb6ac34f6104cbe28a466c7 0.0 +a9566f812a634f1b709810bb0cf50629 0.0 +a957f3e1f57e99be7c1c28de7f016780 0.0 +a9b72251b244f66d8296965d9435218c 0.0 +a9e1acfa6cc2678b1fcc40f49007d4c5 0.0 +a9e6fc1854a3fd8873b32c9fbd9ac13a 0.0 +aa738f71de2d14bf826740d8df65e5f2 0.0 +aacaf5f360c110204da1051a50c5ba5f 0.0 +ab0b78445a54df766c12448fa0ad6d49 0.0 +ab2ef9bffd8e25c75290c0a2f6a8f85c 0.0 +acfd094c6c92700cdcf89371abdd104b 0.0 +ad01a1417ca1d8a5a7a768ea78e45673 0.0 +ad8991870b8bdd236d97d01487ddadc6 0.0 +adc59da8759a4276a8f218e237e27f12 0.0 +ae791ca848029549cd27ece21344d8a1 0.0 +ae793fc8909a69dde3c7757780299e14 0.0 +aee0d6f2626271eacf89d2e803440657 0.0 +aefd4044e43af5915f9a3fac602e9308 0.0 +af25adac3aa4a6a6f6c97b23b7755273 0.0 +b01e64261beff06c591132b8f0cf3099 0.0 +b098aa6c11cba636420401399b83be7c 0.0 +b148aa1f06e0eea5a72ac72fdf3ac867 0.0 +b153e0852342c0738da791930625716f 0.0 +b1f2146bef78066448576fceeb6b644b 0.0 +b265615da6b98d477507607fc51972f7 0.0 +b29deb0964b5328b6206ea33b9035302 0.0 +b2ab597a902ff227a5ba76030cd6002e 0.0 +b2e3852763d37eff884d326836ccec27 0.0 +b36ff490f4df87e30600ed347f23cbdc 0.0 +b39a1bb517361c2a87f8fb48d66a49ee 0.0 +b3b1ae423dc7f3d8942237d115a5bf86 0.0 +b3d06445a910a9a444919e41f5da39c3 0.0 +b3e2d6b8bb4b97afa07c0d048746b712 0.0 +b3ea95770cf649371d22e1a1d5aa3c0d 0.0 +b423592b0ae631882095792b27729b9c 0.0 +b4446b03208372a5dd17608d78f7e3e8 0.0 +b460255b8269b55301e0c3c3e3da252c 0.0 +b47e328fa7998e8085a30dc2a03506c0 0.0 +b47e999a38113e0e4e2b139e8b861fdd 0.0 +b48a25941ae901a73b4a2830cc24b382 0.0 +b507596e6af67ab90ce421ce6f40b0af 0.0 +b55ddaf95d9d2217ea087863a7afbbad 0.0 +b6985598d3f4a9b830bbe1c6a665f5fe 0.0 +b796b2132a5015f869c8b5ac44a0e2bf 0.0 +b8c685d6d691d57d63a05b0eaf5a669b 0.0 +b8c6906ea995f21303d44ab7b21655c6 0.0 +b955f67a541a149dd3b179dc62d37a72 0.0 +b9d953d2c367d1b3150ccf062dacfe83 0.0 +b9fefd4224e459a6a0d21db63b1c0d03 0.0 +ba88d4e4e6a24ecc2a5aab6bdfbb77f5 0.0 +bad4f7c5ada34a1f813946abcfe5c556 0.0 +bb1c2099a32a335b1a55f44d3ba54484 0.0 +bb8cd42775d7feb5b54059f90e5ce9eb 0.0 +bc0588863994a8f20e7dbce7a6fb8b96 0.0 +bc23d2ee539bf2f52faf789289af7879 0.0 +bc4ae61d84daab04b0e888d22f7d3f69 0.0 +bd0f4e14387ee1ac7e5fe586cadbbed4 0.0 +bd8cf9d4f4744a93802336d81b60966e 0.0 +bda6b6e7da7508c68057140e7bd6cd8d 0.0 +bdb2c60864ae18c4302c9f144219512e 0.0 +be480a1e4a4e71fe774ccd3e4ff22945 0.0 +be9eb15986b4bdfad6c474a30e7ce4b9 0.0 +bed1b5521bddc2d35732fafc25043f19 0.0 +bf8144aac6a30e6695ad6bf8f49131ab 0.0 +bfb7bb16ab570748b3a5d099e9426af1 0.0 +bfd6e1ccc45f37b290d63de0053c212e 0.0 +c07ef20fbf08691cd223cba17009e12f 0.0 +c0b31b31a1d47acfa4b2a6b279ee631b 0.0 +c12331989624002d4f790eb1d19dad02 0.0 +c1365ec008032ee718dcafaf5ac17adb 0.0 +c1a5735daf6f1e6157aeafb503b9e564 0.0 +c24ac2e6e7002af9827563df39144c55 0.0 +c2cd19f77efced924e3eccd8bc6750be 0.0 +c2efeb6d250b34f682ae6380682f60b3 0.0 +c30a545d14731276f649c2428c0babe7 0.0 +c326a5572886b04b8ec92047c9415a00 0.0 +c348a7cc121fa43fb14ca92cc4273c2e 0.0 +c3937c933413c88df1db4b761e0e3ac7 0.0 +c3cb5f0be6d5e3a4761a78606c1e4113 0.0 +c4b0455f8d6d59d4caafda4b3aa90622 0.0 +c4b11e3e5340bdf421aeb4ba0aff0269 0.0 +c4cceb02f4ce674101aa2c0d1317cdf6 0.0 +c4e57b91cc2be5a2232b3612abdf4c0c 0.0 +c59161ae395fd5322d2f192f13cfb31d 0.0 +c5b95a83a06195f219b0edd9ab18fb1d 0.0 +c5e3c5422835403541b0af331a2cc649 0.0 +c6178d46f91b123b2c226120a3167a34 0.0 +c6959c6d7f3f2806418eddfeeb3f2d22 0.0 +c7408e951d6050a4ea360aa404050896 0.0 +c7ec80af1d984fddec04831296fd65a5 0.0 +c7ff7e806765a39b6cdf66a15b63f6bb 0.0 +c870a3c711d733d9058cd2274a101381 0.0 +c8933e6cd4ce9389f4ad6e2e24dbf5b9 0.0 +c8ae16a39fbfa227aadd2e6d5a63da7e 0.0 +c8fce068920feb387167d44c01689295 0.0 +c936431ab7a77c5828a3da971da51acd 0.0 +c942f59feffce9c3ab527135de234101 0.0 +c98ea813f96e96f25ba321f74703bf6b 0.0 +c99c4c951e6f4745973043285ccf486b 0.0 +c9ccc527189a7a19902fc022a72c3bae 0.0 +ca0fb2462b67d4296fdb8de1372d9165 0.0 +ca5b38f92987671538ac4f8f5b4ee95d 0.0 +cac55aa795998014361e14836ddae2bc 0.0 +caf54b4995a78b51266cb0e4aed4deae 0.0 +cbb1dee8bf80a6cf676e15d39d9979d1 0.0 +cbfaac9f291ac42563f27903d0f684a1 0.0 +cc3e4918ee1c089c5bed6cab11dbee83 0.0 +cc42ed01e236e8f05d25a7310d47e354 0.0 +cc5f74d0b0787e9ca4f97835c2c0f2a2 0.0 +cc968157f7691aab95df444e8cd103e2 0.0 +ccce7fe8aa849bed027f6898300e0c45 0.0 +cce0f21cdf5597d900d303fdac05b33c 0.0 +ccfb4c8a7a57ffb8fd5212276ff2b193 0.0 +cd1fc0b5ef8bb9823eb279222f0d0860 0.0 +cd5f131980408e798875e41b3c0d53de 0.0 +cdce04d738e587eb6a58f8a79ed36c20 0.0 +cdfd52e813292000f1bbc5c4d7c95b4b 0.0 +ce33f26f3bd4784cdb63910753fa0792 0.0 +ce399235aeab566680d0ad1ac6f9c7a4 0.0 +ce9976fb696a210e526fb161c15ed88a 0.0 +cea0486054293b47714d155ca349b763 0.0 +ceaf720138cf7bdfb66e2dbdae539e38 0.0 +cee9ade29a61d7669cc2710549611c53 0.0 +ceedb016e7628567e25ad61c46a8be83 0.0 +ceefb8fade04925c7bbfad924171a220 0.0 +cf54928a038081788aa5939c49ae5340 0.0 +cf8eb2fb3d885d1919ba916bc0975347 0.0 +d0309ad131312d425619892c703b13ad 0.0 +d05c86b5bfc092d8677507fb1eae8d66 0.0 +d061a99148d649c4eca4836c5f4b5b68 0.0 +d0c34b21c7c96271a1bc5f7fe82df3a0 0.0 +d0f02fb55f33f41f45d8b5a6a6a5b018 0.0 +d103541d4efc81020afaef43c0f02c02 0.0 +d117a20b7daabc35e9d810f3a93d18b5 0.0 +d1539f8c2855fe568d1313f20d26710d 0.0 +d208cad7c585049e04076ac7df960e7f 0.0 +d213f55b066d42f6c6fea9f1d27582c5 0.0 +d2589a845c837dbf413021f74e82ce0f 0.0 +d28170caeb000a27998d838a8e7d5de8 0.0 +d284b92d7518959fe5d52aa45b687394 0.0 +d28f5cab517f832750bbf62798e58dc3 0.0 +d2aa3a30c8e178110125b88dfc7e6f45 0.0 +d315a0b30c8e21db4cfe89e65c0b2bf1 0.0 +d3211b7a04e5fb36a383450b8f5710e2 0.0 +d32627161d829a1488c2a047669cb29f 0.0 +d32d7b4a5e805f7e43f7823bf3eb566d 0.0 +d34887a684a1acc690b8f3644cb11c12 0.0 +d371cae3627eb71177294af103c68940 0.0 +d39f37b814ebd81091a949f8bd9d1710 0.0 +d3d99580d90cca486a23372a474e9571 0.0 +d3f86c6a6fd03654e0848a1fb1ad1385 0.0 +d43ad42f3b1625379a2429c10f419eda 0.0 +d4e63b08a25162d359541e38c6e484e5 0.0 +d4e8fb8d73378ac761ec8eb3faf71804 0.0 +d5b4f33a93b1580c123d306690d0ffb9 0.0 +d5d727a0e5ba892a10e9c81ef29d02c0 0.0 +d666cafbfcffb984b12c4a405df6c7c9 0.0 +d6752c4c0b83bb0ba7df8368b3c94d6a 0.0 +d6bb5703483ac68992e09ce17683c52f 0.0 +d6bc69828ae0ef27e99c01c9e7df86b0 0.0 +d6c46ad81c01997055a3b713c0d5ee1b 0.0 +d6e76cfe58d253204f5589d78cc79bd1 0.0 +d7130a2536c5b200a01662b82ff93d06 0.0 +d73c014c9a033812619aa44e9cae934f 0.0 +d7466ab97edf938c5ed46f6bb1649b60 0.0 +d780f9d98701c8ab19b4488869bd5be6 0.0 +d9294a924ce5ef9df6e464b4ef2f9db2 0.0 +d93dfe29130fd71bd30fcdeefea2862b 0.0 +d97a97d4f8974683e4a66de090129c1c 0.0 +d98796acd66eb71638defd318991adfd 0.0 +d9d0120f569d8e15590c6486f4ffed36 0.0 +d9e7a2013a2b6863cae05c51be41848b 0.0 +d9ef9c1fd69f0b398b331c428991204b 0.0 +da5463f9a3163db4528898c49e7fa54c 0.0 +db6e4e3d6bea23bd5c619e4dd4ef5b87 0.0 +db9caf76f81e72dac22fd1a55da6d5ce 0.0 +dbf76c1b3ed4745cb94c15374d951beb 0.0 +dc92897ae65716d40ff3b2746a2a6527 0.0 +dd50bb187bc6f99222e626ddc810909a 0.0 +dde2f514908a4fcaa80827346c7b7a19 0.0 +de0ad18436d210c9b60044fc7b9caf90 0.0 +de478a19bf7c5ab5e75d3dfcb742f4d2 0.0 +de6891b6f7a1f35bd9ccbc058b9e1a77 0.0 +def8acc0fc88cc9a9cf110370ecc2c37 0.0 +e0fdbc7f687a7ea0cf13009c2e501197 0.0 +e10c0e74616a50d8956a945d0b6dd531 0.0 +e21d9f482315985036cf80d1b20de58b 0.0 +e2bf5a8c1878477d542ef764b910e5a2 0.0 +e30c40e583572ed45fef99d6a32d3924 0.0 +e32053e0d7a8b525d0b062beb2ae11ce 0.0 +e392de248b88befeab2319aebd7872c3 0.0 +e3a4a62adc4e83c274978806164b474a 0.0 +e4207d118a1ffe33509edaf320ac2a7c 0.0 +e4d8026eb8e261594d51750b1080dbf7 0.0 +e56aff2928773e4f9d4646bebe35123c 0.0 +e5a43b018c81cedd19e9a5354d32d469 0.0 +e6441fdd2f0ec36ec914d7154a64061a 0.0 +e644522cf6d7222c9da7f9ecf614cd89 0.0 +e6a34eb113dba66df0b8bbec907a8f5d 0.0 +e6f747cd89d512cf187e8472cfb250a1 0.0 +e7037dc2701d6b9666d2c0dab6110ae7 0.0 +e78cb60fcb9cadfa0a32ba3ac4b2e95a 0.0 +e79e5e4c871bac3c43de566188e10002 0.0 +e80317d0fb0618cf19a96ef454fef9de 0.0 +e82ab12c51a893c6d7938a16632199a8 0.0 +e84bea8ae61342674744560dd7de4721 0.0 +e86212f766f010236a072bfbc04774b4 0.0 +e8cff5dd9314935749206c1d83214d77 0.0 +e94776066de6ff852fc7a43e7a0626cd 0.0 +e9c73fbac5dd73dd5e3ada5664ae95fb 0.0 +ea6265476f08a35fdb764ae98206ad5e 0.0 +eae4215acb2d651ce76c5e4d10f3d839 0.0 +eaea5d7b84c08fdef5d8ab40f707e37e 0.0 +ebab7cfc7858bfb00c486bba21d6ca6d 0.0 +ebb5ea4b9b617249c40513ded403e30b 0.0 +ebfae3fd8d9da7341650be7f4f6c13e1 0.0 +ec38f851c5429708e114208c539ae458 0.0 +ec6c9ea52e88226c339487585ea02f42 0.0 +ecaa9f4e15a28f212d9bd60f749191ab 0.0 +ecc877a3410d54ea784131356fe5ea73 0.0 +ecff0a63780369ddcdc800ab97fb81f9 0.0 +ed1528f4822674c9e1da64b84c778e9f 0.0 +ee062262ac3b97896676e558bb08986a 0.0 +ee41b2201102d120e0ceff1eb49ba6cf 0.0 +ee5c4bf663b722fc809746f322a4f6f4 0.0 +ee90bebacf6867cd5b4c487cb587ea9a 0.0 +ef4045fe369d078db89c253c9ddbd123 0.0 +ef467d766ba05adf651d1fc6a30cba06 0.0 +ef7c8af53de2ee3385027bc6b4bf0883 0.0 +f05a6141cb84e0c95470be3e92085b93 0.0 +f09ca081a69806aca5de24d404ad4c6c 0.0 +f10155af1849a17996f302d71b32398c 0.0 +f12011ad5219b22b6ca790103333a755 0.0 +f19fa34c0c987ab3bd8aa42d8a4d21ec 0.0 +f1da0f084f3e5b7957d11d01abe7013d 0.0 +f283cd6d309acf7626b1fbc0079d275d 0.0 +f2b4aaab4b89a51ec6205485018c9419 0.0 +f307aa8ff39ee31213f4d9e1bfce6dcb 0.0 +f3153e589a8718a2a1109a6e181617f7 0.0 +f31aab4ff2dba1e72d9ea251e447844d 0.0 +f31ac04c4b89a126b2406e811dff97fa 0.0 +f3b9619b167cd0ec5f9c55a7dd6c7ee6 0.0 +f3c30aa47b3639f25d168a810ee07fd9 0.0 +f3cac486ad34144511deb96b29ded2c5 0.0 +f402dfa5da0f4bd53468557a1a6b01e3 0.0 +f434ebfe13e3764e53f40e7b99e07a39 0.0 +f45b62ab6ec22fb20364a7e05088158f 0.0 +f47f8e690205be8c0572db3c32829f43 0.0 +f4909ad74d5b44aa7c3694798c21ea87 0.0 +f4cd813a1b8a862f7a285466b25c6302 0.0 +f5487404313a4fb57bc3489c167e9a37 0.0 +f56e589e8377da78834cf577a69b939c 0.0 +f5dd3f079f8866010ff9e1ce86dea070 0.0 +f5f4ef252850e0b1f378923731257d69 0.0 +f65ee26124609d6de91d4bffee014357 0.0 +f6c6e7419ddde1e2e1d4a790ec6babfe 0.0 +f710c0927080e422094a96ffe13b389c 0.0 +f73160a94abee0441ab5a573877744d2 0.0 +f7a5b80128b001df0f52bdad023aeb23 0.0 +f7ce5d68ad002cdc285273d049516c84 0.0 +f7e75337c2baaabcd5c9cbfa83ce5ef1 0.0 +f7ef98bb6d0061b9368a72b1ff40aad0 0.0 +f80a17436037d706dc728dd265b7c21e 0.0 +f837443696652157e220ae13e330e0e6 0.0 +f83918824d8dd7875a4b478adf4ee601 0.0 +f85dae8239789b16d0f8dcac9e272361 0.0 +f8dc4d17a9589b91dc466d20015518e4 0.0 +f94eeb84a8ab5049e8e0cbcc078de30c 0.0 +f994313e9f7ddae7f7d6806221d6be70 0.0 +f9b52205cb2d03153fd394a290212a10 0.0 +f9f5f08e8da4cc9740518223846563db 0.0 +fa09b814b417561651db81db34860ea5 0.0 +fa1d5d724ccb4287e07ea1caa9d35502 0.0 +fa71c8409cbcaad5dd98b8d80a46b07b 0.0 +fad561b7eab58e57b71a09a8b7f990c8 0.0 +fba43f263a40d5a9cc7f37f1551b13f9 0.0 +fc613984c6bd68a102eb7daee76a24a7 0.0 +fc7466fe7b054b641298ab8b5c707d21 0.0 +fc9717bf86bf07fe748f608b4f2c57c6 0.0 +fcab01e402145abc9e946d12aad1cde5 0.0 +fcfab546634e10be9800b9a4118b8dc9 0.0 +fd069fff020b15638483c7e49d2ef9cb 0.0 +fd1830279629e35893c2cc7538b028a9 0.0 +fd1f139259c53276619476db0cc81913 0.0 +fd21badba5eecdf5a284d5db7aa0679b 0.0 +fd8cc2ec2e11078f3635cdc7fb477823 0.0 +fda9e2638dfa1f4eebff04a14575f763 0.0 +fdcd6808ef8269653d25dce4a55a025d 0.0 +fea3411c847e6627afb5e78b88e2e9af 0.0 +fefc7999a7e316dfa98bb6b63d6cfda9 0.0 +ff2b5301608beca5896495311a512610 0.0 +ffaecab289059c048c7494d4595a746c 0.0 diff --git a/q2_types/feature_data/tests/test_formats.py b/q2_types/feature_data/tests/test_formats.py index 5c389cb3..2a7e6a10 100644 --- a/q2_types/feature_data/tests/test_formats.py +++ b/q2_types/feature_data/tests/test_formats.py @@ -31,7 +31,8 @@ MixedCaseAlignedDNASequencesDirectoryFormat, MixedCaseAlignedRNAFASTAFormat, MixedCaseAlignedRNASequencesDirectoryFormat, - SequenceCharacteristicsDirectoryFormat, SequenceCharacteristicsFormat + SequenceCharacteristicsDirectoryFormat, SequenceCharacteristicsFormat, + ImportanceFormat, ImportanceDirectoryFormat ) from qiime2.plugin.testing import TestPluginBase from qiime2.plugin import ValidationError @@ -781,6 +782,40 @@ def test_differential_format_bad_type(self): format.validate() +class TestImportanceFormat(TestPluginBase): + package = 'q2_types.feature_data.tests' + + def test_importance_format_validate_positive(self): + filepath = self.get_data_path('importance.tsv') + format = ImportanceFormat(filepath, mode='r') + format.validate(level='min') + format.validate() + + def test_importance_format_validate_negative_nonnumeric(self): + filepath = self.get_data_path('chardonnay.map.txt') + format = ImportanceFormat(filepath, mode='r') + with self.assertRaisesRegex(ValidationError, 'numeric values'): + format.validate() + + def test_importance_format_validate_negative_empty(self): + filepath = self.get_data_path('empty_file.txt') + format = ImportanceFormat(filepath, mode='r') + with self.assertRaisesRegex(ValidationError, 'one data record'): + format.validate() + + def test_importance_format_validate_negative(self): + filepath = self.get_data_path('garbage.txt') + format = ImportanceFormat(filepath, mode='r') + with self.assertRaisesRegex(ValidationError, 'two or more fields'): + format.validate() + + def test_importance_dir_fmt_validate_positive(self): + filepath = self.get_data_path('importance.tsv') + shutil.copy(filepath, self.temp_dir.name) + format = ImportanceDirectoryFormat(self.temp_dir.name, mode='r') + format.validate() + + class TestProteinFASTAFormats(TestPluginBase): package = 'q2_types.feature_data.tests' diff --git a/q2_types/feature_data/tests/test_transformer.py b/q2_types/feature_data/tests/test_transformer.py index 4038a85a..3556f882 100644 --- a/q2_types/feature_data/tests/test_transformer.py +++ b/q2_types/feature_data/tests/test_transformer.py @@ -30,7 +30,7 @@ RNAIterator, AlignedRNAIterator, BLAST6Format, MixedCaseDNAFASTAFormat, MixedCaseRNAFASTAFormat, MixedCaseAlignedDNAFASTAFormat, MixedCaseAlignedRNAFASTAFormat, - SequenceCharacteristicsFormat + SequenceCharacteristicsFormat, ImportanceFormat ) from q2_types.feature_data._deferred_setup._transformers import ( _taxonomy_formats_to_dataframe, _dataframe_to_tsv_taxonomy_format, @@ -1601,5 +1601,48 @@ def test_sequence_characteristics_format_to_metadata(self): assert_frame_equal(obs.to_dataframe(), self.exp_df) +class TestImportanceFormatTransformers(TestPluginBase): + package = 'q2_types.feature_data.tests' + + def test_pd_dataframe_to_importance_format(self): + transformer = self.get_transformer(pd.DataFrame, ImportanceFormat) + exp = pd.DataFrame([1, 2, 3, 4], + columns=['importance'], index=['a', 'b', 'c', 'd']) + obs = transformer(exp) + obs = pd.read_csv(str(obs), sep='\t', header=0, index_col=0) + + assert_frame_equal(exp, obs) + + def test_importance_format_to_pd_dataframe(self): + _, obs = self.transform_format( + ImportanceFormat, pd.DataFrame, 'importance.tsv') + exp_index = pd.Index(['74ec9fe6ffab4ecff6d5def74298a825', + 'c82032c40c98975f71892e4be561c87a', + '79280cea51a6fe8a3432b2f266dd34db', + 'f7686a74ca2d3729eb66305e8a26309b'], + name='id') + exp = pd.DataFrame([0.44469828320835586, 0.07760118417569697, + 0.06570251750505914, 0.061718558716901406], + columns=['importance'], + index=exp_index) + + assert_frame_equal(exp, obs[:4]) + + def test_importance_format_to_metadata(self): + _, obs = self.transform_format( + ImportanceFormat, qiime2.Metadata, 'importance.tsv') + exp_index = pd.Index(['74ec9fe6ffab4ecff6d5def74298a825', + 'c82032c40c98975f71892e4be561c87a', + '79280cea51a6fe8a3432b2f266dd34db', + 'f7686a74ca2d3729eb66305e8a26309b'], + name='id') + exp = pd.DataFrame([0.44469828320835586, 0.07760118417569697, + 0.06570251750505914, 0.061718558716901406], + columns=['importance'], + index=exp_index) + + assert_frame_equal(obs.to_dataframe()[:4], exp) + + if __name__ == '__main__': unittest.main() diff --git a/q2_types/feature_data/tests/test_type.py b/q2_types/feature_data/tests/test_type.py index 4b184a57..dc8dbbd2 100644 --- a/q2_types/feature_data/tests/test_type.py +++ b/q2_types/feature_data/tests/test_type.py @@ -19,7 +19,8 @@ AlignedRNASequencesDirectoryFormat, AlignedRNASequence, PairedRNASequencesDirectoryFormat, PairedEndRNASequence, BLAST6, BLAST6DirectoryFormat, SequenceCharacteristics, - SequenceCharacteristicsDirectoryFormat + SequenceCharacteristicsDirectoryFormat, Importance, + ImportanceDirectoryFormat ) from qiime2.plugin.testing import TestPluginBase @@ -128,6 +129,13 @@ def test_sequence_characteristics_semantic_type_format_registration(self): FeatureData[SequenceCharacteristics], SequenceCharacteristicsDirectoryFormat) + def test_importance_semantic_type_registration(self): + self.assertRegisteredSemanticType(Importance) + + def test_importance_semantic_type_format_registration(self): + self.assertSemanticTypeRegisteredToFormat( + FeatureData[Importance], ImportanceDirectoryFormat) + if __name__ == "__main__": unittest.main() From f3c01571bb282730062ca3aef4aaf7e0e6c611f9 Mon Sep 17 00:00:00 2001 From: VinzentRisch Date: Tue, 19 May 2026 14:24:30 +0200 Subject: [PATCH 2/3] remove _MultiColumnNumericFormat and inline the logic for importance --- q2_types/feature_data/_formats.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/q2_types/feature_data/_formats.py b/q2_types/feature_data/_formats.py index 222e01fa..38cc5efd 100644 --- a/q2_types/feature_data/_formats.py +++ b/q2_types/feature_data/_formats.py @@ -532,7 +532,7 @@ def _validate_file_not_empty(has_data): "file in addition to the header line.") -class _MultiColumnNumericFormat(model.TextFileFormat): +class ImportanceFormat(model.TextFileFormat): def _validate(self, n_records=None): """Validate rows with an identifier followed by numeric values.""" with self.open() as fh: @@ -571,10 +571,6 @@ def _validate_(self, level): self._validate(record_count_map[level]) -class ImportanceFormat(_MultiColumnNumericFormat): - pass - - ImportanceDirectoryFormat = model.SingleFileDirectoryFormat( 'ImportanceDirectoryFormat', 'importance.tsv', ImportanceFormat) From 8e70ff2fb5706ec21a4dd837895dfeee9b242828 Mon Sep 17 00:00:00 2001 From: VinzentRisch Date: Tue, 19 May 2026 21:55:51 +0200 Subject: [PATCH 3/3] removed has_data helper in validation --- q2_types/feature_data/_formats.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/q2_types/feature_data/_formats.py b/q2_types/feature_data/_formats.py index 38cc5efd..af3ad898 100644 --- a/q2_types/feature_data/_formats.py +++ b/q2_types/feature_data/_formats.py @@ -524,14 +524,6 @@ def validate(self, n_records=None): ) -def _validate_file_not_empty(has_data): - """Validate that a delimited text format contains at least one record.""" - if not has_data: - raise ValidationError( - "There must be at least one data record present in the " - "file in addition to the header line.") - - class ImportanceFormat(model.TextFileFormat): def _validate(self, n_records=None): """Validate rows with an identifier followed by numeric values.""" @@ -563,7 +555,10 @@ def _validate(self, n_records=None): if n_records is not None and (line_number - 1) >= n_records: break - _validate_file_not_empty(has_data) + if not has_data: + raise ValidationError( + "There must be at least one data record present in the " + "file in addition to the header line.") def _validate_(self, level): """Validate this format using QIIME 2's min or max validation level."""