From 3aa00e234e122f3cedffdc21c00a430fee7984a8 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Tue, 3 Sep 2024 14:44:45 +0200 Subject: Adding new CSV file context. --- src/argaze/utils/contexts/File.py | 213 ++++++ src/argaze/utils/demo/csv_file_context.json | 10 + src/argaze/utils/demo/gaze_positions.csv | 1052 +++++++++++++++++++++++++++ 3 files changed, 1275 insertions(+) create mode 100644 src/argaze/utils/contexts/File.py create mode 100644 src/argaze/utils/demo/csv_file_context.json create mode 100644 src/argaze/utils/demo/gaze_positions.csv (limited to 'src') diff --git a/src/argaze/utils/contexts/File.py b/src/argaze/utils/contexts/File.py new file mode 100644 index 0000000..91c64e2 --- /dev/null +++ b/src/argaze/utils/contexts/File.py @@ -0,0 +1,213 @@ +"""Define eye tracking data file context""" + +""" +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import logging +import time +import math +import threading + +import pandas +import numpy + +from argaze import ArFeatures, DataFeatures, GazeFeatures + + +class CSV(ArFeatures.DataPlaybackContext): + + @DataFeatures.PipelineStepInit + def __init__(self, **kwargs): + + # Init ArContext class + super().__init__() + + # Init private attributes + self.__path = None + self.__separator = ',' + self.__timestamp_column = None + self.__x_column = None + self.__y_column = None + self.__start = math.nan + self.__end = math.nan + self.__duration = 0. + self.__progression = 0. + + @property + def path(self) -> str: + """Path to data file.""" + return self.__path + + @path.setter + def path(self, path: str): + + self.__path = path + + @property + def separator(self) -> str: + """Value delimiter character""" + return self.__separator + + @separator.setter + def separator(self, separator: str): + + self.__separator = separator + + @property + def timestamp_column(self) -> str: + """Select timestamp column.""" + return self.__timestamp_column + + @timestamp_column.setter + def timestamp_column(self, timestamp_column: str): + + self.__timestamp_column = timestamp_column + + @property + def x_column(self) -> str: + """Select x column.""" + return self.__x_column + + @x_column.setter + def x_column(self, x_column: str): + + self.__x_column = x_column + + @property + def y_column(self) -> str: + """Select y column.""" + return self.__y_column + + @y_column.setter + def y_column(self, y_column: str): + + self.__y_column = y_column + @property + def start(self) -> int|float: + """Start reading timestamp.""" + return self.__start + + @start.setter + def start(self, start: int|float): + + self.__start = start + + @property + def end(self) -> int|float: + """End reading timestamp.""" + return self.__end + + @end.setter + def end(self, end: int|float): + + self.__end = end + + @property + def duration(self) -> int|float: + """Get data duration.""" + + return self.__duration + + @property + def progression(self) -> float: + """Get data processing progression between 0 and 1.""" + + return self.__progression + + @DataFeatures.PipelineStepEnter + def __enter__(self): + + logging.info('CSV file context starts...') + + # Load gaze positions from a CSV file into Panda Dataframe + data_selector = { + self.__timestamp_column: numpy.float64, + self.__x_column: numpy.float64, + self.__y_column: numpy.float64 + } + + dataframe = pandas.read_csv(self.__path, delimiter = self.__separator, low_memory = False, usecols=data_selector.keys(), dtype=data_selector) + + # Rename columns with generic names + dataframe.rename(columns={ + self.__timestamp_column: 'timestamp', + self.__x_column: 'x', + self.__y_column: 'y' + }, inplace=True) + + # Optionnaly select a time range + if not math.isnan(self.start): + + dataframe = dataframe.loc[(dataframe['timestamp'] >= self.start)] + + if not math.isnan(self.end): + + dataframe = dataframe.loc[(dataframe['timestamp'] <= self.end)] + + # Filter unvalid gaze positions + len_before = len(dataframe) + dataframe = dataframe[(dataframe['x'].notna() & dataframe['y']).notna()] + + if len(dataframe) != len_before: + logging.info('%i unvalid gaze positions have been removed', len_before - len(dataframe)) + + # Open reading thread + self.__reading_thread = threading.Thread(target=self.__read, kwargs={'dataframe': dataframe}) + + logging.debug('> starting reading thread...') + self.__reading_thread.start() + + @DataFeatures.PipelineStepExit + def __exit__(self, exception_type, exception_value, exception_traceback): + + logging.info('CSV file context stops...') + + # Close data stream + self.stop() + + # Stop reading thread + threading.Thread.join(self.__reading_thread) + + def __read(self, dataframe: pandas.DataFrame): + """Read and process gaze positions from dataframe.""" + + start_ts = dataframe.iloc[0].timestamp + end_ts = dataframe.iloc[-1].timestamp + + self.__duration = end_ts - start_ts + self.__progression = 0. + + logging.info('Reading %i gaze positions from %s to %s...', len(dataframe), f'{start_ts}', f'{end_ts}') + + for index, row in dataframe.iterrows(): + + # Stop reading + if not self.is_running(): + + break + + # Pause reading + while self.is_paused() and self.is_running(): + + time.sleep(0.1) + + # Process gaze position + self._process_gaze_position(x = row['x'], y = row['y'], timestamp = row['timestamp']) + + # Update progression + self.__progression = row['timestamp'] / self.__duration + diff --git a/src/argaze/utils/demo/csv_file_context.json b/src/argaze/utils/demo/csv_file_context.json new file mode 100644 index 0000000..a09914f --- /dev/null +++ b/src/argaze/utils/demo/csv_file_context.json @@ -0,0 +1,10 @@ +{ + "argaze.utils.contexts.File.CSV" : { + "name": "CSV file data playback", + "path": "./src/argaze/utils/demo/gaze_positions.csv", + "timestamp_column": "Timestamp (ms)", + "x_column": "Gaze Position X (px)", + "y_column": "Gaze Position Y (px)", + "pipeline": "gaze_analysis_pipeline.json" + } +} \ No newline at end of file diff --git a/src/argaze/utils/demo/gaze_positions.csv b/src/argaze/utils/demo/gaze_positions.csv new file mode 100644 index 0000000..558c995 --- /dev/null +++ b/src/argaze/utils/demo/gaze_positions.csv @@ -0,0 +1,1052 @@ +"Timestamp (ms)","Gaze Position X (px)","Gaze Position Y (px)" +6016,400,443 +6056,400,443 +6106,401,443 +6128,401,443 +6168,401,442 +6367,401,442 +6409,401,442 +6486,401,442 +7310,408,433 +7334,415,427 +7375,435,412 +7397,441,409 +7438,445,405 +7472,446,405 +7509,446,404 +7532,446,404 +7570,449,392 +7593,450,384 +7631,450,378 +7653,450,377 +7705,432,371 +7730,415,365 +7766,390,353 +7788,376,345 +7828,334,318 +7847,318,306 +7890,296,288 +7912,286,277 +7950,278,263 +7978,275,256 +8018,268,246 +8039,266,245 +8074,265,244 +8092,264,243 +8128,262,243 +8185,263,242 +8205,264,241 +8241,265,231 +8261,265,228 +8305,267,227 +8337,267,226 +8392,267,228 +8427,269,232 +8445,270,232 +8481,272,231 +8501,273,228 +8537,273,219 +8558,272,217 +8592,272,217 +8613,271,218 +8650,271,222 +8671,271,225 +8703,272,227 +8724,272,227 +8755,274,227 +8776,274,226 +8813,275,224 +8834,275,223 +8866,275,223 +8886,279,225 +8922,292,228 +8944,312,227 +8981,351,222 +9000,382,218 +9033,424,214 +9053,447,213 +9087,510,216 +9104,538,216 +9137,591,218 +9156,620,220 +9192,691,219 +9212,719,216 +9246,788,214 +9267,812,215 +9300,855,216 +9319,878,215 +9352,900,215 +9371,907,216 +9403,915,217 +9420,915,217 +9464,915,217 +9484,915,218 +9519,913,219 +9538,912,219 +9573,904,222 +9592,893,224 +9626,875,225 +9645,871,226 +9677,869,226 +9738,869,227 +9760,870,229 +9798,872,231 +9818,872,231 +9851,875,232 +9871,879,232 +9904,883,230 +9925,884,229 +9963,886,228 +9984,886,227 +10073,887,229 +10125,892,234 +10146,894,234 +10181,895,233 +10202,896,231 +10232,896,229 +10252,896,229 +10341,896,229 +10363,896,232 +10399,894,247 +10420,894,254 +10454,890,274 +10472,887,284 +10519,866,316 +10540,858,328 +10573,842,352 +10590,830,370 +10621,816,386 +10641,801,399 +10671,780,415 +10690,770,422 +10723,749,435 +10742,734,442 +10772,717,449 +10790,699,458 +10823,673,468 +10839,659,471 +10868,639,477 +10885,625,481 +10921,597,492 +10941,587,496 +10975,566,508 +10991,558,513 +11025,545,523 +11044,542,527 +11078,537,536 +11095,536,540 +11126,535,548 +11142,535,551 +11177,538,556 +11196,538,557 +11230,541,559 +11247,542,559 +11288,542,559 +11331,542,559 +11349,541,559 +11383,540,558 +11441,542,558 +11462,544,559 +11497,552,562 +11518,558,566 +11549,561,569 +11571,562,569 +11605,562,570 +11657,565,564 +11676,565,561 +11711,564,557 +11766,564,558 +11787,565,560 +11822,569,569 +11841,569,570 +11877,571,570 +11898,572,568 +11933,573,564 +11954,574,561 +11988,575,559 +12009,575,559 +12078,575,560 +12115,578,564 +12137,583,565 +12171,599,560 +12192,607,549 +12229,612,537 +12254,613,535 +12288,613,536 +12305,613,537 +12334,613,539 +12354,613,539 +12388,617,541 +12406,624,540 +12438,638,534 +12458,647,530 +12495,685,512 +12515,706,502 +12547,752,474 +12567,779,449 +12602,811,405 +12622,830,380 +12653,848,359 +12671,864,341 +12706,881,316 +12726,887,308 +12760,890,305 +12776,892,305 +12812,896,301 +12831,898,300 +12868,901,299 +12888,911,296 +12926,928,284 +12947,936,280 +12983,957,266 +13000,963,262 +13034,969,257 +13053,969,257 +13087,969,258 +13108,969,260 +13142,970,266 +13159,971,267 +13189,971,267 +13216,972,266 +13249,972,261 +13271,970,256 +13310,964,252 +13331,963,252 +13367,962,253 +13388,962,255 +13422,962,257 +13443,963,257 +13480,964,256 +13500,964,255 +13536,964,253 +13556,964,253 +13590,964,254 +13611,964,255 +13647,965,257 +13668,965,257 +13705,966,256 +13725,967,253 +13762,959,243 +13782,944,238 +13816,914,234 +13837,893,233 +13870,830,223 +13890,806,216 +13922,751,204 +13941,718,201 +13974,655,192 +13993,629,188 +14030,565,184 +14051,539,184 +14082,491,186 +14100,467,186 +14132,420,189 +14150,393,189 +14182,363,190 +14198,349,189 +14232,324,188 +14252,315,188 +14286,306,190 +14305,303,190 +14338,295,191 +14358,295,191 +14394,295,190 +14414,296,190 +14448,299,188 +14468,302,186 +14501,311,178 +14521,317,174 +14556,319,174 +14614,318,177 +14634,318,181 +14666,318,182 +14686,319,182 +14721,320,181 +14741,320,180 +14776,319,179 +14795,318,179 +14835,313,181 +14856,312,185 +14896,312,186 +14917,312,186 +14950,315,185 +14971,316,184 +15007,316,182 +15027,315,182 +15069,309,182 +15094,302,187 +15127,285,199 +15144,276,205 +15178,261,219 +15204,256,223 +15238,250,229 +15256,243,239 +15290,235,263 +15309,229,274 +15344,217,294 +15363,212,302 +15400,205,314 +15419,204,314 +15453,204,314 +15482,203,313 +15517,204,307 +15537,204,305 +15569,203,304 +15586,203,303 +15621,202,303 +15641,203,302 +15673,208,296 +15694,209,294 +15732,210,291 +15753,210,291 +15790,210,290 +15808,210,291 +15842,211,292 +15861,211,292 +15899,212,292 +15924,212,291 +15955,209,290 +15973,209,290 +16010,208,291 +16032,208,291 +16070,208,287 +16091,210,279 +16122,210,258 +16140,208,244 +16174,205,213 +16193,204,203 +16223,203,195 +16239,203,192 +16273,203,190 +16291,203,190 +16325,203,192 +16345,205,202 +16377,210,210 +16397,211,210 +16433,213,208 +16454,213,205 +16488,211,202 +16507,211,202 +16543,211,202 +16565,211,203 +16600,212,205 +16621,213,206 +16654,214,206 +16674,214,206 +16713,214,203 +16734,213,203 +16768,212,203 +16788,213,206 +16823,223,224 +16843,227,229 +16876,241,236 +16894,252,242 +16930,263,252 +16950,269,258 +16987,273,262 +17006,278,267 +17037,284,272 +17054,288,275 +17089,290,275 +17106,291,276 +17139,299,282 +17162,303,285 +17197,305,286 +17217,306,287 +17256,307,287 +17277,307,285 +17315,302,279 +17337,302,279 +17373,304,281 +17394,306,282 +17427,308,281 +17448,308,281 +17484,308,280 +17505,307,280 +17544,308,281 +17567,309,282 +17603,316,285 +17624,326,291 +17662,350,319 +17683,361,336 +17719,389,378 +17738,403,396 +17768,435,430 +17788,451,444 +17822,486,473 +17842,499,482 +17875,523,500 +17894,538,510 +17928,552,519 +17947,557,522 +17981,565,528 +17998,566,529 +18033,568,527 +18051,569,527 +18085,572,527 +18102,573,526 +18136,574,522 +18153,575,520 +18185,578,518 +18206,579,517 +18242,580,517 +18300,581,517 +18321,582,517 +18359,585,513 +18379,586,509 +18411,590,498 +18432,592,491 +18467,593,487 +18489,594,487 +18527,594,486 +18582,595,490 +18601,596,490 +18638,597,491 +18660,598,490 +18696,599,483 +18717,599,481 +18750,599,480 +18771,600,483 +18810,603,496 +18830,604,500 +18866,609,508 +18888,613,513 +18924,614,513 +18945,615,514 +18983,621,530 +19001,622,538 +19035,624,548 +19060,625,554 +19093,626,567 +19110,626,570 +19145,626,571 +19164,626,572 +19199,628,576 +19218,628,576 +19249,631,576 +19266,632,575 +19304,633,573 +19325,633,573 +19405,633,574 +19428,637,576 +19467,642,578 +19488,642,578 +19546,643,578 +19583,644,577 +19604,645,576 +19636,649,572 +19654,651,569 +19686,654,567 +19707,657,565 +19745,666,559 +19764,672,555 +19801,691,535 +19822,704,514 +19853,720,489 +19872,740,462 +19907,771,419 +19926,791,382 +19960,814,335 +19977,825,315 +20010,846,289 +20030,859,275 +20063,877,258 +20080,885,249 +20115,897,240 +20134,901,238 +20170,902,239 +20190,903,246 +20224,905,252 +20242,906,253 +20277,908,258 +20296,910,266 +20330,911,275 +20350,910,276 +20384,910,279 +20404,909,282 +20443,908,289 +20464,908,290 +20560,907,290 +20597,907,290 +20630,907,289 +20665,907,286 +20686,907,285 +20745,907,286 +20777,908,288 +20798,911,288 +20835,923,283 +20854,937,272 +20891,955,247 +20913,964,231 +20947,973,211 +20968,980,196 +21004,986,175 +21021,989,166 +21054,990,142 +21071,989,135 +21100,988,129 +21120,987,129 +21156,983,131 +21177,980,134 +21213,978,137 +21232,977,142 +21270,974,158 +21292,974,162 +21326,969,169 +21348,969,172 +21381,967,177 +21402,965,180 +21436,965,181 +21494,965,179 +21516,964,179 +21554,959,178 +21572,957,178 +21607,949,181 +21629,948,182 +21666,947,183 +21686,947,184 +21723,942,185 +21745,936,185 +21778,920,183 +21797,910,181 +21833,892,180 +21854,890,181 +21889,889,181 +21918,889,181 +21954,895,186 +21973,903,189 +22008,922,198 +22029,928,200 +22069,930,200 +22091,928,200 +22128,909,192 +22149,902,191 +22182,895,191 +22205,894,191 +22251,893,191 +22278,894,193 +22317,894,194 +22338,894,194 +22375,895,194 +22396,896,193 +22433,900,188 +22454,902,187 +22492,915,187 +22513,920,188 +22550,924,190 +22571,930,195 +22609,949,212 +22631,962,219 +22667,979,225 +22686,991,226 +22717,1000,227 +22734,1004,228 +22770,1005,228 +22790,1005,230 +22821,1005,231 +22850,1005,231 +22886,1003,231 +22906,1001,231 +22943,985,232 +22964,975,231 +23003,959,230 +23025,956,231 +23063,954,233 +23084,954,233 +23116,954,235 +23135,956,236 +23174,956,239 +23195,956,241 +23231,954,244 +23250,953,244 +23288,948,242 +23309,941,239 +23347,918,228 +23366,906,226 +23404,898,224 +23424,894,223 +23460,892,221 +23480,890,221 +23513,890,222 +23530,891,224 +23568,893,229 +23589,894,232 +23625,905,245 +23646,912,248 +23682,930,248 +23704,932,248 +23742,931,247 +23760,930,247 +23793,928,248 +23814,927,249 +23854,926,251 +23876,926,252 +23908,926,252 +23927,926,252 +23967,926,254 +23989,926,255 +24027,928,258 +24049,930,259 +24081,932,258 +24102,933,252 +24141,929,240 +24163,929,239 +24213,929,239 +24235,930,239 +24269,940,247 +24290,951,258 +24327,958,264 +24345,958,264 +24385,958,265 +24404,959,266 +24440,959,268 +24463,959,272 +24504,962,283 +24525,963,285 +24559,961,285 +24579,961,285 +24616,955,282 +24638,953,282 +24673,948,279 +24691,944,276 +24724,939,272 +24744,938,272 +24781,937,272 +24802,937,272 +24837,940,272 +24858,943,270 +24898,944,260 +24920,941,257 +24956,933,256 +24978,931,257 +25011,929,262 +25030,929,263 +25072,931,266 +25093,931,266 +25129,924,267 +25150,909,266 +25188,879,261 +25210,847,260 +25245,797,265 +25263,759,274 +25298,682,286 +25318,629,288 +25353,472,278 +25373,412,270 +25407,273,250 +25427,239,243 +25461,187,227 +25481,158,210 +25518,147,198 +25538,147,198 +25568,147,198 +25589,149,198 +25629,174,201 +25649,194,206 +25686,235,222 +25704,252,229 +25738,281,236 +25758,291,237 +25794,296,238 +25824,296,238 +25860,296,242 +25880,296,243 +25934,296,243 +25972,297,243 +25991,297,243 +26026,297,244 +26046,298,247 +26078,301,249 +26098,302,249 +26137,303,246 +26158,303,244 +26195,302,243 +26213,302,243 +26251,300,250 +26271,300,251 +26302,300,251 +26321,303,248 +26358,305,243 +26376,303,240 +26409,302,239 +26431,301,239 +26470,295,240 +26492,293,241 +26529,291,242 +26550,291,242 +26588,287,238 +26609,284,237 +26642,279,235 +26663,277,237 +26702,272,246 +26723,267,254 +26761,262,268 +26782,259,272 +26821,258,273 +26840,257,272 +26877,246,268 +26902,242,268 +26937,242,268 +26955,245,266 +26993,267,263 +27013,274,262 +27046,278,258 +27066,280,251 +27102,279,246 +27149,279,247 +27171,280,250 +27205,289,252 +27224,294,249 +27259,298,239 +27280,298,223 +27315,296,208 +27334,297,202 +27370,303,192 +27391,304,190 +27428,304,189 +27459,304,190 +27494,303,197 +27513,303,197 +27550,302,198 +27567,301,198 +27603,294,200 +27624,284,207 +27662,272,224 +27684,268,233 +27719,270,241 +27740,273,244 +27774,275,248 +27795,274,250 +27831,273,251 +27853,273,251 +27888,284,255 +27907,292,255 +27945,304,256 +27966,305,257 +28003,308,265 +28022,311,272 +28056,327,294 +28077,337,304 +28117,374,334 +28138,400,351 +28173,432,372 +28193,456,389 +28224,480,408 +28241,488,416 +28276,505,439 +28295,514,455 +28329,519,469 +28349,521,475 +28385,528,491 +28405,529,495 +28438,530,497 +28455,533,501 +28492,548,516 +28510,554,522 +28543,566,534 +28563,577,545 +28599,604,575 +28619,610,581 +28654,612,585 +28674,613,588 +28707,615,593 +28727,615,594 +28774,613,589 +28795,608,584 +28828,602,578 +28845,602,578 +28880,599,578 +28900,598,579 +28931,595,579 +28951,593,579 +28982,593,580 +29040,592,579 +29059,587,577 +29094,575,577 +29115,567,578 +29147,558,579 +29167,555,579 +29207,555,579 +29251,555,578 +29271,555,577 +29309,554,575 +29330,550,573 +29369,549,573 +29420,552,574 +29446,571,577 +29494,615,569 +29517,627,561 +29554,635,547 +29578,635,545 +29634,635,545 +29672,629,540 +29692,623,535 +29728,608,523 +29746,606,522 +29778,600,518 +29799,597,514 +29840,597,514 +29859,598,516 +29896,600,524 +29917,600,527 +29953,600,529 +29974,600,529 +30011,605,517 +30033,606,509 +30068,606,508 +30089,606,509 +30121,605,517 +30142,604,522 +30181,603,527 +30200,604,529 +30244,606,530 +30269,608,529 +30310,609,528 +30331,609,528 +30368,605,533 +30389,602,535 +30428,591,536 +30447,580,532 +30484,558,515 +30505,540,498 +30540,513,471 +30559,491,451 +30591,460,424 +30609,442,408 +30647,402,372 +30667,387,359 +30702,348,332 +30722,333,321 +30758,306,303 +30779,289,292 +30812,273,282 +30829,267,278 +30864,254,275 +30888,243,274 +30933,224,272 +30953,217,270 +30984,214,269 +31002,214,269 +31047,215,269 +31078,216,267 +31096,216,267 +31143,215,267 +31162,214,268 +31196,213,271 +31213,213,273 +31250,216,274 +31272,217,272 +31311,219,261 +31332,218,257 +31366,217,256 +31398,218,257 +31436,220,263 +31457,221,264 +31492,224,262 +31513,229,258 +31552,230,247 +31574,229,242 +31612,228,237 +31633,227,232 +31670,230,229 +31689,237,224 +31729,254,212 +31756,267,207 +31791,289,208 +31812,292,209 +31845,291,211 +31865,286,221 +31902,280,236 +31924,279,244 +31962,280,248 +31984,289,248 +32021,305,242 +32043,312,237 +32083,313,236 +32139,313,238 +32158,312,238 +32192,312,239 +32224,312,239 +32264,316,235 +32285,317,232 +32323,317,224 +32344,317,223 +32392,317,225 +32430,318,235 +32451,318,238 +32586,317,239 +32609,313,244 +32644,301,254 +32665,295,257 +32707,290,257 +32728,288,256 +32764,285,255 +32784,284,255 +32823,287,261 +32845,290,264 +32883,314,264 +32904,338,257 +32940,372,245 +32961,398,238 +32999,454,238 +33020,478,240 +33054,524,239 +33074,558,236 +33112,620,231 +33132,645,229 +33168,707,224 +33189,733,225 +33223,784,222 +33243,800,221 +33279,840,223 +33296,851,225 +33332,867,227 +33353,873,226 +33394,891,226 +33416,898,227 +33452,899,227 +33480,899,228 +33512,900,233 +33530,901,236 +33569,901,237 +33629,900,237 +33647,898,237 +33680,896,238 +33697,896,239 +33737,894,240 +33758,893,240 +33798,890,243 +33819,887,247 +33856,882,254 +33877,882,256 +33911,882,257 +33929,882,257 +33969,883,257 +33990,883,258 +34027,884,261 +34049,884,263 +34089,884,265 +34111,886,265 +34147,893,263 +34169,902,258 +34207,923,233 +34229,929,223 +34265,944,203 +34290,951,189 +34325,955,170 +34346,955,159 +34382,955,155 +34413,954,155 +34449,952,165 +34471,951,175 +34506,949,189 +34527,950,195 +34564,951,197 +34586,952,198 +34627,954,199 +34649,955,202 +34685,955,214 +34704,955,221 +34737,956,223 +34758,958,223 +34798,959,223 +34817,959,222 +34854,957,222 +34874,955,223 +34914,953,228 +34938,954,231 +34973,959,238 +34994,964,244 +35030,968,249 +35049,967,250 +35091,965,252 +35113,962,258 +35149,958,267 +35171,956,270 +35209,956,271 +35265,956,271 +35299,949,266 +35319,943,264 +35353,940,263 +35373,937,263 +35414,932,263 +35438,928,263 +35469,921,260 +35490,914,248 +35530,905,223 +35552,904,207 +35585,908,198 +35604,910,196 +35638,915,192 +35658,918,191 +35696,920,190 +35750,920,193 +35768,921,195 +35802,925,201 +35821,928,202 +35864,941,208 +35886,945,211 +35924,946,219 +35945,944,228 +35983,942,244 +36005,942,248 +36044,942,250 +36062,942,250 +36100,939,248 +36122,926,243 +36163,914,243 +36185,907,243 +36223,893,243 +36243,891,243 +36282,890,243 +36304,889,244 +36341,887,246 +36360,886,248 +36403,885,253 +36425,882,259 +36459,878,268 +36481,874,272 +36515,854,275 +36535,818,275 +36569,756,275 +36589,728,279 +36625,660,296 +36643,635,302 +36673,589,309 +36690,573,311 +36731,555,313 +36757,554,313 +36843,555,313 +36863,559,316 +36897,566,322 +36917,573,325 +36957,597,329 +36981,615,326 +37030,633,316 +37054,633,314 +37095,634,314 +37117,634,315 +37153,633,316 +37174,633,317 +37212,635,319 +37233,637,319 +37274,639,318 +37295,639,315 +37334,633,311 +37355,628,310 +37389,623,311 +37407,621,313 +37443,620,315 +37461,620,316 +37497,621,317 +37515,623,318 +37555,626,317 +37576,626,317 +37610,627,320 +37630,628,324 +37667,629,325 +37687,630,326 +37722,633,326 +37742,634,325 +37779,634,324 +37801,634,323 -- cgit v1.1