├── core ├── __init__.py ├── resources │ ├── first_step │ │ ├── map │ │ │ └── map.txt │ │ ├── test │ │ │ └── test_data │ │ └── train │ │ │ ├── train_data_2 │ │ │ └── train_data_1 │ └── second_step │ │ ├── map │ │ └── map.txt │ │ ├── test │ │ └── test_data │ │ └── train │ │ └── train_data_2 ├── __main__.py ├── event.py ├── tensorboard_writer.py ├── interaction_index.py ├── network.py ├── interaction_mapper.py ├── conditional_index.py ├── data_sampler.py ├── run.py ├── trainer.py ├── metric_profiler.py ├── config.py └── loader.py ├── test ├── __init__.py ├── test_event.py ├── test_ewma.py ├── resources │ ├── map │ │ └── map.txt │ ├── test │ │ └── test_data │ ├── interaction_index │ │ └── interaction_index.txt │ └── train │ │ ├── train_data_2 │ │ └── train_data_1 ├── test_metric_resource.py ├── test_data_sampler.py ├── test_machine_metrics.py ├── test_interaction_mapper.py ├── test_interaction_index.py ├── test_conditional_index.py ├── test_network.py ├── test_loader.py └── test_trainer.py ├── setup.sh ├── doc └── figures │ ├── json_profiling.png │ ├── falcon_reco_example.png │ ├── tensorboard_example.png │ └── falcon_reco_profiling_example.png ├── .gitignore ├── environment.yml ├── falcon_rest_api ├── cnt.py ├── config.py ├── multi_config.py ├── ewma.py ├── machine_metrics.py ├── metric_aggregator.py ├── reco.py └── multi_recos.py ├── README.md └── LICENSE /core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | conda env update --file ./environment.yml 3 | -------------------------------------------------------------------------------- /doc/figures/json_profiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otto-de-legacy/crystal-gazer/master/doc/figures/json_profiling.png -------------------------------------------------------------------------------- /doc/figures/falcon_reco_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otto-de-legacy/crystal-gazer/master/doc/figures/falcon_reco_example.png -------------------------------------------------------------------------------- /doc/figures/tensorboard_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otto-de-legacy/crystal-gazer/master/doc/figures/tensorboard_example.png -------------------------------------------------------------------------------- /doc/figures/falcon_reco_profiling_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otto-de-legacy/crystal-gazer/master/doc/figures/falcon_reco_profiling_example.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ 3 | *.swp 4 | *.pyc 5 | *.xcf 6 | *.aux 7 | *.brf 8 | *.idx 9 | *.log 10 | *.out 11 | *.toc 12 | *.auxlog 13 | /data/part-00000 14 | output/* 15 | /core/resources_full/* 16 | stuff 17 | __main_private__.py 18 | output_full -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: crystal 2 | channels: 3 | - defaults 4 | - conda-forge 5 | dependencies: 6 | - python=3.6.2 7 | - tensorflow=1.3.0 8 | - numpy=1.13.1 9 | - matplotlib=2.1.0 10 | - pandas=0.20.3 11 | - scipy=1.1.0 12 | - falcon=1.4.1 13 | - gunicorn=19.9.0 14 | - psutil 15 | - pip: 16 | - nmslib 17 | -------------------------------------------------------------------------------- /test/test_event.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import core.loader as ld 4 | 5 | 6 | class TestEvent(TestCase): 7 | def test_event(self): 8 | event1 = ld.Event("1", "2") 9 | event2 = ld.Event("1", "3") 10 | 11 | self.assertTrue(event1 == event1, msg='equality comparer') 12 | self.assertFalse(event1 == event2, msg='inequality comparer') 13 | -------------------------------------------------------------------------------- /test/test_ewma.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import numpy as np 4 | 5 | from falcon_rest_api.ewma import EWMA 6 | 7 | 8 | class TestEWMA(TestCase): 9 | 10 | def test_works_with_vectors(self): 11 | ewma = EWMA(1) 12 | 13 | ewma.step(np.array([100.0, 100.0], dtype=np.float32)) 14 | ewma.step(np.array([100.0, 0.0], dtype=np.float32)) 15 | 16 | np.testing.assert_array_equal(ewma.get_values(), [100, 50]) 17 | -------------------------------------------------------------------------------- /test/resources/map/map.txt: -------------------------------------------------------------------------------- 1 | _,0 2 | a,1 3 | b,2 4 | c,3 5 | d,4 6 | e,5 7 | f,6 8 | g,7 9 | h,8 10 | i,9 11 | j,10 12 | k,11 13 | l,12 14 | m,13 15 | n,14 16 | o,15 17 | p,16 18 | q,17 19 | r,18 20 | s,19 21 | t,20 22 | u,21 23 | v,22 24 | w,23 25 | x,24 26 | y,25 27 | z,26 28 | aa,27 29 | ab,28 30 | ac,29 31 | ad,30 32 | ae,31 33 | af,32 34 | ag,33 35 | ah,34 36 | ai,35 37 | aj,36 38 | ak,37 39 | al,38 40 | am,39 41 | an,40 42 | ao,41 43 | ap,42 44 | aq,43 45 | ar,44 46 | as,45 47 | at,46 48 | au,47 49 | av,48 -------------------------------------------------------------------------------- /core/resources/first_step/map/map.txt: -------------------------------------------------------------------------------- 1 | _,0 2 | a,1 3 | b,2 4 | c,3 5 | d,4 6 | e,5 7 | f,6 8 | g,7 9 | h,8 10 | i,9 11 | j,10 12 | k,11 13 | l,12 14 | m,13 15 | n,14 16 | o,15 17 | p,16 18 | q,17 19 | r,18 20 | s,19 21 | t,20 22 | u,21 23 | v,22 24 | w,23 25 | x,24 26 | y,25 27 | z,26 28 | aa,27 29 | ab,28 30 | ac,29 31 | ad,30 32 | ae,31 33 | af,32 34 | ag,33 35 | ah,34 36 | ai,35 37 | aj,36 38 | ak,37 39 | al,38 40 | am,39 41 | an,40 42 | ao,41 43 | ap,42 44 | aq,43 45 | ar,44 46 | as,45 47 | at,46 48 | au,47 49 | av,48 -------------------------------------------------------------------------------- /test/test_metric_resource.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | from unittest import TestCase 3 | 4 | # from falcon_rest_api.recos import MetricsResource 5 | 6 | ResponseMock = namedtuple("response_mock", [ 7 | "status", 8 | "media" 9 | ]) 10 | 11 | 12 | class TestMetricsResource(TestCase): 13 | 14 | def test_works_with_vectors(self): 15 | # TODO: mock correctly 16 | # mr = MetricsResource() 17 | # mr.on_get(None, ResponseMock(None, None)) 18 | 19 | self.assertTrue(1 == 1, msg="Should not fail") 20 | # np.testing.assert_array_equal(ewma.get_values(), [100, 50]) 21 | -------------------------------------------------------------------------------- /core/__main__.py: -------------------------------------------------------------------------------- 1 | from core.config import Config 2 | from core.run import run 3 | 4 | if __name__ == '__main__': 5 | print("Load new data with smaller map and start training from beginning with random initialization (if output folder is empty).") 6 | run(Config(root_folder="./resources/first_step", output_folder="/.././output")) 7 | 8 | print("Load new data with larger map and increase map and cathegories in second step (with random values for new ones and given values for old ones).") 9 | run(Config(root_folder="./resources/second_step", output_folder="/.././output")) 10 | input("Press Enter to continue...") 11 | -------------------------------------------------------------------------------- /falcon_rest_api/cnt.py: -------------------------------------------------------------------------------- 1 | class CNT(object): # TODO: define filter interface 2 | def __init__(self): 3 | self.values = None 4 | 5 | def reset(self): 6 | self.values = None 7 | 8 | def step(self, cnt): 9 | if self.values is None: 10 | self.values = cnt 11 | else: 12 | self.values = self.values + cnt 13 | 14 | def __call__(self, i=None): 15 | if self.values is None: 16 | return None 17 | if i is None: 18 | return self.values 19 | else: 20 | return self.values[i] 21 | 22 | def values(self): 23 | return self.values 24 | -------------------------------------------------------------------------------- /falcon_rest_api/config.py: -------------------------------------------------------------------------------- 1 | class Config: 2 | """Contains static configurations""" 3 | 4 | def __init__(self, source): 5 | self.source_dir = source # can be several source paths for indices... also only one 6 | # self.interaction_vectors_url = self.source_dirs + "interaction_index" 7 | # self.interaction_map_url = self.source_dirs + "map" 8 | 9 | self.method = "hnsw" 10 | # self.method = "ghtree" 11 | self.space = "cosinesimil" 12 | 13 | def to_string(self): 14 | ret_string = """ 15 | General parameters of the config: 16 | 17 | """ 18 | return ret_string 19 | -------------------------------------------------------------------------------- /falcon_rest_api/multi_config.py: -------------------------------------------------------------------------------- 1 | class MultiConfig: 2 | """Contains static configurations""" 3 | 4 | def __init__(self, source=[]): 5 | self.source_dirs = source # can be several source paths for indices... also only one 6 | # self.interaction_vectors_urls = [dir + "/interaction_index.txt" for dir in self.source_dirs] 7 | # self.interaction_map_urls = [dir + "/map" for dir in self.source_dirs] 8 | 9 | # self.method = "hnsw" 10 | self.method = "ghtree" 11 | self.space = "cosinesimil" 12 | 13 | def to_string(self): 14 | ret_string = """ 15 | General parameters of the config: 16 | 17 | """ 18 | return ret_string 19 | -------------------------------------------------------------------------------- /falcon_rest_api/ewma.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | class EWMA(object): # TODO: define filter interface 5 | def __init__(self, half_life_count): 6 | self.values = None 7 | self.factor = np.exp(np.log(0.5) / half_life_count) 8 | 9 | def reset(self): 10 | self.values = None 11 | 12 | def step(self, y): 13 | if self.values is None: 14 | self.values = y 15 | else: 16 | self.values = (self.values - y) * self.factor + y 17 | 18 | def __call__(self, i=None): 19 | if self.values is None: 20 | return None 21 | if i is None: 22 | return self.values 23 | else: 24 | return self.values[i] 25 | 26 | def get_values(self): 27 | return self.values 28 | -------------------------------------------------------------------------------- /test/test_data_sampler.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import numpy as np 4 | 5 | from core.data_sampler import DataSampler 6 | 7 | 8 | class TestNetwork(TestCase): 9 | def test_constructor(self): 10 | np.random.seed(0) 11 | rs = DataSampler(np.arange(0, 100, 1), np.array([0.01] * 100), 10) 12 | res = rs.rvs(2) 13 | np.testing.assert_array_equal(rs.bucket_sizes, np.array([10] * 10), err_msg="check bucket sizes") 14 | np.testing.assert_array_equal(res, np.array([50, 53]), err_msg="check draw from one bucket") 15 | 16 | def test_get_by_condition(self): 17 | np.random.seed(0) 18 | rs = DataSampler(np.arange(0, 100, 1), np.array([0.01] * 100), 10) 19 | res = rs.get_by_condition(lambda x: x > 80) 20 | np.testing.assert_array_equal(res, np.arange(81, 100, 1), err_msg="check bucket sizes") 21 | -------------------------------------------------------------------------------- /test/test_machine_metrics.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | from unittest import TestCase 3 | import falcon_rest_api.machine_metrics as met 4 | 5 | class TestMetricsResource(TestCase): 6 | 7 | def test_memory_usage_psutil(self): 8 | mem = met.memory_usage_psutil() 9 | print("mem usage psutil [MB]: " + str(mem)) 10 | self.assertTrue(mem > 0) 11 | 12 | def test_memory_usage_resource(self): 13 | mem = met.memory_usage_resource() 14 | print("mem usage resource [?]: " + str(mem)) 15 | self.assertTrue(mem > 0) 16 | 17 | def test_memory_usage_ps(self): 18 | mem = met.memory_usage_ps() 19 | print("mem usage ps [?]: " + str(mem)) 20 | self.assertTrue(mem > 0) 21 | 22 | def test_memory_usage_ps(self): 23 | cpu_perc = met.cpu_usage_percent() 24 | print("cpu usage [%]: " + str(cpu_perc)) 25 | self.assertTrue(cpu_perc >= 0) 26 | -------------------------------------------------------------------------------- /test/test_interaction_mapper.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import numpy as np 4 | 5 | from core.interaction_mapper import InteractionMapper 6 | 7 | 8 | class TestInteractionMapper(TestCase): 9 | def test_constructor(self): 10 | im = InteractionMapper('./resources/map') 11 | expected = 50 12 | self.assertTrue(im.interaction_class_cnt == expected, 13 | msg=str(im.interaction_class_cnt) + "!=" + str(expected)) 14 | 15 | def test_to_tf(self): 16 | im = InteractionMapper('./resources/map') 17 | tensor = im.idxs_to_tf([0, 1]) 18 | np.testing.assert_array_equal(np.array(tensor.indices), np.array([[0, 0], [1, 1]]), err_msg="indices incorrect") 19 | np.testing.assert_array_equal(np.array(tensor.values), np.array([1, 1]), err_msg="values incorrect") 20 | np.testing.assert_array_equal(np.array(tensor.dense_shape), np.array([2, im.interaction_class_cnt]), 21 | err_msg="shape incorrect") 22 | -------------------------------------------------------------------------------- /core/resources/second_step/map/map.txt: -------------------------------------------------------------------------------- 1 | _,0 2 | a,1 3 | b,2 4 | c,3 5 | d,4 6 | e,5 7 | f,6 8 | g,7 9 | h,8 10 | i,9 11 | j,10 12 | k,11 13 | l,12 14 | m,13 15 | n,14 16 | o,15 17 | p,16 18 | q,17 19 | r,18 20 | s,19 21 | t,20 22 | u,21 23 | v,22 24 | w,23 25 | x,24 26 | y,25 27 | z,26 28 | aa,27 29 | ab,28 30 | ac,29 31 | ad,30 32 | ae,31 33 | af,32 34 | ag,33 35 | ah,34 36 | ai,35 37 | aj,36 38 | ak,37 39 | al,38 40 | am,39 41 | an,40 42 | ao,41 43 | ap,42 44 | aq,43 45 | ar,44 46 | as,45 47 | at,46 48 | au,47 49 | av,48 50 | aw,49 51 | ax,50 52 | ay,51 53 | az,52 54 | ba,53 55 | bb,54 56 | bc,55 57 | bd,56 58 | be,57 59 | bf,58 60 | bg,59 61 | bh,60 62 | bi,61 63 | bj,62 64 | bk,63 65 | bl,64 66 | bm,65 67 | bn,66 68 | bo,67 69 | bp,68 70 | bq,69 71 | br,70 72 | bs,71 73 | bt,72 74 | bu,73 75 | bv,74 76 | bw,75 77 | bx,76 78 | by,77 79 | bz,78 80 | ca,79 81 | cb,80 82 | cc,81 83 | cd,82 84 | ce,83 85 | cf,84 86 | cg,85 87 | ch,86 88 | ci,87 89 | cj,88 90 | ck,89 91 | cl,90 92 | cm,91 93 | cn,92 94 | co,93 95 | cp,94 96 | cq,95 97 | cr,96 98 | cs,97 99 | ct,98 100 | cu,99 -------------------------------------------------------------------------------- /test/test_interaction_index.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | from core.interaction_index import InteractionIndex 4 | from core.interaction_mapper import InteractionMapper 5 | 6 | 7 | class TestInteractionIndex(TestCase): 8 | def test_knn_idx_query(self): 9 | im = InteractionMapper("./resources/map") 10 | iv = [[0.0, 0.0, 0.0], [1.0, 2.0, 3.0]] 11 | ii = InteractionIndex(im, iv) 12 | 13 | result = ii.knn_idx_query(1) 14 | 15 | self.assertTrue(result[0][0] == "a") 16 | 17 | def test_knn_interaction_query(self): 18 | im = InteractionMapper("./resources/map") 19 | iv = [[0.0, 0.0, 0.0], [1.0, 2.0, 3.0]] 20 | ii = InteractionIndex(im, iv) 21 | 22 | result = ii.knn_interaction_query("a") 23 | 24 | self.assertTrue(result[0][0] == "a") 25 | 26 | def test_knn_interaction_query_exception(self): 27 | im = InteractionMapper("./resources/map") 28 | iv = [[0.0, 0.0, 0.0], [1.0, 2.0, 3.0]] 29 | ii = InteractionIndex(im, iv) 30 | 31 | result = ii.knn_interaction_query("") 32 | 33 | self.assertTrue(len(result[0]) == 0) 34 | self.assertTrue(len(result[1]) == 0) 35 | self.assertTrue(len(result[2]) == 0) 36 | -------------------------------------------------------------------------------- /falcon_rest_api/machine_metrics.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | import psutil 5 | 6 | def memory_usage_psutil(): 7 | """STILL FAST, return the memory usage of a Python module in MB (>~ 10000 per second)""" 8 | process = psutil.Process(os.getpid()) 9 | mem = process.memory_info()[0] / float(2 ** 20) 10 | return mem 11 | 12 | def memory_usage_resource(): 13 | """FASTEST disatvantage: no idea of output unit and whats measured (>~ 10000 per second)""" 14 | import resource 15 | rusage_denom = 1024. 16 | if sys.platform == 'darwin': 17 | # ... it seems that in OSX the output is different units ... 18 | rusage_denom = rusage_denom * rusage_denom 19 | mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / rusage_denom 20 | return mem 21 | 22 | def memory_usage_ps(): 23 | """SLOWEST (ca 100 per second)""" 24 | import subprocess 25 | out = subprocess.Popen(['ps', 'v', '-p', str(os.getpid())], 26 | stdout=subprocess.PIPE).communicate()[0].split(b'\n') 27 | vsz_index = out[0].split().index(b'RSS') 28 | mem = float(out[1].split()[vsz_index]) / 1024 29 | return mem 30 | 31 | def cpu_usage_percent(): 32 | """ """ 33 | cpu_perc = psutil.cpu_percent() 34 | return cpu_perc -------------------------------------------------------------------------------- /core/event.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | class Event(): 5 | 6 | def __init__(self, feature_idx, label_idx): 7 | self.feature_idx = feature_idx 8 | self.label_idx = label_idx 9 | self.count = 1 10 | 11 | def __eq__(self, other): 12 | if isinstance(other, self.__class__): 13 | return (self.feature_idx == other.feature_idx) and (self.label_idx == other.label_idx) 14 | else: 15 | return False 16 | 17 | def __mul__(self, other): 18 | return self.count * other.count 19 | 20 | def __add__(self, other): 21 | return self.count + other.count 22 | 23 | def __ne__(self, other): 24 | return not self.__eq__(other) 25 | 26 | def __lt__(self, other): 27 | return self.feature_idx < other.feature_idx 28 | 29 | def __le__(self, other): 30 | return self.feature_idx <= other.feature_idx 31 | 32 | def __str__(self): 33 | return "feature: " + str(self.feature_idx) + ", label:" + str(self.label_idx) 34 | 35 | def __ge__(self, other): 36 | return self.feature_idx >= other.feature_idx 37 | 38 | def __gt__(self, other): 39 | return self.feature_idx > other.feature_idx 40 | 41 | def __hash__(self): 42 | return hash((self.feature_idx, self.label_idx)) 43 | 44 | -------------------------------------------------------------------------------- /test/resources/test/test_data: -------------------------------------------------------------------------------- 1 | 50,85,50,8,50,35,8,35,8,85,8,8,85,8,8,15 2 | 8,76,34,76,78,38,77,79,40,83,77,78,84,83,82,68,8,50 3 | 15,8,34,15,35,37,38,36,39,35,40,41,35,83,78,77,83,84,83,8,50 4 | 15,8,34,15,76,77,78,38,76,79,40,76,8,50 5 | 15,15,92,15,92,15,92,15,92 6 | 15,35,38,37,39,36,40,41,35,15,35,37,39,36,38,40,41,35 7 | 29,30 8 | 15,70,15,70,15 9 | 29,30,32 10 | 3,4,5,6,15,6 11 | 92,15 12 | 68,68,15 13 | 15,6,15,6,3,4,5,15,6,15,6,15 14 | 15,85,8 15 | 15,41 16 | 29,30,8,8,50 17 | 86,86,86 18 | 15,8,34,15,76,78,79,38,77,40,76,8,50,3,4,5 19 | 8,85,34,85,78,77,38,79,40,85,35,38,35,37,39,36,40,41,35,8,50 20 | 95,95,95,95,95,95,15 21 | 29,30,15,35,38,36,37,39,40,41,35,35,38,36,39,37,40,41,35,15,80,81,80,76,38,78,77,79,40,76,83,83,77,78,84,83,76,80,15 22 | 93,15,93,93,15,93,15 23 | 35,36,38,37,39,35,40,35,41,35,76,38,78,79,77,40,76 24 | 29,30 25 | 35,8 26 | 35,8,35,39,37,38,36,40,41,35,39,38,37,36,35,40,41,35,37,39,36,38,35,40,41,35,36,39,37,38,35,40,41,35,38,37,39,36,35,40,41,35,38,39,37,36,35,40,41,35 27 | 15,8,34,15,35,38,36,39,37,40,41,35,80,81,76,38,77,78,79,40,83,77,78,84,83,83,84,83,78,77,83,84,83,77,78,83,8,50,83,8,76,8,80,8,35,8,15,8,15,8,34,15,76,79,38,78,77,40,76,35,38,36,37,39,40,41,35,76,38,77,79,78,40,80,81,80,76,38,79,77,78,40,83,84,83,77,78,83,8,50,15,8,34,15,76,38,79,77,78,40,83,84,77,78,83,84,77,78,83,76,38,79,78,77,40,8,50,15,68,68,35,8,8 -------------------------------------------------------------------------------- /core/resources/first_step/test/test_data: -------------------------------------------------------------------------------- 1 | 50,85,50,8,50,35,8,35,8,85,8,8,85,8,8,15 2 | 8,76,34,76,78,38,77,79,40,83,77,78,84,83,82,68,8,50 3 | 15,8,34,15,35,37,38,36,39,35,40,41,35,83,78,77,83,84,83,8,50 4 | 15,8,34,15,76,77,78,38,76,79,40,76,8,50 5 | 15,15,92,15,92,15,92,15,92 6 | 15,35,38,37,39,36,40,41,35,15,35,37,39,36,38,40,41,35 7 | 29,30 8 | 15,70,15,70,15 9 | 29,30,32 10 | 3,4,5,6,15,6 11 | 92,15 12 | 68,68,15 13 | 15,6,15,6,3,4,5,15,6,15,6,15 14 | 15,85,8 15 | 15,41 16 | 29,30,8,8,50 17 | 86,86,86 18 | 15,8,34,15,76,78,79,38,77,40,76,8,50,3,4,5 19 | 8,85,34,85,78,77,38,79,40,85,35,38,35,37,39,36,40,41,35,8,50 20 | 95,95,95,95,95,95,15 21 | 29,30,15,35,38,36,37,39,40,41,35,35,38,36,39,37,40,41,35,15,80,81,80,76,38,78,77,79,40,76,83,83,77,78,84,83,76,80,15 22 | 93,15,93,93,15,93,15 23 | 35,36,38,37,39,35,40,35,41,35,76,38,78,79,77,40,76 24 | 29,30 25 | 35,8 26 | 35,8,35,39,37,38,36,40,41,35,39,38,37,36,35,40,41,35,37,39,36,38,35,40,41,35,36,39,37,38,35,40,41,35,38,37,39,36,35,40,41,35,38,39,37,36,35,40,41,35 27 | 15,8,34,15,35,38,36,39,37,40,41,35,80,81,76,38,77,78,79,40,83,77,78,84,83,83,84,83,78,77,83,84,83,77,78,83,8,50,83,8,76,8,80,8,35,8,15,8,15,8,34,15,76,79,38,78,77,40,76,35,38,36,37,39,40,41,35,76,38,77,79,78,40,80,81,80,76,38,79,77,78,40,83,84,83,77,78,83,8,50,15,8,34,15,76,38,79,77,78,40,83,84,77,78,83,84,77,78,83,76,38,79,78,77,40,8,50,15,68,68,35,8,8 -------------------------------------------------------------------------------- /test/test_conditional_index.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import pandas as pd 3 | from core.conditional_index import ConditionalIndex 4 | from core.interaction_index import InteractionIndex 5 | from core.interaction_mapper import InteractionMapper 6 | import numpy as np 7 | 8 | 9 | class TestInteractionIndex(TestCase): 10 | 11 | def test_knn_interaction_query(self): 12 | im = InteractionMapper("./resources/map") 13 | pd_df = pd.read_csv("./resources/interaction_index/interaction_index.txt", header=None) 14 | for col in pd_df.columns: 15 | pd_df[col] = pd_df[col].astype(float) 16 | lambdas = [ 17 | lambda key: True if len(key) > 1 else False, 18 | lambda key: True if len(key) <= 1 else False 19 | ] 20 | ci = ConditionalIndex(im, pd_df.values, lambdas) 21 | 22 | ii = InteractionIndex(im, pd_df.values) 23 | 24 | dummy = ii.knn_interaction_query("a", k=100) 25 | 26 | np.testing.assert_array_equal(ci.knn_interaction_query("a", 0, k=3)[0], list(filter(lambda s: len(s) > 1, dummy[0]))[0:3]) 27 | np.testing.assert_array_equal(ci.knn_interaction_query("a", 1, k=3)[0], list(filter(lambda s: len(s) <= 1, dummy[0]))[0:3]) 28 | np.testing.assert_array_equal(ci.knn_interaction_query("a", k=3)[0], ii.knn_interaction_query("a", k=3)[0]) 29 | -------------------------------------------------------------------------------- /core/resources/second_step/test/test_data: -------------------------------------------------------------------------------- 1 | 50,85,50,8,50,35,8,35,8,85,8,8,85,8,8,15 2 | 8,76,34,76,78,38,77,79,40,83,77,78,84,83,82,68,8,50 3 | 15,8,34,15,35,37,38,36,39,35,40,41,35,83,78,77,83,84,83,8,50 4 | 15,8,34,15,76,77,78,38,76,79,40,76,8,50 5 | 15,15,92,15,92,15,92,15,92 6 | 15,35,38,37,39,36,40,41,35,15,35,37,39,36,38,40,41,35 7 | 29,30 8 | 15,70,15,70,15 9 | 29,30,32 10 | 3,4,5,6,15,6 11 | 92,15 12 | 68,68,15 13 | 15,6,15,6,3,4,5,15,6,15,6,15 14 | 15,85,8 15 | 15,41 16 | 29,30,8,8,50 17 | 86,86,86 18 | 15,8,34,15,76,78,79,38,77,40,76,8,50,3,4,5 19 | 8,85,34,85,78,77,38,79,40,85,35,38,35,37,39,36,40,41,35,8,50 20 | 95,95,95,95,95,95,15 21 | 29,30,15,35,38,36,37,39,40,41,35,35,38,36,39,37,40,41,35,15,80,81,80,76,38,78,77,79,40,76,83,83,77,78,84,83,76,80,15 22 | 93,15,93,93,15,93,15 23 | 35,36,38,37,39,35,40,35,41,35,76,38,78,79,77,40,76 24 | 29,30 25 | 35,8 26 | 35,8,35,39,37,38,36,40,41,35,39,38,37,36,35,40,41,35,37,39,36,38,35,40,41,35,36,39,37,38,35,40,41,35,38,37,39,36,35,40,41,35,38,39,37,36,35,40,41,35 27 | 15,8,34,15,35,38,36,39,37,40,41,35,80,81,76,38,77,78,79,40,83,77,78,84,83,83,84,83,78,77,83,84,83,77,78,83,8,50,83,8,76,8,80,8,35,8,15,8,15,8,34,15,76,79,38,78,77,40,76,35,38,36,37,39,40,41,35,76,38,77,79,78,40,80,81,80,76,38,79,77,78,40,83,84,83,77,78,83,8,50,15,8,34,15,76,38,79,77,78,40,83,84,77,78,83,84,77,78,83,76,38,79,78,77,40,8,50,15,68,68,35,8,8 -------------------------------------------------------------------------------- /test/test_network.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import numpy as np 4 | import tensorflow as tf 5 | 6 | import core.interaction_mapper as um 7 | from core.config import Config 8 | from core.network import Network 9 | 10 | cf = Config("'./resources", continue_previous_run=False) 11 | cf.embedding_size = 3 12 | interaction_map = um.InteractionMapper('./resources/map') 13 | 14 | 15 | class TestNetwork(TestCase): 16 | def test_layer_sizes(self): 17 | test_netowrk = Network(cf, interaction_map) 18 | 19 | input_to_layer = tf.sparse_placeholder(tf.float32, shape=[None, interaction_map.interaction_class_cnt], 20 | name="interaction_feature") 21 | out_layer = test_netowrk.predict(input_to_layer) 22 | out_layer_shape = out_layer.get_shape().as_list() 23 | self.assertTrue(out_layer_shape == [None, cf.embedding_size], msg="layer shape") 24 | 25 | def test__initialize_params_(self): 26 | preheated_embeddings = np.array([ 27 | np.array([-1.0, -1.0, -6.0]), 28 | np.array([-1.0, -1.0, 5.0]), 29 | np.array([-1.0, -1.0, 4.0]), 30 | np.array([-1.0, 3.0, -1.0]), 31 | np.array([1.0, 1.0, -1.0]), 32 | np.array([2.0, 1.0, -1.0]), 33 | np.array([1.0, -1.0, 1.0]), 34 | np.array([1.0, -1.0, -1.0])]) 35 | 36 | interaction_sparse_tensor = interaction_map.idxs_to_tf([2]) 37 | 38 | test_netowrk = Network(cf, interaction_map, preheated_embeddings) 39 | 40 | with tf.Session() as sess: 41 | sess.run(tf.global_variables_initializer()) 42 | result = sess.run(test_netowrk.embedd_interaction_sparse_tensor(interaction_sparse_tensor)) 43 | 44 | np.testing.assert_array_equal(result, [[-1.0, -1.0, 4.0]]) 45 | -------------------------------------------------------------------------------- /core/tensorboard_writer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import numpy as np 3 | import tensorflow as tf 4 | import random 5 | from scipy import stats 6 | import os 7 | import core.interaction_mapper as um 8 | from multiprocessing import Process 9 | 10 | 11 | class TensorboardWriter(object): 12 | 13 | def __init__(self, config): 14 | self.cf = config 15 | 16 | def launchTensorBoard(cmd, path): 17 | os.system(cmd + path + "\"") 18 | return 19 | 20 | 21 | 22 | 23 | p = Process(target=launchTensorBoard, args=(self.cf.tb_command, self.cf.tb_dir)) 24 | p.start() 25 | 26 | self.tensorboard_train_writer = tf.summary.FileWriter(self.cf.tb_dir + "/train") 27 | self.tensorboard_test_writer = tf.summary.FileWriter(self.cf.tb_dir + "/test") 28 | self.tensorboard_log_writer = tf.summary.FileWriter(self.cf.tb_dir + "/log") 29 | 30 | def log_info(self, sess, log_txt): 31 | log_tensor = sess.run(tf.summary.text('info', tf.convert_to_tensor(log_txt))) 32 | self.tensorboard_log_writer.add_summary(log_tensor) 33 | self.tensorboard_log_writer.flush() 34 | 35 | def log_scalar(self, y_val, x_val, tag=""): 36 | summary = tf.Summary(value=[tf.Summary.Value(tag=tag, 37 | simple_value=y_val)]) 38 | self.tensorboard_log_writer.add_summary(summary, x_val) 39 | # log_tensor = sess.run(tf.summary.scalar('info', tf.convert_to_tensor(val))) 40 | # self.tensorboard_log_writer.add_summary(log_tensor) 41 | 42 | def add_train_summary(self, train_output, counter): 43 | self.tensorboard_train_writer.add_summary(train_output, counter) 44 | 45 | def add_test_summary(self, test_output, counter): 46 | self.tensorboard_test_writer.add_summary(test_output, counter) 47 | 48 | def flush(self): 49 | self.tensorboard_train_writer.flush() 50 | self.tensorboard_test_writer.flush() 51 | -------------------------------------------------------------------------------- /core/interaction_index.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import nmslib 3 | 4 | import numpy as np 5 | 6 | 7 | class InteractionIndex(object): 8 | def __init__(self, interaction_mapper, interaction_vectors, method="ghtree", space="cosinesimil"): 9 | self.im = interaction_mapper 10 | self.interaction_vectors = interaction_vectors 11 | self.index = nmslib.init(method=method, space=space) 12 | self.index.addDataPointBatch(interaction_vectors) 13 | 14 | if method == "hnsw": 15 | self.index.createIndex({'post': 2}, print_progress=True) 16 | elif method == "ghtree": 17 | self.index.createIndex() 18 | else: 19 | self.index.createIndex() 20 | # if self.cf.short: 21 | # self.index = nmslib.init(method='ghtree', space='cosinesimil') 22 | # self.index = nmslib.init(method='ghtree', space='l2') 23 | 24 | # else: 25 | # # self.index = nmslib.init(method='hnsw', space='cosinesimil') 26 | # # self.index = nmslib.init(method='ghtree', space='l2') 27 | # self.index = nmslib.init(method='ghtree', space='cosinesimil') 28 | # self.index.addDataPointBatch(interaction_vectors) 29 | # # self.index.createIndex({'post': 2}, print_progress=True) 30 | # self.index.createIndex() 31 | 32 | def knn_idx_query(self, idx_int, k=1): 33 | try: 34 | query_vector = self.interaction_vectors[idx_int] 35 | except: 36 | print("Error: no corresponding interaction found") 37 | return [], [], [] 38 | return self.knn_vector_query(query_vector, k=k) 39 | 40 | def knn_vector_query(self, vec, k=1): 41 | query_vector = vec 42 | ids, distances = self.index.knnQuery(query_vector, k=k) 43 | ret_interaction = [self.im.num_to_interaction(id) for id in ids] 44 | return ret_interaction, ids, distances 45 | 46 | def knn_interaction_query(self, interaction_str, k=1): 47 | return self.knn_idx_query(self.im.interaction_to_num(interaction_str), k=k) 48 | 49 | def safe(self, path): 50 | np.savetxt(path + "/interaction_index.txt", self.interaction_vectors, delimiter=",") 51 | self.im.save(path) 52 | -------------------------------------------------------------------------------- /test/test_loader.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import numpy as np 4 | 5 | import core.interaction_mapper as um 6 | import core.loader as ld 7 | from core.config import Config 8 | from core.event import Event 9 | 10 | interaction_input = """1,2,3 11 | 2,3,2,1,3 12 | 2,5,2,4,3""" 13 | 14 | cf = Config("./resources", continue_previous_run=False) 15 | cf.neighboring_interactions = 1 16 | interaction_mapper = um.InteractionMapper('./resources/map') 17 | interaction_mapper.total_interaction_cnt = 6 18 | interaction_mapper.interaction_class_cnt = 8 19 | 20 | 21 | class TestLoader(TestCase): 22 | 23 | def test_user_journey_to_feature_target(self): 24 | cf.neighboring_interactions = 1 25 | np.random.seed(0) 26 | test_string = "1,2,3,3,4,5,6" 27 | loader = ld.Loader(cf, interaction_mapper, "./resources/train") 28 | compare = [Event(1, 2), 29 | Event(2, 3), 30 | Event(3, 4), 31 | Event(4, 5), 32 | Event(5, 6)] 33 | result = loader._user_journey_to_events(test_string) 34 | np.testing.assert_array_equal(compare, result, err_msg=str(compare) + "!=" + str(result)) 35 | 36 | def test_prepare_events(self): 37 | cf.neighboring_interactions = 1 38 | loader = ld.Loader(cf, interaction_mapper, "./resources/train") 39 | result = loader.unique_train_event_cnt 40 | self.assertTrue(507 == result, msg="507 !=" + str(result)) 41 | 42 | def test_batching(self): 43 | cf.neighboring_interactions = 1 44 | cf.fake_frac = 0.52 45 | loader = ld.Loader(cf, interaction_mapper, "./resources/train") 46 | features, labels, dist_vals = loader.get_next_batch(3) 47 | self.assertTrue(features.dense_shape == [3, 8], msg=("was: " + str(features.dense_shape))) 48 | self.assertTrue(labels.dense_shape == [3, 8], msg="was: " + str(labels.dense_shape)) 49 | np.testing.assert_array_equal(dist_vals, [0, 0, 1], err_msg="wrong dist_vals: " + str(dist_vals)) 50 | 51 | def test__prepare_events(self): 52 | cf.neighboring_interactions = 4 53 | cf.fake_frac = 0 54 | cf.bucket_count = 1 55 | loader = ld.Loader(cf, interaction_mapper, "./resources/train") 56 | found_events = loader.random_generator.data_buckets[0] 57 | identical_target = False 58 | for event in found_events: 59 | if event.feature_idx == event.label_idx: 60 | identical_target = True 61 | self.assertTrue(identical_target == False) 62 | -------------------------------------------------------------------------------- /core/network.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | 4 | class Network: 5 | weights = None 6 | biases = None 7 | 8 | def __init__(self, config, interaction_mapper, preheated_embeddings=None): 9 | self.cf = config 10 | self.im = interaction_mapper 11 | self._initialize_params_(preheated_embeddings) 12 | 13 | def _initialize_params_(self, preheated_embeddings=None): 14 | """preheated_embeddings should be a numpy array""" 15 | rand_std = 1/self.cf.embedding_size 16 | num_categories = self.im.interaction_class_cnt 17 | 18 | if preheated_embeddings is not None: 19 | 20 | if not np.array_equal(self.cf.embedding_size, preheated_embeddings.shape[1]): 21 | raise ValueError('preheated_embeddings embedding size does not match the embedding size: ' + str(self.cf.embedding_size)) 22 | if num_categories < len(preheated_embeddings): 23 | raise ValueError('preheated_embeddings are larger than the network is constructed for, num_categories: ' + str(num_categories)) 24 | 25 | if num_categories > len(preheated_embeddings): 26 | print("INFO: filling missing embedding vectors with a random normal distribution.") 27 | missing_vector_cnt = num_categories - len(preheated_embeddings) 28 | new_rand = np.array(np.random.randn(missing_vector_cnt, self.cf.embedding_size) * rand_std, dtype=np.float32) 29 | initial_embedding = tf.Variable(tf.constant(np.concatenate((preheated_embeddings, new_rand), axis=0))) 30 | else: 31 | print("INFO: Using only the given embeddings.") 32 | initial_embedding = tf.Variable(tf.constant(preheated_embeddings)) 33 | else: 34 | print("INFO: Generate random embeddings.") 35 | initial_embedding = tf.Variable(tf.random_normal([num_categories, self.cf.embedding_size], stddev=rand_std)) 36 | 37 | self.weights = { 38 | 'w_embedding': initial_embedding, 39 | 'w_core': tf.Variable(tf.random_normal([self.cf.embedding_size, self.cf.embedding_size], stddev=rand_std)) 40 | } 41 | 42 | self.biases = { 43 | 'b_core': tf.Variable(tf.random_normal([self.cf.embedding_size])) 44 | } 45 | 46 | def predict(self, interaction_sparse_tensor): 47 | out_embedding = self.embedd_interaction_sparse_tensor(interaction_sparse_tensor) 48 | # out_core = self.layer_core(out_embedding) 49 | 50 | return out_embedding 51 | 52 | def embedd_interaction_sparse_tensor(self, sparse_interaction_tensor): 53 | # TODO: check out tensorflow embedding lookup for speed 54 | embedding_matrix = self.weights['w_embedding'] 55 | result = tf.sparse_tensor_dense_matmul(sparse_interaction_tensor, embedding_matrix) 56 | return result 57 | 58 | def layer_core(self, in_tensor): 59 | return tf.matmul(in_tensor, self.weights['w_core']) + self.biases['b_core'] 60 | 61 | -------------------------------------------------------------------------------- /test/test_trainer.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | import numpy as np 4 | import tensorflow as tf 5 | 6 | import core.interaction_mapper as um 7 | import core.network as nw 8 | import core.trainer as tn 9 | from core.config import Config 10 | 11 | dim = 3 12 | cf = Config('./resources', continue_previous_run=False) 13 | cf.embedding_size = dim 14 | interaction_map = um.InteractionMapper('./resources/map') 15 | network = nw.Network(cf, interaction_map) 16 | trainer = tn.Trainer(cf, network) 17 | 18 | 19 | class TestTrainer(TestCase): 20 | 21 | def test_constructor(self): 22 | self.assertTrue(trainer.merged is not None, msg="does not fail") 23 | 24 | def test__loss_identical_input(self): 25 | interaction_vectors = tf.nn.l2_normalize(tf.constant(np.array([ 26 | np.array([1.0, 1.0, 1.0], np.float32), 27 | np.array([1.0, 1.0, 1.0], np.float32)], np.float32)), 1) 28 | 29 | exp_dist = tf.constant(np.array([0.0, 0.0], np.float32)) 30 | 31 | with tf.Session() as sess: 32 | result = sess.run(trainer._loss_(interaction_vectors, interaction_vectors, interaction_vectors, exp_dist)) 33 | 34 | self.assertTrue(result < 0.001, msg="loss for identical input should be 0") 35 | 36 | def test__loss_opposite_input(self): 37 | interaction_vectors = tf.nn.l2_normalize(tf.constant(np.array([ 38 | np.array([1.0, 1.0, 1.0], np.float32), 39 | np.array([1.0, 1.0, 1.0], np.float32)], np.float32)), 1) 40 | 41 | target = tf.nn.l2_normalize(tf.constant(np.array([ 42 | np.array([-1.0, -1.0, -1.0], np.float32), 43 | np.array([-1.0, -1.0, -1.0], np.float32)], np.float32)), 1) 44 | 45 | exp_dist = tf.constant(np.array([1.0, 1.0], np.float32)) 46 | 47 | with tf.Session() as sess: 48 | result = sess.run(trainer._loss_(interaction_vectors, interaction_vectors, target, exp_dist)) 49 | 50 | self.assertTrue(result < 0.001, msg="loss for opposite input should be exp_dist") 51 | 52 | def test__single_dist_(self): 53 | prediction = tf.constant(np.array([ 54 | np.array([1.0, 1.0, 1.0]), 55 | np.array([1.0, 1.0, 1.0])])) 56 | 57 | with tf.Session() as sess: 58 | result = sess.run(trainer._single_dist_(prediction, prediction)) 59 | 60 | self.assertTrue(len(result) == 2, msg="length incorrect") 61 | self.assertTrue(sum(abs(result - [0, 0])) < 0.001, msg="result incorrect for identical input") 62 | 63 | target = tf.constant(np.array([ 64 | np.array([-1.0, -1.0, -1.0]), 65 | np.array([-1.0, -1.0, -1.0])])) 66 | 67 | with tf.Session() as sess: 68 | result = sess.run(trainer._single_dist_(prediction, target)) 69 | 70 | self.assertTrue(sum(abs(result - [1.0, 1.0])) < 0.001, msg="result incorrect for opposite input") 71 | 72 | def test__normalization_penalty_(self): 73 | vectors = tf.constant(np.array([ 74 | np.array([4.0, 4.0, 4.0, 4.0], dtype=np.float32), 75 | np.array([4.0, 4.0, 4.0, 4.0], dtype=np.float32)])) 76 | with tf.Session() as sess: 77 | result = sess.run(trainer._normalization_penalty_(vectors)) 78 | 79 | self.assertTrue(result == 49.0, msg="") -------------------------------------------------------------------------------- /core/interaction_mapper.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import numpy as np 3 | import tensorflow as tf 4 | from shutil import copyfile 5 | 6 | 7 | class InteractionMapper(object): 8 | def __init__(self, map_path): 9 | 10 | self.interaction_map_path = map_path 11 | self.num_to_interaction_dict, self.interaction_to_num_dict, max_interaction_num = self.load_dictionaries() 12 | self.total_interaction_cnt = max_interaction_num 13 | self.interaction_class_cnt = max_interaction_num + 2 # + default class and cuonting from zero 14 | 15 | def load_dictionaries(self): 16 | 17 | num_to_interaction_dict = dict() 18 | interaction_to_num_dict = dict() 19 | max_interaction_num = 0 20 | 21 | with open(self.interaction_map_path + "/map.txt") as f: 22 | lines = f.read().splitlines() 23 | for line in lines: 24 | entries = line.split(",") 25 | if len(entries) == 2: 26 | 27 | num = int(entries[1]) 28 | interaction = entries[0] 29 | 30 | if max_interaction_num < num: 31 | max_interaction_num = num 32 | 33 | num_to_interaction_dict[num] = interaction 34 | interaction_to_num_dict[interaction] = num 35 | else: 36 | print("Warn: entry seems corrupted (will be ignored), " + line) 37 | print("maximum interaction int found: " + str(max_interaction_num)) 38 | return num_to_interaction_dict, interaction_to_num_dict, max_interaction_num 39 | 40 | def interaction_idx_apply_constraints(self, interaction): 41 | if interaction <= self.total_interaction_cnt: 42 | return interaction 43 | else: 44 | print("WARN: interaction was: " + str(interaction) + ", only maximum of " + str( 45 | self.total_interaction_cnt) + "expected.") 46 | return self.total_interaction_cnt 47 | 48 | def interaction_to_num(self, interaction): 49 | return self.interaction_to_num_dict.get(interaction, self.interaction_class_cnt) 50 | 51 | def num_to_interaction(self, num): 52 | return self.num_to_interaction_dict.get(num, "") 53 | 54 | def idxs_to_tf(self, interaction_int_reps): 55 | batch_size = len(interaction_int_reps) 56 | indices = [] 57 | values = np.ones(batch_size) 58 | shape = [batch_size, self.interaction_class_cnt] 59 | for batch_idx, interaction in enumerate(interaction_int_reps): 60 | interaction_num = self.interaction_idx_apply_constraints(interaction) 61 | indices.append([batch_idx, interaction_num]) 62 | return tf.SparseTensorValue(indices, values, shape) 63 | 64 | def events_to_tf(self, events): 65 | features = self.idxs_to_tf([e.feature for e in events]) 66 | labels = self.idxs_to_tf([e.label for e in events]) 67 | 68 | return features, labels 69 | 70 | def to_string(self): 71 | ret_string = """ 72 | interaction mapping info: 73 | 74 | max interaction int found: """ + str(self.total_interaction_cnt) + """ 75 | assumed unique interactions + 1(default) +1 (index from 0): """ + str(self.interaction_class_cnt) + """ 76 | """ 77 | return ret_string 78 | 79 | def save(self, path): 80 | copyfile(self.interaction_map_path + "/map.txt", path + "/map.txt") 81 | -------------------------------------------------------------------------------- /core/conditional_index.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import nmslib 3 | 4 | import numpy as np 5 | 6 | 7 | class ConditionalIndex(object): 8 | def __init__(self, 9 | interaction_mapper, 10 | interaction_vectors, 11 | lambdas_of_key=list([]), 12 | method="ghtree", 13 | space="cosinesimil", 14 | build_full_index=True): 15 | 16 | self.im = interaction_mapper 17 | self.build_full_index = build_full_index 18 | self.interaction_vectors = interaction_vectors 19 | self.vector_size = len(interaction_vectors[0]) 20 | self.tot_object_cnt = len(interaction_vectors) 21 | 22 | conditional_vectors = [[] for _ in range(len(lambdas_of_key))] 23 | self.conditional_remappings = [dict() for _ in range(len(lambdas_of_key))] #* len(lambdas_of_key) 24 | cnts = [0] * len(lambdas_of_key) 25 | for i, vec in enumerate(interaction_vectors): 26 | key_name = self.im.num_to_interaction(i) 27 | if i % 10000 == 0: 28 | print(str(i)) 29 | for j, fun in enumerate(lambdas_of_key): 30 | if fun(key_name): 31 | self.conditional_remappings[j][cnts[j]] = i 32 | conditional_vectors[j].append(vec) 33 | cnts[j] = cnts[j] + 1 34 | 35 | self.conditional_indices = [] 36 | for j in range(len(lambdas_of_key)): 37 | print("building conditional index...") 38 | self.conditional_indices.append(nmslib.init(method=method, space=space)) 39 | self.conditional_indices[j].addDataPointBatch(conditional_vectors[j]) 40 | if method == "hnsw": 41 | self.conditional_indices[j].createIndex({'post': 2}, print_progress=True) 42 | else: 43 | self.conditional_indices[j].createIndex() 44 | 45 | if self.build_full_index: 46 | print("building full index...") 47 | self.full_index = nmslib.init(method=method, space=space) 48 | self.full_index.addDataPointBatch(self.interaction_vectors) 49 | if method == "hnsw": 50 | self.full_index.createIndex({'post': 2}, print_progress=True) 51 | else: 52 | self.full_index.createIndex() 53 | 54 | 55 | 56 | def knn_vector_query(self, vec, which_index=None, k=1): 57 | query_vector = vec 58 | if which_index is not None: 59 | ids, distances = self.conditional_indices[which_index].knnQuery(query_vector, k=k) 60 | ret_interaction = [self.im.num_to_interaction(self.conditional_remappings[which_index][id]) for id in ids] 61 | return ret_interaction, ids, distances 62 | elif self.build_full_index: # return full query 63 | ids, distances = self.full_index.knnQuery(query_vector, k=k) 64 | ret_interaction = [self.im.num_to_interaction(id) for id in ids] 65 | return ret_interaction, ids, distances 66 | else: 67 | print("ERROR: did not build the full index, please specify the wanted index by providing an integer") 68 | return [], [], [] 69 | 70 | def knn_idx_query(self, idx_int, which_index=None, k=1): 71 | try: 72 | query_vector = self.interaction_vectors[idx_int] 73 | except: 74 | print("Error: no corresponding interaction found") 75 | return [], [], [] 76 | return self.knn_vector_query(query_vector, which_index, k=k) 77 | 78 | def knn_interaction_query(self, interaction_str, which_index=None, k=1): 79 | return self.knn_idx_query(self.im.interaction_to_num(interaction_str), which_index, k=k) 80 | 81 | def safe(self, path): 82 | np.savetxt(path + "/interaction_index.txt", self.interaction_vectors, delimiter=",") 83 | self.im.save(path) 84 | -------------------------------------------------------------------------------- /test/resources/interaction_index/interaction_index.txt: -------------------------------------------------------------------------------- 1 | -3.606674969196319580e-01,-3.401066660881042480e-01,-2.739402949810028076e-01 2 | 2.121080756187438965e-01,-1.369212120771408081e-01,4.798613190650939941e-01 3 | 1.990822255611419678e-01,-3.383659943938255310e-02,1.935769617557525635e-01 4 | 2.424264699220657349e-02,-3.327061831951141357e-01,-1.811371445655822754e-01 5 | 3.982459902763366699e-01,6.637271642684936523e-01,4.405258893966674805e-01 6 | -4.985380172729492188e-01,4.204247295856475830e-01,-3.232162594795227051e-01 7 | 3.481872081756591797e-01,3.762434422969818115e-01,3.295276463031768799e-01 8 | 6.130807995796203613e-01,2.171866595745086670e-02,3.968476355075836182e-01 9 | -8.164949715137481689e-02,-2.928705513477325439e-01,2.266814559698104858e-01 10 | 7.237882018089294434e-01,1.869313605129718781e-02,4.979265034198760986e-01 11 | -2.015585154294967651e-01,3.275489509105682373e-01,3.852422535419464111e-01 12 | -1.673147678375244141e-01,-6.566963791847229004e-01,-1.454118639230728149e-01 13 | 6.490862369537353516e-01,-9.521198458969593048e-03,-4.747462868690490723e-01 14 | -3.484141826629638672e-01,4.742695689201354980e-01,5.075652003288269043e-01 15 | -4.218539297580718994e-01,-3.172385692596435547e-01,4.590567946434020996e-01 16 | -3.883983194828033447e-02,-3.525701463222503662e-01,3.836479485034942627e-01 17 | -1.466140300035476685e-01,1.881533712148666382e-01,-2.654274404048919678e-01 18 | -4.669620692729949951e-01,2.063337415456771851e-01,-2.163386493921279907e-01 19 | 1.314689964056015015e-01,8.920592814683914185e-02,2.985384166240692139e-01 20 | -6.386245489120483398e-01,4.805878400802612305e-01,-3.400329947471618652e-01 21 | -2.807181179523468018e-01,1.822629570960998535e-01,-1.937075704336166382e-01 22 | -4.556678235530853271e-01,2.438870072364807129e-02,2.848663926124572754e-01 23 | -1.624580770730972290e-01,2.413920462131500244e-01,-2.571390569210052490e-01 24 | 1.703463345766067505e-01,-6.096409261226654053e-02,1.775678247213363647e-01 25 | 2.436378896236419678e-01,3.076244704425334930e-02,-1.948756724596023560e-01 26 | -2.190722525119781494e-01,-5.806958079338073730e-01,1.533854603767395020e-01 27 | 2.148722857236862183e-01,-2.481825649738311768e-01,3.114954829216003418e-01 28 | -7.035544514656066895e-02,3.559932578355073929e-03,6.806629300117492676e-01 29 | 6.025252938270568848e-01,-7.848168164491653442e-02,-4.015553370118141174e-02 30 | -4.516124427318572998e-01,2.313833683729171753e-01,-3.917449116706848145e-01 31 | -3.902869820594787598e-01,-3.146697878837585449e-01,1.148736402392387390e-01 32 | -2.284599840641021729e-01,2.824011445045471191e-01,2.457195967435836792e-01 33 | -2.823110222816467285e-01,-7.928730547428131104e-02,3.127407729625701904e-01 34 | 2.025410532951354980e-03,1.229473426938056946e-01,-5.988472606986761093e-03 35 | -9.422522969543933868e-03,-2.923156023025512695e-01,-7.171233892440795898e-01 36 | -4.500901401042938232e-01,-1.267770826816558838e-01,-1.907323151826858521e-01 37 | -8.496683835983276367e-02,-2.806126475334167480e-01,-2.923323214054107666e-01 38 | 7.015712857246398926e-01,-4.255698621273040771e-01,3.139486610889434814e-01 39 | -5.615869164466857910e-01,2.085858583450317383e-01,-1.916405409574508667e-01 40 | 1.357586532831192017e-01,-2.567583024501800537e-01,-2.682809531688690186e-01 41 | -5.225677043199539185e-02,-1.211407855153083801e-01,2.900389730930328369e-01 42 | 2.156189233064651489e-01,-1.466431170701980591e-01,-1.791879087686538696e-01 43 | 1.054098233580589294e-01,-6.841220855712890625e-01,-3.008179664611816406e-01 44 | 1.533340513706207275e-01,2.328467816114425659e-01,4.859318137168884277e-01 45 | 3.878367245197296143e-01,1.918241977691650391e-01,1.099317967891693115e-01 46 | -4.224100410938262939e-01,-5.855655670166015625e-01,-3.751425743103027344e-01 47 | 3.404445648193359375e-01,5.137106776237487793e-02,-5.505413934588432312e-02 48 | -8.562347292900085449e-01,-1.293665319681167603e-01,3.287023007869720459e-01 49 | -4.265097379684448242e-01,-4.322440028190612793e-01,-1.371793150901794434e-01 50 | -4.265097379684448242e-01,-4.322440028190612793e-01,-1.371793150901794434e-01 51 | -------------------------------------------------------------------------------- /core/data_sampler.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import numpy as np 3 | 4 | 5 | class DataSampler(object): 6 | def __init__(self, vals, probs, bucket_count=10): 7 | self.max_prob = max(probs) 8 | self.bucket_count = min(bucket_count, int(len(probs) / 3)) 9 | 10 | print("""RandomSampler: bucketing... 11 | Usage warn: draw first bucket then alll from that bucket. 12 | Should avarage out at the end, not for a single draw!""") 13 | sorted_val_probs = sorted(zip(vals, probs), key=lambda x: x[1], reverse=False) 14 | 15 | bucket_prob_supposed = 1 / self.bucket_count 16 | 17 | self.data_buckets = [np.array([], dtype=np.int32)] * self.bucket_count 18 | self.bucket_probs = [np.array([], dtype=np.float32)] * self.bucket_count 19 | 20 | self.split_idxs = [0] * (self.bucket_count + 1) 21 | 22 | acc_bucket_prob = 0 23 | current_bucket = 0 24 | idx_counter = 0 25 | 26 | for val, prob in sorted_val_probs: 27 | acc_bucket_prob = acc_bucket_prob + prob 28 | 29 | if acc_bucket_prob >= bucket_prob_supposed: 30 | print("bucket determined") 31 | self.split_idxs[current_bucket + 1] = idx_counter 32 | self.bucket_probs[current_bucket] = acc_bucket_prob 33 | current_bucket = current_bucket + 1 34 | acc_bucket_prob = prob 35 | 36 | idx_counter = idx_counter + 1 37 | 38 | self.split_idxs[self.bucket_count] = len(sorted_val_probs) 39 | 40 | for i in range(self.bucket_count): 41 | idx_from = self.split_idxs[i] 42 | idx_to = self.split_idxs[i + 1] 43 | 44 | self.data_buckets[i] = np.array(sorted_val_probs[idx_from:idx_to])[:, 0] 45 | 46 | self.bucket_sizes = [len(bucket) for bucket in self.data_buckets] 47 | 48 | for i in range(len(self.bucket_sizes)): 49 | if self.bucket_sizes[i] == 0: 50 | print("ERROR: one bucket is zero") 51 | if self.bucket_sizes[i] == 1: 52 | print("WARNING: one bucket is small! Content:" + str(self.data_buckets[i][0])) 53 | 54 | print(self.to_string()) 55 | 56 | def get_by_condition(self, lambda_exp=lambda x: x is not None): 57 | res = [] 58 | for bucket in self.data_buckets: 59 | res = res + list(filter(lambda_exp, bucket)) 60 | return res 61 | 62 | def rvs(self, size=1): 63 | chosen_bucket_idx = np.random.randint(0, self.bucket_count) 64 | bucket_size = self.bucket_sizes[chosen_bucket_idx] 65 | if bucket_size is 1: 66 | random_bucket_idxs = np.array([0] * size, np.int32) 67 | else: 68 | random_bucket_idxs = np.random.randint(0, bucket_size - 1, size=size) 69 | return self.data_buckets[chosen_bucket_idx][random_bucket_idxs] 70 | # return np.random.choice(self.vals, size, p=self.probs) SLOW! 71 | # return np.random.choice(self.vals, size) SLOW! 72 | 73 | def get_top_bucket(self): 74 | 75 | ret_dic = dict([ 76 | ("bucket_events", self.data_buckets[-1]), 77 | ("bucket_cnt", self.bucket_sizes[-1]), 78 | ("bucket_prob", self.bucket_probs[-1])]) 79 | 80 | return ret_dic 81 | 82 | def to_string(self): 83 | 84 | ret_string = """ 85 | Result bucket organization: 86 | 87 | maximum probability: """ + str(self.max_prob) + """ 88 | bucket count: """ + str(self.bucket_count) + """ 89 | bucket event counts: """ + str(self.bucket_sizes) + """ 90 | bucket probabilities: """ + str(self.bucket_probs) + """ 91 | """ 92 | # 93 | # for i in range(len(self.data_buckets)): 94 | # to_idx = min(10, len(self.data_buckets[i])) 95 | # events = ", ".join([str(e) for e in self.data_buckets[i][0:to_idx]]) 96 | # approx_prob = str(self.bucket_probs[i] / self.bucket_sizes[i]) 97 | # ret_string = ret_string + "\n\nnapprox prob: " + approx_prob + ", events: " + events 98 | 99 | return ret_string 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Proof of concept (POC) of a recommender of time series categorical data. 2 | We use Tensorboard and nmslib for visualization and nearest neighbor queries, respectively. 3 | 4 | The virtual conda environment can be setup via the included setup.sh script. 5 | 6 | What is under the hood beside python standard libraries such as pandas, scipy, ...: 7 | * nmslib: https://github.com/nmslib/nmslib 8 | * tensorflow: https://github.com/tensorflow/tensorflow 9 | * falcon: https://github.com/falconry/falcon 10 | * gunicorn: https://github.com/benoitc/gunicorn 11 | 12 | Pull-requests are welcome. 13 | 14 | #license 15 | 16 | Copyright 2018 Otto GmbH & Co Kg 17 | 18 | Licensed under the Apache License, Version 2.0 (the "License"); 19 | you may not use this file except in compliance with the License. 20 | You may obtain a copy of the License at 21 | 22 | http://www.apache.org/licenses/LICENSE-2.0 23 | 24 | Unless required by applicable law or agreed to in writing, software 25 | distributed under the License is distributed on an "AS IS" BASIS, 26 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 27 | See the License for the specific language governing permissions and 28 | limitations under the License. 29 | 30 | # training and testing 31 | ## prior data preparation 32 | Prepare data with integer numbers as in test/train_data_small which is used as input. 33 | Each line is one unser interaction history ordered w.r.t. time (see attached data), e.g.: 34 | 35 | ```bash 36 | _,0 37 | a,1 38 | b,2 39 | c,3 40 | d,4 41 | e,5 42 | f,6 43 | ... 44 | ``` 45 | 46 | A map to string is needed (see attached data), e.g.: 47 | 48 | ```bash 49 | 15,8,34,15,76,77,78,38,76,79,40,76,8,50 50 | 15,15,92,15,92,15,92,15,92 51 | 15,35,38,37,39,36,40,41,35,15,35,37,39,36,38,40,41,35 52 | 29,30 53 | 68,68,15 54 | 15,6,15,6,3,4,5,15,6,15,6,15 55 | ... 56 | ``` 57 | 58 | ## overview 59 | Naming convention: 60 | * interaction: one single integer in the history given in the data 61 | * event: one event contains features and targets beside having an occurence count. 62 | 63 | We use the data to generate events. 64 | The events are sparse one-hot encoded according to the integer given in the data file. 65 | Thus, make sure, the user interactions are mapped to unique sequential integer values! 66 | For the translation, we use a mapping, defined in the interaction_map file for easier interpretation. 67 | 68 | 69 | 70 | ## profiling and evaluation 71 | Some performance metrics are plotted with Tensorboard. 72 | Below, the three subsequent runs can be seen, each time adding new data and new cathegories up to 1 million. 73 | The metrics include TODO: explain metrics. 74 | 75 | ![tensorboard_example](doc/figures/tensorboard_example.png) 76 | 77 | The (final) json file produced can be viewed via a chrome browser: 78 | chrome://tracing 79 | 80 | ![json_profiling_example](doc/figures/json_profiling.png) 81 | 82 | 83 | # rest-api falcon 84 | The reco rest api for a single recommender (conditional) index 85 | is shown as example: 86 | ![tensorboard_example](doc/figures/falcon_reco_example.png) 87 | The metrics endpoint is shown in the profiling section below. 88 | 89 | ## starting 90 | We use gunicorn in the virtual environment (see environment.yml) 91 | to start the server. 92 | Start server (set timeout to let it create the index): 93 | ```bash 94 | gunicorn reco:application --timeout=1500 95 | ``` 96 | ## profiling 97 | install: 98 | ```bash 99 | sudo apt install apache2-utils 100 | ``` 101 | profile via, e.g.: 102 | ```bash 103 | ab -c 10 -n 100000 http://127.0.0.1:8000/recos?url=aa 104 | ``` 105 | 106 | Profiling output of the rest-api calls on an i7 local machine for ca. 107 | 600 thousand items with a vector size of 100: 108 | ```bash 109 | Percentage of the requests served within a certain time (ms) 110 | 50% 7 111 | 66% 7 112 | 75% 7 113 | 80% 7 114 | 90% 7 115 | 95% 8 116 | 98% 8 117 | 99% 8 118 | 100% 26 (longest request) 119 | ``` 120 | The internal nmslib call was (shown in the metrics endpoint): 121 | ![tensorboard_example](doc/figures/falcon_reco_profiling_example.png) 122 | 123 | Carl says that's ok. -------------------------------------------------------------------------------- /core/run.py: -------------------------------------------------------------------------------- 1 | import time 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | import pandas as pd 6 | import tensorflow as tf 7 | 8 | import core.loader as ld 9 | from core.interaction_index import InteractionIndex 10 | from core.interaction_mapper import InteractionMapper 11 | from core.metric_profiler import MetricProfiler 12 | from core.network import Network 13 | from core.tensorboard_writer import TensorboardWriter 14 | from core.trainer import Trainer 15 | 16 | 17 | def run(config): 18 | tf.reset_default_graph() 19 | cf = config 20 | um = InteractionMapper(cf.path_interaction_map) 21 | ii = None 22 | mp = False 23 | if cf.continnue_previous_run: 24 | pd_df = pd.read_csv(cf.previous_successful_output_run_dir + "/interaction_indexing/interaction_index.txt", 25 | header=None) 26 | for col in pd_df.columns: 27 | pd_df[col] = pd_df[col].astype(np.float32) 28 | network = Network(cf, um, preheated_embeddings=pd_df.values) 29 | else: 30 | network = Network(cf, um) 31 | train_loader = ld.Loader(cf, um, cf.path_train_data) 32 | test_loader = ld.Loader(cf, um, cf.path_test_data) 33 | trainer = Trainer(cf, network) 34 | 35 | cf.make_dirs() 36 | tbw = TensorboardWriter(cf) 37 | with tf.Session() as sess: 38 | sess.run(tf.global_variables_initializer()) 39 | 40 | log_txt = "Config: " + cf.to_string() + "\n\n" + \ 41 | "Interaction mapper: " + um.to_string() + "\n\n" + \ 42 | "Train Loader @start: " + train_loader.to_string() + "\n\n" + \ 43 | "Test Loader @start: " + test_loader.to_string() 44 | tbw.log_info(sess, log_txt) 45 | 46 | while train_loader.epoch_cnt < cf.epochs: 47 | tb = time.time() 48 | batch_x, batch_y, target_distance = train_loader.get_next_batch(cf.batch_size) 49 | x_label = 1000 * train_loader.event_cnt / train_loader.tot_event_cnt + train_loader.epoch_cnt 50 | 51 | dt_batching = time.time() - tb 52 | tt = time.time() 53 | tensorboard_log_entry = trainer.train(sess, batch_x, batch_y, target_distance) 54 | dt_tensorflow = time.time() - tt 55 | dt_all = time.time() - tb 56 | events_per_sec_in_thousand = cf.batch_size / dt_all / 1000 57 | 58 | tbw.add_train_summary(tensorboard_log_entry, x_label) 59 | tbw.log_scalar(events_per_sec_in_thousand, x_label, tag="performance_metric: 1000 events per second") 60 | tbw.log_scalar(dt_tensorflow / dt_batching, x_label, 61 | tag="performance_metric: delta time tensorflow / delta time batch processing") 62 | 63 | if train_loader.new_epoch: 64 | batch_x, batch_y, target_distance = test_loader.get_next_batch(cf.batch_size * 100, fake_factor=0) 65 | print("epochs: " + str(train_loader.epoch_cnt)) 66 | print("trainer testing...") 67 | tensorboard_log_entry = trainer.test(sess, batch_x, batch_y, target_distance) 68 | tbw.add_test_summary(tensorboard_log_entry, x_label) 69 | tbw.flush() 70 | 71 | print("calculating embedding...") 72 | embedding_vectors = trainer.get_interaction_embeddings(sess) 73 | print("calculating average normalization...") 74 | tbw.log_scalar(np.average(np.linalg.norm(embedding_vectors, axis=1)), x_label, 75 | tag="evaluation_metric: average norm of embedding vectors (normalization condition will force it towards 1)") 76 | print("building index...") 77 | ii = InteractionIndex(um, embedding_vectors) 78 | print("metric profiling...") 79 | mp = MetricProfiler(cf, sess, tbw, train_loader, um, ii) 80 | mp.log_plots(x_label) 81 | print("epoch done") 82 | 83 | print("final logging...") 84 | mp.log_results() 85 | print("write timeline profile...") 86 | with open(cf.timeline_profile_path, 'w') as f: 87 | f.write(trainer.chrome_trace()) 88 | 89 | tbw.flush() 90 | sess.close() 91 | 92 | print("saving index...") 93 | ii.safe(cf.index_safe_path) 94 | 95 | Path(cf.output_run_dir + '/_SUCCESS').touch() 96 | print("success: _SUCCESS generated") 97 | -------------------------------------------------------------------------------- /core/trainer.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.python.client import timeline 3 | 4 | class Trainer(object): 5 | 6 | def __init__(self, config, network): 7 | self.cf = config 8 | self.network = network 9 | self.batch_cnt = 0 10 | 11 | self.x = None 12 | self.y = None 13 | self.train_output = None 14 | self.test_output = None 15 | self.merged = None 16 | self._initialize_graph() 17 | self._initialize_tensorboard() 18 | 19 | def _initialize_graph(self): 20 | """build graph""" 21 | self.x = tf.sparse_placeholder(tf.float32, shape=[None, self.network.im.interaction_class_cnt], name="interaction_feature") 22 | self.y = tf.sparse_placeholder(tf.float32, shape=[None, self.network.im.interaction_class_cnt], name="interaction_label") 23 | self.d = tf.placeholder(tf.float32, shape=[None], name="expected_dist") # for mixing with falsy predictions 24 | 25 | self.interaction_vectors = self.network.embedd_interaction_sparse_tensor(self.x) 26 | self.pred = self.network.predict(self.x) 27 | self.cost = self._loss_( 28 | self.interaction_vectors, 29 | self.pred, 30 | self.network.embedd_interaction_sparse_tensor(self.y), 31 | self.d 32 | ) 33 | 34 | self.optimizer = tf.train.AdamOptimizer(learning_rate=self.cf.learning_rate).minimize(self.cost) # 35 | 36 | def _initialize_tensorboard(self): 37 | self.run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) 38 | self.run_metadata = tf.RunMetadata() 39 | tf.summary.scalar("evaluation_metric: cost", self.cost) 40 | self.merged = tf.summary.merge_all() 41 | 42 | def _single_dist_(self, prediction, target): 43 | # return tf.reduce_sum(tf.pow(prediction - target, 2), 1) 44 | cos_sim = tf.reduce_sum(tf.multiply(tf.nn.l2_normalize(prediction, 1), tf.nn.l2_normalize(target, 1)), axis=1) 45 | cos_dist = tf.divide(tf.ones_like(cos_sim) - cos_sim, 2) # because sim is [-1,1] where 1 is close, so dist is [0,1] where 0 is close 46 | return cos_dist 47 | 48 | def _single_loss_(self, single_dist, exp_dist): 49 | return tf.pow(single_dist - exp_dist, 2) 50 | 51 | def _normalization_penalty_(self, interaction_vectors): 52 | norm = tf.norm(interaction_vectors, axis=1) 53 | norm_minus_one = tf.pow(norm - tf.ones_like(norm, tf.float32), 2) 54 | interaction_vector_norm_renormalization_condition = tf.reduce_mean(norm_minus_one) 55 | 56 | return interaction_vector_norm_renormalization_condition 57 | 58 | def _loss_(self, interaction_vectors, prediction, target, exp_dist): 59 | single_loss = self._single_loss_(self._single_dist_(prediction, target), exp_dist) 60 | return tf.reduce_mean(single_loss) + self._normalization_penalty_(interaction_vectors) 61 | 62 | def train(self, sess, batch_x, batch_y, exp_dist): 63 | 64 | self.train_output = sess.run([self.optimizer, self.merged], # , self.interaction_vector_norm_renormalization_condition 65 | run_metadata=self.run_metadata, 66 | feed_dict={self.x: batch_x, 67 | self.y: batch_y, 68 | self.d: exp_dist}, 69 | options=self.run_options) 70 | 71 | 72 | 73 | return self.train_output[1] # returns something to log with tensorboard 74 | 75 | def chrome_trace(self): 76 | tl = timeline.Timeline(self.run_metadata.step_stats) 77 | ctf = tl.generate_chrome_trace_format() 78 | return ctf 79 | 80 | def test(self, sess, batch_x, batch_y, exp_dist): 81 | self.test_output = sess.run([self.merged, self.cost], # , self.interaction_vector_norm_renormalization_condition 82 | feed_dict={self.x: batch_x, 83 | self.y: batch_y, 84 | self.d: exp_dist}) 85 | print("test cost: " + str(self.test_output[1])) 86 | return self.test_output[0] 87 | 88 | def get_interaction_embeddings(self, sess): 89 | allclasses_cnt = self.network.im.interaction_class_cnt 90 | interaction_sparse_vectors = self.network.im.idxs_to_tf(range(allclasses_cnt)) 91 | return sess.run(self.network.embedd_interaction_sparse_tensor(self.x), feed_dict={self.x: interaction_sparse_vectors}) 92 | 93 | def print_info_(self): 94 | print("--------------------------------------------------------------") 95 | print("merged:", self.train_output[1]) 96 | -------------------------------------------------------------------------------- /falcon_rest_api/metric_aggregator.py: -------------------------------------------------------------------------------- 1 | import os 2 | from time import gmtime, strftime 3 | 4 | import numpy as np 5 | import psutil as psutil 6 | 7 | 8 | class CNT(object): 9 | """counter""" 10 | 11 | def __init__(self): 12 | self.values = None 13 | 14 | def reset(self): 15 | self.values = None 16 | 17 | def step(self, cnt): 18 | if self.values is None: 19 | self.values = cnt 20 | else: 21 | self.values = self.values + cnt 22 | 23 | def __call__(self, i=None): 24 | if self.values is None: 25 | return None 26 | if i is None: 27 | return self.values 28 | else: 29 | return self.values[i] 30 | 31 | def get_values(self): 32 | return self.values 33 | 34 | 35 | class EWMA(object): 36 | """exponential weighted moving average""" 37 | 38 | def __init__(self, half_life_count): 39 | self.values = None 40 | self.factor = np.exp(np.log(0.5) / half_life_count) 41 | 42 | def reset(self): 43 | self.values = None 44 | 45 | def step(self, y): 46 | if self.values is None: 47 | self.values = y 48 | else: 49 | self.values = (self.values - y) * self.factor + y 50 | 51 | def __call__(self, i=None): 52 | if self.values is None: 53 | return None 54 | if i is None: 55 | return self.values 56 | else: 57 | return self.values[i] 58 | 59 | def get_values(self): 60 | return self.values 61 | 62 | 63 | class EWSTD(object): 64 | """exponential weighted moving standard deviation""" 65 | 66 | def __init__(self, half_life_count): 67 | self.maFilterAvg = EWMA(half_life_count) 68 | self.maFilterSquare = EWMA(half_life_count) 69 | 70 | def reset(self): 71 | self.maFilterAvg.reset() 72 | self.maFilterSquare.reset() 73 | 74 | def step(self, y): 75 | self.maFilterAvg.step(y) 76 | self.maFilterSquare.step(pow(y, 2)) 77 | 78 | def get_std(self): 79 | avgs = self.maFilterSquare.get_values() 80 | sq_avgs = self.maFilterAvg.get_values() 81 | if avgs is None or sq_avgs is None: 82 | return None 83 | else: 84 | return np.sqrt(abs(avgs - pow(sq_avgs, 2))) 85 | 86 | def get_avg(self): 87 | return self.maFilterAvg.get_values() 88 | 89 | 90 | class MetricAggregator(object): 91 | 92 | def __init__(self, config): 93 | 94 | self.config = config 95 | self.efSearch = self.config.efSearch 96 | self.neighbors_counter = CNT() 97 | self.batch_neighbors_counter = CNT() 98 | self.neighbors_counter = CNT() 99 | self.failed_counter = CNT() 100 | self.batch_neighbors_ewstd = EWSTD(self.config.half_life_count_dt) 101 | self.neighbors_ewstd = EWSTD(self.config.half_life_count_dt) 102 | 103 | self.start_time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) 104 | self.latest_error = "" 105 | 106 | def failed_request(self, exception, count=1): 107 | self.latest_error = exception 108 | self.failed_counter.step(count) 109 | 110 | def new_batch_request(self, dt, count=1): 111 | self.batch_neighbors_counter.step(count) 112 | self.batch_neighbors_ewstd.step(dt) 113 | 114 | self.h.observe(dt) 115 | 116 | def new_neighbors_request(self, dt, count=1): 117 | self.neighbors_counter.step(count) 118 | self.neighbors_ewstd.step(dt) 119 | 120 | def get_failed_request_count(self): 121 | return self.failed_counter.get_values() 122 | 123 | def get_batch_req_count(self): 124 | return self.batch_neighbors_counter.get_values() 125 | 126 | def get_neighbors_req_count(self): 127 | return self.neighbors_counter.get_values() 128 | 129 | def get_batch_req_dt_avg(self): 130 | return self.batch_neighbors_ewstd.get_avg() 131 | 132 | def get_neighbors_dt_avg(self): 133 | return self.neighbors_ewstd.get_avg() 134 | 135 | def get_batch_req_dt_std(self): 136 | return self.batch_neighbors_ewstd.get_std() 137 | 138 | def get_neighbors_dt_std(self): 139 | return self.neighbors_ewstd.get_std() 140 | 141 | @staticmethod 142 | def memory_usage_psutil(): 143 | """STILL FAST, return the memory usage of a Python module in MB (>~ 10000 per second)""" 144 | process = psutil.Process(os.getpid()) 145 | mem = process.memory_info()[0] / float(2 ** 20) 146 | return mem 147 | 148 | @staticmethod 149 | def cpu_usage_percent(): 150 | """ """ 151 | cpu_perc = psutil.cpu_percent() 152 | return cpu_perc 153 | -------------------------------------------------------------------------------- /core/metric_profiler.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from collections import namedtuple 3 | from itertools import groupby 4 | 5 | MetricEntry = namedtuple("metric_entry", [ 6 | "interaction", 7 | "truth_corresp_interaction", 8 | "truth_corresp_interaction_idx", 9 | "model_interaction_idx", 10 | "rel_position", 11 | "weight", 12 | "found_q" 13 | ]) 14 | 15 | 16 | class MetricProfiler(object): 17 | def __init__(self, config, sess, tb_writer, loader, interaction_mapper, interaction_index): 18 | self.cf = config 19 | self.tbw = tb_writer 20 | self.ld = loader 21 | self.im = interaction_mapper 22 | self.ii = interaction_index 23 | self.sess = sess 24 | 25 | def calc_metrics(self, interactions_considered_cnt, k, result_cnt): 26 | metric_entries = [] 27 | 28 | for cnt in range(interactions_considered_cnt): 29 | print(str(cnt) + " of " + str(interactions_considered_cnt)) 30 | random_interaction_idx = self.ld.random_generator.rvs(size=1)[0].feature_idx 31 | random_interaction_str = self.im.num_to_interaction(random_interaction_idx) 32 | 33 | events_from_true_data = sorted(self.ld.random_generator.get_by_condition( 34 | lambda event: event.feature_idx == random_interaction_idx), 35 | key=lambda e: e.count, reverse=True)[0:result_cnt] 36 | _, query_res_from_model_idxs, _ = self.ii.knn_idx_query(random_interaction_idx, k=k) 37 | 38 | for truth_interaction_idx, re in enumerate(events_from_true_data): 39 | if re.label_idx in query_res_from_model_idxs: 40 | found_q = True 41 | pos_actual = list(query_res_from_model_idxs).index(re.label_idx) 42 | else: 43 | found_q = False 44 | pos_actual = k + 1 45 | 46 | metric_entries = metric_entries + [ 47 | MetricEntry(interaction=random_interaction_str, 48 | truth_corresp_interaction=self.im.num_to_interaction(re.label_idx), 49 | truth_corresp_interaction_idx=truth_interaction_idx, 50 | model_interaction_idx=pos_actual, 51 | rel_position=max(pos_actual - truth_interaction_idx + 1, 0), 52 | weight=re.count, 53 | found_q=found_q)] 54 | return metric_entries 55 | 56 | def log_plots(self, x_label): 57 | metric_res = self.calc_metrics(self.cf.result_cnt_plots, self.cf.knn_plots, self.cf.events_from_true_data) 58 | 59 | weighted_results = [r.rel_position * r.weight for r in metric_res] 60 | weights = [r.weight for r in metric_res] 61 | weighted_pos_avg = sum(weighted_results) / (sum(weights) + 0.000000001) 62 | 63 | self.tbw.log_scalar(weighted_pos_avg, x_label, 64 | tag="evaluation_metric: weighted_pos_avg k=" + str(self.cf.knn_plots) + ", res=" + str( 65 | self.cf.result_cnt_plots)) 66 | 67 | def log_results(self): 68 | metric_res = self.calc_metrics(self.cf.result_cnt_final, self.cf.knn_plots, self.cf.events_from_true_data) 69 | 70 | for key, group in groupby(metric_res, lambda x: x.interaction): 71 | self.log_group(group) 72 | 73 | def log_group(self, group): 74 | group_list = list(group) 75 | log_str = "truth idx,model idx,relative position,weight,interaction\t\t\n" 76 | cnt = 0 77 | for metric_entry in group_list: 78 | cnt = cnt + 1 79 | if cnt <= 50: 80 | log_str = log_str + str(metric_entry.truth_corresp_interaction_idx) + "\t\t," 81 | if metric_entry.found_q: 82 | log_str = log_str + str(metric_entry.model_interaction_idx) + "\t\t," 83 | log_str = log_str + str(metric_entry.rel_position) + "\t\t," 84 | else: 85 | log_str = log_str + "---" + "\t\t," 86 | log_str = log_str + "---" + "\t\t," 87 | log_str = log_str + str(metric_entry.weight) + "\t\t," 88 | log_str = log_str + metric_entry.truth_corresp_interaction + "\t\t\n" 89 | 90 | weighted_results = [r.rel_position * r.weight for r in group_list] 91 | weights = [r.weight for r in group_list] 92 | weighted_pos_avg = sum(weighted_results) / (sum(weights) + 0.000000001) 93 | 94 | log_str = "total weight: " + str(sum(weights)) + "\t\t\n" + log_str 95 | log_str = "weighted pos avg: " + str(weighted_pos_avg) + "\t\t\n" + log_str 96 | log_str = "our interaction: " + group_list[0].interaction + "\t\t\n" + log_str 97 | 98 | self.tbw.log_info(self.sess, log_str) 99 | print(log_str) 100 | -------------------------------------------------------------------------------- /test/resources/train/train_data_2: -------------------------------------------------------------------------------- 1 | 3,4,5,6 2 | 15,8,76,34,76,79,38,78,77,76,40,76,35,38,37,39,35,36,40,35,41,35,80,81,80,82,83,78,77,83,84,83,15,80,81,80,82,83,78,77,84,83 3 | 15,68 4 | 15,85,77,78,79,38,40,85,35,38,37,36,39,40,41,35,37,38,36,39,40,41,35,85,77,38,79,78,40,85,15 5 | 8,76,34,76,78,77,38,79,40,76,35,83,8,76,34,76,38,79,77,78,40,83,77,83,78,84,83,76,38,79,78,77,40,8 6 | 8,15,80,81,80,83,78,77,84,83,8,50 7 | 86,87,86,87,86,88,86,88,3,4,5,89,68,3,4,5,68,68,68,89,68,89,68,89,68,88,68,88,68,88,68,86,88,86,85,78,38,77,79,40,85,86,68,86,68,86,6,86,6 8 | 86,68,86,68 9 | 15,70,15,70,8,70,34,70,15,70,76,38,76,77,78,40,79,76,83,77,78,84,83,35,38,39,36,37,35,40,41,35,15,68 10 | 15,8,15,35,39,37,36,38,40,41,35,15,76,38,78,40,79,77,76,6,8,50 11 | 8,34,15,76,78,77,79,38,40,76,8,50 12 | 15,85,38,78,77,79,85,40,85,15 13 | 15,90,91,15,91,3,4,5,3,4,5,6,7,8,7 14 | 86,88,86,88,86 15 | 50,8,85,34,85,77,79,78,38,40,8 16 | 8,76,38,78,77,79,40,76,68 17 | 15,61,15,61 18 | 29,30,31,6 19 | 29,30,92,15,92 20 | 29,30 21 | 35,39,37,36,38,40,41,35,37,39,36,35,38,40,41,35,37,39,38,36,35,40,41,35 22 | 29,30 23 | 3,4,5,3,4,5,6 24 | 76,8,76,34,76,38,77,78,79,40,35,38,37,39,36,40,41,35,76,8,76,34,76,38,77,78,79,40,76,35,38,39,37,36,40,41,35,38,39,37,36,76,38,77,79,78,40,76,35,38,39,37,36,40,41,35 25 | 15,68,68,15 26 | 8,34,15,76,79,38,40,77,78,76,35,38,36,39,37,40,41,35,80,81,83,77,78,84,68 27 | 29,30,76,8,76,34,76,78,38,79,77,76,40,76 28 | 15,93,15,93,15,93,15,93 29 | 29,30 30 | 8,3,4,5,6,8,50 31 | 35,39,37,38,35,36,35,40,35,41,35,36,39,37,38,35,40,41,35,39,37,38,35,36,35,40,35,41,35,36,37,39,38,35,40,41,35 32 | 86,85,86,85,79,78,77,38,40,85,35,38,37,36,39,40,41,35,85,77,79,38,78,40,85,86 33 | 86,85,86,85,78,38,77,79,40,85,35,85,35,38,36,39,37,40,41,35,85,35,86 34 | 6,3,4,5 35 | 93,15,93,94,15,94,93,15 36 | 86,68,86,68,86,68,85,78,79,38,77,40,85,68,85,38,79,77,78,40,85,35,38,37,39,36,40,41,35,76,38,79,78,77,40,76,83,77,78,84,83,82 37 | 76,8,76,34,76,78,77,79,76,38,76,40,76,8,50 38 | 3,4,5,6,7,8,9,10,9,8,9,8,6 39 | 86,85,38,77,78,79,40,85,86,85,38,77,79,78,40,85,86,85,38,79,77,78,40,85,86,85,38,77,78,79,40,85,86,85,38,79,77,78,40,85,86,85,38,77,79,40,78,85,83,77,78,84,83,85,86 40 | 72,15,72,15,72,15 41 | 15,68,68 42 | 15,8,34,15,76,78,77,79,38,40,76,15,76,78,77,79,38,40,35,38,37,36,39,40,35,41,35,15,8,50,68,8,68,34,68,35,37,36,39,38,35,40,35,41,35,68,8 43 | 29,30,29,30 44 | 8,76,78,79,77,38,40,76,35,38,36,37,39,40,41,35,76,79,77,38,78,40,76,35,39,37,38,36,40,41,35,76,79,38,78,77,40,35,36,39,37,38,40,41,35 45 | 92,15,92,92,15,92,92,15,92,92,15,92,15,92,92,15,92,92,15,92,15,92,15,92,92,15,92,92,15,92,15,92,92,15,92 46 | 35,39,36,37,38,40,35,41,35,39,37,36,38,40,41,35,37,39,38,36,40,35,41,35,39,36,37,38,40,41,35,39,37,36,38,40,41,35,39,37,38,36,35,40,41,35,37,39,36,38,35,40,35,41,35,37,39,36,38,40,41,35,36,37,39,38,40,41,35,36,39,37,38,40,41,35,39,37,38,36,35,40,35,41,35,15,35,39,37,38,36,35,40,41,35,39,37,38,36,35,40,35,41,35,37,36,39,38,40,41,35,39,37,38,36,35,40,35,41,35,39,37,36,38,40,41,35,36,39,37,38,40,41,35,37,39,36,38,40,35,41,35,39,37,36,38,35,40,41,35,15,35,39,37,38,36,40,35,41,35,37,39,38,36,40,41,35,35,37,39,38,36,35,40,41,35,35,37,39,38,36,35,40,41,35,15,35,39,38,37,36,40,35,41,35,39,37,36,38,40,41,35,36,37,39,38,40,41,35,39,37,38,36,35,40,41,35,15,35,39,37,36,38,40,35,41,35,15,35,36,37,39,38,40,35,41,35,39,38,36,37,40,41,35,37,39,36,38,40,41,35,39,37,38,36,35,40,35,41,35,15,35,37,39,38,36,35,40,41,35,37,36,39,38,40,41,35,37,39,36,38,40,41,35,35,37,39,38,36,35,40,41,35,36,39,37,38,40,41,35,39,37,36,38,40,15,35,36,39,37,38,35,40,35,41,35,15,35,37,39,38,36,35,40,41,35,15,35,37,39,36,38,35,40,35,41,35,38,39,37,36,35,40,35,41,35 47 | 15,6,3,4,5,6,7,6,85,77,78,79,38,40,85,35,38,39,36,37,40,41,35,35,39,38,37,36,40,41,35,85,79,77,38,78,40,85,85,38,77,79,78,40,85,80,81,80,85,38,77,79,78,40,85,76,38,79,77,78,40,76,35,39,38,37,36,40,41,35,35,39,38,37,36,40,41,35,85,38,79,78,77,40,85,80,81,80,85,79,38,77,78,40,85,83,77,78,84,83,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,35,38,37,39,36,40,35,41,35,35,35,38,39,37,36,40,35,41,35,85,79,38,78,77,40,85,35,38,39,37,36,40,41,35,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,85,38,79,77,78,40,85,35,39,38,37,36,40,41,35,35,35,85,35,35,35,35,38,39,37,36,40,41,35,15,3,4,5,6,7,6,7,6,85,38,79,78,77,40,85,35,39,38,37,36,40,41,35,35,39,38,36,37,40,41,35,15,85,79,38,77,78,40,85,35,39,38,37,36,40,41,35,35,39,38,37,36,40,41,35,85,15,85,79,78,38,77,40,85,35,38,39,37,36,40,35,41,35,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,85,85,35,85,15,85,78,79,38,77,40,85,15,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,35,38,37,39,36,35,40,85,35,41,85,15,85,79,78,38,77,40,85,15 48 | 85,35,38,37,39,36,40,41,35,85,38,77,40,78,79,85,35,39,38,37,36,40,41,35,85,38,77,78,79,40,35,38,39,37,36,40,41,35,35,38,39,37,36,40,41,35,85,86,85,38,77,78,79,85,40 49 | 8,34,76,78,38,77,79,40,76,83,77,78,84,83 50 | 30,33 51 | 60,15,60,15 52 | 15,8,34,15,35,38,39,37,36,40,41,35,15,80,81,82,82,35,38,39,37,36,40,41,35,80,8,15,6 53 | 72,15,72 54 | 30,32,33 55 | 15,29,15,85,8,85,34,85,78,77,79,85,38,40,85,35,38,37,39,36,35,40,41,35,38,37,39,36,40,41,35,85,38,79,77,78,40,8,85,29,30,29 56 | 3,4,5,3,4,5,6 57 | 15,8,34,15,76,78,77,79,38,40,76,15,35,36,39,37,38,40,35,41,35 58 | 8,34,15,80,81,15 59 | 15,3,4,5,3,4,5,15,6,15,65 60 | 15,76,8,76,34,76,78,38,77,79,40,76,77,38,79,78,40,76 61 | 15,85,8,15,85,8,85,34,85,77,78,79,38,40,85 -------------------------------------------------------------------------------- /core/resources/first_step/train/train_data_2: -------------------------------------------------------------------------------- 1 | 3,4,5,6 2 | 15,8,76,34,76,79,38,78,77,76,40,76,35,38,37,39,35,36,40,35,41,35,80,81,80,82,83,78,77,83,84,83,15,80,81,80,82,83,78,77,84,83 3 | 15,68 4 | 15,85,77,78,79,38,40,85,35,38,37,36,39,40,41,35,37,38,36,39,40,41,35,85,77,38,79,78,40,85,15 5 | 8,76,34,76,78,77,38,79,40,76,35,83,8,76,34,76,38,79,77,78,40,83,77,83,78,84,83,76,38,79,78,77,40,8 6 | 8,15,80,81,80,83,78,77,84,83,8,50 7 | 86,87,86,87,86,88,86,88,3,4,5,89,68,3,4,5,68,68,68,89,68,89,68,89,68,88,68,88,68,88,68,86,88,86,85,78,38,77,79,40,85,86,68,86,68,86,6,86,6 8 | 86,68,86,68 9 | 15,70,15,70,8,70,34,70,15,70,76,38,76,77,78,40,79,76,83,77,78,84,83,35,38,39,36,37,35,40,41,35,15,68 10 | 15,8,15,35,39,37,36,38,40,41,35,15,76,38,78,40,79,77,76,6,8,50 11 | 8,34,15,76,78,77,79,38,40,76,8,50 12 | 15,85,38,78,77,79,85,40,85,15 13 | 15,90,91,15,91,3,4,5,3,4,5,6,7,8,7 14 | 86,88,86,88,86 15 | 50,8,85,34,85,77,79,78,38,40,8 16 | 8,76,38,78,77,79,40,76,68 17 | 15,61,15,61 18 | 29,30,31,6 19 | 29,30,92,15,92 20 | 29,30 21 | 35,39,37,36,38,40,41,35,37,39,36,35,38,40,41,35,37,39,38,36,35,40,41,35 22 | 29,30 23 | 3,4,5,3,4,5,6 24 | 76,8,76,34,76,38,77,78,79,40,35,38,37,39,36,40,41,35,76,8,76,34,76,38,77,78,79,40,76,35,38,39,37,36,40,41,35,38,39,37,36,76,38,77,79,78,40,76,35,38,39,37,36,40,41,35 25 | 15,68,68,15 26 | 8,34,15,76,79,38,40,77,78,76,35,38,36,39,37,40,41,35,80,81,83,77,78,84,68 27 | 29,30,76,8,76,34,76,78,38,79,77,76,40,76 28 | 15,93,15,93,15,93,15,93 29 | 29,30 30 | 8,3,4,5,6,8,50 31 | 35,39,37,38,35,36,35,40,35,41,35,36,39,37,38,35,40,41,35,39,37,38,35,36,35,40,35,41,35,36,37,39,38,35,40,41,35 32 | 86,85,86,85,79,78,77,38,40,85,35,38,37,36,39,40,41,35,85,77,79,38,78,40,85,86 33 | 86,85,86,85,78,38,77,79,40,85,35,85,35,38,36,39,37,40,41,35,85,35,86 34 | 6,3,4,5 35 | 93,15,93,94,15,94,93,15 36 | 86,68,86,68,86,68,85,78,79,38,77,40,85,68,85,38,79,77,78,40,85,35,38,37,39,36,40,41,35,76,38,79,78,77,40,76,83,77,78,84,83,82 37 | 76,8,76,34,76,78,77,79,76,38,76,40,76,8,50 38 | 3,4,5,6,7,8,9,10,9,8,9,8,6 39 | 86,85,38,77,78,79,40,85,86,85,38,77,79,78,40,85,86,85,38,79,77,78,40,85,86,85,38,77,78,79,40,85,86,85,38,79,77,78,40,85,86,85,38,77,79,40,78,85,83,77,78,84,83,85,86 40 | 72,15,72,15,72,15 41 | 15,68,68 42 | 15,8,34,15,76,78,77,79,38,40,76,15,76,78,77,79,38,40,35,38,37,36,39,40,35,41,35,15,8,50,68,8,68,34,68,35,37,36,39,38,35,40,35,41,35,68,8 43 | 29,30,29,30 44 | 8,76,78,79,77,38,40,76,35,38,36,37,39,40,41,35,76,79,77,38,78,40,76,35,39,37,38,36,40,41,35,76,79,38,78,77,40,35,36,39,37,38,40,41,35 45 | 92,15,92,92,15,92,92,15,92,92,15,92,15,92,92,15,92,92,15,92,15,92,15,92,92,15,92,92,15,92,15,92,92,15,92 46 | 35,39,36,37,38,40,35,41,35,39,37,36,38,40,41,35,37,39,38,36,40,35,41,35,39,36,37,38,40,41,35,39,37,36,38,40,41,35,39,37,38,36,35,40,41,35,37,39,36,38,35,40,35,41,35,37,39,36,38,40,41,35,36,37,39,38,40,41,35,36,39,37,38,40,41,35,39,37,38,36,35,40,35,41,35,15,35,39,37,38,36,35,40,41,35,39,37,38,36,35,40,35,41,35,37,36,39,38,40,41,35,39,37,38,36,35,40,35,41,35,39,37,36,38,40,41,35,36,39,37,38,40,41,35,37,39,36,38,40,35,41,35,39,37,36,38,35,40,41,35,15,35,39,37,38,36,40,35,41,35,37,39,38,36,40,41,35,35,37,39,38,36,35,40,41,35,35,37,39,38,36,35,40,41,35,15,35,39,38,37,36,40,35,41,35,39,37,36,38,40,41,35,36,37,39,38,40,41,35,39,37,38,36,35,40,41,35,15,35,39,37,36,38,40,35,41,35,15,35,36,37,39,38,40,35,41,35,39,38,36,37,40,41,35,37,39,36,38,40,41,35,39,37,38,36,35,40,35,41,35,15,35,37,39,38,36,35,40,41,35,37,36,39,38,40,41,35,37,39,36,38,40,41,35,35,37,39,38,36,35,40,41,35,36,39,37,38,40,41,35,39,37,36,38,40,15,35,36,39,37,38,35,40,35,41,35,15,35,37,39,38,36,35,40,41,35,15,35,37,39,36,38,35,40,35,41,35,38,39,37,36,35,40,35,41,35 47 | 15,6,3,4,5,6,7,6,85,77,78,79,38,40,85,35,38,39,36,37,40,41,35,35,39,38,37,36,40,41,35,85,79,77,38,78,40,85,85,38,77,79,78,40,85,80,81,80,85,38,77,79,78,40,85,76,38,79,77,78,40,76,35,39,38,37,36,40,41,35,35,39,38,37,36,40,41,35,85,38,79,78,77,40,85,80,81,80,85,79,38,77,78,40,85,83,77,78,84,83,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,35,38,37,39,36,40,35,41,35,35,35,38,39,37,36,40,35,41,35,85,79,38,78,77,40,85,35,38,39,37,36,40,41,35,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,85,38,79,77,78,40,85,35,39,38,37,36,40,41,35,35,35,85,35,35,35,35,38,39,37,36,40,41,35,15,3,4,5,6,7,6,7,6,85,38,79,78,77,40,85,35,39,38,37,36,40,41,35,35,39,38,36,37,40,41,35,15,85,79,38,77,78,40,85,35,39,38,37,36,40,41,35,35,39,38,37,36,40,41,35,85,15,85,79,78,38,77,40,85,35,38,39,37,36,40,35,41,35,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,85,85,35,85,15,85,78,79,38,77,40,85,15,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,35,38,37,39,36,35,40,85,35,41,85,15,85,79,78,38,77,40,85,15 48 | 85,35,38,37,39,36,40,41,35,85,38,77,40,78,79,85,35,39,38,37,36,40,41,35,85,38,77,78,79,40,35,38,39,37,36,40,41,35,35,38,39,37,36,40,41,35,85,86,85,38,77,78,79,85,40 49 | 8,34,76,78,38,77,79,40,76,83,77,78,84,83 50 | 30,33 51 | 60,15,60,15 52 | 15,8,34,15,35,38,39,37,36,40,41,35,15,80,81,82,82,35,38,39,37,36,40,41,35,80,8,15,6 53 | 72,15,72 54 | 30,32,33 55 | 15,29,15,85,8,85,34,85,78,77,79,85,38,40,85,35,38,37,39,36,35,40,41,35,38,37,39,36,40,41,35,85,38,79,77,78,40,8,85,29,30,29 56 | 3,4,5,3,4,5,6 57 | 15,8,34,15,76,78,77,79,38,40,76,15,35,36,39,37,38,40,35,41,35 58 | 8,34,15,80,81,15 59 | 15,3,4,5,3,4,5,15,6,15,65 60 | 15,76,8,76,34,76,78,38,77,79,40,76,77,38,79,78,40,76 61 | 15,85,8,15,85,8,85,34,85,77,78,79,38,40,85 -------------------------------------------------------------------------------- /core/resources/second_step/train/train_data_2: -------------------------------------------------------------------------------- 1 | 3,4,5,6 2 | 15,8,76,34,76,79,38,78,77,76,40,76,35,38,37,39,35,36,40,35,41,35,80,81,80,82,83,78,77,83,84,83,15,80,81,80,82,83,78,77,84,83 3 | 15,68 4 | 15,85,77,78,79,38,40,85,35,38,37,36,39,40,41,35,37,38,36,39,40,41,35,85,77,38,79,78,40,85,15 5 | 8,76,34,76,78,77,38,79,40,76,35,83,8,76,34,76,38,79,77,78,40,83,77,83,78,84,83,76,38,79,78,77,40,8 6 | 8,15,80,81,80,83,78,77,84,83,8,50 7 | 86,87,86,87,86,88,86,88,3,4,5,89,68,3,4,5,68,68,68,89,68,89,68,89,68,88,68,88,68,88,68,86,88,86,85,78,38,77,79,40,85,86,68,86,68,86,6,86,6 8 | 86,68,86,68 9 | 15,70,15,70,8,70,34,70,15,70,76,38,76,77,78,40,79,76,83,77,78,84,83,35,38,39,36,37,35,40,41,35,15,68 10 | 15,8,15,35,39,37,36,38,40,41,35,15,76,38,78,40,79,77,76,6,8,50 11 | 8,34,15,76,78,77,79,38,40,76,8,50 12 | 15,85,38,78,77,79,85,40,85,15 13 | 15,90,91,15,91,3,4,5,3,4,5,6,7,8,7 14 | 86,88,86,88,86 15 | 50,8,85,34,85,77,79,78,38,40,8 16 | 8,76,38,78,77,79,40,76,68 17 | 15,61,15,61 18 | 29,30,31,6 19 | 29,30,92,15,92 20 | 29,30 21 | 35,39,37,36,38,40,41,35,37,39,36,35,38,40,41,35,37,39,38,36,35,40,41,35 22 | 29,30 23 | 3,4,5,3,4,5,6 24 | 76,8,76,34,76,38,77,78,79,40,35,38,37,39,36,40,41,35,76,8,76,34,76,38,77,78,79,40,76,35,38,39,37,36,40,41,35,38,39,37,36,76,38,77,79,78,40,76,35,38,39,37,36,40,41,35 25 | 15,68,68,15 26 | 8,34,15,76,79,38,40,77,78,76,35,38,36,39,37,40,41,35,80,81,83,77,78,84,68 27 | 29,30,76,8,76,34,76,78,38,79,77,76,40,76 28 | 15,93,15,93,15,93,15,93 29 | 29,30 30 | 8,3,4,5,6,8,50 31 | 35,39,37,38,35,36,35,40,35,41,35,36,39,37,38,35,40,41,35,39,37,38,35,36,35,40,35,41,35,36,37,39,38,35,40,41,35 32 | 86,85,86,85,79,78,77,38,40,85,35,38,37,36,39,40,41,35,85,77,79,38,78,40,85,86 33 | 86,85,86,85,78,38,77,79,40,85,35,85,35,38,36,39,37,40,41,35,85,35,86 34 | 6,3,4,5 35 | 93,15,93,94,15,94,93,15 36 | 86,68,86,68,86,68,85,78,79,38,77,40,85,68,85,38,79,77,78,40,85,35,38,37,39,36,40,41,35,76,38,79,78,77,40,76,83,77,78,84,83,82 37 | 76,8,76,34,76,78,77,79,76,38,76,40,76,8,50 38 | 3,4,5,6,7,8,9,10,9,8,9,8,6 39 | 86,85,38,77,78,79,40,85,86,85,38,77,79,78,40,85,86,85,38,79,77,78,40,85,86,85,38,77,78,79,40,85,86,85,38,79,77,78,40,85,86,85,38,77,79,40,78,85,83,77,78,84,83,85,86 40 | 72,15,72,15,72,15 41 | 15,68,68 42 | 15,8,34,15,76,78,77,79,38,40,76,15,76,78,77,79,38,40,35,38,37,36,39,40,35,41,35,15,8,50,68,8,68,34,68,35,37,36,39,38,35,40,35,41,35,68,8 43 | 29,30,29,30 44 | 8,76,78,79,77,38,40,76,35,38,36,37,39,40,41,35,76,79,77,38,78,40,76,35,39,37,38,36,40,41,35,76,79,38,78,77,40,35,36,39,37,38,40,41,35 45 | 92,15,92,92,15,92,92,15,92,92,15,92,15,92,92,15,92,92,15,92,15,92,15,92,92,15,92,92,15,92,15,92,92,15,92 46 | 35,39,36,37,38,40,35,41,35,39,37,36,38,40,41,35,37,39,38,36,40,35,41,35,39,36,37,38,40,41,35,39,37,36,38,40,41,35,39,37,38,36,35,40,41,35,37,39,36,38,35,40,35,41,35,37,39,36,38,40,41,35,36,37,39,38,40,41,35,36,39,37,38,40,41,35,39,37,38,36,35,40,35,41,35,15,35,39,37,38,36,35,40,41,35,39,37,38,36,35,40,35,41,35,37,36,39,38,40,41,35,39,37,38,36,35,40,35,41,35,39,37,36,38,40,41,35,36,39,37,38,40,41,35,37,39,36,38,40,35,41,35,39,37,36,38,35,40,41,35,15,35,39,37,38,36,40,35,41,35,37,39,38,36,40,41,35,35,37,39,38,36,35,40,41,35,35,37,39,38,36,35,40,41,35,15,35,39,38,37,36,40,35,41,35,39,37,36,38,40,41,35,36,37,39,38,40,41,35,39,37,38,36,35,40,41,35,15,35,39,37,36,38,40,35,41,35,15,35,36,37,39,38,40,35,41,35,39,38,36,37,40,41,35,37,39,36,38,40,41,35,39,37,38,36,35,40,35,41,35,15,35,37,39,38,36,35,40,41,35,37,36,39,38,40,41,35,37,39,36,38,40,41,35,35,37,39,38,36,35,40,41,35,36,39,37,38,40,41,35,39,37,36,38,40,15,35,36,39,37,38,35,40,35,41,35,15,35,37,39,38,36,35,40,41,35,15,35,37,39,36,38,35,40,35,41,35,38,39,37,36,35,40,35,41,35 47 | 15,6,3,4,5,6,7,6,85,77,78,79,38,40,85,35,38,39,36,37,40,41,35,35,39,38,37,36,40,41,35,85,79,77,38,78,40,85,85,38,77,79,78,40,85,80,81,80,85,38,77,79,78,40,85,76,38,79,77,78,40,76,35,39,38,37,36,40,41,35,35,39,38,37,36,40,41,35,85,38,79,78,77,40,85,80,81,80,85,79,38,77,78,40,85,83,77,78,84,83,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,35,38,37,39,36,40,35,41,35,35,35,38,39,37,36,40,35,41,35,85,79,38,78,77,40,85,35,38,39,37,36,40,41,35,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,85,38,79,77,78,40,85,35,39,38,37,36,40,41,35,35,35,85,35,35,35,35,38,39,37,36,40,41,35,15,3,4,5,6,7,6,7,6,85,38,79,78,77,40,85,35,39,38,37,36,40,41,35,35,39,38,36,37,40,41,35,15,85,79,38,77,78,40,85,35,39,38,37,36,40,41,35,35,39,38,37,36,40,41,35,85,15,85,79,78,38,77,40,85,35,38,39,37,36,40,35,41,35,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,85,85,35,85,15,85,78,79,38,77,40,85,15,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,35,38,37,39,36,35,40,85,35,41,85,15,85,79,78,38,77,40,85,15 48 | 85,35,38,37,39,36,40,41,35,85,38,77,40,78,79,85,35,39,38,37,36,40,41,35,85,38,77,78,79,40,35,38,39,37,36,40,41,35,35,38,39,37,36,40,41,35,85,86,85,38,77,78,79,85,40 49 | 8,34,76,78,38,77,79,40,76,83,77,78,84,83 50 | 30,33 51 | 60,15,60,15 52 | 15,8,34,15,35,38,39,37,36,40,41,35,15,80,81,82,82,35,38,39,37,36,40,41,35,80,8,15,6 53 | 72,15,72 54 | 30,32,33 55 | 15,29,15,85,8,85,34,85,78,77,79,85,38,40,85,35,38,37,39,36,35,40,41,35,38,37,39,36,40,41,35,85,38,79,77,78,40,8,85,29,30,29 56 | 3,4,5,3,4,5,6 57 | 15,8,34,15,76,78,77,79,38,40,76,15,35,36,39,37,38,40,35,41,35 58 | 8,34,15,80,81,15 59 | 15,3,4,5,3,4,5,15,6,15,65 60 | 15,76,8,76,34,76,78,38,77,79,40,76,77,38,79,78,40,76 61 | 15,85,8,15,85,8,85,34,85,77,78,79,38,40,85 -------------------------------------------------------------------------------- /core/config.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import glob 3 | import os 4 | 5 | 6 | class Config: 7 | """Contains static configurations""" 8 | 9 | def __init__(self, root_folder, continue_previous_run=True, output_folder=""): 10 | # DIRECTORIES: 11 | self.root_folder = root_folder 12 | self.path_train_data = self.root_folder + '/train' 13 | self.path_test_data = self.root_folder + '/test' 14 | self.path_interaction_map = self.root_folder + '/map' 15 | self.output_run_dir = os.getcwd() + output_folder + "/run_" + datetime.datetime.now().strftime( 16 | "%Y_%B_%d_%H:%M:%S") 17 | self.tb_dir = self.output_run_dir + "/tensorboard" 18 | self.index_safe_path = self.output_run_dir + "/interaction_indexing" 19 | self.timeline_profile_path = self.output_run_dir + "/timeline_profile/timeline.json" 20 | self.tb_command = "bash -c \"source /home/chambroc/miniconda3/bin/activate crystal && tensorboard --logdir=" 21 | 22 | # PREVIOUS RUN DATA 23 | self.continnue_previous_run = continue_previous_run 24 | self.previous_successful_output_run_dir = None 25 | all_outputs = sorted(glob.glob(os.getcwd() + output_folder + "/*"), reverse=False) 26 | if len(all_outputs) > 0: 27 | for folder in all_outputs: 28 | if len(glob.glob(folder + "/_SUCCESS")) > 0: 29 | self.previous_successful_output_run_dir = folder 30 | if self.continnue_previous_run and (self.previous_successful_output_run_dir is None): 31 | self.continnue_previous_run = False 32 | print("WARN: no successful previous run found!") 33 | input("Press Enter to continue with new random initialization...") 34 | 35 | # NETWORK SETUP: 36 | self.embedding_size = 3 # vector length of user interaction representation 37 | 38 | # TRAINING SETUP: 39 | self.epochs = 50 # number of epochs (epoch = whole train data processed) to train 40 | self.batch_size = 100000 # number of events processed in single step in tensorflow 41 | self.fake_frac = 0.7 # fraction of generated fake events for triplet loss 42 | self.bucket_count = 10 # buckets of the self-made event randomizer 43 | self.bucket_sampling_type = "sigmoid" # can be "sigmoid" or "default", default is sampling by count, sigmoid is samling by sigmoid of count to suppress often occuring events 44 | self.neighboring_interactions = 10 # distance of user_interactions still considered 45 | self.learning_rate = 0.001 # learning rate for tensorflow 46 | 47 | # EVALUATION SETUP: 48 | self.events_from_true_data = 100 # top events considered from true data when calculating weighted_pos_avg 49 | self.knn_plots = 200 # nearest neighbor search for tensorboard plots (weighted_pos_avg) 50 | self.result_cnt_plots = 50 # weighted random interactions considered for weighted_pos_avg when plotting 51 | self.knn_final = 200 # nearest neighbor search explicit logging after entire training 52 | self.result_cnt_final = 50 # weighted random interactions considered for weighted_pos_avg for final log 53 | 54 | def make_dirs(self): 55 | os.mkdir(self.output_run_dir) 56 | 57 | os.mkdir(self.output_run_dir + "/tensorboard") 58 | os.mkdir(self.output_run_dir + "/tensorboard/train") 59 | os.mkdir(self.output_run_dir + "/tensorboard/test") 60 | os.mkdir(self.output_run_dir + "/tensorboard/log") 61 | 62 | os.mkdir(self.output_run_dir + "/timeline_profile") 63 | os.mkdir(self.output_run_dir + "/interaction_indexing") 64 | 65 | def to_string(self): 66 | ret_string = """ 67 | Paths for in and output: 68 | 69 | root_folder: """ + self.root_folder + """ 70 | path_train_data: """ + self.path_train_data + """ 71 | path_test_data: """ + self.path_test_data + """ 72 | path_interaction_map: """ + self.path_interaction_map + """ 73 | 74 | output_run_dir: """ + self.output_run_dir + """ 75 | tb_dir: """ + self.tb_dir + """ 76 | index_safe_path: """ + self.index_safe_path + """ 77 | timeline_profile_path: """ + self.timeline_profile_path + """ 78 | 79 | Previous model dependence: 80 | 81 | previous_successful_output_run_dir: """ + str(self.previous_successful_output_run_dir) + """ 82 | 83 | General parameters of the config: 84 | 85 | epochs: """ + str(self.epochs) + """ 86 | embedding_size: """ + str(self.embedding_size) + """ 87 | batch size: """ + str(self.batch_size) + """ 88 | fake fraction: """ + str(self.fake_frac) + """ 89 | bucket count: """ + str(self.bucket_count) + """ 90 | learning rate: """ + str(self.learning_rate) + """ 91 | neighboring_interactions: """ + str(self.neighboring_interactions) + """ 92 | 93 | Evaluation setup: 94 | 95 | events_from_true_data: """ + str(self.events_from_true_data) + """ 96 | knn_plots: """ + str(self.knn_plots) + """ 97 | result_cnt_plots: """ + str(self.result_cnt_plots) + """ 98 | knn_final: """ + str(self.knn_final) + """ 99 | """ 100 | return ret_string 101 | -------------------------------------------------------------------------------- /falcon_rest_api/reco.py: -------------------------------------------------------------------------------- 1 | # reco.py 2 | import os 3 | import random 4 | import sys 5 | import time 6 | import numpy as np 7 | 8 | import falcon 9 | import pandas as pd 10 | 11 | print(os.getcwd()) 12 | sys.path.insert(0, os.getcwd() + '/../') 13 | 14 | from core.interaction_index import InteractionIndex 15 | from core.interaction_mapper import InteractionMapper 16 | from falcon_rest_api.config import Config 17 | from falcon_rest_api.ewma import EWMA 18 | from falcon_rest_api.cnt import CNT 19 | from core.conditional_index import ConditionalIndex 20 | import falcon_rest_api.machine_metrics as met 21 | 22 | cf = Config("/home/chambroc/Desktop/RecoResults/ThreeInARowMoreEvents/day3/interaction_indexing") 23 | cf.method = "hnsw" 24 | print("loading data...") 25 | pd_df = pd.read_csv(cf.source_dir + "/interaction_index.txt", header=None) 26 | for col in pd_df.columns: 27 | pd_df[col] = pd_df[col].astype(float) 28 | print("building conditional index...") 29 | 30 | filter_funs = [ 31 | lambda key: True if "suche" in key else False, 32 | lambda key: True if "/p/" in key else False, 33 | lambda key: False if ("suche" in key) or ("/p/" in key) else True, 34 | ] 35 | 36 | multi_index = ConditionalIndex( 37 | InteractionMapper(map_path=cf.source_dir), 38 | pd_df.values, 39 | lambdas_of_key=filter_funs, 40 | method=cf.method, 41 | space=cf.space) 42 | # print("building index full...") 43 | # main_index = InteractionIndex(im, pd_df.values, method=cf.method, space=cf.space) 44 | 45 | print("...index ready") 46 | ewma_dt = EWMA(100) 47 | ewma_frac = EWMA(10000) 48 | cnt = CNT() 49 | num_classes = multi_index.im.interaction_class_cnt 50 | 51 | class RecoResource(object): 52 | def on_get(self, req, resp): 53 | t = time.time() 54 | resp.status = falcon.HTTP_200 55 | request_url = req.get_param('url', default=None) 56 | if request_url is None: 57 | random_url_idx = random.randint(0, num_classes) 58 | request_url = multi_index.im.num_to_interaction(random_url_idx) 59 | k = int(req.get_param('k', default=100)) 60 | url_result = multi_index.knn_interaction_query(request_url, k=k)[0] 61 | search_result = multi_index.knn_interaction_query(request_url, 0, k=k)[0] 62 | product_result = multi_index.knn_interaction_query(request_url, 1, k=k)[0] 63 | other_result = multi_index.knn_interaction_query(request_url, 2, k=k)[0] 64 | resp.media = { 65 | 'url': request_url, 66 | 'knn_urls': list(url_result), 67 | 'search_result': list(search_result), 68 | 'product': list(product_result), 69 | 'other': list(other_result) 70 | } 71 | dt = time.time() - t 72 | if dt > 0.05: 73 | bucket = np.array([0.0, 0.0, 0.0, 0.0, 0.0], dtype=np.float32) 74 | elif dt > 0.01: 75 | bucket = np.array([100.0, 0.0, 0.0, 0.0, 0.0], dtype=np.float32) 76 | elif dt > 0.005: 77 | bucket = np.array([100.0, 100.0, 0.0, 0.0, 0.0], dtype=np.float32) 78 | elif dt > 0.001: 79 | bucket = np.array([100.0, 100.0, 100.0, 0.0, 0.0], dtype=np.float32) 80 | elif dt > 0.0005: 81 | bucket = np.array([100.0, 100.0, 100.0, 100.0, 0.0], dtype=np.float32) 82 | else: 83 | bucket = np.array([100.0, 100.0, 100.0, 100.0, 100.0], dtype=np.float32) 84 | ewma_dt.step(dt) 85 | ewma_frac.step(bucket) 86 | cnt.step(1) 87 | 88 | 89 | class MetricsResource(object): 90 | def on_get(self, req, resp): 91 | """Handles GET requests""" 92 | resp.status = falcon.HTTP_200 93 | dt_avg = ewma_dt.values 94 | 95 | 96 | dt_avg_in_s = ewma_dt.values 97 | perc_dt_50 = float(ewma_frac(0)) 98 | perc_dt_10 = float(ewma_frac(1)) 99 | if dt_avg_in_s is None: 100 | statement = "no traffic means, it's fast enough" 101 | elif dt_avg_in_s * 1000 < 5 and perc_dt_50 > 99.99 and perc_dt_10 > 99.8: 102 | statement = "excellent job" 103 | elif dt_avg_in_s * 1000 < 10 and perc_dt_50 > 99.8: 104 | statement = "you need to drill deeper \n - thats what she said" 105 | else: 106 | statement = "your mama is faster than this" 107 | 108 | resp.media = { 109 | 'num_classes': num_classes, 110 | 'embedding_matrix_size': (multi_index.tot_object_cnt, multi_index.vector_size), 111 | 'space': cf.space, 112 | 'method': cf.method, 113 | 'average_last_100_request_duration_in_s': dt_avg, 114 | 'total_calls': cnt.values, 115 | 'mem_usage_mb': met.memory_usage_psutil(), 116 | 'cpu_usage_perc': met.cpu_usage_percent(), 117 | 'perc_last_10000_below_50ms': float(ewma_frac(0)), 118 | 'perc_last_10000_below_10ms': float(ewma_frac(1)), 119 | 'perc_last_10000_below_5ms': float(ewma_frac(2)), 120 | 'perc_last_10000_below_1ms': float(ewma_frac(3)), 121 | 'perc_last_10000_below_0.5ms': float(ewma_frac(4)), 122 | 'what_would_carl_say': statement 123 | } 124 | 125 | 126 | class WhatWouldCarlSay(object): 127 | def on_get(self, req, resp): 128 | """Handles GET requests""" 129 | resp.status = falcon.HTTP_200 130 | dt_avg_in_s = ewma_dt.values 131 | if dt_avg_in_s is None: 132 | statement = "no traffic means, it's fast enough" 133 | elif dt_avg_in_s * 1000 < 5: 134 | statement = "this is fine" 135 | elif dt_avg_in_s * 1000 < 10: 136 | statement = "you can do better" 137 | else: 138 | statement = "your mama is faster than this" 139 | resp.media = { 140 | 'statement': statement 141 | } 142 | 143 | 144 | # falcon.API instances are callable WSGI apps 145 | application = falcon.API() 146 | 147 | # Resources are represented by long-lived class instances 148 | # will handle all requests to the URL path 149 | application.add_route('/reco', RecoResource()) 150 | application.add_route('/metrics', MetricsResource()) 151 | application.add_route('/whatwouldcarlsay', WhatWouldCarlSay()) 152 | -------------------------------------------------------------------------------- /core/loader.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import math 3 | import random 4 | 5 | import numpy as np 6 | 7 | from core.data_sampler import DataSampler 8 | from core.event import Event 9 | 10 | 11 | class Loader(object): 12 | def __init__(self, config, interaction_mapper, path): 13 | """will try to read ALL files in path!""" 14 | self.cf = config 15 | self.root_path = path 16 | self.random_generator, self.tot_event_cnt, self.unique_train_event_cnt = self._prepare_events() 17 | self.im = interaction_mapper 18 | self.epoch_cnt = 0 19 | self.batch_cnt = 0 20 | self.event_cnt = 0 21 | self.new_epoch = True 22 | 23 | def _user_journey_to_events(self, journey_string): 24 | """journey_string needs to be comma separated integers, i.e., 15,35,37,38,...""" 25 | user_interaction = journey_string.split(",") 26 | events = [] 27 | for i in range(len(user_interaction) - 1): 28 | interaction = user_interaction[i] 29 | f_idx = int(interaction) 30 | 31 | for n in range(self.cf.neighboring_interactions + 1): 32 | if n + i > len(user_interaction) - 1: 33 | break 34 | interaction_plus_n = user_interaction[i + n] 35 | t_idx = int(interaction_plus_n) 36 | if f_idx is not t_idx: 37 | events.append(Event(f_idx, t_idx)) 38 | return events 39 | 40 | def _prepare_events(self): 41 | """generating all events and defining the data_sampler""" 42 | events = dict() 43 | cnt_tot_events = 0 44 | cnt_uniqe_events = 0 45 | 46 | for file_url in glob.glob(self.root_path + "/*"): 47 | with open(file_url) as f: 48 | for line in f: 49 | for new_event in self._user_journey_to_events(line): 50 | cnt_tot_events = cnt_tot_events + 1 51 | if new_event in events: 52 | events[new_event] = events[new_event] + 1 53 | else: 54 | events[new_event] = 1 55 | cnt_uniqe_events = cnt_uniqe_events + 1 56 | if cnt_tot_events % 100000 is 0: 57 | print("Events in list: " + str(cnt_tot_events)) 58 | print("Events in dict: " + str(len(events))) 59 | 60 | xk = list(events.keys()) 61 | for e, cnt in zip(events, events.values()): # TODO: make this nicer by aggregation and sum elements 62 | e.count = cnt 63 | 64 | if self.cf.bucket_sampling_type is "sigmoid": 65 | pk = list(map(lambda x: 1 / (1 + math.exp(-x)) - 1/2, np.array(list(events.values())))) 66 | pk = np.array(pk) / sum(pk) 67 | else: 68 | pk = list(np.array(list(events.values())) / cnt_tot_events) 69 | 70 | random_generator = DataSampler(xk, pk, bucket_count=self.cf.bucket_count) # 71 | return random_generator, cnt_tot_events, cnt_uniqe_events 72 | 73 | 74 | def _update_processed_state(self, batch_size): 75 | """update metainformation for processing""" 76 | if self.event_cnt % self.unique_train_event_cnt >= (self.event_cnt + batch_size) % self.unique_train_event_cnt: 77 | self.epoch_cnt += 1 78 | self.new_epoch = True 79 | self.batch_cnt += 1 80 | self.event_cnt += batch_size 81 | 82 | 83 | def get_random_events(self, size): 84 | return self.random_generator.rvs(size=size) 85 | 86 | 87 | def get_next_batch(self, batch_size, fake_factor=None): 88 | """draw random batch according to random_sampler and fake events for triplet loss""" 89 | if fake_factor is None: 90 | fake_factor = self.cf.fake_frac 91 | 92 | eff_batch_size = min(batch_size, self.unique_train_event_cnt) 93 | 94 | self.new_epoch = False 95 | 96 | fake_batch_size = int(eff_batch_size * fake_factor) 97 | real_batch_size = eff_batch_size - fake_batch_size 98 | 99 | real_batch_events = self.get_random_events(real_batch_size) 100 | fake_batch_events = self.get_random_events(fake_batch_size) 101 | 102 | fake_batch_events_clone = [Event(e.feature_idx, random.randint(0, self.im.total_interaction_cnt)) for e in 103 | fake_batch_events] 104 | 105 | full_events = np.concatenate((real_batch_events, fake_batch_events_clone), axis=0) 106 | 107 | features = self.im.idxs_to_tf([e.feature_idx for e in full_events]) 108 | labels = self.im.idxs_to_tf([e.label_idx for e in full_events]) 109 | target_distance = np.concatenate((np.zeros(len(real_batch_events), np.float32), 110 | np.ones(len(fake_batch_events), np.float32)), axis=0) 111 | 112 | self._update_processed_state(eff_batch_size) 113 | return features, labels, target_distance 114 | 115 | 116 | def get_all_data(self): 117 | """return all events""" 118 | return self.random_generator.get_by_condition() 119 | 120 | 121 | def to_string(self): 122 | ret_string = """ 123 | General parameters of the loader: 124 | 125 | events considered in total: """ + str(self.tot_event_cnt) + """ 126 | unique train events: """ + str(self.unique_train_event_cnt) + """ 127 | epochs processed: """ + str(self.epoch_cnt) + """ 128 | batches processed: """ + str(self.batch_cnt) + """ 129 | events processed: """ + str(self.event_cnt) + """ 130 | 131 | 132 | """ + self.random_generator.to_string() + """\n\ntop bucket: \n\n""" 133 | 134 | top_bucket_info = "" 135 | top_bucket = self.random_generator.get_top_bucket() 136 | cnt = top_bucket["bucket_cnt"] 137 | prob = top_bucket["bucket_prob"] 138 | single_event_prob = prob / cnt 139 | avg_occurence_per_top_event = self.tot_event_cnt * single_event_prob 140 | 141 | top_bucket_info = top_bucket_info + "avg event occurence: " + str(avg_occurence_per_top_event) + "\n\n" 142 | top_bucket_info = top_bucket_info + """---------------------------------------------------- 143 | """ 144 | for e in top_bucket["bucket_events"][0:20]: 145 | top_bucket_info = top_bucket_info + "feature: " + self.im.num_to_interaction( 146 | e.feature_idx) + ", feature_idx: " + str(e.feature_idx) + """ 147 | """ 148 | top_bucket_info = top_bucket_info + "target: " + self.im.num_to_interaction( 149 | e.label_idx) + ", label_idx: " + str(e.label_idx) + """" 150 | """ 151 | top_bucket_info = top_bucket_info + "occurence count: " + str(e.count) + """ 152 | """ 153 | top_bucket_info = top_bucket_info + """---------------------------------------------------- 154 | """ 155 | 156 | return ret_string + top_bucket_info 157 | -------------------------------------------------------------------------------- /falcon_rest_api/multi_recos.py: -------------------------------------------------------------------------------- 1 | # reco.py 2 | import os 3 | import random 4 | import sys 5 | import time 6 | import numpy as np 7 | 8 | import falcon 9 | import operator 10 | import pandas as pd 11 | 12 | print(os.getcwd()) 13 | sys.path.insert(0, os.getcwd() + '/../') 14 | 15 | from core.interaction_index import InteractionIndex 16 | from core.interaction_mapper import InteractionMapper 17 | from falcon_rest_api.multi_config import MultiConfig 18 | from falcon_rest_api.ewma import EWMA 19 | from falcon_rest_api.cnt import CNT 20 | 21 | # 22 | # import os 23 | # import psutil 24 | # process = psutil.Process(os.getpid()) 25 | # print(process.memory_info().rss) 26 | 27 | cf = MultiConfig([ 28 | # "/home/chambroc/Desktop/RecoResults/ThreeInARow/day1/interaction_indexing", 29 | # "/home/chambroc/Desktop/RecoResults/ThreeInARow/day2/interaction_indexing", 30 | # "/home/chambroc/Desktop/RecoResults/ThreeInARow/day3/interaction_indexing", 31 | # "/home/chambroc/Desktop/RecoResults/ThreeInARow120/day1/interaction_indexing", 32 | "/home/chambroc/Desktop/RecoResults/ThreeInARow120/day2/interaction_indexing", 33 | "/home/chambroc/Desktop/RecoResults/ThreeInARow120/day3/interaction_indexing", 34 | # "/home/chambroc/Desktop/RecoResults/ThreeInARowMoreEvents/day1/interaction_indexing", 35 | "/home/chambroc/Desktop/RecoResults/ThreeInARowMoreEvents/day2/interaction_indexing", 36 | "/home/chambroc/Desktop/RecoResults/ThreeInARowMoreEvents/day3/interaction_indexing", 37 | ]) 38 | cf.method='ghtree' 39 | print("building maps and indices......") 40 | iis = [] 41 | for dir in cf.source_dirs: 42 | print(dir) 43 | im = InteractionMapper(map_path=dir) 44 | print("...map ready") 45 | print("building index...") 46 | pd_df = pd.read_csv(dir + "/interaction_index.txt", header=None) 47 | for col in pd_df.columns: 48 | pd_df[col] = pd_df[col].astype(float) 49 | iis = iis + [InteractionIndex(im, pd_df.values, method=cf.method, space=cf.space)] 50 | print("...index ready") 51 | 52 | num_classes = iis[0].im.interaction_class_cnt 53 | ewma_dt = EWMA(100) 54 | ewma_frac = EWMA(10000) 55 | cnt = CNT() 56 | jaccard_cnt = CNT() 57 | tot_jaccard = CNT() 58 | 59 | 60 | class RecoResource(object): 61 | def on_get(self, req, resp): 62 | t = time.time() 63 | resp.status = falcon.HTTP_200 64 | request_url = req.get_param('url') 65 | k_val = int(req.get_param('k', default=10)) 66 | multi_results = [ii.knn_interaction_query(request_url, k=k_val)[0] for ii in iis] 67 | intersecting_results = list( 68 | set(multi_results[0]).intersection(*[set(res) for res in multi_results[1:len(multi_results)]])) 69 | union_res = set().union(*[set(s) for s in multi_results]) 70 | resulting_merge = dict() 71 | for res in union_res: 72 | resulting_merge[res] = 0 73 | for q_res in multi_results: 74 | if res in q_res: 75 | resulting_merge[res] = resulting_merge[res] + 1 76 | resulting_merge_tups = sorted(resulting_merge.items(), key=operator.itemgetter(1), reverse=True) 77 | ret_dict = {'url': request_url, 78 | 'sources': cf.source_dirs, 79 | 'intersecting_results': intersecting_results, 80 | 'weighted results': resulting_merge_tups} 81 | for idx, res in enumerate(multi_results): 82 | ret_dict['knn_urls_' + str(idx)] = list(res) 83 | resp.media = ret_dict 84 | # PROFILING FROM HERE: 85 | dt = time.time() - t 86 | if dt > 0.05: 87 | bucket = np.array([0.0, 0.0, 0.0, 0.0, 0.0], dtype=np.float32) 88 | elif dt > 0.01: 89 | bucket = np.array([100.0, 0.0, 0.0, 0.0, 0.0], dtype=np.float32) 90 | elif dt > 0.005: 91 | bucket = np.array([100.0, 100.0, 0.0, 0.0, 0.0], dtype=np.float32) 92 | elif dt > 0.001: 93 | bucket = np.array([100.0, 100.0, 100.0, 0.0, 0.0], dtype=np.float32) 94 | elif dt > 0.0005: 95 | bucket = np.array([100.0, 100.0, 100.0, 100.0, 0.0], dtype=np.float32) 96 | else: 97 | bucket = np.array([100.0, 100.0, 100.0, 100.0, 100.0], dtype=np.float32) 98 | ewma_dt.step(dt) 99 | ewma_frac.step(bucket) 100 | cnt.step(1) 101 | 102 | 103 | class DrawRandomResource(object): 104 | def on_get(self, req, resp): 105 | resp.status = falcon.HTTP_200 106 | k_val = int(req.get_param('k', default=10)) 107 | random_url_idx = random.randint(0, num_classes) 108 | url_str = iis[0].im.num_to_interaction(random_url_idx) 109 | multi_results = [ii.knn_idx_query(random_url_idx, k=k_val)[0] for ii in iis] 110 | intersecting_results = list( 111 | set(multi_results[0]).intersection(*[set(res) for res in multi_results[1:len(multi_results)]])) 112 | union_res = set().union(*[set(s) for s in multi_results]) 113 | resulting_merge = dict() 114 | for res in union_res: 115 | resulting_merge[res] = 0 116 | for q_res in multi_results: 117 | if res in q_res: 118 | resulting_merge[res] = resulting_merge[res] + 1 119 | resulting_merge_tups = sorted(resulting_merge.items(), key=operator.itemgetter(1), reverse=True) 120 | ret_dict = {'url': url_str, 121 | 'sources': cf.source_dirs, 122 | 'intersecting_results': intersecting_results, 123 | 'weighted results': resulting_merge_tups} 124 | for idx, res in enumerate(multi_results): 125 | ret_dict['knn_urls_' + str(idx)] = list(res) 126 | resp.media = ret_dict 127 | 128 | 129 | class JaccardResource(object): 130 | def on_get(self, req, resp): 131 | resp.status = falcon.HTTP_200 132 | request_url = req.get_param('url') 133 | k_val = int(req.get_param('k', default=10)) 134 | multi_results = [ii.knn_interaction_query(request_url, k=k_val) for ii in iis] 135 | ret_dict = {'url': request_url, 136 | 'sources': cf.source_dirs} 137 | all_jaccard = np.array([]) 138 | for i in range(len(multi_results)): 139 | for j in range(i + 1, len(multi_results)): 140 | a = set(multi_results[i][0]) 141 | b = set(multi_results[j][0]) 142 | union_len = len(a.union(a, b)) 143 | intersec_len = len(a.intersection(b)) 144 | jd = 1 - intersec_len / union_len 145 | ret_dict[str(i) + "vs" + str(j)] = jd 146 | all_jaccard = np.append(all_jaccard, jd) 147 | resp.media = ret_dict 148 | tot_jaccard.step(all_jaccard) 149 | jaccard_cnt.step(1) 150 | 151 | 152 | class JaccardRandomResource(object): 153 | def on_get(self, req, resp): 154 | 155 | resp.status = falcon.HTTP_200 156 | k_val = int(req.get_param('k', default=10)) 157 | 158 | random_url_idx = random.randint(0, num_classes) 159 | url_str = iis[0].im.num_to_interaction(random_url_idx) 160 | multi_results = [ii.knn_idx_query(random_url_idx, k=k_val)[0] for ii in iis] 161 | 162 | ret_dict = {'url': url_str, 163 | 'sources': cf.source_dirs} 164 | all_jaccard = np.array([]) 165 | for i in range(len(multi_results)): 166 | for j in range(i + 1, len(multi_results)): 167 | a = set(multi_results[i]) 168 | b = set(multi_results[j]) 169 | union_len = len(a.union(a, b)) 170 | intersec_len = len(a.intersection(b)) 171 | jd = 1 - intersec_len / union_len 172 | ret_dict[str(i) + "vs" + str(j)] = jd 173 | all_jaccard = np.append(all_jaccard, jd) 174 | resp.media = ret_dict 175 | 176 | tot_jaccard.step(all_jaccard) 177 | jaccard_cnt.step(1) 178 | 179 | 180 | class MetricsResource(object): 181 | def on_get(self, req, resp): 182 | """Handles GET requests""" 183 | resp.status = falcon.HTTP_200 184 | dt_avg = ewma_dt.values 185 | resp.media = { 186 | 'average_last_100_request_duration_in_s': dt_avg, 187 | 'total_calls': cnt.values, 188 | 'jaccard_cnt': jaccard_cnt.values, 189 | 'jaccard_avgs': list(tot_jaccard.values / jaccard_cnt.values), 190 | 'perc_last_10000_below_50ms': float(ewma_frac(0)), 191 | 'perc_last_10000_below_10ms': float(ewma_frac(1)), 192 | 'perc_last_10000_below_5ms': float(ewma_frac(2)), 193 | 'perc_last_10000_below_1ms': float(ewma_frac(3)), 194 | 'perc_last_10000_below_0.5ms': float(ewma_frac(4)) 195 | } 196 | 197 | 198 | class WhatWouldCarlSay(object): 199 | def on_get(self, req, resp): 200 | """Handles GET requests""" 201 | resp.status = falcon.HTTP_200 202 | dt_avg_in_s = ewma_dt.values 203 | if dt_avg_in_s is None: 204 | statement = "no traffic means, it's fast enough" 205 | elif dt_avg_in_s * 1000 < 5: 206 | statement = "this is fine" 207 | elif dt_avg_in_s * 1000 < 10: 208 | statement = "you can do better" 209 | else: 210 | statement = "your mama is faster than this" 211 | resp.media = { 212 | 'statement': statement 213 | } 214 | 215 | 216 | application = falcon.API() 217 | application.add_route('/reco', RecoResource()) 218 | application.add_route('/randomreco', DrawRandomResource()) 219 | application.add_route('/metrics', MetricsResource()) 220 | application.add_route('/jaccard', JaccardResource()) 221 | application.add_route('/randomjaccard', JaccardRandomResource()) 222 | application.add_route('/whatwouldcarlsay', WhatWouldCarlSay()) 223 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /test/resources/train/train_data_1: -------------------------------------------------------------------------------- 1 | 1,2,3,4,5,6,7,8,9,10,11,12,11,12,8,13,8,14,8,13,8,13,8 2 | 15,16 3 | 17,18,17,19,15,17,21,19,17 4 | 20,22,23,22,24,22,25,26,25,26 5 | 27,28,27,28,27 6 | 29,30,31,32,33,32,33 7 | 15,8,34,15,35,36,37,38,35,39,40,41,35,44,45,8,50,15,51,52,53,52,54,52,55,56,55,57,55,58,55,59,60,61,62,63,64,65 8 | 66,18,66,67 9 | 8,35,34,35,37,38,39,35,36,40,35,41,35,37,38,39,36,35,40,41,35,37,38,39,36,35,40,41,35,35,37,36,38,39,40,35,41,35,68,69,68,35,38,37,39,36,35,40,41,35 10 | 70,71,15,71,15,72,15,73,72,15,72 11 | 29,30,74 12 | 15,75,15,75,15,75,15 13 | 6,8,6,76,38,77,78,79,76,40,76,35,38,39,37,36,35,40,35,41,35,76,38,79,77,78,76,40,76,8,50 14 | 86,86,86,85,38,77,85,78,79,40,85,85,15,85,38,79,77,78,40,85 15 | 15,85,38,85,77,78,79,40,85,15 16 | 15,83,8,83,34,83,78,77,84,83 17 | 15,76,8,76,34,76,78,77,79,38,76,40,76,35,38,37,36,39,35,40,35,41,35,80,81,80,82,83,78,77,83,84,83,83,80,81,80,82,82,8,50 18 | 86,86,3,4,5,6,7,6,8,7,8,34,86,85,78,79,77,38,40,85,8 19 | 86,85,86,85,38,78,77,79,40,85 20 | 15,3,4,5,15 21 | 92,15,92,29,30,31 22 | 8,34,35,38,39,37,36,35,40,41,35,83,77,78,83,84,83,6 23 | 15,6,3,4,5,5,3,4,5,5,6,3,4,5,3,4,5,6,15,85,38,78,77,79,40,85,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,85,35,85,38,77,79,78,40,85,15,29,29,6,29,15 24 | 15,8,34,15,3,4,5,3,4,5,3,4,5,6,7,6,7 25 | 9,76,78,38,40,76,68,3,4,5,6,3,4,5,93,15,93,3,4,5,3,4,5,6,7,7,34,6,15,3,4,5,6,7,6,76,78,79,77,38,40,76,76,38,79,77,78,40,76,76,79,77,38,78,40,76,79,77,38,78,40,76,6,7,6,15,6,8,6,34,6,7 26 | 15,3,4,5,68,68,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,68,6,3,4,5,6,7,8,7,34,6,7 27 | 35,8,35,34,35,38,36,37,39,35,40,41,35,83,78,77,83,84,83 28 | 15,85,38,78,77,79,40,85,15,29,15,85,79,38,77,78,40,85,15,29,15,85,79,78,38,77,40,85,85,80,81,82,80,35,39,37,35,36,38,40,35,41,35,37,36,39,35,38,40,35,41,35,39,37,38,36,40,41,35 29 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6 30 | 15,76,78,38,77,79,40,76 31 | 76,8,76,34,76,78,38,79,77,76,40,76,8,50 32 | 15,3,4,5,6 33 | 15,85,78,79,77,38,85,40,85,77,79,38,78,40,85,15 34 | 30,32,33,32 35 | 15,70,71,15,71,71 36 | 15,35,8,35,34,35,39,37,36,38,35,40,35,41,35,82,82,8,50 37 | 15,75 38 | 86,86,3,4,5,5,6,3,4,5,5,3,4,5,5 39 | 8,76,8,15,35,8,15,76,8 40 | 15,85,8,85,34,85,79,77,78,38,40,85,35,38,37,39,36,40,35,41,35,38,39,37,36,40,35,41,35,85,38,77,79,78,40,85,38,77,79,78,40,8 41 | 6,3,4,5,3,4,5,3,4,5,6,7,8,7,34,8,50 42 | 15,8,34,15,35,37,38,36,39,35,40,35,41,35,80,81,80,35,38,36,39,37,35,40,35,41,35,8,50 43 | 15,85,78,79,38,77,40,85,85,38,79,77,40,78,85,85,38,78,79,77,40,85,85,38,77,79,78,40,85,85,38,79,78,77,40,85,85,79,77,38,78,40,85 44 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,15,3,4,5,6,15,3,4,5,6,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,3,4,5,6,15,6,7,8,8,6,15,6,7 45 | 86,6,86,6,85,8,85,78,38,85,86,40,86,85,83,84,78,83,80,81,80,83,84,78,83,80,81,80,83,84,78,83,85,38,78,40,85,8 46 | 15,35,8,35,34,35,39,36,37,38,40,35,41,35,8 47 | 15,9,15 48 | 76,8,76,34,76,78,38,77,76,79,40,76,83,77,78,83,84,83,68,76,79,38,77,78,40,76,68,76,79,38,78,77,76,40,76,83,84,77,78,83,76,38,79,77,78,76,40,76,68,15 49 | 15,76,8,76,34,76,78,77,76,38,79,40,76,8,50,76,8,76,34,76,79,77,78,38,76,40,76,8,50,15,76,8,76,77,38,78,79,76,40,76,82,76,83,78,77,83,84,83,8,50 50 | 29,30,29 51 | 76,78,77,79,38,40,76,79,77,38,78,40,76,83,83,77,78,83,84,83 52 | 15,72,15,72,15 53 | 15,6,15,3,4,5,3,4,5,15,68,6,15,6,7,8,7,34,8,50,50,8,8,7,8,7,8,8,7,8,7,8,6,15,8,34,15,35,38,37,36,35,39,35,40,41,35,8,50,35,8,15,8,15 54 | 29,30 55 | 86,86,86 56 | 50,15,85,8,85,34,85,38,79,78,77,85,40,85,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,35,38,37,39,36,40,41,35,35,38,37,39,36,40,41,35,85,38,79,78,77,40,85,83,77,78,84,83,85,38,79,77,78,40,85,8 57 | 15,35,8,35,38,39,36,37,35,40,41,35,83,78,83,84,83,80,81 58 | 15,76,8,76,34,76,78,38,77,79,40,76 59 | 85,35,38,37,36,39,40,41,35,85,38,78,77,79,40,85,15,85,79,38,78,77,85,40,15 60 | 8,35,8,35,34,35,38,37,39,36,35,40,35,41,35,37,39,36,38,35,40,35,41,35,80,81,80,82,82,8,50 61 | 76,78,38,77,79,76,40,76 62 | 92,15,92,15,92,15,92,15,3,4,5,3,4,5 63 | 86,70,15,70,70,86 64 | 86,86,86,85,86,85,38,77,78,79,40,85,86 65 | 8,34,15,35,37,38,39,36,40,35,41,35 66 | 70,15,70,15,70 67 | 15,85,38,77,78,79,40,35,38,37,39,36,40,41,35,85,38,77,79,78,40,85,15,85,77,78,79,38,40,35,38,39,37,36,35,40,35,41,35,15 68 | 8,68,34,68,8,50 69 | 15,76,8,76,34,76,77,38,78,79,40,76,83,77,78,83,84,83,8,50 70 | 15,92,15,92,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,3,5,3,4,5,3,4,5,3,4,5,15,6,15,3,4,5,6,7,8,7,34,29,30 71 | 86,86,85,78,77,79,38,40,85,35,38,37,36,35,39,40,41,35,85,77,79,38,78,40 72 | 15,68,68,68,6,15 73 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,7,8,9,10,8,9,10,11,12,11,12,7,34 74 | 15,85,38,77,79,78,40,85,15 75 | 70,15,70,15,70,15,70 76 | 15,6 77 | 29,30 78 | 15,8,15,35,38,37,36,39,35,40,41,35,83,78,77,83,84,83,15,80,81,83,78,77,83,93,84,93,15,93,35,37,38,39,35,36,40,41,35,83,84,77,78,83 79 | 86,68,86,68,68,3,4,5,6,7,6 80 | 50,85,8,85,34,85,38,78,77,79,85,40,85,6,15,3,4,5,3,4,5,6,85,79,38,78,77,40,85,6,7,6,3,4,5,6,3,4,5,5,6,15,6,15,3,4,5,6,7,6,85,79,78,77,38,40,8,85 81 | 8,76,34,76,78,38,77,79,40,76,8,50 82 | 6,8,6,34,68,68,35,38,36,37,39,40,41,35 83 | 15,8,34,15,76,38,77,78,40,79,83,77,83,78,84,6,83,84,77,78,83,3,4,5,3,4,5,3,4,5,15,3,4,5,3,4,5,3,4,5,15,3,4,5,6,7,15,35,38,36,37,35,39,40,41,35,35,38,37,36,39,35,40,41,35,35,38,37,36,39,35,40,41,35,15 84 | 15,35,8,35,34,35,38,36,37,39,40,41,35,76,38,77,78,79,40,76,76,35,38,37,39,36,40,41,35,15,35,8,35,34,35,38,36,37,39,40,41,35 85 | 92,15,92 86 | 35,8,35,34,35,39,37,38,36,35,40,41,35,83,77,78,83,84,83,3,4,5,6,15,6,15,6 87 | 29,30,32,33 88 | 15,85,78,77,38,79,40,85,35,38,36,37,39,40,41,35,85,79,38,78,77,40,85 89 | 86,68,86,68,68,68,68,68,15,68,86 90 | 93,15,93,93,15 91 | 15,35,8,35,34,35,37,36,35,38,39,40,41,35,35,38,37,36,35,39,40,35,41,35,35,37,38,35,39,36,35,40,41,35,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,8,50 92 | 15,6 93 | 68,68 94 | 15,6,85,77,78,38,79,85,35,40,35,38,37,39,36,40,41,35,82,35,35,39,38,37,36,40,41,35,15,6,85,79,77,78,38,40,85,35,38,39,37,36,40,41,35,15,85,77,78,79,38,40,85,35,38,37,39,36,40,41,35,85,35,85,77,38,79,78,40,85,85,77,79,38,78,40,85,85,85,38,79,77,78,40,85,35,38,36,39,37,40,41,35,76,38,79,78,77,40,76,76,85,79,38,78,77,40,85,15,6,85,79,78,38,77,40,85,35,38,36,37,39,40,41,35,15,85,79,38,78,77,40,85,15,85,79,78,77,38,40,85,35,38,37,36,39,40,41,35 95 | 86,86,85,77,38,78,79,40,85,86,86,85,38,77,78,79,40,85 96 | 8,76,34,76,78,79,77,76,38,40,76,8 97 | 29,30,15,29,30,32,33,74 98 | 60,15,60,60,15,60 99 | 68,6,7,68,35,37,39,38,36,35,40,41,35,82,35,35,38,36,37,39,35,40,35,41,35,35,68,35,37,39,38,36,35,40,41,35,35,35,35,38,37,39,36,40,35,41,35,35,38,37,39,36,35,40,35,41,35,35,37,39,38,36,35,40,35,41,35,78,84,77,35,38,37,39,36,35,40,35,41,35 100 | 50,85,50,8,8,8,8,8,8,7,8,8,7,8,8,7,8,68,68,68,15,85,8,85,38,79,77,78,85,40,85,83,77,78,84,83,85,38,77,79,40,78,85,8 101 | 15,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35,85,38,79,77,40,78,85,80,81,80,85,38,77,79,78,40,85,83,77,78,84,83,85,38,77,79,78,40,85 102 | 15,8,34,15,35,39,38,37,36,35,40,35,41,35,83,35,83,78,77,83,84,83,82,80,81,82,83,84,78,77,83,8,50 103 | 29,30 104 | 15,85,38,77,78,85,79,40,85,35,38,36,37,39,40,35,41,35,15 105 | 50,86,50,86 106 | 29,30 107 | 15,76,8,34,8,76,34,76,78,79,77,38,40,76,68,68,15 108 | 72,15,72,15,6,3,4,5,3,4,5,6,72,15,72,15,6,15 109 | 15,76,8,76,34,76,38,77,78,79,40,83,77,78,83,84,83,8,50,15,76,8,76,34,76,79,77,78,38,40,83,84,77,78,83,8,50 110 | 35,8,35,34,35,37,36,38,39,40 111 | 15,8,34,15,76,38,78,77,79,40,76,8,50 112 | 15,68,68,68,15,51 113 | 86,85,38,77,78,79,40,85 114 | 15,3,4,5,8,34,6,15,6,7 115 | 15,76,8,76,34,76,38,77,78,79,40,35,38,36,37,39,35,40,41,35,35,38,37,39,36,35,40,76,38,77,79,78,40,15,76,38,79,78,77,40,35,38,39,37,35,36,40,41,35,35,76 116 | 15,3,4,5,3,4,5,6,15,3,4,5,15 117 | 15,76,8,68,68 118 | 15,51,15,93,15,93,93,15,93 119 | 76,8,76,78,38,40,76,78,38,40,76,78,38,40,76,78,38,40,3,4,5,6,7,7,34,35,38,39,37,36,40,41,35 120 | 15,6,7,8,7,34,8,15 121 | 86,85,86,85,78,77,79,38,40,85,86,35,37,36,39,38,40,35,41,35 122 | 15,30,30,15 123 | 70,15,70,15,70 124 | 86,85,86,85,78,77,38,79,40,85,86,85,86,85,38,79,78,77,40,85,85,38,77,79,78,40,85,80,81,80,85,79,77,38,78,40,85,35,38,36,39,37,40,41,35,85,79,77,38,78,40,85,85,80,81,80,85,79,38,78,77,40,85,85,38,77,79,78,40,85,83,77,78,84,83 125 | 76,8 126 | 86,85,86,85,38,77,79,78,40,85,83,77,78,84,83,85,79,38,77,78,40,85,86 127 | 15,68,68,6,7,8,7,34,6,7,35,38,36,37,39,40,35,41,35 128 | 50,76,8,76,38,77,78,79,40,76,83,77,84,78,83,8,50 129 | 15,8,76,34,76,78,77,79,38,40,76,35,38,37,36,39,35,40,35,41,35 130 | 15,92,15,92,15,68 131 | 35,8,35,34,35,39,37,36,38,35,40,41,35 132 | 29,30,31 133 | 15,85,78,38,79,77,85,40,85,15 134 | 35,8,50,8,76,78,77,79,38,76,40,76 135 | 15,76,38,77,78,76,40,79,76,79,38,77,78,76,40,76,38,77,79,78,40,76,15,76,38,77,78,79,40,76 136 | 15,68,68 137 | 85,35,38,37,36,39,40,41,35,85,38,40,77,78,79,83,77,78,84,83,85,77,85,38,79,40,78,85,86,85,38,77,35,78,35,38,40,36,37,79,39,40,41,35,85,38,77,79,40,78,83,77,78,84,83 138 | 86,86 139 | 50,86,50,85,50,8,83,8,85,8,86,8,86,8,86,85,86,85,8,85,34,85,77,85,38,86,78,40,79,85,86,85,77,79,38,78,40,85,77,79,38,78,40,85,83,77,78,84,83,85,77,38,79,78,40,85,8,86 140 | 35,8,35,34,35,38,39,37,36,35,40,41,35 141 | 15,3,4,5,6,3,4,5,6,7,6,8,7,8,34 142 | 15,35,37,38,36,39,35,40,41,35,6 143 | 35,6,35,37,39,38,36,35,40,41,35,80,81,80,83,77,78,83,84,83,82,3,4,5,6,3,4,5,3,4,5,6,35,38,37,39,35,36,35,40,41,35,83,84,83,77,83,78,83,82,83,6,7,15,35,38,37,39,36,35,40,41,35,83,84,77,83,78,83,6,15,90,3,4,5,3,4,5,6 144 | 15 145 | 8,76,34,76,78,38,79,77,40,76,76,38,79,78,77,40,76,3,4,5,3,4,5,3,4,5,3,4,5,15,3,4,5,6,15,3,4,5,6,7 146 | 29,30,3,4,5,3,4 147 | 68,8,68,34,68,8,76,78,38,77,79,40,68,8,50 148 | 50,68,80,8,80,34,80,81,83,78,77,84,83,8,50 149 | 15,3,4,5 150 | 15 151 | 8,34,15,8,50,8,76,34,76,78,38,77,79,76,40,76,83,77,78,83,84,83,76,38,77,79,78,40,76,8,50 152 | 86,6,86,68,6,15,6,86,86,86,68,68,6,86,86,86,86,86,86 153 | 15,70,15,70,80,8,80,34,80,81,80,83,78,77,83,84,83,68,15,35,37,36,39,35,38,40,35,41,35 154 | 29,30,15 155 | 15,93,15,93 156 | 15,8,34,15,80,81,80,35,39,38,37,36,40,41,35 157 | 86,86,18,86 158 | 29,30 159 | 15,85,38,77,78,79,40,85,15 160 | 29,30 161 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,7,8,9,10,8,7,34 162 | 15,35,38,36,37,39,40,41,35 163 | 15,76,8,76,34,76,38,78,77,79,40,76,8,50 164 | 29,30 165 | 35,8 166 | 3,4,5,3,4,5,3,4,5,6 167 | 29,30 168 | 29,30 169 | 15,68,68,6,8,6,34,68,68,8,50 170 | 30,31 171 | 15,6,7,8,34,6,7,35,37,39,38,36,35,40,41,35,37,39,38,36,35,40,41,35,80,81,80,82,35,36,38,39,37,40,35,41,35,35,38,39,36,37,35,40,41,35 172 | 15,3,4,5,3,4,5,6 173 | 8,34,83,77,83,78,84,83,84,83,77,78,83,84,77,78,83,8,50,83,8 174 | 8,34,15,76,38,77,78,79,40,35,38,39,37,36,35,40,41,35,35,38,37,39,36,35,40,41,35,76,38,79,78,77,40,8,15 175 | 8,34,15,35,36,37,39,38,35,40,35,41,35,8,50 176 | 6,15,6,3,4,5,3,4,5,6,7,8,7,34,8,6,80,81,82,82,76,77,38,78,79,40,76,83,77,78,84,83,76,38,79,77,78,40,80,81,6,8,50,15,35,8,35,34,35,38,39,37,36,40,41,35,38,39,37,36,40,41,35,76,38,79,77,78,40,76,80,81,80,81,76,38,77,79,78,40,76,83,84,77,78,83,76,38,79,78,77,40,76,76,77,38,79,78,40,76,79,77,38,78,40,76,80,81,76,38,79,78,77,40,76,35,38,39,37,36,40,41,35,76,38,77,79,78,40,76,35,38,39,37,36,40,41,35,38,39,37,36,40,41,35,76,38,79,78,77,40,76,83,84,77,78,83,76,38,79,78,77,40,76,8,50,76,8,35,76,8,35,8,76,8,80,8,76,8,76,8,8,76,8,83,8,76,8,80,8,76,8,35,8,35,8 177 | 94,15,94,94,94,93,94,15,93,15,93,75,75,75,93,75,94,93,94,15,94,75,94,94,15,94,94,15,94,75,75,75,75,94,15,93,94,93,15,93,75,93,94,93,15,94,15,94,94,94,15,94,94,15,94,15,94,75,94,75,94,15,94,94,15,94,75,94,15,94,15,94,75,75,75,94 178 | 29,30 179 | 72,15,72,15,23,23,15,72,15,72,15,72,72,15,72,72,15 180 | 83,8 181 | 15,76,8,35,36,39,38,37,40,41,35,38,37,39,36,35,40,41,35,38,37,39,36,35,40,41,35,38,36,37,39,40,41,35,38,37,39,36,40,41,35 182 | 72,15,72,72,15,72,72,15,72,72,15,72,72,15,72 183 | 83,85,77,78,79,38,40,83,77,78,84,83,15,85,77,85,78,38,79,40,85,83,77,78,84,83,85,77,85,38,79,78,40,35,38,36,37,39,35,40,41,35,38,36,39,37,40,35,41,35,37,38,39,36,35,40,41,35,36,39,37,38,35,40,41,35,36,38,37,39,40,35,41,35,15,85,77,79,78,38,40,35,38,37,39,36,40,35,41,35,38,36,39,37,40,35,41,35,35,38,36,39,37,40,35,41,35,35,38,37,36,39,40,35,41,35 184 | 85,8,85,34,85,78,38,77,85,79,40,85,85,79,38,78,77,85,40,85,68,68,85,79,78,8,77,38,40,8,85,79,38,78,77,40,85,79,38,78,77,40,85,79,77,38,78,40,85,79,38,78,77,40,85,79,77,38,78,40 185 | 15,35,38,39,35,37,36,40,41,35,82,15,80,81,82,80,81,80,81,80,15,35,39,37,35,38,36,40,41,35,15 186 | 92,15,92 187 | 15,68,15 188 | 8,76,34,76,78,79,38,77,40,76,3,4,5,6,7,8 189 | 86,85,86,85,8,85,8,8,85,8,34,86,85,86,85,78,79,38,77,40,85,35,38,37,36,39,40,41,35,85,38,77,79,78,40,85,35,39,38,37,36,40,41,35,85,38,77,79,78,40,85,83,77,78,84,83,83 190 | 86,86,86,3,4,5,86 191 | 15,68,68,68,68,68,68,6,15 192 | 15,85,77,78,85,79,38,40,85,77,78,79,38,85,40,85,15,85,77,38,78,79,40,85,15,29,15,85,38,79,77,78,40,85 193 | 35,8 194 | 15,93 195 | 86,85,77,78,79,38,40,85,35,38,37,36,39,40,35,41,35,82,35,35,85,86,86,6,86,86 196 | 35,8,35,34,35,37,36,39,35,38,35,40,41,35,8 197 | 29,30,31 198 | 8,76,34,76,79,38,77,78,40,76 199 | 8,34,15,76,78,77,76,79,38,76,40,76,35,38,37,36,39,35,40,35,41,35,8,50,15,8,34,15,35,38,37,39,36,35,40,41,35,80,81,80,83,77,83,78,83,84,83,80,81,80,82,82,82,15,35,38,37,39,35,36,35,40,41,35,8,50 200 | 80,8,80,34,80,81,80,81,80,76,38,77,78,79,40,76,80,83,84,78,77,83,76,38,77,79,78,40,76,38,79,77,78,40,76 201 | 86,86,86,85,86,85,86,85,38,77,78,79,85,40,85 202 | 86,86 203 | 15,8,34,15,76,38,77,78,79,40,76,83,77,78,84,83,8,50,83,8,76,8,15,8,15 204 | 70,29 205 | 15,92,15,92,15 206 | 8,15,9,15,76,78,38,40,76,3,4,5,6,7,6,7,7,34,6,8,50 207 | 15,85,38,78,77,79,40,85,29,30,29,31,85,79,38,77,78,40,85,15,85,79,38,77,78,40,85,15,85,79,78,38,77,40,85,15 208 | 15,70,15,70,15 209 | 15,8,34,15,80,81,82,82,82 210 | 29,30 211 | 85,78,77,79,38,40,80,81,80,85,77,38,79,78,40,35,38,36,37,39,40,41,35,68,68,85,79,77,78,38,40,35,38,39,37,36,40,35,41,35,68,85,78,77,79,38,40,35,38,39,37,36,40,41,35,35,37,39,38,36,40,41,35 212 | 29,30 213 | 6,3,4,5,3,4,5,6 214 | 29,30 215 | 29,30,15,68 216 | 83,8,83,34,83,78,77,83,84,83 217 | 92,15,92 218 | 92,93,15 219 | 15 220 | 15,85,38,77,78,79,85,40,85,35,38,39,37,36,40,41,35,85,38,79,77,78,40,85,83,77,84,78,83,83,85,83,85,35,85,83,85,83,35,38,37,39,36,40,41,35,85,35,15 221 | 15,70,15,70,15 222 | 3,4,5,3,4,5,3,4,5,3,4,5 223 | 29,30 224 | 15,3,4,5,6,8,6,34,6,7,6 225 | 86,8 226 | 86,85,86 227 | 15,85,8,85,8,85,8,85,34,85,77,38,78,85,79,40,85,80,85,80,81,80,76,38,77,79,78,40,76,83,77,78,84,83,68,83,68,68,83,84,78,77,83,76,38,77,79,78,40,76 228 | 50,8,76,34,76,38,77,79,78,40,35,38,37,39,36,35,40,41,35,76,38,77,79,78,40,76,35,38,39,37,36,35,40,41,35,35,39,38,37,36,35,40,41,35,15,76,38,79,77,78,40,76,8,50 229 | 85,15,85,77,78,79,38,40,85,15,85,77,78,79,38,40,35,39,38,37,36,35,40,35,41,35,15,85,77,79,78,38,40,35,38,39,37,36,35,40,35,41,35,35,38,39,37,36,40,35,41,35,85,38,77,40,78,79,35,39,38,37,36,40,35,41,35,85,38,77,79,78,40,85,35,39,38,37,36,40,35,41,35 230 | 86,85,86,85,78,77,79,38,40,85,35,38,39,37,36,40,41,35,38,37,39,36,40,41,35,85,77,38,79,78,40,85,83,77,78,84,83,85,79,77,38,78,40,85,86,85,86,85,77,78,79,38,40,85,35,38,39,37,36,40,41,35,38,39,37,36,40,41,35,85,79,77,38,78,40,85,83,77,78,84,83,85,86,85,86,86,86 231 | 86,85,86,85,78,77,79,38,40,85,79,77,38,78,40,85,86,85,79,78,77,38,40,85,86,85,86,85,38,79,78,77,40,85,79,77,38,78,40,85,86,85,86,85,38,79,78,77,85,35,40,35,38,36,37,39,40,41,35,86,85,79,78,77,38,40,85,86,85,86,85,38,79,78,77,40,85,86,85,79,77,78,38,40,85,86,85,86,85,38,79,78,77,40,85,77,38,79,78,40,85,86,85,86,85,79,77,78,38,40,85,77,38,79,78,86,40,86,85,86,85,79,78,77,38,40,85,86,85,86,85,86,85,38,79,77,78,40,85,86,85,86,85,38,78,77,79,40,85,86,85,86,85,86,85,79,77,78,38,85,40,85,77,79,38,78,86,40,85,86,85,86,85,79,78,77,38,40,85,79,77,38,78,40,85,86,86,86,85,79,38,78,77,40,85,86,86,3,4,5,5,6,86,85,86,85,38,79,77,78,40,85,86,85,38,79,78,77,40,85,86,85,86,85,79,38,78,77,40,85,86,86,86,85,86,85,79,78,38,77,40,85,86,85,86,85,38,79,77,78,40,85,38,79,78,77,86,40,86 232 | 29,30,29,30 233 | 15,3,4,5,3,4,5,15 234 | 15,85,8,15 235 | 3,4,5,6,7,8,9,10,11,12,7,34 236 | 15,76,8,76,34,76,79,78,77,38,40,76,35,38,35,37,36,39,35,40,41,35,35,8,50,50 237 | 3,4,5,15 238 | 15,21,15 239 | 29,30 240 | 15,85,38,77,79,78,40,85 241 | 15,8,34,15,76,78,77,38,79,76,40,76,8,50 242 | 15,68,68,15 243 | 50,15 244 | 35,8,35,34,35,37,35,39,38,36,35,40,41,35,8,50,76,8,76,34,76,77,78,76,79,38,40,76,76,79,38,78,77,76,40,76,3,4,5,72,15,72,15,72,15,72,3,4,5,15,6,76,79,78,77,38,76,40,76,8,50,76,8,76,34,76,79,78,77,76,38,40,76,35,38,37,35,39,35,36,40,41,35,35,37,38,39,36,35,40,35,41,35,8,50,3,4,5,3,4,5,3,4,5,3,4,5,6,3,4,5,6,3,4,5,6,3,4,5,6,3,4,5,6,15,6,7,8,7,34,76,77,79,76,38,76,78,76,40,76,8,50,35,8,35,34,35,37,35,39,35,38,36,35,40,41,35,35,37,38,39,35,36,35,40,41,35,35,35,37,38,39,35,36,40,35,41,35,76,79,38,78,77,76,40,76,76,77,79,38,78,76,40,76,76,79,77,38,78,76,40,76,8,50,76,8,76,34,76,79,78,77,76,38,76,40,76,8,50 245 | 29,30 246 | 15,68,68 247 | 86,68,86,68,68 248 | 15,76,8,76,34,76,38,77,78,79,40,76,92,15,92,76,38,78,77,79,40,76 249 | 29,30 250 | 15,85,78,77,38,79,40,85,15,6,15 251 | 15,90,91,15,91,91,15,91,91,15,91,91,15,91,91,15,91,15,90,91,15,91,90,91,15,91,15 252 | 86,85,86,85,38,78,77,79,40,85 253 | 86,86,85,38,77,78,79,40,85 254 | 8,34 255 | 76,8,76,34,76,38,77,78,79,40,76 256 | 15,3,4,5,60,15,60,15,9,9,6 257 | 15,8,34,15,76,78,38,77,79,40,76,79,78,38,77,40,76,79,38,78,77,40,76,8,50 258 | 15,6,15,3,4,5,3,4,5,3,4,5,5,3,4,5,3,4,5,5,3,4,5 259 | 15,76,8,76,8,76,8,15,76,8,76,8,76,79,78,38,77,40,76,35,38,39,37,36,40,41,35,35,38,36,37,39,40,41,35,38,39,37,36,40,41,35,15,76,38,79,78,77,40,76,76,79,38,77,78,40,76,76,38,77,79,78,40,76,3,4,5,6 260 | 35,85,77,78,79,38,40,85,68,68,68,85,79,77,78,38,40,85,35,38,37,39,36,40,35,41,35,3,4,5,6,7,6,35,37,36,38,39,40,41,35,15,68,85,38,78,77,79,40,85,35,37,38,39,36,40,35,41,35,35,38,37,36,39,40,41,35,35,38,37,36,39,40,35,41,35,85,38,79,78,77,40,85,68,68,85,79,38,77,78,40,85,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,68,68,68,85,79,38,78,77,40,85,35,38,37,36,39,40,35,41,35,35,38,36,39,37,40,41,35,85,79,38,77,78,40,85,68,85,79,38,78,40,85,35,38,37,39,77,36,40,41,35,85,38,77,79,78,40,85,15,85,79,38,78,77,40,85,35,38,37,39,36,40,35,41,35,68,68,15,68,68,68,85,79,78,77,38,40,85,35,38,36,37,39,40,41,35,38,36,37,39,40,41,35,85,35,85,79,38,78,77,40,85,15,68 261 | 15,15 262 | 15,6,15,6,7,15,6,7,35,36,38,37,39,35,40,41,35 263 | 86,85,78,77,38,79,40,35,38,36,39,37,40,35,41,35,35,37,36,38,39,35,40,41,35,86,86 264 | 15,85,78,79,77,38,40,85,83,77,78,84,83,85,38,79,77,78,40,85,15,85,79,78,38,77,85,40,85,83,84,77,78,83,85,79,38,77,85,78,40,15 265 | 15,85,38,77,78,79,40,85 266 | 29,30 267 | 15,29,15 268 | 15,76,8,76,34,76,78,38,77,79,76,40,76,3,4,5,6,7 269 | 8,34,15,68,68,68,68 270 | 15,3,4,5,6,15,3,4,5,6,15,8,34,15,6,3,4,5,3,4,5,3,4,5,6,7,8,50,15,8,34,15,35,38,39,37,36,40,41,35,35,38,37,39,36,40,41,35,8,50 271 | 50,76,8,76,34,76,79,38,77,78,40,83,84,77,78,83,77,78,84,83,8,50,8,76,34,76,78,38,77,79,40,83,84,77,78,83,8,50 272 | 15,60,15,60,15 273 | 15,85,77,38,78,79,40,85,79,77,78,85,15,38,15,85,79,77,38,78,40,85,79,78,77,38,40,85,15,85,38,77,78,79,40,85,76,38,79,77,78,40,76,35,37,36,38,39,40,41,35,76,38,79,78,40,77,76,83,85,83,85,77,79,38,78,40,85,80,81,82,80,82,82,80,85,38,79,78,77,40,85,76,79,38,77,78,40,76,79,78,38,77,40,76,79,38,77,78,40,76,79,77,38,78,40,76,38,79,77,78,40,76,85,79,38,78,77,40,85,35,38,39,37,36,40,41,35,15,85,79,77,38,78,40,85,15,85,79,77,38,78,40,85,85,79,38,77,78,40,85 274 | 15,3,4,5,3,4 275 | 68,68,68,15 276 | 15,6,15,68,6,15 277 | 15,3,4,5,6,7,8,7,8,76,34,76,38,77,78,35,38,39,37,36,35,40,41,35 278 | 86,85,86,85,78,38,79,77,40,85,83,77,78,84,83,86,86,86 279 | 8,34 280 | 61,15,61 281 | 8,34,15,35,36,37,35,39,38,35,40,35,41,35,82,76,38,77,78,79,76,40,76,8,50,15,6,8,6,76,78,77,79,38,76,40,76,38,79,77,78,40,76,83,77,78,83,84,83,35,38,37,36,35,39,40,41,35,76,79,38,78,77,76,40,35,38,37,39,36,35,40,41,35,8,50 282 | 3,4,5,6,7,8,9,10,11,12,11,12,7,34,6,3,4,5,6,7,6,3,4,5,6,7,68,35,38,36,39,37,40,41,35,35,37,39,38,35,36,40,35,41,35,68,6,3,4,5,6,7,6,3,4,5,6,7,3,4,5,6,7,6,3,4,5,6,7,6 283 | 76,8,76,34,76,78,79,38,77,76,40,76,80,81,35,38,35,37,36,39,35,40,41,35,76,79,77,38,78,40,76,80,81,80,81,80,81,80,76,79,78,38,76,77,40,76 284 | 15,68 285 | 15,68,3,4,5 286 | 15 287 | 86,86,3,4,5,86,86 288 | 15,3,4,5,6,8,6,34,6,3,4,5,6,76,38,78,76,77,79,40,76,35,38,37,35,39,36,40,41,35,6 289 | 6,15,6,15,3,4,5 290 | 15,35,8,35,34,35,37,36,38,35,39,40,41,35,76,38,77,78,40,76,79,76,15,35,36,35,37,39,38,40,41,35,15,35,37,36,39,35,38,40,41,35,35,37,38,39,35,36,35,40,41,35,76,79,38,78,77,76,40,76,15,35,36,35,37,39,38,40,41,35,76,38,78,77,76,79,40,76,83,77,83,78,83,84,83,82,82,82,15,35,37,39,35,36,38,40,41,35,35,37,38,35,39,36,35,40,41,35,76,79,38,78,77,40,76,35,37,36,38,39,35,40,41,35,80,81,82,83,77,84,83,78,83,82,35,37,35,39,38,36,40,41,35,82,35,76,79,38,78,77,40,76 291 | 15,15 292 | 29,30,30,30,32,33 293 | 15,85,38,77,78,79,40,35,38,39,37,36,40,41,35,85,38,77,79,78,40,85,15 294 | 15,68,68,68,68,68,68,68,68,68,68,68 295 | 72,15,72 296 | 15,85,78,38,79,77,40,85,83,77,78,84,83,85,79,77,38,78,40,85,15 297 | 15,85,78,38,77,79,40,85,85,38,79,77,78,40,85 298 | 86,85,79,78,77,38,40,85,86 299 | 76,8,76,34,76,78,79,77,38,76,40,76,8,3,4,5,6,7,76,79,78,77,38,76,40,76,8,50 300 | 15,9,15,9,8,9,8,76,78,38,76,40,76,3,4,5,6,7,7,34,15,9,76,78,79,38,77,76,40,76,35,38,37,36,39,35,40,41,35,35,39,38,37,36,35,40,41,35,83,84,77,78,83,35,37,38,39,35,36,40,41,35,8,50,8,76,34,76,79,78,38,77,76,40,76,15,70,15,35,35,38,35,39,36,37,35,40,35,41,35,35,35,35,38,39,37,35,36,35,40,35,41,35 301 | 86,85,86,85,79,77,78,85,38,40,85,77,79,38,78,40,85,35,38,37,39,36,40,41,35,37,38,36,39,40,41,35,85,77,79,38,78,40,86,85,86,85,79,78,77,38,40,85,35,38,37,39,36,40,41,35,37,38,36,39,40,41,35,85,77,79,38,78,40,85,86,85,86,85,86,85,78,77,38,79,40,85,35,38,37,36,39,40,41,35,85,38,77,79,78,40,85,86,85,86,85,38,77,79,78,40,85,35,37,38,36,39,40,41,35,35,37,38,36,39,40,41,35,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,85,38,79,78,77,40,85,86 302 | 86,85,86,85,38,78,79,77,40,85,86 303 | 29,30,32,33,32 304 | 15,35,8,76,8,76,34,35,38,39,37,36,35,40,41,35,76,38,77,78,79,40,76,76,38,79,77,78,40,76,76,38,79,77,78,40,76,8,15 305 | 15,35,37,39,36,38,35,40,41,35,15,35,39,37,36,38,35,40,35,41,35 306 | 3,4,5,3,4,5,3,4,5,6,7,8,9,10,8,6,7,8,8,6,7,8,9,8,6,7,8,9,10,11,12,7,34 307 | 35,8,35,34,35,36,37,39,38,35,40,41,35,15,76,38,78,77,79,40,83,77,78,84,83 308 | 72,15,72,3,4,5,6 309 | 86,85,8,85,34,85,77,38,78,79,40,80,81,82,80,82,80 310 | 15,8,34,15,35,38,37,36,35,39,35,40,41,35 311 | 3,4,5,15,6,15,6,7,6,8,9 312 | 15,85,78,38,77,79,40,35,38,37,35,36,39,40,41,35 313 | 76,8,76,34,77,79,38,78,76,40,76 314 | 15,3,4,5,6,15 315 | 15,3,4,5,3,4,5,6,3,4,5,6,7,8,7,34,8,50 316 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,60,15,60,15,6,8,6,34,6,7,8,50,15 317 | 8,76,8 318 | 15,80,81,76,77,38,78,79,40,76,83,15,35,36,37,38,39,40,41,35 319 | 29,30,29,30 320 | 3,4,5,6,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,3,4,5,3,4,5,3,4,5,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,3,4,5,15,3,4,5,15,3,4,5,6,7,8,9,10,11,12,11,12,7,34 321 | 86,85,77,38,78,79,40,85,83,77,78,84,83,86,85,77,78,79,38,40,85 322 | 15,8,34,15,76,38,78,77,79,76,40,76,80,81,80,82,8,50 323 | 6,68,6 324 | 86,85,38,77,78,79,40 325 | 15,76,8,76,34,76,79,78,77,38,40,76 326 | 35,8,35,34,35,37,36,38,39,35,40,41,35,15,76,38,77,78,79,76,40,76,35,37,39,36,38,35,40,41,35,76,38,79,78,77,76,40,76,30,32,33,30,35,37,38,36,39,35,40,41,35,35,35 327 | 15,85,77,78,38,79,40,85,35,38,36,39,37,40,41,35,85,38,79,77,78,40,85,83,77,78,84,83,85,38,79,78,77,85,35,40,35,38,37,39,36,40,41,35,85,38,77,79,40,78,85 328 | 15,76,8,76,34,76,78,79,38,77,76,40,76,83,77,78,83,84,83,8,50 329 | 68,8,68,34,68,35,38,35,39,37,36,40,41,35,82,68,68,68,68,8 330 | 15,3,4,5,3,4,5,3,4,5,15,3,4,5,15,3,4,5,60,15,60,15,6,3,4,5,6,15,3,4,5,15 331 | 86,85,78,77,38,40,79,85,77,38,79,78,40,35,38,39,37,36,40,41,35 332 | 15,8,34,15,76,38,78,77,76,79,76,40,76,8,50,8 333 | 15,8,34,15,35,38,39,37,36,40,35,41,35 334 | 86,68,86,85,38,77,78,79,40,85,86,86,86,86,86,86 335 | 30,29,30 336 | 8,8,34,35,37,36,39,38,40,41,35,35,38,39,37,36,40,35,41,35,35,38,37,39,36,40,41,35,37,39,36,38,40,35,41,35 337 | 8,76,34,76,78,77,38,79,40,76,68,68,68,68,68,68,68,68,68,68,68,3,4,5,6,8,76,38,79,78,77,76,40,76,6,92,15,92,93,15,93,3,4,5,6,7,6,3,4,5,6,93,15,93,6,8,50 338 | 86,86,86,6,86,86,3,4,5,3,4,5,86,86,3,4,5,3,4,5,5 339 | 15,92,15,92,92,15,92,15 340 | 93,15,93 341 | 8,35,34,35,37,39,36,38,40,41,35,35,35,8,35,37,39,36,38,40,41,35,35,8,35,34,35,38,37,39,36,40,41,35,35,36,37,39,38,40,41,35,8,35,39,36,37,38,40,41,35,35,8 342 | 92,15,92 343 | 15,8,34,15,35,38,39,37,36,40,35,41,35,35,38,37,39,36,35,40 344 | 8,34,15,76,38,77,78,79,76,40,76,83,77,78,84,83,8,50 345 | 8,76,34,76,78,79,77,38,40,76,35,38,36,37,39,40,41,35,8,50,35,8,76,8 346 | 3,4,5,3,4,5,6 347 | 29,30 348 | 15,8,34,15,35,39,37,36,38,40,35,41,35,76,38,78,79,77,40,76,8,50,15,8,34,15,35,39,37,36,38,40,35,41,35,35,39,37,38,36,40,35,41,35,35,39,38,37,36,40,35,41,35,35,38,39,37,36,40,35,41,35,35,39,37,38,36,35,40,35,41,35,35,39,37,38,36,35,40,35,41,35,35,39,37,38,36,40,41,35,35,39,37,38,36,40,41,35,8,50 349 | 68,72,15,72 350 | 29,30,29,30,29,30,29,30 351 | 15,76,8,15,76,8,9,8,35,8,15 352 | 91,15,91 353 | 15,76,78,38,77,79,40,76,15,76,79,78,38,77,40,76,35,38,39,36,37,40,41,35,76,77,38,79,78,40,15,76,79,77,78,38,40,35,38,39,37,36,40,41,35,76,77,38,79,78,40,76,15,76,78,77,79,38,40,35,38,36,39,37,40,41,35,76,79,38,77,40,78,15 354 | 85,38,77,78,85,79,40,85,93,15,93,85,38,78,77,79,85,40,85,68,3,4,5,6,7 355 | 15,8,34,15,76,77,38,78,79,40,76,92,15,92 356 | 15,76,78,38,77,79,76,40,76,8,50,8,76,34,76,38,77,79,78,40,76,92,15 357 | 3,4,5,3,4,5,6,7,8,9,10,11,12,11,12,8,11,9,11,9,8,6,15,3,4,5,3,4,5,6,7,8,13,8,8,6,7,8,8,76,8,6,15 358 | 15,3,4 359 | 15,8,15,76,77,38,78,79,76,40,76,8,50 360 | 15,29,15,3,4,5,5,6,3,4,5,5,3,4,5,5 361 | 15,8,34,15,35,39,36,37,35,38,40,41,35,82,8,50,15,76,8,76,34,76,77,38,40,76,78,76,79,76,80,81,80,8,50 362 | 15,76,8,76,38,77,78,79,40,76,6 363 | 30,30 364 | 15,8,34,15,76,77,38,78,79,40,83,77,78,83,84,83,83,8,50,8,76,34,76,78,38,77,79,40,76,38,77,79,78,40,76,35,38,37,36,39,40,41,35,76,38,77,79,78,40,83,77,78,84,83,8,50,8,76,34,76,38,78,77,79,40,83,77,78,84,83,8,50 365 | 15,72 366 | 15,76,38,77,78,79,40,76,6,15,3,4,5,6,80,81,80,83,83,77,78,83,84,83,6,7,15,35,38,37,36,39,35,40,35,41,35,15,35,37,36,39,35,38,35,40,41,35,15,35,36,37,39,38,35,40,41,35,80,81,80,82,82,80,81,80,35,38,37,39,36,35,40,41,35,15,35,37,39,36,38,35,40,41,35,82,35 367 | 29,30,29,30 368 | 15,80,8,80,34,80,81,82 369 | 15,88,88,15,88,15,3,4,5,88,88,88,88,3,5,3,4,5,3,4,5,6,3,4,5,3,4,5,3,4,5,6,15,88,88,88,15,3,4,5,3,4,5,6,3,4,5,3,4,5,3,4,5,6,3,4,5,6 370 | 15,8,34,15,76,79,78,77,76,38,40,76 371 | 3,4,5,15 372 | 3,4,5,6,7,8,7,34,8,50,15 373 | 85,78,38,77,79,40,85 374 | 8,8,34,84,77,78,8,84,78,77 375 | 15,68,15 376 | 3,4,5,6,7,8,6,15 377 | 15,68,76,8,76,34,76,78,38,79,77,40,76,35,38,36,39,37,35,40,41,35,35,35,38,39,37,36,35,40,41,35 378 | 35,8,35,34,35,37,39,36,35,38,40,35,41,35 379 | 3,4,5,6,7,8,9,10,11,12,7,34 380 | 15,85,8,85,34,85,78,79,77,38,40,85,8 381 | 15,3,4,5,3,4,5,15,6,3,4,5,6,3,4,5,6,15,3,4,5,6 382 | 76,78,38,77,79,76,40,76,79,38,77,78,40,76,80,81,35,38,37,35,39,36,40,41,35,76,79,38,78,40,76,77,76,15,35,38,37,39,36,35,40,41,35,80,81,80,76,38,79,77,78,40,76,15 383 | 29,30 384 | 15,85,78,79,38,77,40 385 | 35,8,35,34,35,39,37,36,38,40,41,35,8,35,37,39,36,38,40,41,35,35,38,39,37,36,40,35,36,39,38,37,40,41,35,35,38,39,37,36,40 386 | 72,15,72,72,15,72 387 | 35,8,35,34,35,36,37,35,38,39,40,41,35,83,78,77,83,84,83 388 | 35,8,35,34,35,38,37,35,36,39,35,40 389 | 15,8,34,15,76,77,78,79,38,40,76,76,77,79,38,78,40,76,83,77,78,84,83,8,50,50,3,4,5,3,4,5,6,3,4,5,3,4,5,6,3,4,5,6,76,8,76,34,76,38,77,78,79,40,8,50,15,76,8,6,8,6,34,6,76,79,38,78,77,40,76,6,3,4,5,6,7,76,79,78,77,38,40,76,8,50,15,8,34,15,76,79,78,77,38,40,76,80,81,35,38,36,39,37,40,41,35,8,50 390 | 29,30,31 391 | 86,6,85,8,34,85,77,38,78,79,40,85 392 | 86,85,86,8,85,8,85,38,77,78,79,85,86,40,86,85,8 393 | 29,30 394 | 6,15,3,4,5,3,4,5,15,3,4,5,6,7,8,13,8 395 | 8,34,15,35,37,39,36,35,38,40,41,35,85 396 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6 397 | 50,8,76,34,76,78,77,38,79,40,76,83,84,78,77,83,82,8,50 398 | 15,8,34,15,80,81,80,82,83,77,78,84,83,8,50 399 | 35,8,8,35,34,35,37,35,36,39,35,38,40,35,41,35,8,50 400 | 8,34,78,77,84 401 | 76,38,78,77,79,40,76 402 | 15,35,8,35,34,35,37,36,35,39,38,40,41,35,82,35,36,35,38,37,39,40,41,35 403 | 15,76,8,15,85 404 | 8,35,34,35,39,36,37,38,40,41,35,8,15,35,39,37,38,35,36,40,41,35,38,39,37,36,40,35,41,35,39,37,36,35,38,35,40,41,35,38,39,37,36,40,35,41,35 405 | 3,4,5,6,7,8,9,10,11,12,7,34,35,38,39,36,37,40,41,35,8,50,35,8,8,8,8,8,6,34,6,76,78,79,38,77,40,35,38,39,36,35,37,40,41,35,8,50,35,8,76,8,6,8,7,7,8,11,9,8,6 406 | 85,77,38,78,79,40,85,83,77,84,78,83,85,77,38,79,40,78,35,38,39,37,36,40,41,35,35,39,37,38,36,40,41,35,24,24 407 | 29,30 408 | 29,30 409 | 15,85,38,77,85,78,79,85,40,83,77,84,78,83,83 410 | 76,8,76,34,76,77,38,78,79,76,40,76,35,38,39,36,35,37,35,40,35 411 | 15,8,34,15,76,77,38,78,79,40,76,80,81,80,35,38,36,39,37,35,40,41,35,35,38,39,37,36,35,40,41,35 412 | 29,30,29,30 413 | 15,85,38,77,85,78,79,40,35,38,36,39,37,40,41,35,85,38,77,79,78,40,80,81,80,85,38,77,79,40,78,83,77,78,84,83,83,85,38,77,79,40,78,85,15 414 | 15,35,8,35,34,35,38,36,39,35,37,40,41,35,35,38,39,37,35,36,35,40,41,35,8,50,35,8,15 415 | 15,3,4,5,6,3,4,5,5,6,7,8,6,35,8,35,39,36,37,38,35,40,41,35,83,78,77,83,84,83,35,39,36,38,37,40,35,41,35,80,81,80,35,39,38,37,36,35,40,41,35,83,84,78,77,83,6,15,3,4,5,6,8,50 416 | 92,15,92,76,38,78,77,76,79,40,76,35,38,35,37,35,39,36,40,41,35,92,15,92,35,38,37,35,36,39,40,41,35 417 | 35,8 418 | 29,30 419 | 15,76,8,76,34,76,77,38,78,79,76,40,76,15,8,50,60,15,60,15 420 | 15,21 421 | 35,8,35,34,35,39,36,37,38,40,41,35,8,50,35,8,35,34,35,39,37,36,38,40,41,35,8,50,35,8,35,34,35,37,39,36,38,35,40,41,35,8,50,35,8,35,34,35,39,37,35,36,38,40,35,41,35,8,50 422 | 3,4,5 423 | 29,30 424 | 92,8,92,34,92,15,92,76,79,78,38,77,40,76,76,79,38,77,78 425 | 15,68 426 | 15,8,34,15 427 | 6,35,39,37,38,36,40,35,41,35,82,35,37,39,38,36,35,40,35,41,35,68,68,68,35,39,37,36,38,35,40,41,35 428 | 18,15 429 | 8,34,15,35,36,37,39,38,35,40,35,41,35,8,50 430 | 8,34,78,77,84,68,35,36,37,39,38,40,41,35,8,50,35,8,68,6,8,35,8,35,8,35,34,35,37,36,39,35,38,40,35,41,35,8,50,35,8,35,36,39,37,38,40,35,41,35,8,50 431 | 30,31 432 | 15,8,34,15,35,36,38,39,35,37,40,41,35,80,81,80,81,80,81,80,83,77,78,83,84,83,68,68,68,15,68,15,68,15,68,68,68,15 433 | 86,86,86,85,38,77,78,79,40,85,8 434 | 76,8,76,34,76,79,78,38,76,77,40,76,68,68,68,68,68,3,4,5,68,3,4,5,6,7 435 | 85,15,85,38,77,78,79,40,85,83,77,78,84,83,85,38,77,79,78,40,85,35,38,37,39,36,40,41,35,85,79,38,77,78,40,85,80,81,80,85,38,77,79,78,40,85,83,84,77,78,83,85,38,77,79,78,40,85,80,81,80,85,38,79,77,78,40,85,15,85,38,77,78,79,40,85,8 436 | 15,6,15,6,15,3,4,5,3,4,5 437 | 92,92,15 438 | 15,85,77,78,79,38,40,35,38,37,39,36,40,35,41,35,35,38,39,37,36,35,40,41,35,35,37,38,39,36,35,40,41,35,85,38,79,77,78,40,85,83,77,78,84,83 439 | 86,85,86,85,8,85,34,85,38,78,77,79,86,40,86,85,86,85,68,3,4,5,6,7,68,68,68,85,79,77,38,78,40,85,83,77,78,84,83,76,38,77,79,78,40,76,8 440 | 8,35,37,38,39,36,35,40,41,35,80,81,80,82,82,82,82,82,76,38,78,77,79,40,76,8,50 441 | 29,30 442 | 15,92,15,92,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,92,15,92,15 443 | 15,6,15 444 | 68,68,68,68,68,68,68,68,68,8,68 445 | 3,4,5,6,7,8,9,10,11,12,11,12,11,12,8,8,34,6,7,6,15,76,38,77,79,78,40,76,15,6,15 446 | 3,4,5,6,7,8,9,10,9 447 | 15,35,8,35,34,35,37,38,39,36,35,40,41,35 448 | 29,30 449 | 15,35,8,35,38,39,37,35,36,40,41,35,8,35,34,35,38,39,35,37,36,40,41,35,82,35 450 | 15,76,8,76,38,78,79,83,40,77,83,77,78,83,84,83 451 | 15,70,71,15,71 452 | 76,8,76,34,76,77,38,78,79,40,83,77,83,78,84,83,76,38,79,77,78,40,35,38,35,39,36,37,40,41,35,76,38,77,79,78,40,80,81,80,81,80,81,80,76,79,38,77,78,40,76,8,50 453 | 15,8,15,76,77,38,78,76,79,40,76,8,50 454 | 86,86,86,86,86,86,86,15 455 | 29,30,15,8,34,15,76,83,38,78,77,79,83,77,83,84,78,83,8,50 456 | 35,8,8,15 457 | 86,85,38,78,77,79,40,85,83,77,78,84,83,82,83 458 | 8,34,84,78,77 459 | 30,29,30 460 | 35,8 461 | 29,30 462 | 8,35,8,76,8 463 | 35,8,35,34,35,36,37,38,39,35,40,41,35,83,77,78,83,84,83,82,35,38,37,35,36,39,35,40,41,35,80,81,83,84,77,78,83,84,80,81,80,35,38,37,35,36,39,35,40,35,41,35 464 | 50,85,8,85,77,78,79,85,38,40,85,80,81,82,80,82,82,80,85,38,79,78,77,40,85,35,38,36,37,39,40,41,35,85,38,79,78,77,40,85,85,38,79,78,77,40,85,8,85,38,79,77,78,40,85,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,85,38,79,77,78,40,85,8 465 | 29,30 466 | 29,30 467 | 15,72,15,72 468 | 29,30 469 | 3,4,5,3,4,5,3,4,5,6,7,8,7 470 | 15,70,15,70,15,51,51 471 | 29,30,29,31,29,30,29 472 | 86,86 473 | 15,3,4,5,6,79 474 | 15,68,68 475 | 86,86,3,4,5 476 | 68,83,83,77,78,84,83,83,76,77,38,78,40,79,76,77,38,79,40,78,76,76,76,83,84,83,77,78,83,83,83,84,83,78,77,83,78,77,84,83 477 | 6,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,3,4,5,92,15,92,92,15,92,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,92,15,92,15,92,15,92,3,4,5,3,4,5,15,92,15,92,3,4,5,15,6,7,8,7,34 478 | 60,15,60,15 479 | 15,8,15,76,78,77,76,38,79,40,76,83,77,83,78,83,84,83,8,50 480 | 35,38,37,36,39,35,40,41,35,68,68,68,68,68,68,93,15,93,68,68 481 | 15,8,34,15,35,38,37,36,39,35,40,41,35,68,76,79,38,78,77,76,40,76,8,50 482 | 35,8,35,34,35,38,39,37,36,40,41,35 483 | 15,85,38,78,79,77,40,85,35,38,36,37,39,40,35,41,35,85,79,78,38,77,40,85,15 484 | 76,8,76,34,76,38,77,78,76,40,79,76,8,50,15,3,4,5,15,3,4,5,6,15,3,4,5,6,15,8 485 | 29,30 486 | 93,15,93 487 | 15,35,8,35,34,35,37,36,38,39,40,41,35,8,50 488 | 15,6,3,4,5,6 489 | 15,76,8,76,34,76,38,77,78,76,79,40,76,83,77,78,83,84,83 490 | 86,85,86,85,38,77,78,79,40,85,86 491 | 15,51 492 | 15,6,15 493 | 15,6,7,8,9,10,8,9,10,8 494 | 15,6,15,3,4,5,6 495 | 15,85,38,77,79,78,40,85,85,38,79,78,77,40,85,15 496 | 8,76,78,77,79,38,40,76,80,81,80,82 497 | 29,30 498 | 3,4,5,6,3,4,5,6,7,8,6,15 499 | 15,8,15,76,77,78,79,83,38,83,77,78,84,83,6,8,50,15 500 | 15,8,34,15,35,38,36,37,39,40,41,35,8,50 501 | 35,38,37,39,36,35,40,41,35,76,77,38,79,78,83,76,83,77,78,83,84,83,76,77,76,38,35,37,35,38,37,39,35,40,41,35,76,8,76,34,8,15,8 502 | 15,85,8,85,34,85,79,38,78,77,85,40,85,85,38,79,78,77,40,85,15,6,15,85,38,79,78,77,40,85,15,85,38,79,78,77,40,85,15,85,79,78,38,77,40,85,15,6,85,38,79,78,77,40,85 503 | 76,78,79,77,38,40,76,79,78,38,77,40,76,78,38,79,77,40,76,77,38,79,78,40,76 504 | 15,85,77,78,38,79,40,83,77,78,84,83,15,85,77,79,78,38,40,35,38,37,36,39,40,41,35,85,38,79,78,77,40,85,35,37,36,38,39,40,41,35,15,85,77,78,38,79,40,85 505 | 15,92,15,92,15 506 | 15,8,34,15,76,78,76,77,76,38,79,40,76,76,38,79,77,78,40,76,38,77,79,78,40,76,68,68 507 | 6,7,8,7,34,8,50 508 | 8,78,77,84 509 | 15,3,4,5,6,3,4,5,3,4,5,6,15 510 | 15,68,68,68,68,15 511 | 8,76,34,76,77,78,79,38,40,35,38,39,37,36,40,41,35,76,38,77,79,78,40,76,8,50,32,33,32,33,32,8,76,34,76,77,79,78,38,35,38,37,39,36,40,41,35,76,38,77,78,79,40,76,8,50,35,8,35,38,39,37,36,40,41,35,76,38,78,79,77,40,8,50,8,76,34,76,77,78,38,79,40,35,38,39,37,36,40,41,35,76,79,38,78,77,40,76,8,50 512 | 86,85,86,85,86,85,78,77,38,79,40,85 513 | 15,76,8,76,8,76,34,76,79,38,78,77,40,76,35,38,39,37,36,35,40,35,41,35,80,81,80,82 514 | 29,30,32,33,30,29,30 515 | 15,8,34,15,76,78,79,77,38,40,35,38,37,39,36,40,41,35,76,38,77,79,40,78,80,81,76,38,79,77,78,40,76,79,78,77,38,40,76,8,50 516 | 15,29,15 517 | 15,68,68,15,68 518 | 29,30 519 | 15,68,68,15,68,68,15,68,68,15 520 | 86,86 521 | 86,85,86,85,78,79,77,38,40,85,35,38,37,36,39,40,41,35,37,38,36,39,40,41,35,85,79,38,77,78,40,85,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,86,85,86,85,79,78,77,38,40,85,35,38,37,39,36,40,35,41,35,82,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,35,41,35,37,36,38,39,40,35,41,35,85,79,77,38,78,40,86,85,86,85,79,38,78,77,40,85,35,38,37,39,36,40,35,41,35,38,37,36,39,40,35,41,35,85,77,38,79,78,40,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,86,85,86,85,79,78,38,77,40,85,35,38,37,36,39,40,35,41,35,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,37,38,36,39,40,35,41,35,86,85,86,85,79,38,78,77,40,85,35,38,39,36,35,37,40,41,35,38,37,39,36,40,35,41,35,86,85,86,85,79,38,77,78,40,85,35,37,38,39,36,40,35,41,35,37,38,36,39,40,35,41,35,85,79,77,38,78,40,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,35,41,35,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,86,85,86,85,79,78,77,38,40,85,35,38,36,37,39,35,40,41,35,37,38,36,39,40,41,35,85,79,77,38,78,40,85,86,85,86,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,86,85,86,85,79,38,78,77,40,85,35,38,37,39,36,40,35,41,35,37,38,36,39,40,41,35,86,85,86,85,79,78,77,38,85,35,40,35,38,37,36,39,40,41,35,37,38,36,39,40,35,41,35,24,35,37,38,36,39,40,35,41,35,86,85,86,85,78,38,77,79,40,85,35,38,36,37,39,40,41,35,86,85,86,85,79,78,38,77,40,85,35,38,37,39,36,40,41,35,86,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35,86,85,86,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35,85,38,79,77,78,40,85,86 522 | 15,8,34,15,76,77,38,78,79,40,76,38,79,77,78,40,76,15,76,38,77,78,79,40,76,79,77,76,78,38,40 523 | 86,85,77,38,78,79,40,80,81,82,80,80,81,80,86 524 | 15,8,34,35,39,38,36,37,35,40,41,35 525 | 3,4,5 526 | 3,4,5,6,76,8,76,34,76,38,77,78,79,40,76,76,38,79,77,78,40,76,35,38,36,37,39,40,41,35,76,38,79,78,77,40,6,79 527 | 15,70,15,70,74 528 | 29,30,31,6,8,34,80,81,80,82,29,30 529 | 29,30 530 | 15,8,34,15,76,77,38,78,79,76,40,76 531 | 15,8,34,15,3,4,5,15,3,4,5,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,7,8,50 532 | 8,34,15,76,78,77,38,79,76,40,76,8,50,15,8,34,15,76,79,38,77,78,76,40,76,8,50 533 | 29,30,29,68,29,15,85,77,78,38,85,79,40,85,77,38,79,78,40,85,77,79,38,78,40,85,15,85,38,77,78,85,79,40,85,35,38,36,37,39,35,40,41,35,15,68,68,15 534 | 15,35,37,39,36,38,35,40,41,35 535 | 35,8,35,34,35,37,36,39,38,35,40,41,35,38,36,39,37,40,35,41,35,38,37,39,36,40,35,41,35,76,78,38,79,77,40,76 536 | 15,70 537 | 3,4,5,6,15,92,92,15,92,15,6,7,8,7,34,76,78,38,79,77,76,40,76,93,15,93 538 | 76,8,76,34,76,78,38,77,79,40,76,76,79,38,78,77,40,76 539 | 50,86,86,86,85,86,85,8,85,34,85,77,78,85,38,86,79,86,40,85,86,86,85,86,85,79,77,78,38,40,8,85,86,86,86,86,86,86 540 | 72,15,72,72,15,72,72,15,72,15,72,15,72,15 541 | 86,85,86,85,78,38,77,79,40,85,35,38,36,37,39,40,41,35,85,38,79,77,78,40,85,80,81,80,86,85,86,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35 542 | 68,76,8,76,34,76,78,38,77,79,40,76,80,81,82,80,76,38,79,78,77,40,76,8,50,32,33,30,76,8,68,30,32,33,30 543 | 76,8,76,34,76,80,81,80,82,82,82,82 544 | 35,8,35,34,35,36,39,37,35,38,40,41,35 545 | 15,51,51,3,4,5,3,4,5,6,76,8,76,34,76,77,78,38,76,79,40,76,8,50,6,7,8,7,34 546 | 29,30,29,15 547 | 15,8,34,35,36,37,38,35,39,35,40,41,35,8,50,15,68,68,15,8,34,35,37,36,38,35,39,35,40,41,35,68,68,15,51 548 | 85,77,79,38,78,40,85,86,85,77,79,85,78,38,40,85,77,79,78,38,40,85,77,85,38,79,78,40,85,86,15 549 | 29,30 550 | 8,35,34,35,37,39,36,35,38,35,40,35,41,35,83,77,78,83,84,83,8,50,8,35,34,35,37,38,39,36,35,40,35,41,35,83,84,78,77,83,35,37,39,36,35,38,40,35,41,35,8,50,8,35,34,35,37,39,38,36,35,40,35,41,35,8,50,8,35,37,39,36,35,38,35,40,35,41,35,83,84,78,77,83,8,50,8,35,34,35,37,38,39,36,35,40,35,41,35,83,84,78,77,83,8,50,8,35,34,37,39,36,35,38,35,40,35,41,35,83,84,78,77,83,8,50,8,50,8,76,34,76,38,79,78,77,40,76,8,50,8,35,34,35,37,39,36,35,38,35,40,35,41,35,83,78,77,83,84,83,8,35,34,35,38,39,37,35,36,35,40,41,35,83,84,77,78,83,8,50,3,4,5,8,34,35,37,38,39,36,35,40,35,41,35,35,36,39,37,38,40,35,41,35,8,50,35,8,3,4,5,6,8,35,34,35,37,39,38,36,35,40,35,41,35,8,50,6,8,6 551 | 29,30 552 | 76,8,76,8 553 | 76,8,76,34,76,79,78,77,38,40,76 554 | 76,40,76,80,81,80,8,50 555 | 3,4,5,3,4,5,6 556 | 6,3,4,5,6,15 557 | 15,68,6,8,8,8,8,6,8,34,6,80,81,80,82,80,6,15,6,3,4,5,3,4,5,6 558 | 15,3,4,5,15,3,4,5,15,68,3,4,5,68,3,4,5,68,15,6,15 559 | 8,34,15,76,78,77,38,79,76,40,76,80,81,80,82,83,78,77,83,84,83,8,50 560 | 76,38,77,78,79,40,76,38,77,79,78,40,76,76,8,76,34,76,38,77,78,79,40,76,80,81,35,38,37,39,36,40,41,35,80,81,83,77,78,84,83,84,78,77,83,84,77,78,83 561 | 15,8,34,15,35,38,37,39,36,40,41,35,15 562 | 8,34,15,80,81,35,37,39,36,38,40,41,35,76,38,77,78,40,79,76,8,50 563 | 29,30,15,3,4,5,3,4,5,3,4,5,3,4,5,8,34,6,8,50 564 | 35,8,35,38,36,37,39,35,40,41,35,83,78,83,77,84,83 565 | 86,85,86,85,38,78,79,77,40,85,86,85,86 566 | 15,8,15,76,77,38,78,40,79,83,77,83,78,84,83,68,8,50 567 | 29,30,31 568 | 76,8,76,78,38,40,76,3,4,5,6,7,7,34,6,15,6,7,15,6,3,4,5,6,7,15,76,78,79,77,38,40,76,76,38,77,79,78,40,6,3,4,5,3,4,5,3,4,5,6,7,15,6,7,7,15 569 | 86,85,78,38,77,79,40,85,86,85,86,85,78,38,77,79,40,85,86 570 | 76,8,35,8 571 | 15,70,74,70,15,70,15,70,15 572 | 15,6,3,4,5,6,7,8,6,3,4,5,6,7,8,9,10,11,12,7,34,35,36,39,37,38,40,41,35,80,81,83,78,84,83,77,83 573 | 15,85,78,77,38,79,40,85,83,77,78,84,83,84,83,83,84,78,77,83,15,70,15,70,15,85,38,79,78,77,40,85 574 | 3,4,5 575 | 15,8,34,15,76,78,77,79,76,38,40,76,8,50,15,8,15,76,78,76,79,77,38,40,76,8,50,8,34,68,68,8,50,15,68,15,68 576 | 3,4,5,3,4,5,5,6,3,4,5,6,7,8,8,13,8,8,8,6 577 | 34,6,35,38,37,36,39,40,41,35,80,81,15,3,4,5,6,7,6 578 | 15,8,34,15,76,38,78,77,79,40,76 579 | 6,86,85,8,85,34,85,77,38,78,79,40,85,35,38,37,39,36,40,41,35,85,38,77,79,78,40,85,8 580 | 35,8 581 | 15,85,78,79,77,38,40,85,15,85,79,78,77,38,40,85,35,85,35,38,36,37,39,40,41,35,85,79,77,38,78,40,85,15,85,78,79,77,38,40,85,35,38,36,39,37,40,35,41,35,36,38,39,37,40,41,35,85,79,38,77,78,40,85,15,85,79,77,78,38,40,85,85,85,85,85,38,79,78,77,40,85,15,85,79,78,77,38,40,85,35,38,37,39,35,36,40,41,35,85,77,79,38,78,40,85,15 582 | 29,30 583 | 86,85,78,38,77,79,40,85,35,38,36,37,39,40,41,35 584 | 92,15,92,92,15,92 585 | 29,30 586 | 68,68,68,68,68,68,15 587 | 8,6,34,68,3,4,5,6,7,6,8,50,76,8,76,38,77,78,79,40,68,3,4,5,6,7,6,8,50 588 | 15,85,8,85,34,85,38,77,85,79,78,40,85,68,85,38,77,79,40,78,85,8 589 | 29,30 590 | 15,85,78,79,77,38,40,85,85,85 591 | 15,8,34,15,76,77,38,78,79,40,76,8,50 592 | 8,7,34,6,3,4,5,6,15,3,4,5,3,4,5,15,6 593 | 15,68 594 | 15,6,76,8,76,34,76,38,77,78,79,40,76 595 | 15,35,8,15 596 | 29,30 597 | 15,8,34,15,76,78,77,38,79,40,83,77,83,78,84,83 598 | 15,35,8,35,34,35,38,35,36,39,37,40,41,35,80,81,83,78,77,83,84,83,80,81,80,35,38,37,39,35,36,35,40,41,35,80,81,80,83,84,83,78,83,77,80,81,80,83,84,77,83,78,83,8,50 599 | 50,85,50,8,85,8,15,85,8,85,38,79,78,77,85,40,85,8,85,38,77,79,78,40,85,8,15 600 | 8,76,34,76,78,77,79,76,38,76,40,76,15,8,76,34,76,79,78,77,76,38,76,40,76,8,76,34,76,79,78,77,76,38,76,40,76,8,76,34,76,78,77,79,76,38,76,40,76,8,76,79,78,77,76,38,76,40,76,8,76,34,76,79,78,77,76,38,76,40,76,8,76,34,76,79,78,38,77,76,40,76,8,76,34,76,79,38,78,77,76,40,76 601 | 15,85,78,38,77,79,40,85,15,68,85,38,78,77,79,40,85,85,79,38,78,77,85,40,85 602 | 15,70,15,70 603 | 15,72,15,72 604 | 15,22,22,22,22,22,22,15,22,22,22,22,15,22 605 | 92,15,92 606 | 15,70,15,51 607 | 86,85,86,85,78,77,38,79,40,85,35,38,36,39,37,40,41,35,85,35,85,79,77,38,78,40,85,80,81,80,85,80,85,79,38,77,78,40,85,85,77,79,38,78,40,85,85,38,77,79,78,40,85,85,38,77,79,40,85,78,85,77,79,38,78,40,85,85,77,38,79,78,40,85,83,78,77,84,83,86,86,86,85,78,38,77,79,40,85 608 | 8,76,34,76,38,78,77,79,76,40 609 | 15,8,34,15,35,39,37,38,36,35,40,41,35,80,81,80,76,38,78,77,40,79,76,8,50 610 | 15,35,8,35,34,35,38,39,37,35,36,40,41,35,80,81,82,80,76,38,79,78,77,40,76,76,79,38,78,77,40,76,8,50 611 | 35,8,35,8 612 | 15,6 613 | 15,85,38,78,79,77,40,85,15 614 | 29,30,32,33 615 | 29,30,32,33,32,33,30,32,30,32,30,33,32,33 616 | 29,30,29,31,29,15,3,4,5,6,85,78,77,38,79,40,85,6,7,6 617 | 29,30,29 618 | 15,92,15,92,15 619 | 15,76,38,77,78,79,40,76,15 620 | 15,3,4,5,6,15,6,7,8 621 | 15,8,34,15,35,36,37,39,38,35,40,41,35,8,50 622 | 15,8,15,76,78,77,38,79,40,76,6,3,4,5,68,3,4,5,6,8,50,15,68,68,15,68,68,68,3,4,5,68,8,68,34,68,76,38,77,78,79,40,76,8,50 623 | 29,30,31,3,4,5 624 | 86,85,78,85,38,77,79,40,85,68,85,38,79,77,78,40,85,86,85,79,38,78,77,40,83,77,78,84,83,85,79,38,77,78,40,35,38,37,39,36,40,41,35 625 | 15,8,50 626 | 68,15,3,4,5,6,7,8,7,34,6,7,8,50,7,8,15 627 | 29,30 628 | 29,30 629 | 29,30 630 | 15,8,34,15,80,81,80,83,77,78,84,83,83,84,77,78,80,81,80,15,8,15,70,15,70,70 631 | 15,85,38,77,78,79,40,76,35,38,36,37,39,40,41,35,76,85,77,78,38,85,79,85,40,85 632 | 15,6,15,3,4,5 633 | 8,34,15,80,81,80,82,83,77,83,78,83,84,83,82 634 | 6,68 635 | 15,68 636 | 86,85,38,77,79,78,40,85,83,84,83,77,78,83,85,86,85,6,3,4,5,5,6,7,68,68,6,86,6,7,6,86,86 637 | 15,68,68,15,85,78,38,40,35,38,37,36,39,40,35,41,35,85,78,38,40,35,38,36,39,37,40,35,41,35 638 | 29,30,31,72,15,72 639 | 35,8,35,34,35,37,39,36,38,40,41,35,8,50,35,8,8,35,8,35,34,35,37,38,39,36,40,41,35,8,50,35,8,35,8,35,34,35,37,38,39,36,40,41,35,8,50,35,8,35,34,35,37,38,39,36,40,35,41,35,8,50 640 | 15,35,8,35,34,35,38,39,37,36,40,41,35,6,7,15,6,15,6,76,8,76,34,76,78,79,77,38,40,76,35,38,39,37,36,40,41,35,6,35,38,39,37,36,40,41,35,6,7,15,3,4,5,6,7,15,3,4,5,6,3,4,5,6,15,68,3,4,5,6,3,4,5,6 641 | 29,30 642 | 3,4,5,3,4,5,6,7,8 643 | 29,30,15 644 | 15,6,15 645 | 15,76,8,76,77,78,79,38,40,76 646 | 35,38,37,39,36,40,35,41,35,76,38,77,78,79,40,76,85,77,38,79,78,40,85,3,4,5,6,7,6,85,79,78,77,38,40,85,38,77,79,78,40,85 647 | 8,76,34,76,38,78,77,79,76,40,76,15,3,4,5 648 | 76,8,76,34,76,78,77,76,38,79,40,76,83,77,78,83,84,83,8,50,15,76,8,76,34,76,78,77,38,79,40,76,83,77,78,83,84,83,8,50 649 | 29,30 650 | 15,8,34,15,76,78,38,77,79,76,40,76,15,60,15,60 651 | 29,30 652 | 8,15 653 | 86,86,86,86,15 654 | 29,30,29 655 | 86,68,86,68,68,86,86,86,86,86,86,86,68,86,86,86,86,86,86,68,86,86,86 656 | 15,85,77,78,38,79,40,85,85,38,79,77,78,40,85,15,85,77,78,38,79,40,85,77,78,79,85,38,40,85,15,85,79,85,77,78,38,40,85 657 | 15,35,37,36,38,35,39,40,35,41,35,92,15,92,15 658 | 3,4,5,15 659 | 15,8,15,35,38,35,36,37,39,40,41,35,76,38,77,40,78,79,76,83,77,83,78,84,83,8,50,8,76,34,76,38,77,78,40,79,76,83,77,78,84,83 660 | 86,85,86,85,8,86 661 | 29,30,32,33,72,15,72,15 662 | 15,85,77,78,79,38,40,35,38,39,37,36,40,41,35,85,38,79,78,77,40,80,81,80,85,77,85,38,78,79,40,85,83,77,84,78,83,85,77,38,79,78,40,85,15,85,77,38,79,78,40,35,38,39,36,37,40,35,41,35,85,78,80,81,82,80,82,80,85,79,38,78,77,40,85,85,38,77,79,78,40,85,77,38,79,78,40,85,15,3,4,5 663 | 86,85,77,38,78,79,40,35,38,37,36,39,40,41,35 664 | 15,85,77,38,78,79,40,85,35,38,37,36,39,40,41,35 665 | 35,8,35,34,35,37,36,35,39,38,35,40,41,35 666 | 15,85,78,79,77,38,40,85,83,77,83,84,78,83,85,15 667 | 92,15,92,15,3,4,5,92 668 | 18,15 669 | 72,15,72,15 670 | 8,34,78,84,77,8,50,8,34,84,77,78,8,50 671 | 6,3,4,5,3,4,5,15,6,7,8,7,6,34,6,7,8,50 672 | 8,34,15,68,76,79,77,78,76,38,76,40,76,83,84,83,77,78,83,8,50,15,8,34,15,68,76,38,79,78,76,77,76,40,76,8,50 673 | 76,8,76,34,76,77,38,78,79,40,76,80,81,82,76,77,38,79,78,40,83,77,78,84,83,82,83,76,38,79,77,78,40,76,35,38,39,36,37,40,41,35,76,77,38,79,78,40,76,80,81,82,76,79,38,78,77,40,76,76,77,79,38,78,40,76,76,80,76,80,81,76,35,76,35,76,35,39,38,37,36,40,35,41,76,35,83,84,77,78,76,79,77,38,78,40,80,76,80,81,76,79,77,38,78,8,40,15 674 | 29,30 675 | 29,30,32,33,32,33,32 676 | 15,8,15,76,77,38,78,79,40,76,15 677 | 29,30 678 | 86,85,86,85,78,79,77,38,40,85,35,38,36,37,39,40,41,35,85,79,77,38,78,86,85,40 679 | 86,85,86,85,78,38,77,79,40,85,86,85,86,85,79,78,38,77,40,85,86 680 | 29,30 681 | 86,86,86,86 682 | 29,30 683 | 6,68,3,4,5,68 684 | 15,85,78,79,77,38,40,85,85,38,79,77,40,78,85,15 685 | 15,3,4,5,6,8,34,6,7 686 | 92,15,92,8,92,34,92,15,92,68,76,77,38,78,76,79,40,76,83,77,83,78,83,84,83,35,38,35,36,39,37,35,40,41,35,80,81,82,68,68,15,92,15,92,68 687 | 72,15,72,72,15 688 | 29,30 689 | 86,3,4,5,6,7,6,8,6,8,6,3,4,5,5,86,85,8,85,86,85,8,9,85,9,85,38,78,85,40,86,85,86,85,86,86,3,4,5,6,7,6,8,8,8,86,86,86,86,6,8,8,86,8,86,8,86 690 | 3,4,5 691 | 70,15,70 692 | 86,85,86,85,38,78,77,79,40,85,86,85,86,85,78,77,38,79,40,85,86 693 | 6,68 694 | 15,85,38,77,78,79,40,85,85,38,79,78,77,40,85,38,77,78,79,40,35,38,39,37,36,40,41,35,15 695 | 3,4 696 | 35,38,37,39,36,35,40,41,35,38,39,35,36,37,40,41,35,38,39,37,35,36,40,41,35,76,38,78,77,40,79,76,83,83,77,78,83,84,83,76,79,77,38,78,40,76,79,38,78,77,40,76,78,79,77,38,76,40,76,83,77,83,78,84,83,76,79,77,38,78,40,35,38,37,39,36,40,35,41,35 697 | 93,15,93,15 698 | 83,8 699 | 15,8,34,15,35,37,39,35,36,35,38,35,40,41,35,8,50,15 700 | 76,8,76,34,76,77,78,79,76,38,40,76,76,38,77,79,78,40,76,3,4,5,3,4,5,3,4,5,6,8,50 701 | 15,8,34,15,76,78,79,38,77,40,76,83,77,78,83,84,83,77,78,84,83,8,15 702 | 15,6,3,4,5 703 | 15,3,4,5,3,4,5,3,4,5,3,4,5,8,34,6,3,4,5,6,76,78,38,77,76,79,40,76,6,76,38,77,76,79,40,78,76,6,76,79,38,78,77,76,40,76,68,68,68,68,68,68,68,8,50 704 | 8,76,34,76,38,77,78,79,40,76,8,15,8,50 705 | 72,15,72,72,15,72 706 | 8,34,80,81,80,82,35,37,36,39,35,38,35,40,41,35,15 707 | 15,85,38,77,78,79,40,85 708 | 8,9,8,34,6,7 709 | 35,39,38,37,36,35,40,41,35,39,37,38,36,35,40,35,41,35,36,38,39,37,35,40,41,35,82 710 | 50,8,76,38,78,77,79,40,76,8,50 711 | 15,76,8,76,34,76,78,38,77,79,40,76,76,79,77,38,78,40,83,77,83,78,84,83,15 712 | 15,35,38,36,39,37,40,35,41,35 -------------------------------------------------------------------------------- /core/resources/first_step/train/train_data_1: -------------------------------------------------------------------------------- 1 | 1,2,3,4,5,6,7,8,9,10,11,12,11,12,8,13,8,14,8,13,8,13,8 2 | 15,16 3 | 17,18,17,19,15,17,21,19,17 4 | 20,22,23,22,24,22,25,26,25,26 5 | 27,28,27,28,27 6 | 29,30,31,32,33,32,33 7 | 15,8,34,15,35,36,37,38,35,39,40,41,35,44,45,8,50,15,51,52,53,52,54,52,55,56,55,57,55,58,55,59,60,61,62,63,64,65 8 | 66,18,66,67 9 | 8,35,34,35,37,38,39,35,36,40,35,41,35,37,38,39,36,35,40,41,35,37,38,39,36,35,40,41,35,35,37,36,38,39,40,35,41,35,68,69,68,35,38,37,39,36,35,40,41,35 10 | 70,71,15,71,15,72,15,73,72,15,72 11 | 29,30,74 12 | 15,75,15,75,15,75,15 13 | 6,8,6,76,38,77,78,79,76,40,76,35,38,39,37,36,35,40,35,41,35,76,38,79,77,78,76,40,76,8,50 14 | 86,86,86,85,38,77,85,78,79,40,85,85,15,85,38,79,77,78,40,85 15 | 15,85,38,85,77,78,79,40,85,15 16 | 15,83,8,83,34,83,78,77,84,83 17 | 15,76,8,76,34,76,78,77,79,38,76,40,76,35,38,37,36,39,35,40,35,41,35,80,81,80,82,83,78,77,83,84,83,83,80,81,80,82,82,8,50 18 | 86,86,3,4,5,6,7,6,8,7,8,34,86,85,78,79,77,38,40,85,8 19 | 86,85,86,85,38,78,77,79,40,85 20 | 15,3,4,5,15 21 | 92,15,92,29,30,31 22 | 8,34,35,38,39,37,36,35,40,41,35,83,77,78,83,84,83,6 23 | 15,6,3,4,5,5,3,4,5,5,6,3,4,5,3,4,5,6,15,85,38,78,77,79,40,85,85,38,79,77,78,40,85,35,38,39,37,36,40,41,35,85,35,85,38,77,79,78,40,85,15,29,29,6,29,15 24 | 15,8,34,15,3,4,5,3,4,5,3,4,5,6,7,6,7 25 | 9,76,78,38,40,76,68,3,4,5,6,3,4,5,93,15,93,3,4,5,3,4,5,6,7,7,34,6,15,3,4,5,6,7,6,76,78,79,77,38,40,76,76,38,79,77,78,40,76,76,79,77,38,78,40,76,79,77,38,78,40,76,6,7,6,15,6,8,6,34,6,7 26 | 15,3,4,5,68,68,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,68,6,3,4,5,6,7,8,7,34,6,7 27 | 35,8,35,34,35,38,36,37,39,35,40,41,35,83,78,77,83,84,83 28 | 15,85,38,78,77,79,40,85,15,29,15,85,79,38,77,78,40,85,15,29,15,85,79,78,38,77,40,85,85,80,81,82,80,35,39,37,35,36,38,40,35,41,35,37,36,39,35,38,40,35,41,35,39,37,38,36,40,41,35 29 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6 30 | 15,76,78,38,77,79,40,76 31 | 76,8,76,34,76,78,38,79,77,76,40,76,8,50 32 | 15,3,4,5,6 33 | 15,85,78,79,77,38,85,40,85,77,79,38,78,40,85,15 34 | 30,32,33,32 35 | 15,70,71,15,71,71 36 | 15,35,8,35,34,35,39,37,36,38,35,40,35,41,35,82,82,8,50 37 | 15,75 38 | 86,86,3,4,5,5,6,3,4,5,5,3,4,5,5 39 | 8,76,8,15,35,8,15,76,8 40 | 15,85,8,85,34,85,79,77,78,38,40,85,35,38,37,39,36,40,35,41,35,38,39,37,36,40,35,41,35,85,38,77,79,78,40,85,38,77,79,78,40,8 41 | 6,3,4,5,3,4,5,3,4,5,6,7,8,7,34,8,50 42 | 15,8,34,15,35,37,38,36,39,35,40,35,41,35,80,81,80,35,38,36,39,37,35,40,35,41,35,8,50 43 | 15,85,78,79,38,77,40,85,85,38,79,77,40,78,85,85,38,78,79,77,40,85,85,38,77,79,78,40,85,85,38,79,78,77,40,85,85,79,77,38,78,40,85 44 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,15,3,4,5,6,15,3,4,5,6,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,3,4,5,6,15,6,7,8,8,6,15,6,7 45 | 86,6,86,6,85,8,85,78,38,85,86,40,86,85,83,84,78,83,80,81,80,83,84,78,83,80,81,80,83,84,78,83,85,38,78,40,85,8 46 | 15,35,8,35,34,35,39,36,37,38,40,35,41,35,8 47 | 15,9,15 48 | 76,8,76,34,76,78,38,77,76,79,40,76,83,77,78,83,84,83,68,76,79,38,77,78,40,76,68,76,79,38,78,77,76,40,76,83,84,77,78,83,76,38,79,77,78,76,40,76,68,15 49 | 15,76,8,76,34,76,78,77,76,38,79,40,76,8,50,76,8,76,34,76,79,77,78,38,76,40,76,8,50,15,76,8,76,77,38,78,79,76,40,76,82,76,83,78,77,83,84,83,8,50 50 | 29,30,29 51 | 76,78,77,79,38,40,76,79,77,38,78,40,76,83,83,77,78,83,84,83 52 | 15,72,15,72,15 53 | 15,6,15,3,4,5,3,4,5,15,68,6,15,6,7,8,7,34,8,50,50,8,8,7,8,7,8,8,7,8,7,8,6,15,8,34,15,35,38,37,36,35,39,35,40,41,35,8,50,35,8,15,8,15 54 | 29,30 55 | 86,86,86 56 | 50,15,85,8,85,34,85,38,79,78,77,85,40,85,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,35,38,37,39,36,40,41,35,35,38,37,39,36,40,41,35,85,38,79,78,77,40,85,83,77,78,84,83,85,38,79,77,78,40,85,8 57 | 15,35,8,35,38,39,36,37,35,40,41,35,83,78,83,84,83,80,81 58 | 15,76,8,76,34,76,78,38,77,79,40,76 59 | 85,35,38,37,36,39,40,41,35,85,38,78,77,79,40,85,15,85,79,38,78,77,85,40,15 60 | 8,35,8,35,34,35,38,37,39,36,35,40,35,41,35,37,39,36,38,35,40,35,41,35,80,81,80,82,82,8,50 61 | 76,78,38,77,79,76,40,76 62 | 92,15,92,15,92,15,92,15,3,4,5,3,4,5 63 | 86,70,15,70,70,86 64 | 86,86,86,85,86,85,38,77,78,79,40,85,86 65 | 8,34,15,35,37,38,39,36,40,35,41,35 66 | 70,15,70,15,70 67 | 15,85,38,77,78,79,40,35,38,37,39,36,40,41,35,85,38,77,79,78,40,85,15,85,77,78,79,38,40,35,38,39,37,36,35,40,35,41,35,15 68 | 8,68,34,68,8,50 69 | 15,76,8,76,34,76,77,38,78,79,40,76,83,77,78,83,84,83,8,50 70 | 15,92,15,92,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,3,5,3,4,5,3,4,5,3,4,5,15,6,15,3,4,5,6,7,8,7,34,29,30 71 | 86,86,85,78,77,79,38,40,85,35,38,37,36,35,39,40,41,35,85,77,79,38,78,40 72 | 15,68,68,68,6,15 73 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,7,8,9,10,8,9,10,11,12,11,12,7,34 74 | 15,85,38,77,79,78,40,85,15 75 | 70,15,70,15,70,15,70 76 | 15,6 77 | 29,30 78 | 15,8,15,35,38,37,36,39,35,40,41,35,83,78,77,83,84,83,15,80,81,83,78,77,83,93,84,93,15,93,35,37,38,39,35,36,40,41,35,83,84,77,78,83 79 | 86,68,86,68,68,3,4,5,6,7,6 80 | 50,85,8,85,34,85,38,78,77,79,85,40,85,6,15,3,4,5,3,4,5,6,85,79,38,78,77,40,85,6,7,6,3,4,5,6,3,4,5,5,6,15,6,15,3,4,5,6,7,6,85,79,78,77,38,40,8,85 81 | 8,76,34,76,78,38,77,79,40,76,8,50 82 | 6,8,6,34,68,68,35,38,36,37,39,40,41,35 83 | 15,8,34,15,76,38,77,78,40,79,83,77,83,78,84,6,83,84,77,78,83,3,4,5,3,4,5,3,4,5,15,3,4,5,3,4,5,3,4,5,15,3,4,5,6,7,15,35,38,36,37,35,39,40,41,35,35,38,37,36,39,35,40,41,35,35,38,37,36,39,35,40,41,35,15 84 | 15,35,8,35,34,35,38,36,37,39,40,41,35,76,38,77,78,79,40,76,76,35,38,37,39,36,40,41,35,15,35,8,35,34,35,38,36,37,39,40,41,35 85 | 92,15,92 86 | 35,8,35,34,35,39,37,38,36,35,40,41,35,83,77,78,83,84,83,3,4,5,6,15,6,15,6 87 | 29,30,32,33 88 | 15,85,78,77,38,79,40,85,35,38,36,37,39,40,41,35,85,79,38,78,77,40,85 89 | 86,68,86,68,68,68,68,68,15,68,86 90 | 93,15,93,93,15 91 | 15,35,8,35,34,35,37,36,35,38,39,40,41,35,35,38,37,36,35,39,40,35,41,35,35,37,38,35,39,36,35,40,41,35,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,8,50 92 | 15,6 93 | 68,68 94 | 15,6,85,77,78,38,79,85,35,40,35,38,37,39,36,40,41,35,82,35,35,39,38,37,36,40,41,35,15,6,85,79,77,78,38,40,85,35,38,39,37,36,40,41,35,15,85,77,78,79,38,40,85,35,38,37,39,36,40,41,35,85,35,85,77,38,79,78,40,85,85,77,79,38,78,40,85,85,85,38,79,77,78,40,85,35,38,36,39,37,40,41,35,76,38,79,78,77,40,76,76,85,79,38,78,77,40,85,15,6,85,79,78,38,77,40,85,35,38,36,37,39,40,41,35,15,85,79,38,78,77,40,85,15,85,79,78,77,38,40,85,35,38,37,36,39,40,41,35 95 | 86,86,85,77,38,78,79,40,85,86,86,85,38,77,78,79,40,85 96 | 8,76,34,76,78,79,77,76,38,40,76,8 97 | 29,30,15,29,30,32,33,74 98 | 60,15,60,60,15,60 99 | 68,6,7,68,35,37,39,38,36,35,40,41,35,82,35,35,38,36,37,39,35,40,35,41,35,35,68,35,37,39,38,36,35,40,41,35,35,35,35,38,37,39,36,40,35,41,35,35,38,37,39,36,35,40,35,41,35,35,37,39,38,36,35,40,35,41,35,78,84,77,35,38,37,39,36,35,40,35,41,35 100 | 50,85,50,8,8,8,8,8,8,7,8,8,7,8,8,7,8,68,68,68,15,85,8,85,38,79,77,78,85,40,85,83,77,78,84,83,85,38,77,79,40,78,85,8 101 | 15,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35,85,38,79,77,40,78,85,80,81,80,85,38,77,79,78,40,85,83,77,78,84,83,85,38,77,79,78,40,85 102 | 15,8,34,15,35,39,38,37,36,35,40,35,41,35,83,35,83,78,77,83,84,83,82,80,81,82,83,84,78,77,83,8,50 103 | 29,30 104 | 15,85,38,77,78,85,79,40,85,35,38,36,37,39,40,35,41,35,15 105 | 50,86,50,86 106 | 29,30 107 | 15,76,8,34,8,76,34,76,78,79,77,38,40,76,68,68,15 108 | 72,15,72,15,6,3,4,5,3,4,5,6,72,15,72,15,6,15 109 | 15,76,8,76,34,76,38,77,78,79,40,83,77,78,83,84,83,8,50,15,76,8,76,34,76,79,77,78,38,40,83,84,77,78,83,8,50 110 | 35,8,35,34,35,37,36,38,39,40 111 | 15,8,34,15,76,38,78,77,79,40,76,8,50 112 | 15,68,68,68,15,51 113 | 86,85,38,77,78,79,40,85 114 | 15,3,4,5,8,34,6,15,6,7 115 | 15,76,8,76,34,76,38,77,78,79,40,35,38,36,37,39,35,40,41,35,35,38,37,39,36,35,40,76,38,77,79,78,40,15,76,38,79,78,77,40,35,38,39,37,35,36,40,41,35,35,76 116 | 15,3,4,5,3,4,5,6,15,3,4,5,15 117 | 15,76,8,68,68 118 | 15,51,15,93,15,93,93,15,93 119 | 76,8,76,78,38,40,76,78,38,40,76,78,38,40,76,78,38,40,3,4,5,6,7,7,34,35,38,39,37,36,40,41,35 120 | 15,6,7,8,7,34,8,15 121 | 86,85,86,85,78,77,79,38,40,85,86,35,37,36,39,38,40,35,41,35 122 | 15,30,30,15 123 | 70,15,70,15,70 124 | 86,85,86,85,78,77,38,79,40,85,86,85,86,85,38,79,78,77,40,85,85,38,77,79,78,40,85,80,81,80,85,79,77,38,78,40,85,35,38,36,39,37,40,41,35,85,79,77,38,78,40,85,85,80,81,80,85,79,38,78,77,40,85,85,38,77,79,78,40,85,83,77,78,84,83 125 | 76,8 126 | 86,85,86,85,38,77,79,78,40,85,83,77,78,84,83,85,79,38,77,78,40,85,86 127 | 15,68,68,6,7,8,7,34,6,7,35,38,36,37,39,40,35,41,35 128 | 50,76,8,76,38,77,78,79,40,76,83,77,84,78,83,8,50 129 | 15,8,76,34,76,78,77,79,38,40,76,35,38,37,36,39,35,40,35,41,35 130 | 15,92,15,92,15,68 131 | 35,8,35,34,35,39,37,36,38,35,40,41,35 132 | 29,30,31 133 | 15,85,78,38,79,77,85,40,85,15 134 | 35,8,50,8,76,78,77,79,38,76,40,76 135 | 15,76,38,77,78,76,40,79,76,79,38,77,78,76,40,76,38,77,79,78,40,76,15,76,38,77,78,79,40,76 136 | 15,68,68 137 | 85,35,38,37,36,39,40,41,35,85,38,40,77,78,79,83,77,78,84,83,85,77,85,38,79,40,78,85,86,85,38,77,35,78,35,38,40,36,37,79,39,40,41,35,85,38,77,79,40,78,83,77,78,84,83 138 | 86,86 139 | 50,86,50,85,50,8,83,8,85,8,86,8,86,8,86,85,86,85,8,85,34,85,77,85,38,86,78,40,79,85,86,85,77,79,38,78,40,85,77,79,38,78,40,85,83,77,78,84,83,85,77,38,79,78,40,85,8,86 140 | 35,8,35,34,35,38,39,37,36,35,40,41,35 141 | 15,3,4,5,6,3,4,5,6,7,6,8,7,8,34 142 | 15,35,37,38,36,39,35,40,41,35,6 143 | 35,6,35,37,39,38,36,35,40,41,35,80,81,80,83,77,78,83,84,83,82,3,4,5,6,3,4,5,3,4,5,6,35,38,37,39,35,36,35,40,41,35,83,84,83,77,83,78,83,82,83,6,7,15,35,38,37,39,36,35,40,41,35,83,84,77,83,78,83,6,15,90,3,4,5,3,4,5,6 144 | 15 145 | 8,76,34,76,78,38,79,77,40,76,76,38,79,78,77,40,76,3,4,5,3,4,5,3,4,5,3,4,5,15,3,4,5,6,15,3,4,5,6,7 146 | 29,30,3,4,5,3,4 147 | 68,8,68,34,68,8,76,78,38,77,79,40,68,8,50 148 | 50,68,80,8,80,34,80,81,83,78,77,84,83,8,50 149 | 15,3,4,5 150 | 15 151 | 8,34,15,8,50,8,76,34,76,78,38,77,79,76,40,76,83,77,78,83,84,83,76,38,77,79,78,40,76,8,50 152 | 86,6,86,68,6,15,6,86,86,86,68,68,6,86,86,86,86,86,86 153 | 15,70,15,70,80,8,80,34,80,81,80,83,78,77,83,84,83,68,15,35,37,36,39,35,38,40,35,41,35 154 | 29,30,15 155 | 15,93,15,93 156 | 15,8,34,15,80,81,80,35,39,38,37,36,40,41,35 157 | 86,86,18,86 158 | 29,30 159 | 15,85,38,77,78,79,40,85,15 160 | 29,30 161 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,7,8,9,10,8,7,34 162 | 15,35,38,36,37,39,40,41,35 163 | 15,76,8,76,34,76,38,78,77,79,40,76,8,50 164 | 29,30 165 | 35,8 166 | 3,4,5,3,4,5,3,4,5,6 167 | 29,30 168 | 29,30 169 | 15,68,68,6,8,6,34,68,68,8,50 170 | 30,31 171 | 15,6,7,8,34,6,7,35,37,39,38,36,35,40,41,35,37,39,38,36,35,40,41,35,80,81,80,82,35,36,38,39,37,40,35,41,35,35,38,39,36,37,35,40,41,35 172 | 15,3,4,5,3,4,5,6 173 | 8,34,83,77,83,78,84,83,84,83,77,78,83,84,77,78,83,8,50,83,8 174 | 8,34,15,76,38,77,78,79,40,35,38,39,37,36,35,40,41,35,35,38,37,39,36,35,40,41,35,76,38,79,78,77,40,8,15 175 | 8,34,15,35,36,37,39,38,35,40,35,41,35,8,50 176 | 6,15,6,3,4,5,3,4,5,6,7,8,7,34,8,6,80,81,82,82,76,77,38,78,79,40,76,83,77,78,84,83,76,38,79,77,78,40,80,81,6,8,50,15,35,8,35,34,35,38,39,37,36,40,41,35,38,39,37,36,40,41,35,76,38,79,77,78,40,76,80,81,80,81,76,38,77,79,78,40,76,83,84,77,78,83,76,38,79,78,77,40,76,76,77,38,79,78,40,76,79,77,38,78,40,76,80,81,76,38,79,78,77,40,76,35,38,39,37,36,40,41,35,76,38,77,79,78,40,76,35,38,39,37,36,40,41,35,38,39,37,36,40,41,35,76,38,79,78,77,40,76,83,84,77,78,83,76,38,79,78,77,40,76,8,50,76,8,35,76,8,35,8,76,8,80,8,76,8,76,8,8,76,8,83,8,76,8,80,8,76,8,35,8,35,8 177 | 94,15,94,94,94,93,94,15,93,15,93,75,75,75,93,75,94,93,94,15,94,75,94,94,15,94,94,15,94,75,75,75,75,94,15,93,94,93,15,93,75,93,94,93,15,94,15,94,94,94,15,94,94,15,94,15,94,75,94,75,94,15,94,94,15,94,75,94,15,94,15,94,75,75,75,94 178 | 29,30 179 | 72,15,72,15,23,23,15,72,15,72,15,72,72,15,72,72,15 180 | 83,8 181 | 15,76,8,35,36,39,38,37,40,41,35,38,37,39,36,35,40,41,35,38,37,39,36,35,40,41,35,38,36,37,39,40,41,35,38,37,39,36,40,41,35 182 | 72,15,72,72,15,72,72,15,72,72,15,72,72,15,72 183 | 83,85,77,78,79,38,40,83,77,78,84,83,15,85,77,85,78,38,79,40,85,83,77,78,84,83,85,77,85,38,79,78,40,35,38,36,37,39,35,40,41,35,38,36,39,37,40,35,41,35,37,38,39,36,35,40,41,35,36,39,37,38,35,40,41,35,36,38,37,39,40,35,41,35,15,85,77,79,78,38,40,35,38,37,39,36,40,35,41,35,38,36,39,37,40,35,41,35,35,38,36,39,37,40,35,41,35,35,38,37,36,39,40,35,41,35 184 | 85,8,85,34,85,78,38,77,85,79,40,85,85,79,38,78,77,85,40,85,68,68,85,79,78,8,77,38,40,8,85,79,38,78,77,40,85,79,38,78,77,40,85,79,77,38,78,40,85,79,38,78,77,40,85,79,77,38,78,40 185 | 15,35,38,39,35,37,36,40,41,35,82,15,80,81,82,80,81,80,81,80,15,35,39,37,35,38,36,40,41,35,15 186 | 92,15,92 187 | 15,68,15 188 | 8,76,34,76,78,79,38,77,40,76,3,4,5,6,7,8 189 | 86,85,86,85,8,85,8,8,85,8,34,86,85,86,85,78,79,38,77,40,85,35,38,37,36,39,40,41,35,85,38,77,79,78,40,85,35,39,38,37,36,40,41,35,85,38,77,79,78,40,85,83,77,78,84,83,83 190 | 86,86,86,3,4,5,86 191 | 15,68,68,68,68,68,68,6,15 192 | 15,85,77,78,85,79,38,40,85,77,78,79,38,85,40,85,15,85,77,38,78,79,40,85,15,29,15,85,38,79,77,78,40,85 193 | 35,8 194 | 15,93 195 | 86,85,77,78,79,38,40,85,35,38,37,36,39,40,35,41,35,82,35,35,85,86,86,6,86,86 196 | 35,8,35,34,35,37,36,39,35,38,35,40,41,35,8 197 | 29,30,31 198 | 8,76,34,76,79,38,77,78,40,76 199 | 8,34,15,76,78,77,76,79,38,76,40,76,35,38,37,36,39,35,40,35,41,35,8,50,15,8,34,15,35,38,37,39,36,35,40,41,35,80,81,80,83,77,83,78,83,84,83,80,81,80,82,82,82,15,35,38,37,39,35,36,35,40,41,35,8,50 200 | 80,8,80,34,80,81,80,81,80,76,38,77,78,79,40,76,80,83,84,78,77,83,76,38,77,79,78,40,76,38,79,77,78,40,76 201 | 86,86,86,85,86,85,86,85,38,77,78,79,85,40,85 202 | 86,86 203 | 15,8,34,15,76,38,77,78,79,40,76,83,77,78,84,83,8,50,83,8,76,8,15,8,15 204 | 70,29 205 | 15,92,15,92,15 206 | 8,15,9,15,76,78,38,40,76,3,4,5,6,7,6,7,7,34,6,8,50 207 | 15,85,38,78,77,79,40,85,29,30,29,31,85,79,38,77,78,40,85,15,85,79,38,77,78,40,85,15,85,79,78,38,77,40,85,15 208 | 15,70,15,70,15 209 | 15,8,34,15,80,81,82,82,82 210 | 29,30 211 | 85,78,77,79,38,40,80,81,80,85,77,38,79,78,40,35,38,36,37,39,40,41,35,68,68,85,79,77,78,38,40,35,38,39,37,36,40,35,41,35,68,85,78,77,79,38,40,35,38,39,37,36,40,41,35,35,37,39,38,36,40,41,35 212 | 29,30 213 | 6,3,4,5,3,4,5,6 214 | 29,30 215 | 29,30,15,68 216 | 83,8,83,34,83,78,77,83,84,83 217 | 92,15,92 218 | 92,93,15 219 | 15 220 | 15,85,38,77,78,79,85,40,85,35,38,39,37,36,40,41,35,85,38,79,77,78,40,85,83,77,84,78,83,83,85,83,85,35,85,83,85,83,35,38,37,39,36,40,41,35,85,35,15 221 | 15,70,15,70,15 222 | 3,4,5,3,4,5,3,4,5,3,4,5 223 | 29,30 224 | 15,3,4,5,6,8,6,34,6,7,6 225 | 86,8 226 | 86,85,86 227 | 15,85,8,85,8,85,8,85,34,85,77,38,78,85,79,40,85,80,85,80,81,80,76,38,77,79,78,40,76,83,77,78,84,83,68,83,68,68,83,84,78,77,83,76,38,77,79,78,40,76 228 | 50,8,76,34,76,38,77,79,78,40,35,38,37,39,36,35,40,41,35,76,38,77,79,78,40,76,35,38,39,37,36,35,40,41,35,35,39,38,37,36,35,40,41,35,15,76,38,79,77,78,40,76,8,50 229 | 85,15,85,77,78,79,38,40,85,15,85,77,78,79,38,40,35,39,38,37,36,35,40,35,41,35,15,85,77,79,78,38,40,35,38,39,37,36,35,40,35,41,35,35,38,39,37,36,40,35,41,35,85,38,77,40,78,79,35,39,38,37,36,40,35,41,35,85,38,77,79,78,40,85,35,39,38,37,36,40,35,41,35 230 | 86,85,86,85,78,77,79,38,40,85,35,38,39,37,36,40,41,35,38,37,39,36,40,41,35,85,77,38,79,78,40,85,83,77,78,84,83,85,79,77,38,78,40,85,86,85,86,85,77,78,79,38,40,85,35,38,39,37,36,40,41,35,38,39,37,36,40,41,35,85,79,77,38,78,40,85,83,77,78,84,83,85,86,85,86,86,86 231 | 86,85,86,85,78,77,79,38,40,85,79,77,38,78,40,85,86,85,79,78,77,38,40,85,86,85,86,85,38,79,78,77,40,85,79,77,38,78,40,85,86,85,86,85,38,79,78,77,85,35,40,35,38,36,37,39,40,41,35,86,85,79,78,77,38,40,85,86,85,86,85,38,79,78,77,40,85,86,85,79,77,78,38,40,85,86,85,86,85,38,79,78,77,40,85,77,38,79,78,40,85,86,85,86,85,79,77,78,38,40,85,77,38,79,78,86,40,86,85,86,85,79,78,77,38,40,85,86,85,86,85,86,85,38,79,77,78,40,85,86,85,86,85,38,78,77,79,40,85,86,85,86,85,86,85,79,77,78,38,85,40,85,77,79,38,78,86,40,85,86,85,86,85,79,78,77,38,40,85,79,77,38,78,40,85,86,86,86,85,79,38,78,77,40,85,86,86,3,4,5,5,6,86,85,86,85,38,79,77,78,40,85,86,85,38,79,78,77,40,85,86,85,86,85,79,38,78,77,40,85,86,86,86,85,86,85,79,78,38,77,40,85,86,85,86,85,38,79,77,78,40,85,38,79,78,77,86,40,86 232 | 29,30,29,30 233 | 15,3,4,5,3,4,5,15 234 | 15,85,8,15 235 | 3,4,5,6,7,8,9,10,11,12,7,34 236 | 15,76,8,76,34,76,79,78,77,38,40,76,35,38,35,37,36,39,35,40,41,35,35,8,50,50 237 | 3,4,5,15 238 | 15,21,15 239 | 29,30 240 | 15,85,38,77,79,78,40,85 241 | 15,8,34,15,76,78,77,38,79,76,40,76,8,50 242 | 15,68,68,15 243 | 50,15 244 | 35,8,35,34,35,37,35,39,38,36,35,40,41,35,8,50,76,8,76,34,76,77,78,76,79,38,40,76,76,79,38,78,77,76,40,76,3,4,5,72,15,72,15,72,15,72,3,4,5,15,6,76,79,78,77,38,76,40,76,8,50,76,8,76,34,76,79,78,77,76,38,40,76,35,38,37,35,39,35,36,40,41,35,35,37,38,39,36,35,40,35,41,35,8,50,3,4,5,3,4,5,3,4,5,3,4,5,6,3,4,5,6,3,4,5,6,3,4,5,6,3,4,5,6,15,6,7,8,7,34,76,77,79,76,38,76,78,76,40,76,8,50,35,8,35,34,35,37,35,39,35,38,36,35,40,41,35,35,37,38,39,35,36,35,40,41,35,35,35,37,38,39,35,36,40,35,41,35,76,79,38,78,77,76,40,76,76,77,79,38,78,76,40,76,76,79,77,38,78,76,40,76,8,50,76,8,76,34,76,79,78,77,76,38,76,40,76,8,50 245 | 29,30 246 | 15,68,68 247 | 86,68,86,68,68 248 | 15,76,8,76,34,76,38,77,78,79,40,76,92,15,92,76,38,78,77,79,40,76 249 | 29,30 250 | 15,85,78,77,38,79,40,85,15,6,15 251 | 15,90,91,15,91,91,15,91,91,15,91,91,15,91,91,15,91,15,90,91,15,91,90,91,15,91,15 252 | 86,85,86,85,38,78,77,79,40,85 253 | 86,86,85,38,77,78,79,40,85 254 | 8,34 255 | 76,8,76,34,76,38,77,78,79,40,76 256 | 15,3,4,5,60,15,60,15,9,9,6 257 | 15,8,34,15,76,78,38,77,79,40,76,79,78,38,77,40,76,79,38,78,77,40,76,8,50 258 | 15,6,15,3,4,5,3,4,5,3,4,5,5,3,4,5,3,4,5,5,3,4,5 259 | 15,76,8,76,8,76,8,15,76,8,76,8,76,79,78,38,77,40,76,35,38,39,37,36,40,41,35,35,38,36,37,39,40,41,35,38,39,37,36,40,41,35,15,76,38,79,78,77,40,76,76,79,38,77,78,40,76,76,38,77,79,78,40,76,3,4,5,6 260 | 35,85,77,78,79,38,40,85,68,68,68,85,79,77,78,38,40,85,35,38,37,39,36,40,35,41,35,3,4,5,6,7,6,35,37,36,38,39,40,41,35,15,68,85,38,78,77,79,40,85,35,37,38,39,36,40,35,41,35,35,38,37,36,39,40,41,35,35,38,37,36,39,40,35,41,35,85,38,79,78,77,40,85,68,68,85,79,38,77,78,40,85,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,68,68,68,85,79,38,78,77,40,85,35,38,37,36,39,40,35,41,35,35,38,36,39,37,40,41,35,85,79,38,77,78,40,85,68,85,79,38,78,40,85,35,38,37,39,77,36,40,41,35,85,38,77,79,78,40,85,15,85,79,38,78,77,40,85,35,38,37,39,36,40,35,41,35,68,68,15,68,68,68,85,79,78,77,38,40,85,35,38,36,37,39,40,41,35,38,36,37,39,40,41,35,85,35,85,79,38,78,77,40,85,15,68 261 | 15,15 262 | 15,6,15,6,7,15,6,7,35,36,38,37,39,35,40,41,35 263 | 86,85,78,77,38,79,40,35,38,36,39,37,40,35,41,35,35,37,36,38,39,35,40,41,35,86,86 264 | 15,85,78,79,77,38,40,85,83,77,78,84,83,85,38,79,77,78,40,85,15,85,79,78,38,77,85,40,85,83,84,77,78,83,85,79,38,77,85,78,40,15 265 | 15,85,38,77,78,79,40,85 266 | 29,30 267 | 15,29,15 268 | 15,76,8,76,34,76,78,38,77,79,76,40,76,3,4,5,6,7 269 | 8,34,15,68,68,68,68 270 | 15,3,4,5,6,15,3,4,5,6,15,8,34,15,6,3,4,5,3,4,5,3,4,5,6,7,8,50,15,8,34,15,35,38,39,37,36,40,41,35,35,38,37,39,36,40,41,35,8,50 271 | 50,76,8,76,34,76,79,38,77,78,40,83,84,77,78,83,77,78,84,83,8,50,8,76,34,76,78,38,77,79,40,83,84,77,78,83,8,50 272 | 15,60,15,60,15 273 | 15,85,77,38,78,79,40,85,79,77,78,85,15,38,15,85,79,77,38,78,40,85,79,78,77,38,40,85,15,85,38,77,78,79,40,85,76,38,79,77,78,40,76,35,37,36,38,39,40,41,35,76,38,79,78,40,77,76,83,85,83,85,77,79,38,78,40,85,80,81,82,80,82,82,80,85,38,79,78,77,40,85,76,79,38,77,78,40,76,79,78,38,77,40,76,79,38,77,78,40,76,79,77,38,78,40,76,38,79,77,78,40,76,85,79,38,78,77,40,85,35,38,39,37,36,40,41,35,15,85,79,77,38,78,40,85,15,85,79,77,38,78,40,85,85,79,38,77,78,40,85 274 | 15,3,4,5,3,4 275 | 68,68,68,15 276 | 15,6,15,68,6,15 277 | 15,3,4,5,6,7,8,7,8,76,34,76,38,77,78,35,38,39,37,36,35,40,41,35 278 | 86,85,86,85,78,38,79,77,40,85,83,77,78,84,83,86,86,86 279 | 8,34 280 | 61,15,61 281 | 8,34,15,35,36,37,35,39,38,35,40,35,41,35,82,76,38,77,78,79,76,40,76,8,50,15,6,8,6,76,78,77,79,38,76,40,76,38,79,77,78,40,76,83,77,78,83,84,83,35,38,37,36,35,39,40,41,35,76,79,38,78,77,76,40,35,38,37,39,36,35,40,41,35,8,50 282 | 3,4,5,6,7,8,9,10,11,12,11,12,7,34,6,3,4,5,6,7,6,3,4,5,6,7,68,35,38,36,39,37,40,41,35,35,37,39,38,35,36,40,35,41,35,68,6,3,4,5,6,7,6,3,4,5,6,7,3,4,5,6,7,6,3,4,5,6,7,6 283 | 76,8,76,34,76,78,79,38,77,76,40,76,80,81,35,38,35,37,36,39,35,40,41,35,76,79,77,38,78,40,76,80,81,80,81,80,81,80,76,79,78,38,76,77,40,76 284 | 15,68 285 | 15,68,3,4,5 286 | 15 287 | 86,86,3,4,5,86,86 288 | 15,3,4,5,6,8,6,34,6,3,4,5,6,76,38,78,76,77,79,40,76,35,38,37,35,39,36,40,41,35,6 289 | 6,15,6,15,3,4,5 290 | 15,35,8,35,34,35,37,36,38,35,39,40,41,35,76,38,77,78,40,76,79,76,15,35,36,35,37,39,38,40,41,35,15,35,37,36,39,35,38,40,41,35,35,37,38,39,35,36,35,40,41,35,76,79,38,78,77,76,40,76,15,35,36,35,37,39,38,40,41,35,76,38,78,77,76,79,40,76,83,77,83,78,83,84,83,82,82,82,15,35,37,39,35,36,38,40,41,35,35,37,38,35,39,36,35,40,41,35,76,79,38,78,77,40,76,35,37,36,38,39,35,40,41,35,80,81,82,83,77,84,83,78,83,82,35,37,35,39,38,36,40,41,35,82,35,76,79,38,78,77,40,76 291 | 15,15 292 | 29,30,30,30,32,33 293 | 15,85,38,77,78,79,40,35,38,39,37,36,40,41,35,85,38,77,79,78,40,85,15 294 | 15,68,68,68,68,68,68,68,68,68,68,68 295 | 72,15,72 296 | 15,85,78,38,79,77,40,85,83,77,78,84,83,85,79,77,38,78,40,85,15 297 | 15,85,78,38,77,79,40,85,85,38,79,77,78,40,85 298 | 86,85,79,78,77,38,40,85,86 299 | 76,8,76,34,76,78,79,77,38,76,40,76,8,3,4,5,6,7,76,79,78,77,38,76,40,76,8,50 300 | 15,9,15,9,8,9,8,76,78,38,76,40,76,3,4,5,6,7,7,34,15,9,76,78,79,38,77,76,40,76,35,38,37,36,39,35,40,41,35,35,39,38,37,36,35,40,41,35,83,84,77,78,83,35,37,38,39,35,36,40,41,35,8,50,8,76,34,76,79,78,38,77,76,40,76,15,70,15,35,35,38,35,39,36,37,35,40,35,41,35,35,35,35,38,39,37,35,36,35,40,35,41,35 301 | 86,85,86,85,79,77,78,85,38,40,85,77,79,38,78,40,85,35,38,37,39,36,40,41,35,37,38,36,39,40,41,35,85,77,79,38,78,40,86,85,86,85,79,78,77,38,40,85,35,38,37,39,36,40,41,35,37,38,36,39,40,41,35,85,77,79,38,78,40,85,86,85,86,85,86,85,78,77,38,79,40,85,35,38,37,36,39,40,41,35,85,38,77,79,78,40,85,86,85,86,85,38,77,79,78,40,85,35,37,38,36,39,40,41,35,35,37,38,36,39,40,41,35,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,85,38,79,78,77,40,85,86 302 | 86,85,86,85,38,78,79,77,40,85,86 303 | 29,30,32,33,32 304 | 15,35,8,76,8,76,34,35,38,39,37,36,35,40,41,35,76,38,77,78,79,40,76,76,38,79,77,78,40,76,76,38,79,77,78,40,76,8,15 305 | 15,35,37,39,36,38,35,40,41,35,15,35,39,37,36,38,35,40,35,41,35 306 | 3,4,5,3,4,5,3,4,5,6,7,8,9,10,8,6,7,8,8,6,7,8,9,8,6,7,8,9,10,11,12,7,34 307 | 35,8,35,34,35,36,37,39,38,35,40,41,35,15,76,38,78,77,79,40,83,77,78,84,83 308 | 72,15,72,3,4,5,6 309 | 86,85,8,85,34,85,77,38,78,79,40,80,81,82,80,82,80 310 | 15,8,34,15,35,38,37,36,35,39,35,40,41,35 311 | 3,4,5,15,6,15,6,7,6,8,9 312 | 15,85,78,38,77,79,40,35,38,37,35,36,39,40,41,35 313 | 76,8,76,34,77,79,38,78,76,40,76 314 | 15,3,4,5,6,15 315 | 15,3,4,5,3,4,5,6,3,4,5,6,7,8,7,34,8,50 316 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,60,15,60,15,6,8,6,34,6,7,8,50,15 317 | 8,76,8 318 | 15,80,81,76,77,38,78,79,40,76,83,15,35,36,37,38,39,40,41,35 319 | 29,30,29,30 320 | 3,4,5,6,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,3,4,5,3,4,5,3,4,5,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,3,4,5,15,3,4,5,15,3,4,5,6,7,8,9,10,11,12,11,12,7,34 321 | 86,85,77,38,78,79,40,85,83,77,78,84,83,86,85,77,78,79,38,40,85 322 | 15,8,34,15,76,38,78,77,79,76,40,76,80,81,80,82,8,50 323 | 6,68,6 324 | 86,85,38,77,78,79,40 325 | 15,76,8,76,34,76,79,78,77,38,40,76 326 | 35,8,35,34,35,37,36,38,39,35,40,41,35,15,76,38,77,78,79,76,40,76,35,37,39,36,38,35,40,41,35,76,38,79,78,77,76,40,76,30,32,33,30,35,37,38,36,39,35,40,41,35,35,35 327 | 15,85,77,78,38,79,40,85,35,38,36,39,37,40,41,35,85,38,79,77,78,40,85,83,77,78,84,83,85,38,79,78,77,85,35,40,35,38,37,39,36,40,41,35,85,38,77,79,40,78,85 328 | 15,76,8,76,34,76,78,79,38,77,76,40,76,83,77,78,83,84,83,8,50 329 | 68,8,68,34,68,35,38,35,39,37,36,40,41,35,82,68,68,68,68,8 330 | 15,3,4,5,3,4,5,3,4,5,15,3,4,5,15,3,4,5,60,15,60,15,6,3,4,5,6,15,3,4,5,15 331 | 86,85,78,77,38,40,79,85,77,38,79,78,40,35,38,39,37,36,40,41,35 332 | 15,8,34,15,76,38,78,77,76,79,76,40,76,8,50,8 333 | 15,8,34,15,35,38,39,37,36,40,35,41,35 334 | 86,68,86,85,38,77,78,79,40,85,86,86,86,86,86,86 335 | 30,29,30 336 | 8,8,34,35,37,36,39,38,40,41,35,35,38,39,37,36,40,35,41,35,35,38,37,39,36,40,41,35,37,39,36,38,40,35,41,35 337 | 8,76,34,76,78,77,38,79,40,76,68,68,68,68,68,68,68,68,68,68,68,3,4,5,6,8,76,38,79,78,77,76,40,76,6,92,15,92,93,15,93,3,4,5,6,7,6,3,4,5,6,93,15,93,6,8,50 338 | 86,86,86,6,86,86,3,4,5,3,4,5,86,86,3,4,5,3,4,5,5 339 | 15,92,15,92,92,15,92,15 340 | 93,15,93 341 | 8,35,34,35,37,39,36,38,40,41,35,35,35,8,35,37,39,36,38,40,41,35,35,8,35,34,35,38,37,39,36,40,41,35,35,36,37,39,38,40,41,35,8,35,39,36,37,38,40,41,35,35,8 342 | 92,15,92 343 | 15,8,34,15,35,38,39,37,36,40,35,41,35,35,38,37,39,36,35,40 344 | 8,34,15,76,38,77,78,79,76,40,76,83,77,78,84,83,8,50 345 | 8,76,34,76,78,79,77,38,40,76,35,38,36,37,39,40,41,35,8,50,35,8,76,8 346 | 3,4,5,3,4,5,6 347 | 29,30 348 | 15,8,34,15,35,39,37,36,38,40,35,41,35,76,38,78,79,77,40,76,8,50,15,8,34,15,35,39,37,36,38,40,35,41,35,35,39,37,38,36,40,35,41,35,35,39,38,37,36,40,35,41,35,35,38,39,37,36,40,35,41,35,35,39,37,38,36,35,40,35,41,35,35,39,37,38,36,35,40,35,41,35,35,39,37,38,36,40,41,35,35,39,37,38,36,40,41,35,8,50 349 | 68,72,15,72 350 | 29,30,29,30,29,30,29,30 351 | 15,76,8,15,76,8,9,8,35,8,15 352 | 91,15,91 353 | 15,76,78,38,77,79,40,76,15,76,79,78,38,77,40,76,35,38,39,36,37,40,41,35,76,77,38,79,78,40,15,76,79,77,78,38,40,35,38,39,37,36,40,41,35,76,77,38,79,78,40,76,15,76,78,77,79,38,40,35,38,36,39,37,40,41,35,76,79,38,77,40,78,15 354 | 85,38,77,78,85,79,40,85,93,15,93,85,38,78,77,79,85,40,85,68,3,4,5,6,7 355 | 15,8,34,15,76,77,38,78,79,40,76,92,15,92 356 | 15,76,78,38,77,79,76,40,76,8,50,8,76,34,76,38,77,79,78,40,76,92,15 357 | 3,4,5,3,4,5,6,7,8,9,10,11,12,11,12,8,11,9,11,9,8,6,15,3,4,5,3,4,5,6,7,8,13,8,8,6,7,8,8,76,8,6,15 358 | 15,3,4 359 | 15,8,15,76,77,38,78,79,76,40,76,8,50 360 | 15,29,15,3,4,5,5,6,3,4,5,5,3,4,5,5 361 | 15,8,34,15,35,39,36,37,35,38,40,41,35,82,8,50,15,76,8,76,34,76,77,38,40,76,78,76,79,76,80,81,80,8,50 362 | 15,76,8,76,38,77,78,79,40,76,6 363 | 30,30 364 | 15,8,34,15,76,77,38,78,79,40,83,77,78,83,84,83,83,8,50,8,76,34,76,78,38,77,79,40,76,38,77,79,78,40,76,35,38,37,36,39,40,41,35,76,38,77,79,78,40,83,77,78,84,83,8,50,8,76,34,76,38,78,77,79,40,83,77,78,84,83,8,50 365 | 15,72 366 | 15,76,38,77,78,79,40,76,6,15,3,4,5,6,80,81,80,83,83,77,78,83,84,83,6,7,15,35,38,37,36,39,35,40,35,41,35,15,35,37,36,39,35,38,35,40,41,35,15,35,36,37,39,38,35,40,41,35,80,81,80,82,82,80,81,80,35,38,37,39,36,35,40,41,35,15,35,37,39,36,38,35,40,41,35,82,35 367 | 29,30,29,30 368 | 15,80,8,80,34,80,81,82 369 | 15,88,88,15,88,15,3,4,5,88,88,88,88,3,5,3,4,5,3,4,5,6,3,4,5,3,4,5,3,4,5,6,15,88,88,88,15,3,4,5,3,4,5,6,3,4,5,3,4,5,3,4,5,6,3,4,5,6 370 | 15,8,34,15,76,79,78,77,76,38,40,76 371 | 3,4,5,15 372 | 3,4,5,6,7,8,7,34,8,50,15 373 | 85,78,38,77,79,40,85 374 | 8,8,34,84,77,78,8,84,78,77 375 | 15,68,15 376 | 3,4,5,6,7,8,6,15 377 | 15,68,76,8,76,34,76,78,38,79,77,40,76,35,38,36,39,37,35,40,41,35,35,35,38,39,37,36,35,40,41,35 378 | 35,8,35,34,35,37,39,36,35,38,40,35,41,35 379 | 3,4,5,6,7,8,9,10,11,12,7,34 380 | 15,85,8,85,34,85,78,79,77,38,40,85,8 381 | 15,3,4,5,3,4,5,15,6,3,4,5,6,3,4,5,6,15,3,4,5,6 382 | 76,78,38,77,79,76,40,76,79,38,77,78,40,76,80,81,35,38,37,35,39,36,40,41,35,76,79,38,78,40,76,77,76,15,35,38,37,39,36,35,40,41,35,80,81,80,76,38,79,77,78,40,76,15 383 | 29,30 384 | 15,85,78,79,38,77,40 385 | 35,8,35,34,35,39,37,36,38,40,41,35,8,35,37,39,36,38,40,41,35,35,38,39,37,36,40,35,36,39,38,37,40,41,35,35,38,39,37,36,40 386 | 72,15,72,72,15,72 387 | 35,8,35,34,35,36,37,35,38,39,40,41,35,83,78,77,83,84,83 388 | 35,8,35,34,35,38,37,35,36,39,35,40 389 | 15,8,34,15,76,77,78,79,38,40,76,76,77,79,38,78,40,76,83,77,78,84,83,8,50,50,3,4,5,3,4,5,6,3,4,5,3,4,5,6,3,4,5,6,76,8,76,34,76,38,77,78,79,40,8,50,15,76,8,6,8,6,34,6,76,79,38,78,77,40,76,6,3,4,5,6,7,76,79,78,77,38,40,76,8,50,15,8,34,15,76,79,78,77,38,40,76,80,81,35,38,36,39,37,40,41,35,8,50 390 | 29,30,31 391 | 86,6,85,8,34,85,77,38,78,79,40,85 392 | 86,85,86,8,85,8,85,38,77,78,79,85,86,40,86,85,8 393 | 29,30 394 | 6,15,3,4,5,3,4,5,15,3,4,5,6,7,8,13,8 395 | 8,34,15,35,37,39,36,35,38,40,41,35,85 396 | 15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6 397 | 50,8,76,34,76,78,77,38,79,40,76,83,84,78,77,83,82,8,50 398 | 15,8,34,15,80,81,80,82,83,77,78,84,83,8,50 399 | 35,8,8,35,34,35,37,35,36,39,35,38,40,35,41,35,8,50 400 | 8,34,78,77,84 401 | 76,38,78,77,79,40,76 402 | 15,35,8,35,34,35,37,36,35,39,38,40,41,35,82,35,36,35,38,37,39,40,41,35 403 | 15,76,8,15,85 404 | 8,35,34,35,39,36,37,38,40,41,35,8,15,35,39,37,38,35,36,40,41,35,38,39,37,36,40,35,41,35,39,37,36,35,38,35,40,41,35,38,39,37,36,40,35,41,35 405 | 3,4,5,6,7,8,9,10,11,12,7,34,35,38,39,36,37,40,41,35,8,50,35,8,8,8,8,8,6,34,6,76,78,79,38,77,40,35,38,39,36,35,37,40,41,35,8,50,35,8,76,8,6,8,7,7,8,11,9,8,6 406 | 85,77,38,78,79,40,85,83,77,84,78,83,85,77,38,79,40,78,35,38,39,37,36,40,41,35,35,39,37,38,36,40,41,35,24,24 407 | 29,30 408 | 29,30 409 | 15,85,38,77,85,78,79,85,40,83,77,84,78,83,83 410 | 76,8,76,34,76,77,38,78,79,76,40,76,35,38,39,36,35,37,35,40,35 411 | 15,8,34,15,76,77,38,78,79,40,76,80,81,80,35,38,36,39,37,35,40,41,35,35,38,39,37,36,35,40,41,35 412 | 29,30,29,30 413 | 15,85,38,77,85,78,79,40,35,38,36,39,37,40,41,35,85,38,77,79,78,40,80,81,80,85,38,77,79,40,78,83,77,78,84,83,83,85,38,77,79,40,78,85,15 414 | 15,35,8,35,34,35,38,36,39,35,37,40,41,35,35,38,39,37,35,36,35,40,41,35,8,50,35,8,15 415 | 15,3,4,5,6,3,4,5,5,6,7,8,6,35,8,35,39,36,37,38,35,40,41,35,83,78,77,83,84,83,35,39,36,38,37,40,35,41,35,80,81,80,35,39,38,37,36,35,40,41,35,83,84,78,77,83,6,15,3,4,5,6,8,50 416 | 92,15,92,76,38,78,77,76,79,40,76,35,38,35,37,35,39,36,40,41,35,92,15,92,35,38,37,35,36,39,40,41,35 417 | 35,8 418 | 29,30 419 | 15,76,8,76,34,76,77,38,78,79,76,40,76,15,8,50,60,15,60,15 420 | 15,21 421 | 35,8,35,34,35,39,36,37,38,40,41,35,8,50,35,8,35,34,35,39,37,36,38,40,41,35,8,50,35,8,35,34,35,37,39,36,38,35,40,41,35,8,50,35,8,35,34,35,39,37,35,36,38,40,35,41,35,8,50 422 | 3,4,5 423 | 29,30 424 | 92,8,92,34,92,15,92,76,79,78,38,77,40,76,76,79,38,77,78 425 | 15,68 426 | 15,8,34,15 427 | 6,35,39,37,38,36,40,35,41,35,82,35,37,39,38,36,35,40,35,41,35,68,68,68,35,39,37,36,38,35,40,41,35 428 | 18,15 429 | 8,34,15,35,36,37,39,38,35,40,35,41,35,8,50 430 | 8,34,78,77,84,68,35,36,37,39,38,40,41,35,8,50,35,8,68,6,8,35,8,35,8,35,34,35,37,36,39,35,38,40,35,41,35,8,50,35,8,35,36,39,37,38,40,35,41,35,8,50 431 | 30,31 432 | 15,8,34,15,35,36,38,39,35,37,40,41,35,80,81,80,81,80,81,80,83,77,78,83,84,83,68,68,68,15,68,15,68,15,68,68,68,15 433 | 86,86,86,85,38,77,78,79,40,85,8 434 | 76,8,76,34,76,79,78,38,76,77,40,76,68,68,68,68,68,3,4,5,68,3,4,5,6,7 435 | 85,15,85,38,77,78,79,40,85,83,77,78,84,83,85,38,77,79,78,40,85,35,38,37,39,36,40,41,35,85,79,38,77,78,40,85,80,81,80,85,38,77,79,78,40,85,83,84,77,78,83,85,38,77,79,78,40,85,80,81,80,85,38,79,77,78,40,85,15,85,38,77,78,79,40,85,8 436 | 15,6,15,6,15,3,4,5,3,4,5 437 | 92,92,15 438 | 15,85,77,78,79,38,40,35,38,37,39,36,40,35,41,35,35,38,39,37,36,35,40,41,35,35,37,38,39,36,35,40,41,35,85,38,79,77,78,40,85,83,77,78,84,83 439 | 86,85,86,85,8,85,34,85,38,78,77,79,86,40,86,85,86,85,68,3,4,5,6,7,68,68,68,85,79,77,38,78,40,85,83,77,78,84,83,76,38,77,79,78,40,76,8 440 | 8,35,37,38,39,36,35,40,41,35,80,81,80,82,82,82,82,82,76,38,78,77,79,40,76,8,50 441 | 29,30 442 | 15,92,15,92,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,92,15,92,15 443 | 15,6,15 444 | 68,68,68,68,68,68,68,68,68,8,68 445 | 3,4,5,6,7,8,9,10,11,12,11,12,11,12,8,8,34,6,7,6,15,76,38,77,79,78,40,76,15,6,15 446 | 3,4,5,6,7,8,9,10,9 447 | 15,35,8,35,34,35,37,38,39,36,35,40,41,35 448 | 29,30 449 | 15,35,8,35,38,39,37,35,36,40,41,35,8,35,34,35,38,39,35,37,36,40,41,35,82,35 450 | 15,76,8,76,38,78,79,83,40,77,83,77,78,83,84,83 451 | 15,70,71,15,71 452 | 76,8,76,34,76,77,38,78,79,40,83,77,83,78,84,83,76,38,79,77,78,40,35,38,35,39,36,37,40,41,35,76,38,77,79,78,40,80,81,80,81,80,81,80,76,79,38,77,78,40,76,8,50 453 | 15,8,15,76,77,38,78,76,79,40,76,8,50 454 | 86,86,86,86,86,86,86,15 455 | 29,30,15,8,34,15,76,83,38,78,77,79,83,77,83,84,78,83,8,50 456 | 35,8,8,15 457 | 86,85,38,78,77,79,40,85,83,77,78,84,83,82,83 458 | 8,34,84,78,77 459 | 30,29,30 460 | 35,8 461 | 29,30 462 | 8,35,8,76,8 463 | 35,8,35,34,35,36,37,38,39,35,40,41,35,83,77,78,83,84,83,82,35,38,37,35,36,39,35,40,41,35,80,81,83,84,77,78,83,84,80,81,80,35,38,37,35,36,39,35,40,35,41,35 464 | 50,85,8,85,77,78,79,85,38,40,85,80,81,82,80,82,82,80,85,38,79,78,77,40,85,35,38,36,37,39,40,41,35,85,38,79,78,77,40,85,85,38,79,78,77,40,85,8,85,38,79,77,78,40,85,35,38,37,39,36,40,41,35,35,38,37,36,39,40,41,35,85,38,79,77,78,40,85,8 465 | 29,30 466 | 29,30 467 | 15,72,15,72 468 | 29,30 469 | 3,4,5,3,4,5,3,4,5,6,7,8,7 470 | 15,70,15,70,15,51,51 471 | 29,30,29,31,29,30,29 472 | 86,86 473 | 15,3,4,5,6,79 474 | 15,68,68 475 | 86,86,3,4,5 476 | 68,83,83,77,78,84,83,83,76,77,38,78,40,79,76,77,38,79,40,78,76,76,76,83,84,83,77,78,83,83,83,84,83,78,77,83,78,77,84,83 477 | 6,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,3,4,5,92,15,92,92,15,92,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,15,92,15,92,15,92,15,92,3,4,5,3,4,5,15,92,15,92,3,4,5,15,6,7,8,7,34 478 | 60,15,60,15 479 | 15,8,15,76,78,77,76,38,79,40,76,83,77,83,78,83,84,83,8,50 480 | 35,38,37,36,39,35,40,41,35,68,68,68,68,68,68,93,15,93,68,68 481 | 15,8,34,15,35,38,37,36,39,35,40,41,35,68,76,79,38,78,77,76,40,76,8,50 482 | 35,8,35,34,35,38,39,37,36,40,41,35 483 | 15,85,38,78,79,77,40,85,35,38,36,37,39,40,35,41,35,85,79,78,38,77,40,85,15 484 | 76,8,76,34,76,38,77,78,76,40,79,76,8,50,15,3,4,5,15,3,4,5,6,15,3,4,5,6,15,8 485 | 29,30 486 | 93,15,93 487 | 15,35,8,35,34,35,37,36,38,39,40,41,35,8,50 488 | 15,6,3,4,5,6 489 | 15,76,8,76,34,76,38,77,78,76,79,40,76,83,77,78,83,84,83 490 | 86,85,86,85,38,77,78,79,40,85,86 491 | 15,51 492 | 15,6,15 493 | 15,6,7,8,9,10,8,9,10,8 494 | 15,6,15,3,4,5,6 495 | 15,85,38,77,79,78,40,85,85,38,79,78,77,40,85,15 496 | 8,76,78,77,79,38,40,76,80,81,80,82 497 | 29,30 498 | 3,4,5,6,3,4,5,6,7,8,6,15 499 | 15,8,15,76,77,78,79,83,38,83,77,78,84,83,6,8,50,15 500 | 15,8,34,15,35,38,36,37,39,40,41,35,8,50 501 | 35,38,37,39,36,35,40,41,35,76,77,38,79,78,83,76,83,77,78,83,84,83,76,77,76,38,35,37,35,38,37,39,35,40,41,35,76,8,76,34,8,15,8 502 | 15,85,8,85,34,85,79,38,78,77,85,40,85,85,38,79,78,77,40,85,15,6,15,85,38,79,78,77,40,85,15,85,38,79,78,77,40,85,15,85,79,78,38,77,40,85,15,6,85,38,79,78,77,40,85 503 | 76,78,79,77,38,40,76,79,78,38,77,40,76,78,38,79,77,40,76,77,38,79,78,40,76 504 | 15,85,77,78,38,79,40,83,77,78,84,83,15,85,77,79,78,38,40,35,38,37,36,39,40,41,35,85,38,79,78,77,40,85,35,37,36,38,39,40,41,35,15,85,77,78,38,79,40,85 505 | 15,92,15,92,15 506 | 15,8,34,15,76,78,76,77,76,38,79,40,76,76,38,79,77,78,40,76,38,77,79,78,40,76,68,68 507 | 6,7,8,7,34,8,50 508 | 8,78,77,84 509 | 15,3,4,5,6,3,4,5,3,4,5,6,15 510 | 15,68,68,68,68,15 511 | 8,76,34,76,77,78,79,38,40,35,38,39,37,36,40,41,35,76,38,77,79,78,40,76,8,50,32,33,32,33,32,8,76,34,76,77,79,78,38,35,38,37,39,36,40,41,35,76,38,77,78,79,40,76,8,50,35,8,35,38,39,37,36,40,41,35,76,38,78,79,77,40,8,50,8,76,34,76,77,78,38,79,40,35,38,39,37,36,40,41,35,76,79,38,78,77,40,76,8,50 512 | 86,85,86,85,86,85,78,77,38,79,40,85 513 | 15,76,8,76,8,76,34,76,79,38,78,77,40,76,35,38,39,37,36,35,40,35,41,35,80,81,80,82 514 | 29,30,32,33,30,29,30 515 | 15,8,34,15,76,78,79,77,38,40,35,38,37,39,36,40,41,35,76,38,77,79,40,78,80,81,76,38,79,77,78,40,76,79,78,77,38,40,76,8,50 516 | 15,29,15 517 | 15,68,68,15,68 518 | 29,30 519 | 15,68,68,15,68,68,15,68,68,15 520 | 86,86 521 | 86,85,86,85,78,79,77,38,40,85,35,38,37,36,39,40,41,35,37,38,36,39,40,41,35,85,79,38,77,78,40,85,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,86,85,86,85,79,78,77,38,40,85,35,38,37,39,36,40,35,41,35,82,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,35,41,35,37,36,38,39,40,35,41,35,85,79,77,38,78,40,86,85,86,85,79,38,78,77,40,85,35,38,37,39,36,40,35,41,35,38,37,36,39,40,35,41,35,85,77,38,79,78,40,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,86,85,86,85,79,78,38,77,40,85,35,38,37,36,39,40,35,41,35,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,37,38,36,39,40,35,41,35,86,85,86,85,79,38,78,77,40,85,35,38,39,36,35,37,40,41,35,38,37,39,36,40,35,41,35,86,85,86,85,79,38,77,78,40,85,35,37,38,39,36,40,35,41,35,37,38,36,39,40,35,41,35,85,79,77,38,78,40,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,35,41,35,86,85,86,85,79,38,78,77,40,85,35,37,38,39,36,40,41,35,86,85,86,85,79,78,77,38,40,85,35,38,36,37,39,35,40,41,35,37,38,36,39,40,41,35,85,79,77,38,78,40,85,86,85,86,85,38,79,78,77,40,85,35,38,37,39,36,40,41,35,86,85,86,85,79,38,78,77,40,85,35,38,37,39,36,40,35,41,35,37,38,36,39,40,41,35,86,85,86,85,79,78,77,38,85,35,40,35,38,37,36,39,40,41,35,37,38,36,39,40,35,41,35,24,35,37,38,36,39,40,35,41,35,86,85,86,85,78,38,77,79,40,85,35,38,36,37,39,40,41,35,86,85,86,85,79,78,38,77,40,85,35,38,37,39,36,40,41,35,86,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35,86,85,86,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35,85,38,79,77,78,40,85,86 522 | 15,8,34,15,76,77,38,78,79,40,76,38,79,77,78,40,76,15,76,38,77,78,79,40,76,79,77,76,78,38,40 523 | 86,85,77,38,78,79,40,80,81,82,80,80,81,80,86 524 | 15,8,34,35,39,38,36,37,35,40,41,35 525 | 3,4,5 526 | 3,4,5,6,76,8,76,34,76,38,77,78,79,40,76,76,38,79,77,78,40,76,35,38,36,37,39,40,41,35,76,38,79,78,77,40,6,79 527 | 15,70,15,70,74 528 | 29,30,31,6,8,34,80,81,80,82,29,30 529 | 29,30 530 | 15,8,34,15,76,77,38,78,79,76,40,76 531 | 15,8,34,15,3,4,5,15,3,4,5,15,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,3,4,5,6,7,8,50 532 | 8,34,15,76,78,77,38,79,76,40,76,8,50,15,8,34,15,76,79,38,77,78,76,40,76,8,50 533 | 29,30,29,68,29,15,85,77,78,38,85,79,40,85,77,38,79,78,40,85,77,79,38,78,40,85,15,85,38,77,78,85,79,40,85,35,38,36,37,39,35,40,41,35,15,68,68,15 534 | 15,35,37,39,36,38,35,40,41,35 535 | 35,8,35,34,35,37,36,39,38,35,40,41,35,38,36,39,37,40,35,41,35,38,37,39,36,40,35,41,35,76,78,38,79,77,40,76 536 | 15,70 537 | 3,4,5,6,15,92,92,15,92,15,6,7,8,7,34,76,78,38,79,77,76,40,76,93,15,93 538 | 76,8,76,34,76,78,38,77,79,40,76,76,79,38,78,77,40,76 539 | 50,86,86,86,85,86,85,8,85,34,85,77,78,85,38,86,79,86,40,85,86,86,85,86,85,79,77,78,38,40,8,85,86,86,86,86,86,86 540 | 72,15,72,72,15,72,72,15,72,15,72,15,72,15 541 | 86,85,86,85,78,38,77,79,40,85,35,38,36,37,39,40,41,35,85,38,79,77,78,40,85,80,81,80,86,85,86,85,79,78,38,77,40,85,35,38,37,36,39,40,41,35 542 | 68,76,8,76,34,76,78,38,77,79,40,76,80,81,82,80,76,38,79,78,77,40,76,8,50,32,33,30,76,8,68,30,32,33,30 543 | 76,8,76,34,76,80,81,80,82,82,82,82 544 | 35,8,35,34,35,36,39,37,35,38,40,41,35 545 | 15,51,51,3,4,5,3,4,5,6,76,8,76,34,76,77,78,38,76,79,40,76,8,50,6,7,8,7,34 546 | 29,30,29,15 547 | 15,8,34,35,36,37,38,35,39,35,40,41,35,8,50,15,68,68,15,8,34,35,37,36,38,35,39,35,40,41,35,68,68,15,51 548 | 85,77,79,38,78,40,85,86,85,77,79,85,78,38,40,85,77,79,78,38,40,85,77,85,38,79,78,40,85,86,15 549 | 29,30 550 | 8,35,34,35,37,39,36,35,38,35,40,35,41,35,83,77,78,83,84,83,8,50,8,35,34,35,37,38,39,36,35,40,35,41,35,83,84,78,77,83,35,37,39,36,35,38,40,35,41,35,8,50,8,35,34,35,37,39,38,36,35,40,35,41,35,8,50,8,35,37,39,36,35,38,35,40,35,41,35,83,84,78,77,83,8,50,8,35,34,35,37,38,39,36,35,40,35,41,35,83,84,78,77,83,8,50,8,35,34,37,39,36,35,38,35,40,35,41,35,83,84,78,77,83,8,50,8,50,8,76,34,76,38,79,78,77,40,76,8,50,8,35,34,35,37,39,36,35,38,35,40,35,41,35,83,78,77,83,84,83,8,35,34,35,38,39,37,35,36,35,40,41,35,83,84,77,78,83,8,50,3,4,5,8,34,35,37,38,39,36,35,40,35,41,35,35,36,39,37,38,40,35,41,35,8,50,35,8,3,4,5,6,8,35,34,35,37,39,38,36,35,40,35,41,35,8,50,6,8,6 551 | 29,30 552 | 76,8,76,8 553 | 76,8,76,34,76,79,78,77,38,40,76 554 | 76,40,76,80,81,80,8,50 555 | 3,4,5,3,4,5,6 556 | 6,3,4,5,6,15 557 | 15,68,6,8,8,8,8,6,8,34,6,80,81,80,82,80,6,15,6,3,4,5,3,4,5,6 558 | 15,3,4,5,15,3,4,5,15,68,3,4,5,68,3,4,5,68,15,6,15 559 | 8,34,15,76,78,77,38,79,76,40,76,80,81,80,82,83,78,77,83,84,83,8,50 560 | 76,38,77,78,79,40,76,38,77,79,78,40,76,76,8,76,34,76,38,77,78,79,40,76,80,81,35,38,37,39,36,40,41,35,80,81,83,77,78,84,83,84,78,77,83,84,77,78,83 561 | 15,8,34,15,35,38,37,39,36,40,41,35,15 562 | 8,34,15,80,81,35,37,39,36,38,40,41,35,76,38,77,78,40,79,76,8,50 563 | 29,30,15,3,4,5,3,4,5,3,4,5,3,4,5,8,34,6,8,50 564 | 35,8,35,38,36,37,39,35,40,41,35,83,78,83,77,84,83 565 | 86,85,86,85,38,78,79,77,40,85,86,85,86 566 | 15,8,15,76,77,38,78,40,79,83,77,83,78,84,83,68,8,50 567 | 29,30,31 568 | 76,8,76,78,38,40,76,3,4,5,6,7,7,34,6,15,6,7,15,6,3,4,5,6,7,15,76,78,79,77,38,40,76,76,38,77,79,78,40,6,3,4,5,3,4,5,3,4,5,6,7,15,6,7,7,15 569 | 86,85,78,38,77,79,40,85,86,85,86,85,78,38,77,79,40,85,86 570 | 76,8,35,8 571 | 15,70,74,70,15,70,15,70,15 572 | 15,6,3,4,5,6,7,8,6,3,4,5,6,7,8,9,10,11,12,7,34,35,36,39,37,38,40,41,35,80,81,83,78,84,83,77,83 573 | 15,85,78,77,38,79,40,85,83,77,78,84,83,84,83,83,84,78,77,83,15,70,15,70,15,85,38,79,78,77,40,85 574 | 3,4,5 575 | 15,8,34,15,76,78,77,79,76,38,40,76,8,50,15,8,15,76,78,76,79,77,38,40,76,8,50,8,34,68,68,8,50,15,68,15,68 576 | 3,4,5,3,4,5,5,6,3,4,5,6,7,8,8,13,8,8,8,6 577 | 34,6,35,38,37,36,39,40,41,35,80,81,15,3,4,5,6,7,6 578 | 15,8,34,15,76,38,78,77,79,40,76 579 | 6,86,85,8,85,34,85,77,38,78,79,40,85,35,38,37,39,36,40,41,35,85,38,77,79,78,40,85,8 580 | 35,8 581 | 15,85,78,79,77,38,40,85,15,85,79,78,77,38,40,85,35,85,35,38,36,37,39,40,41,35,85,79,77,38,78,40,85,15,85,78,79,77,38,40,85,35,38,36,39,37,40,35,41,35,36,38,39,37,40,41,35,85,79,38,77,78,40,85,15,85,79,77,78,38,40,85,85,85,85,85,38,79,78,77,40,85,15,85,79,78,77,38,40,85,35,38,37,39,35,36,40,41,35,85,77,79,38,78,40,85,15 582 | 29,30 583 | 86,85,78,38,77,79,40,85,35,38,36,37,39,40,41,35 584 | 92,15,92,92,15,92 585 | 29,30 586 | 68,68,68,68,68,68,15 587 | 8,6,34,68,3,4,5,6,7,6,8,50,76,8,76,38,77,78,79,40,68,3,4,5,6,7,6,8,50 588 | 15,85,8,85,34,85,38,77,85,79,78,40,85,68,85,38,77,79,40,78,85,8 589 | 29,30 590 | 15,85,78,79,77,38,40,85,85,85 591 | 15,8,34,15,76,77,38,78,79,40,76,8,50 592 | 8,7,34,6,3,4,5,6,15,3,4,5,3,4,5,15,6 593 | 15,68 594 | 15,6,76,8,76,34,76,38,77,78,79,40,76 595 | 15,35,8,15 596 | 29,30 597 | 15,8,34,15,76,78,77,38,79,40,83,77,83,78,84,83 598 | 15,35,8,35,34,35,38,35,36,39,37,40,41,35,80,81,83,78,77,83,84,83,80,81,80,35,38,37,39,35,36,35,40,41,35,80,81,80,83,84,83,78,83,77,80,81,80,83,84,77,83,78,83,8,50 599 | 50,85,50,8,85,8,15,85,8,85,38,79,78,77,85,40,85,8,85,38,77,79,78,40,85,8,15 600 | 8,76,34,76,78,77,79,76,38,76,40,76,15,8,76,34,76,79,78,77,76,38,76,40,76,8,76,34,76,79,78,77,76,38,76,40,76,8,76,34,76,78,77,79,76,38,76,40,76,8,76,79,78,77,76,38,76,40,76,8,76,34,76,79,78,77,76,38,76,40,76,8,76,34,76,79,78,38,77,76,40,76,8,76,34,76,79,38,78,77,76,40,76 601 | 15,85,78,38,77,79,40,85,15,68,85,38,78,77,79,40,85,85,79,38,78,77,85,40,85 602 | 15,70,15,70 603 | 15,72,15,72 604 | 15,22,22,22,22,22,22,15,22,22,22,22,15,22 605 | 92,15,92 606 | 15,70,15,51 607 | 86,85,86,85,78,77,38,79,40,85,35,38,36,39,37,40,41,35,85,35,85,79,77,38,78,40,85,80,81,80,85,80,85,79,38,77,78,40,85,85,77,79,38,78,40,85,85,38,77,79,78,40,85,85,38,77,79,40,85,78,85,77,79,38,78,40,85,85,77,38,79,78,40,85,83,78,77,84,83,86,86,86,85,78,38,77,79,40,85 608 | 8,76,34,76,38,78,77,79,76,40 609 | 15,8,34,15,35,39,37,38,36,35,40,41,35,80,81,80,76,38,78,77,40,79,76,8,50 610 | 15,35,8,35,34,35,38,39,37,35,36,40,41,35,80,81,82,80,76,38,79,78,77,40,76,76,79,38,78,77,40,76,8,50 611 | 35,8,35,8 612 | 15,6 613 | 15,85,38,78,79,77,40,85,15 614 | 29,30,32,33 615 | 29,30,32,33,32,33,30,32,30,32,30,33,32,33 616 | 29,30,29,31,29,15,3,4,5,6,85,78,77,38,79,40,85,6,7,6 617 | 29,30,29 618 | 15,92,15,92,15 619 | 15,76,38,77,78,79,40,76,15 620 | 15,3,4,5,6,15,6,7,8 621 | 15,8,34,15,35,36,37,39,38,35,40,41,35,8,50 622 | 15,8,15,76,78,77,38,79,40,76,6,3,4,5,68,3,4,5,6,8,50,15,68,68,15,68,68,68,3,4,5,68,8,68,34,68,76,38,77,78,79,40,76,8,50 623 | 29,30,31,3,4,5 624 | 86,85,78,85,38,77,79,40,85,68,85,38,79,77,78,40,85,86,85,79,38,78,77,40,83,77,78,84,83,85,79,38,77,78,40,35,38,37,39,36,40,41,35 625 | 15,8,50 626 | 68,15,3,4,5,6,7,8,7,34,6,7,8,50,7,8,15 627 | 29,30 628 | 29,30 629 | 29,30 630 | 15,8,34,15,80,81,80,83,77,78,84,83,83,84,77,78,80,81,80,15,8,15,70,15,70,70 631 | 15,85,38,77,78,79,40,76,35,38,36,37,39,40,41,35,76,85,77,78,38,85,79,85,40,85 632 | 15,6,15,3,4,5 633 | 8,34,15,80,81,80,82,83,77,83,78,83,84,83,82 634 | 6,68 635 | 15,68 636 | 86,85,38,77,79,78,40,85,83,84,83,77,78,83,85,86,85,6,3,4,5,5,6,7,68,68,6,86,6,7,6,86,86 637 | 15,68,68,15,85,78,38,40,35,38,37,36,39,40,35,41,35,85,78,38,40,35,38,36,39,37,40,35,41,35 638 | 29,30,31,72,15,72 639 | 35,8,35,34,35,37,39,36,38,40,41,35,8,50,35,8,8,35,8,35,34,35,37,38,39,36,40,41,35,8,50,35,8,35,8,35,34,35,37,38,39,36,40,41,35,8,50,35,8,35,34,35,37,38,39,36,40,35,41,35,8,50 640 | 15,35,8,35,34,35,38,39,37,36,40,41,35,6,7,15,6,15,6,76,8,76,34,76,78,79,77,38,40,76,35,38,39,37,36,40,41,35,6,35,38,39,37,36,40,41,35,6,7,15,3,4,5,6,7,15,3,4,5,6,3,4,5,6,15,68,3,4,5,6,3,4,5,6 641 | 29,30 642 | 3,4,5,3,4,5,6,7,8 643 | 29,30,15 644 | 15,6,15 645 | 15,76,8,76,77,78,79,38,40,76 646 | 35,38,37,39,36,40,35,41,35,76,38,77,78,79,40,76,85,77,38,79,78,40,85,3,4,5,6,7,6,85,79,78,77,38,40,85,38,77,79,78,40,85 647 | 8,76,34,76,38,78,77,79,76,40,76,15,3,4,5 648 | 76,8,76,34,76,78,77,76,38,79,40,76,83,77,78,83,84,83,8,50,15,76,8,76,34,76,78,77,38,79,40,76,83,77,78,83,84,83,8,50 649 | 29,30 650 | 15,8,34,15,76,78,38,77,79,76,40,76,15,60,15,60 651 | 29,30 652 | 8,15 653 | 86,86,86,86,15 654 | 29,30,29 655 | 86,68,86,68,68,86,86,86,86,86,86,86,68,86,86,86,86,86,86,68,86,86,86 656 | 15,85,77,78,38,79,40,85,85,38,79,77,78,40,85,15,85,77,78,38,79,40,85,77,78,79,85,38,40,85,15,85,79,85,77,78,38,40,85 657 | 15,35,37,36,38,35,39,40,35,41,35,92,15,92,15 658 | 3,4,5,15 659 | 15,8,15,35,38,35,36,37,39,40,41,35,76,38,77,40,78,79,76,83,77,83,78,84,83,8,50,8,76,34,76,38,77,78,40,79,76,83,77,78,84,83 660 | 86,85,86,85,8,86 661 | 29,30,32,33,72,15,72,15 662 | 15,85,77,78,79,38,40,35,38,39,37,36,40,41,35,85,38,79,78,77,40,80,81,80,85,77,85,38,78,79,40,85,83,77,84,78,83,85,77,38,79,78,40,85,15,85,77,38,79,78,40,35,38,39,36,37,40,35,41,35,85,78,80,81,82,80,82,80,85,79,38,78,77,40,85,85,38,77,79,78,40,85,77,38,79,78,40,85,15,3,4,5 663 | 86,85,77,38,78,79,40,35,38,37,36,39,40,41,35 664 | 15,85,77,38,78,79,40,85,35,38,37,36,39,40,41,35 665 | 35,8,35,34,35,37,36,35,39,38,35,40,41,35 666 | 15,85,78,79,77,38,40,85,83,77,83,84,78,83,85,15 667 | 92,15,92,15,3,4,5,92 668 | 18,15 669 | 72,15,72,15 670 | 8,34,78,84,77,8,50,8,34,84,77,78,8,50 671 | 6,3,4,5,3,4,5,15,6,7,8,7,6,34,6,7,8,50 672 | 8,34,15,68,76,79,77,78,76,38,76,40,76,83,84,83,77,78,83,8,50,15,8,34,15,68,76,38,79,78,76,77,76,40,76,8,50 673 | 76,8,76,34,76,77,38,78,79,40,76,80,81,82,76,77,38,79,78,40,83,77,78,84,83,82,83,76,38,79,77,78,40,76,35,38,39,36,37,40,41,35,76,77,38,79,78,40,76,80,81,82,76,79,38,78,77,40,76,76,77,79,38,78,40,76,76,80,76,80,81,76,35,76,35,76,35,39,38,37,36,40,35,41,76,35,83,84,77,78,76,79,77,38,78,40,80,76,80,81,76,79,77,38,78,8,40,15 674 | 29,30 675 | 29,30,32,33,32,33,32 676 | 15,8,15,76,77,38,78,79,40,76,15 677 | 29,30 678 | 86,85,86,85,78,79,77,38,40,85,35,38,36,37,39,40,41,35,85,79,77,38,78,86,85,40 679 | 86,85,86,85,78,38,77,79,40,85,86,85,86,85,79,78,38,77,40,85,86 680 | 29,30 681 | 86,86,86,86 682 | 29,30 683 | 6,68,3,4,5,68 684 | 15,85,78,79,77,38,40,85,85,38,79,77,40,78,85,15 685 | 15,3,4,5,6,8,34,6,7 686 | 92,15,92,8,92,34,92,15,92,68,76,77,38,78,76,79,40,76,83,77,83,78,83,84,83,35,38,35,36,39,37,35,40,41,35,80,81,82,68,68,15,92,15,92,68 687 | 72,15,72,72,15 688 | 29,30 689 | 86,3,4,5,6,7,6,8,6,8,6,3,4,5,5,86,85,8,85,86,85,8,9,85,9,85,38,78,85,40,86,85,86,85,86,86,3,4,5,6,7,6,8,8,8,86,86,86,86,6,8,8,86,8,86,8,86 690 | 3,4,5 691 | 70,15,70 692 | 86,85,86,85,38,78,77,79,40,85,86,85,86,85,78,77,38,79,40,85,86 693 | 6,68 694 | 15,85,38,77,78,79,40,85,85,38,79,78,77,40,85,38,77,78,79,40,35,38,39,37,36,40,41,35,15 695 | 3,4 696 | 35,38,37,39,36,35,40,41,35,38,39,35,36,37,40,41,35,38,39,37,35,36,40,41,35,76,38,78,77,40,79,76,83,83,77,78,83,84,83,76,79,77,38,78,40,76,79,38,78,77,40,76,78,79,77,38,76,40,76,83,77,83,78,84,83,76,79,77,38,78,40,35,38,37,39,36,40,35,41,35 697 | 93,15,93,15 698 | 83,8 699 | 15,8,34,15,35,37,39,35,36,35,38,35,40,41,35,8,50,15 700 | 76,8,76,34,76,77,78,79,76,38,40,76,76,38,77,79,78,40,76,3,4,5,3,4,5,3,4,5,6,8,50 701 | 15,8,34,15,76,78,79,38,77,40,76,83,77,78,83,84,83,77,78,84,83,8,15 702 | 15,6,3,4,5 703 | 15,3,4,5,3,4,5,3,4,5,3,4,5,8,34,6,3,4,5,6,76,78,38,77,76,79,40,76,6,76,38,77,76,79,40,78,76,6,76,79,38,78,77,76,40,76,68,68,68,68,68,68,68,8,50 704 | 8,76,34,76,38,77,78,79,40,76,8,15,8,50 705 | 72,15,72,72,15,72 706 | 8,34,80,81,80,82,35,37,36,39,35,38,35,40,41,35,15 707 | 15,85,38,77,78,79,40,85 708 | 8,9,8,34,6,7 709 | 35,39,38,37,36,35,40,41,35,39,37,38,36,35,40,35,41,35,36,38,39,37,35,40,41,35,82 710 | 50,8,76,38,78,77,79,40,76,8,50 711 | 15,76,8,76,34,76,78,38,77,79,40,76,76,79,77,38,78,40,83,77,83,78,84,83,15 712 | 15,35,38,36,39,37,40,35,41,35 --------------------------------------------------------------------------------