<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sam &#38; Max &#187; django</title>
	<atom:link href="http://sametmax.com/tag/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://sametmax.com</link>
	<description>Du code, du cul</description>
	<lastBuildDate>Sat, 07 Nov 2015 10:56:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1</generator>
	<item>
		<title>On avait un de nos sites qui ramait, quand soudain&#8230; 17</title>
		<link>http://sametmax.com/on-avait-un-de-nos-sites-qui-ramait-quand-soudain/</link>
		<comments>http://sametmax.com/on-avait-un-de-nos-sites-qui-ramait-quand-soudain/#comments</comments>
		<pubDate>Sat, 18 Jul 2015 09:49:30 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[perf]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=16632</guid>
		<description><![CDATA[<blockquote>- Allez, Max, fais moi un copier/coller !
- Non.
- Alleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeez. C'est drôle !
- Putain tu fais chier.</blockquote>
]]></description>
				<content:encoded><![CDATA[<blockquote><p>- Allez, Max, fais moi un copier/coller !<br />
&#8211; Non.<br />
&#8211; Alleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeez. C&#8217;est drôle !<br />
&#8211; Putain tu fais chier.</p></blockquote>
<pre>
SELECT * FROM "video" INNER JOIN "video_sites" ON ("video"."id" = "video_sites"."video_id") WHERE ("video_sites"."site_id" = 1 AND "video"."status" = 'online' AND NOT ("video"."id" IN (SELECT * FROM "video" U0 WHERE U0."id" IN (68, 98, 102, 103, 109, 121, 128, 129, 131, 132, 133, 230, 231, 232, 235, 236, 238, 240, 241, 242, 243, 245, 247, 248, 249, 251, 252, 253, 255, 256, 257, 259, 261, 262, 264, 266, 267, 270, 271, 272, 273, 275, 277, 279, 281, 282, 283, 284, 285, 286, 287, 288, 289, 291, 292, 293, 294, 295, 296, 297, 299, 300, 301, 302, 303, 304, 305, 307, 309, 311, 314, 315, 317, 318, 319, 320, 322, 324, 325, 327, 329, 330, 331, 333, 334, 336, 337, 338, 339, 340, 342, 344, 345, 346, 347, 348, 350, 352, 353, 354, 355, 356, 359, 360, 361, 368, 369, 371, 372, 374, 377, 378, 380, 382, 385, 386, 387, 388, 389, 390, 393, 394, 395, 399, 401, 402, 404, 405, 407, 409, 410, 411, 412, 413, 414, 415, 416, 418, 557, 561, 589, 596, 599, 600, 602, 606, 611, 612, 620, 622, 623, 626, 629, 636, 642, 645, 646, 656, 663, 677, 679, 682, 685, 691, 692, 695, 699, 719, 762, 865, 1059, 1066, 1068, 1069, 1072, 1075, 1085, 1088, 1090, 1092, 1093, 1094, 1096, 1100, 1101, 1102, 1103, 1138, 1148, 1163, 1172, 1194, 1197, 1204, 1211, 1216, 1218, 1230, 1243, 1297, 1326, 1333, 1334, 1347, 1351, 1377, 1383, 1386, 1448, 1454, 1476, 1503, 1546, 1574, 1599, 1612, 1616, 1620, 1629, 1648, 1660, 1666, 1679, 1705, 1729, 1731, 1739, 1766, 1802, 1855, 1861, 1891, 1970, 2064, 2077, 2108, 2143, 2268, 2275, 2289, 2342, 2365, 2402, 2408, 2422, 2504, 2523, 2537, 2621, 2684, 2707, 2711, 2737, 2819, 2898, 2925, 3323, 3334, 3356, 3370, 3424, 3438, 3480, 3488, 3506, 4311, 4547, 4733, 4779, 4840, 4853, 4871, 4890, 4930, 4940, 5107, 5178, 5188, 5189, 5190, 5191, 5192, 5193, 5194, 5195, 5196, 5197, 5198, 5199, 5200, 5201, 5202, 5203, 5204, 6427, 6428, 6445, 6447, 6449, 6489, 6494, 6495, 6515, 6551, 6552, 6572, 6586, 6599, 6682, 6916, 6924, 6927, 6950, 6957, 6963, 6968, 6975, 6981, 7094, 7251, 7257, 7272, 7434, 7496, 7507, 7511, 7536, 7660, 7666, 7720, 7764, 7846, 7852, 7861, 7864, 7925, 7936, 7962, 7984, 7994, 8032, 8102, 8110, 8122, 8126, 8166, 8277, 8278, 8281, 8300, 8341, 8351, 8374, 8407, 8497, 8515, 8544, 8559, 8583, 8593, 8604, 8614, 8650, 8702, 8733, 8772, 8852, 8865, 8873, 8883, 8894, 8912, 8987, 8999, 9011, 9061, 9068, 9100, 9108, 9120, 9213, 9259, 9419, 9430, 9441, 9545, 9583, 9641, 9656, 9668, 9672, 9711, 9726, 9807, 9814, 9819, 9833, 9847, 9904, 9963, 10000, 10002, 10006, 10041, 10106, 10119, 10169, 10202, 10232, 10249, 10277, 10279, 10327, 10357, 10449, 10528, 10550, 10603, 10639, 10670, 10728, 10779, 10780, 10783, 10817, 10910, 11130, 11150, 11169, 11182, 11223, 11231, 11293, 11298, 11299, 11349, 11353, 11356, 11361, 11368, 11374, 11378, 11383, 11392, 11394, 11396, 11401, 11405, 11413, 11414, 11418, 11424, 11430, 11431, 11442, 11444, 11497, 11498, 11526, 11561, 11591, 11592, 11593, 11801, 11802, 12312, 12351, 12352, 12353, 12414, 12415, 12416, 12417, 12418, 12419, 12420, 12421, 12422, 12423, 12424, 12425, 12426, 12427, 12542, 12543, 12544, 12619, 12620, 12621, 12764, 12765, 12903, 12904, 12905, 12954, 12955, 12956, 13016, 13017, 13018, 13019, 13020, 13021, 13022, 13023, 13024, 13025, 13026, 13027, 13223, 13224, 13225, 13374, 13375, 13376, 13514, 13515, 13516, 13562, 13624, 13625, 13626, 13627, 13628, 13629, 13630, 13631, 13632, 13633, 13634, 13635, 13636, 13637, 13638, 13821, 13822, 13950, 13951, 13952, 14074, 14075, 14076, 14120, 14121, 14172, 14173, 14174, 14175, 14176, 14177, 14178, 14179, 14402, 14403, 14404, 14460, 14461, 14748, 14749, 14750, 14853, 14854, 14855, 14857, 14858, 14920, 14921, 14922, 14923, 14924, 14925, 14926, 14927, 14928, 14929, 14931, 14932, 14933, 14934, 15159, 15160, 15161, 15378, 15379, 15380, 15443, 15444, 15528, 15529, 15530, 15710, 15711, 15712, 15803, 15805, 15806, 15807, 15808, 15857, 15858, 15859, 15860, 15861, 15862, 15863, 15864, 15865, 15866, 15867, 15868, 15869, 15870, 15871, 15872, 16084, 16085, 16086, 16288, 16289, 16290, 16350, 16351, 16352, 16432, 16433, 16434, 16599, 16600, 16601, 16694, 16695, 16696, 16697, 16698, 16746, 16747, 16748, 16749, 16750, 16751, 16752, 16753, 16908, 16983, 16984, 16985, 17173, 17174, 17175, 17243, 17244, 17245, 17317, 17318, 17319, 17441, 17442, 17553, 17554, 17555, 17638, 17639, 17640, 17687, 17688, 17689, 17690, 17691, 17692, 17693, 17694, 17695, 17911, 17912, 17913, 18099, 18223, 18224, 18225, 18425, 18426, 18427, 18517, 18518, 18519, 18574, 18575, 18576, 18577, 18578, 18579, 18580, 18581, 18775, 18776, 18982, 18983, 18984, 18988, 18989, 18990, 19116, 19117, 19190, 19191, 19192, 19220, 19221, 19222, 19358, 19359, 19360, 19505, 19506, 19507, 19508, 19509, 19510, 19511, 19512, 19708, 19709, 19887, 19888, 19889, 19893, 19894, 19895, 20070, 20071, 20072, 20096, 20097, 20098, 20200, 20201, 20202, 20275, 20276, 20277, 20278, 20279, 20280, 20281, 20282, 20283, 20488, 20489, 20490, 20542, 20543, 20660, 20661, 20662, 20663, 20664, 20665, 20666, 20865, 20866, 20867, 21181, 21182, 21183, 21208, 21209, 21210, 21349, 21350, 21351, 21425, 21464, 21465, 21466, 21467, 21468, 21469, 21470, 21471, 21472, 21473, 21633, 21634, 21635, 21869, 21870, 21871, 21875, 21876, 21877, 22002, 22003, 22004, 22029, 22030, 22031, 22132, 22133, 22134, 22313, 22314, 22315, 22319, 22320, 22321, 22356, 22451, 22452, 22453, 22474, 22475, 22476, 22562, 22563, 22564, 22594, 22595, 22596, 22689, 22690, 22691, 22692, 22693, 22694, 22695, 22696, 22697, 22755, 22756, 22757, 22829, 22830, 22846, 22979, 22980, 22981, 22982, 23089, 23090, 23091, 23094, 23095, 23096, 23097, 23098, 23119, 23120, 23121, 23122, 23123, 23128, 23129, 23130, 23144, 23145, 23158, 23159, 23312, 23313, 23343, 23367, 23368, 23448, 23462, 23463, 23464, 23532, 23533, 23534, 23535, 23653, 23654, 23656, 23657, 23723, 23724, 23725, 23737, 23738, 23803, 23881, 23882, 23883, 23884, 24002, 24003, 24004, 24010, 24011, 24012, 24029, 24031, 24040, 24127, 24128, 24244, 24245, 24269, 24276, 24290, 24334, 24338, 24339, 24378, 24387, 24393, 24402, 24595, 24596, 24597, 24611, 24612, 24622, 24623, 24624, 24640, 24641, 24642, 24643, 24657, 24658, 24686, 24788, 24831, 24832, 24914, 24915, 24965, 24988, 24989, 24992, 25003, 25004, 25005, 25112, 25113, 25127, 25233, 25234, 25330, 25331, 25332, 25368, 25390, 25409, 25417, 25419, 25444, 25445, 25637, 25638, 25639, 25654, 25670, 25671, 25672, 25686, 25687, 25688, 25695, 25696, 25837, 25915, 25937, 25938, 25948, 25949, 25962, 25993, 25994, 26049, 26051, 26052, 26053, 26061, 26095, 26096, 26097, 26230, 26231, 26334, 26347, 26350, 26351, 26457, 26510, 26512, 26519, 26520, 26740, 26742, 26758, 26759, 26780, 26800, 26801, 26803, 26832, 26833, 27031, 27034, 27035, 27064, 27065, 27066, 27082, 27175, 27293, 27294, 27317, 27318, 27405, 27418, 27420, 27456, 27508, 27509, 27510, 27511, 27654, 27660, 27672, 27686, 27775, 27852, 27853, 27854, 27862, 27880, 28082, 28092, 28093, 28107, 28219, 28270, 28276, 28277, 28278, 28284, 28366, 28374, 28375, 28376, 28381, 28478, 28479, 28484, 28489, 28600, 28601, 28602, 28606, 28607, 28608, 28693, 28718, 28719, 28894, 28895, 28896, 28899, 28901, 28916, 28917, 28931, 29102, 29115, 29129, 29130, 29131, 29147, 29150, 29304, 29305, 29311, 29312, 29316, 29317, 29318, 29435, 29450, 29451, 29463, 29473, 29474, 29530, 29602, 29603, 29616, 29617, 29628, 29629, 29736, 29761, 29762, 29763, 29777, 29778, 29795, 29797, 29902, 29903, 29908, 29967, 29976, 30094, 30110, 30112, 30136, 30137, 30258, 30261, 30277, 30278, 30279, 30362, 30398, 30400, 30401, 30418, 30419, 30459, 30562, 30563, 30635, 30690, 30703, 30823, 30824, 30843, 30844, 30967, 30968, 30976, 30977, 31071, 31083, 31084, 31087, 31098, 31099, 31211, 31212, 31213, 31221, 31345, 31346, 31369, 31420, 31423, 31424, 31474, 31475, 31476, 31477, 31493, 31494, 31596, 31597, 31598, 31609, 31610, 31625, 31741, 31742, 31743, 31760, 31870, 31871, 31881, 31909, 31965, 31990, 32001, 32003, 32009, 32010, 32113, 32122, 32123, 32147, 32234, 32236, 32237, 32238, 32244, 32245, 32306, 32344, 32577, 32676, 32690, 32696, 32716, 32717, 32768, 32771, 32776, 32837, 32838, 32962, 33090, 33193, 33299, 33300, 33303, 33304, 33686, 33705, 33784, 33867, 34027, 34333, 34437, 34460, 34507, 34757, 34845, 34868, 34946, 34947, 34967, 35106, 35136, 35240, 35241, 35321, 35413, 35414, 35537, 35538, 35616, 35707, 36023, 36028, 36058, 36059, 36298, 36299, 36524, 36636, 36659, 36720, 36890, 36891, 36939, 36966, 37021, 37022, 37041, 37042, 37043, 37044, 37047, 37048, 37066, 37101, 37102, 37124, 37125, 37161, 37176, 37177, 37255, 37298, 37315, 37370, 37416, 37417, 37432, 37504, 37554, 37571, 37624, 37639, 37655, 37656, 37704, 37706, 37736, 37737, 37787, 37788, 37818, 38398, 38399, 38430, 38431, 38524, 38590, 38639, 38858, 38859, 39141, 39228, 39314, 39387, 39509, 39729, 40240, 40253, 40298, 40299, 40369, 40370, 40371, 40372, 40426, 40427, 40428, 40429, 40837, 40882, 40889, 40890, 40926, 40928, 40929, 40965, 40966, 40970, 41007, 41015, 41016, 41067, 41068, 41077, 41078, 41110, 41114, 41115, 41161, 41162, 41171, 41172, 41200, 41201, 41210, 41211, 41240, 41241, 41247, 41248, 41276, 41277, 41285, 41329, 41330, 41339, 41340, 41369, 41370, 41408, 41409, 41438, 41608, 41609, 41708, 41790, 41791, 41871, 41908, 41940, 42011, 42110, 42143, 42145, 42184, 42275, 42278, 42389, 42460, 42733, 42747, 42919, 43146, 43173, 43176, 43382, 43798, 43801, 43802, 43804, 43811, 43982, 43990, 44020, 44022, 44025, 44243, 44257, 44590, 44629, 44639, 44653, 44654, 44660, 44669, 44671, 44672, 44673, 44674, 44676, 44995, 44999, 45002, 45003, 45008, 45010, 45014, 45016, 45018, 45019, 45020, 45100, 45104, 45106, 45119, 45142, 45143, 45262, 45391, 45392, 45393, 45394, 45396, 45397, 45399, 45400, 45401, 45533, 45684, 45716, 45870, 45983, 45989, 45998, 46002, 46012, 46013, 46016, 46017, 46019, 46020, 46077, 46162, 46359, 46365, 46424, 46432, 46433, 46437, 46441, 46442, 46443, 46446, 46537, 46538, 46540, 46542, 46552, 46579, 46580, 46581, 46583, 46584, 46780, 46895, 46897, 46899, 46902, 46905, 46906, 46908, 46909, 46912, 47103, 47263, 47311, 47347, 47477, 47539, 47547, 47568, 47573, 47586, 47587, 47589, 47593, 47595, 47917, 47963, 47965, 47968, 47969, 47972, 47973, 47974, 47976, 48029, 48030, 48031, 48032, 48036, 48054, 48057, 48158, 48164, 48261, 48263, 48265, 48267, 48268, 48269, 48270, 48272, 48274, 48417, 48523, 48546, 48580, 48696, 48724, 48731, 48746, 48750, 48760, 48762, 48763, 48765, 48768, 48770, 48862, 49019, 49062, 49064, 49066, 49067, 49069, 49070, 49072, 49074, 49135, 49137, 49138, 49139, 49141, 49151, 49177, 49178, 49179, 49180, 49287, 49351, 49353, 49354, 49356, 49358, 49360, 49362, 49364, 49365, 49565, 49598, 49706, 49748, 49755, 49775, 49780, 49791, 49793, 49795, 49798, 49799, 49801, 49814, 49815, 49831, 49871, 50105, 50156, 50158, 50162, 50164, 50168, 50169, 50171, 50175, 50228, 50231, 50272, 50340, 50350, 50356, 50444, 50446, 50447, 50449, 50451, 50453, 50455, 50457, 50464, 50583, 50618, 50644, 50689, 50899, 50905, 50921, 50924, 50930, 50932, 50933, 50934, 50935, 50937, 50951, 50952, 51009, 51092, 51176, 51237, 51239, 51240, 51242, 51243, 51244, 51245, 51246, 51286, 51287, 51288, 51289, 51294, 51323, 51325, 51326, 51327, 51328, 51330, 51377, 51428, 51429, 51431, 51432, 51434, 51435, 51436, 51567, 51649, 51659, 51666, 51677, 51687, 51871, 51928, 52186, 52196, 52219, 52223, 52231, 52233, 52234, 52235, 52237, 52269, 52271, 52290, 52341, 52347, 52462, 52598, 52623, 52640, 52650, 52722, 52725, 52734, 52737, 52738, 52742, 52745, 52748, 52750, 52753, 52754, 52760, 52763, 52764, 52767, 52769, 52770, 52773, 52884, 52889, 52891, 52893, 52908, 52914, 52919, 52923, 52932, 52938, 52952, 52969, 52998, 53097, 53108, 53185, 53188, 53189, 53191, 53193, 53195, 53196, 53197, 53198, 53252, 53343, 53354, 53367, 53426, 53475, 53478, 53481, 53483, 53486, 53489, 53491, 53492, 53576, 53661, 53706, 53739, 53970, 54023, 54044, 54209, 54212, 54263, 54273, 54288, 54320, 54332, 54345, 54347, 54349, 54351, 54353, 54355, 54479, 54481, 54513, 54586, 54647, 54767, 54816, 54885, 54889, 54891, 54893, 54894, 54897, 54898, 55009, 55015, 55016, 55018, 55020, 55028, 55106, 55129, 55131, 55136, 55141, 55142, 55148, 55153, 55161, 55191, 55255, 55271, 55276, 55280, 55285, 55301, 55317, 55318, 55319, 55320, 55322, 55323, 55324, 55325, 55327, 55394, 55411, 55534, 55540, 55602, 55733, 55735, 55736, 55738, 55740, 55742, 55744, 55746, 55747, 55817, 55846, 55916, 56005, 56090, 56125, 56178, 56225, 56253, 56264, 56303, 56309, 56334, 56409, 56414, 56505, 56708, 56723, 56789, 56792, 56808, 56819, 56823, 56825, 56826, 56828, 56838, 56855, 56858, 56861, 56865, 56867, 56871, 56873, 56875, 56930, 56931, 56932, 56934, 56936, 56944, 56977, 57032, 57082, 57083, 57084, 57085, 57086, 57087, 57089, 57090, 57091, 57186, 57189, 57190, 57252, 57323, 57558, 57650, 57656, 57686, 57696, 57720, 57722, 57725, 57727, 57730, 57732, 57736, 57738, 57739, 57740, 57742, 57743, 57744, 57747, 57749, 57796, 57797, 57809, 57846, 57848, 57851, 57853, 57865, 57879, 57889, 57982, 58102, 58223, 58234, 58292, 58523, 58531, 58556, 58559, 58566, 58567, 58568, 58569, 58570, 58571, 58599, 58601, 58639, 58747, 58760, 59017, 59153, 59154, 59155, 59156, 59157, 59158, 59179, 59180, 59181, 59182, 59183, 59225, 59226, 59227, 59228, 59229, 59230, 59281, 59282, 59283, 59378, 59389, 59423, 59451, 59476, 59477, 59502, 59510, 59547, 59558, 59559, 59562, 59580, 59588, 59649, 59697, 59756, 59766, 59769, 59770, 59792, 59793, 59906, 59944, 59976, 59977, 60011, 60058, 60059, 60085, 60086, 60087, 60088, 60091, 60112, 60117, 60120, 60152, 60198, 60212, 60213, 60252, 60258, 60310, 60318, 60319, 60327, 60334, 60410, 60468, 60470, 60471, 60475, 60476, 60496, 60586, 60599, 60634, 60674, 60717, 60728, 60760, 60789, 60793, 60815, 60816, 60840, 60843, 60844, 60855, 60860, 60861, 60872, 60888, 60899, 60908, 60909, 60912, 60917, 60929, 60933, 60934, 60948, 60963, 60964, 60971, 60978, 60992, 60996, 60999, 61001, 61007, 61043, 61047, 61062, 61089, 61090, 61106, 61109, 61112, 61113, 61125, 61132, 61135, 61146, 61152, 61156, 61160, 61178, 61182, 61190, 61198, 61201, 61204, 61216, 61222, 61223, 61241, 61259, 61270, 61309, 61322, 61323, 61324, 61327, 61339, 61354, 61358, 61371, 61379, 61381, 61407, 61442, 61445, 61449, 61451, 61453, 61456, 61482, 61488, 61495, 61499, 61500, 61510, 61515, 61549, 61551, 61564, 61590, 61607, 61613, 61622, 61632, 61633, 61635, 61658, 61663, 61664, 61689, 61709, 61727, 61730, 61735, 61737, 61741, 61744, 61752, 61753, 61769, 61794, 61819, 61829, 61837, 61839, 61844, 61847, 61865, 61866, 61872, 61875, 61877, 61880, 61885, 61887, 61889, 61901, 61908, 61929, 61935, 61941, 61943, 61950, 61954, 61969, 61983, 62006, 62007, 62028, 62029, 62034, 62047, 62054, 62063, 62080, 62088, 62089, 62093, 62094, 62111, 62125, 62144, 62154, 62155, 62178, 62188, 62196, 62198, 62207, 62210, 62233, 62248, 62254, 62267, 62283, 62292, 62305, 62309, 62316, 62317, 62320, 62324, 62345, 62361, 62362, 62366, 62367, 62371, 62382, 62390, 62391, 62392, 62406, 62427, 62447, 62457, 62460, 62463, 62465, 62476, 62513, 62522, 62527, 62537, 62539, 62548, 62552, 62555, 62561, 62563, 62574, 62576, 62580, 62599, 62628, 62636, 62639, 62644, 62650, 62655, 62665, 62672, 62687, 62697, 62701, 62704, 62705, 62706, 62714, 62722, 62732, 62749, 62778, 62780, 62800, 62808, 62816, 62825, 62835, 62837, 62854, 62864, 62865, 62874, 62876, 62910, 62929, 62932, 62935, 62983, 62986, 63001, 63017, 63018, 63019, 63030, 63032, 63034, 63054, 63077, 63104, 63126, 63158, 63162, 63167, 63169, 63208, 63258, 63265, 63290, 63315, 63327, 63361, 63390, 63393, 63396, 63420, 63459, 63465, 63477, 63516, 63564, 63571, 63575, 63591, 63598, 63634, 63659, 63673, 63682, 63697, 63708, 63735, 63741, 63742, 63789, 63805, 63807, 63834, 63853, 63858, 63872, 63881, 63906, 63936, 63941, 63962, 63982, 63993, 64018, 64021, 64039, 64041, 64060, 64080, 64090, 64095, 64106, 64115, 64129, 64155, 64157, 64160, 64163, 64188, 64196, 64236, 64244, 64250, 64256, 64286, 64324, 64373, 64385, 64403, 64420, 64426, 64432, 64443, 64520, 64528, 64530, 64541, 64547, 64550, 64561, 64587, 64612, 64631, 64650, 64663, 64723, 64728, 64822, 64894, 64901, 64923, 64935, 64950, 64956, 65004, 65041, 65085, 65109, 65121, 65152, 65153, 65162, 65212, 65231, 65274, 65286, 65292, 65307, 65308, 65369, 65377, 65402, 65404, 65407, 65423, 65446, 65459, 65474, 65475, 65485, 65491, 65493, 65542, 65577, 65604, 65615, 65616, 65638, 65652, 65659, 65668, 65684, 65693, 65694, 65720, 65732, 65737, 65766, 65798, 65814, 65821, 65822, 65826, 65851, 65865, 65891, 65903, 65904, 65910, 65911, 65921, 65924, 65934, 65951, 65952, 65974, 65982, 66001, 66041, 66053, 66068, 66070, 66103, 66107, 66129, 66130, 66144, 66147, 66150, 66153, 66156, 66158, 66193, 66195, 66212, 66233, 66265, 66313, 66318, 66329, 66347, 66348, 66349, 66357, 66360, 66363, 66387, 66413, 66418, 66462, 66463, 66469, 66479, 66483, 66511, 66513, 66563, 66572, 66583, 66592, 66597, 66603, 66617, 66648, 66659, 66663, 66666, 66693, 66723, 66736, 66742, 66751, 66845, 66856, 66869, 66872, 66885, 66919, 66969, 67066, 67068, 67095, 67129, 67145, 67191, 67237, 67270, 67313, 67436, 67453, 67470, 67471, 67522, 67525, 67557, 67565, 67572, 67593, 67633, 67634, 67713, 67747, 67758, 67813, 67884, 67890, 67927, 67934, 67937, 67985, 68008, 68016, 68493, 68499, 68513, 70289, 70310, 70326, 70437, 70456, 70466, 70473, 70667, 70683, 70780, 70789, 70790, 70799, 70805, 70876, 70895, 70938, 70964, 70965, 71032, 71044, 71047, 71073, 71077, 71078, 71134, 71157, 71163, 71167, 71181, 71194, 71225, 71233, 71248, 71250, 71254, 71304, 71313, 71319, 71321, 71328, 71408, 71439, 71446, 71567, 71583, 71594, 71605, 71610, 71692, 71698, 71719, 71823, 71871, 71872, 71885, 71936, 71942, 71945, 71969, 71982, 72049, 72056, 72072, 72149, 72161, 72192, 72195, 72206, 72219, 72232, 72234, 72264, 72298, 72321, 72323, 72391, 72396, 72401, 72515, 72516, 72520, 72526, 72546, 72622, 72646, 72662, 72663, 72675, 72677, 72732, 72746, 72798, 72872, 73000, 73026, 73064, 73069, 73098, 73102, 73117, 73130, 73149, 73239, 73292, 73326, 73364, 73452, 73610, 73622, 73645, 73660, 73685, 73788, 73849, 73851, 73868, 73904, 73991, 74070, 74085, 74181, 74184, 74210, 74227, 74284, 74296, 74308, 74314, 74322, 74326, 74336, 74384, 74404, 74459, 74469, 74525, 74580, 74681, 74691, 74746, 74749, 74778, 74784, 74930, 74984, 74994, 75027, 75125, 75130, 75163, 75184, 75185, 75202, 75206, 75234, 75238, 75258, 75297, 75312, 75326, 75423, 75436, 75446, 75480, 75481, 75489, 75512, 75513, 75534, 75561, 75568, 75574, 75576, 75583, 75595, 75616, 75623, 75659, 75674, 75688, 75714, 75751, 75776, 75785, 75818, 75832, 75902, 75940, 76057, 76073, 76075, 76229, 76245, 76298, 76355, 76357, 76365, 76407, 76415, 76416, 76430, 76463, 76561, 76674, 76722, 76812, 76821, 76831, 76842, 76884, 77028, 77038, 77103, 77180, 77247, 77432, 77475, 77482, 77738, 77785, 78079, 78130, 78201, 78232, 78262, 78344, 78361, 78404, 78606, 78704, 78832, 78844, 78868, 79035, 79153, 79155, 79227, 79373, 79521, 79813, 79868, 79972, 80170, 80182, 80216, 80272, 80329, 80338, 80362, 80393, 80509, 80812, 80853, 80868, 80950, 80971, 80988, 81049, 81065, 81169, 81176, 81230, 81621, 81624, 81776, 81861, 81900, 81981, 82006, 82040, 82059, 82072, 82082, 82617, 82699, 82891, 82903, 83000, 83008, 83174, 83678, 83883, 83999, 84258, 84349, 84485, 84526, 84531, 84578, 84689, 84722, 84780, 84847, 84912, 84921, 84974, 85013, 85021, 85050, 85100, 85113, 85126, 85138, 85216, 85227, 85238, 85314, 85353, 85402, 85448, 85460, 85484, 85506, 85518, 85572, 85586, 85756, 85836, 85861, 85862, 85874, 85913, 85914, 85949, 85965, 86141, 86160, 86173, 86229, 86258, 86312, 86347, 86510, 86568, 86593, 86628, 86668, 89064, 89867, 90071, 91804, 91815, 92168, 92451, 92729, 92744, 92757, 92884, 93174, 93611, 93787, 95556, 95636, 95884, 95910, 95930, 96008, 96107, 96417, 96559, 96672, 96778, 96868, 97409, 97529, 97585, 97640, 97881, 97960, 98042, 98127, 98129, 98173, 98213, 98239, 98283, 98349, 98396, 98447, 98533, 100414, 102705, 103970, 103976, 103977, 103979, 103980, 103999, 104000, 104013, 104017, 104022, 104023, 104026, 104034, 104040, 104045, 104047, 104081, 104083, 104105, 104107, 104109, 104120, 104123, 104136, 104149, 104153, 104154, 104162, 104163, 104169, 104191, 104203, 104209, 104212, 104215, 104220, 104224, 104236, 104247, 104249, 104279, 104304, 104308, 104309, 104312, 104316, 104318, 104320, 104326, 104329, 104331, 104335, 104342, 104347, 104348, 104365, 104374, 104381, 104386, 104395, 104411, 104421, 104436, 104442, 104453, 104455, 104476, 104478, 104495, 104500, 104506, 104520, 104894, 104947, 105170, 105189, 105246, 105307, 105366, 105368, 105468, 105508, 105509, 105569, 105620, 105630, 105638, 105650, 105701, 105714, 105726, 105732, 105736, 105762, 105769, 105795, 105815, 105832, 105861, 106174, 106382, 106409, 106637, 106797, 106926, 107066, 107280, 107297, 107321, 107512, 107562, 107663, 107689, 107764, 107799, 107842, 107845, 107887, 107888, 108033, 108168, 108444, 108483, 108547, 108794, 109573, 109658, 109936, 110228, 110231, 110236, 110247, 110328, 110386, 110477, 110554, 110698, 111065, 111204, 111232, 111320, 111335, 111344, 111352, 111530, 111531, 111534, 111546, 111599, 111771, 111965, 112002, 112057, 112149, 112608, 112614, 112735, 112748, 113010, 113019, 113028, 113192, 113289, 113383, 113386, 113620, 113637, 113802, 113865, 113967, 113990, 114046, 114107, 114129, 114156, 114169, 114214, 114223, 114253, 114287, 114375, 114523, 114930, 114988, 115115, 115143, 115272, 115430, 115431, 115743, 115851, 115913, 115921, 115926, 116031, 116043, 116055, 116740, 116756, 116955, 117028, 117032, 117041, 117061, 117102, 117239, 117359, 117390, 117420, 117604, 117709, 117847, 118061, 118292, 118294, 118310, 118328, 118425, 118480, 118482, 118581, 118611, 118766, 118811, 118907, 119025, 119054, 119082, 119150, 119172, 119208, 119251, 119371, 119378, 119501, 119604, 119729, 119735, 119823, 119859, 119889, 119934, 120057, 120063, 120098, 120114, 120187, 120210, 120316, 120402, 120425, 120433, 120439, 120534, 120573, 120598, 120608, 120622, 120660, 120688, 120789, 120937, 121009, 121456, 121657, 122345, 122369, 122375, 122924, 123038, 123596, 123745, 124085, 124398, 124446, 124454, 124512, 124818, 124865, 124950, 124962, 124994, 125018, 125028, 125057, 125111, 125210, 125261, 125301, 125304, 125547, 125673, 125714, 125730, 125764, 125783, 125864, 125880, 125979, 126023, 126093, 126174, 126227, 126228, 126229, 126375, 126644, 126687, 126695, 126701, 126715, 126722, 126744, 126799, 126976, 126988, 127020, 127075, 127091, 127215, 127274, 127314, 127385, 127485, 127593, 127604, 127757, 127825, 127910, 128022, 128050, 128118, 128200, 128279, 128293, 128316, 128441, 128559, 128572, 128597, 128689, 128693, 128702, 128734, 128917, 128966, 128990, 129312, 129452, 129716, 129720, 129750, 129826, 129901, 129976, 130061, 130070, 130072, 130116, 130234, 130303, 130374, 130516, 130599, 130682, 130686, 130796, 130840, 130876, 130956, 130958, 130984, 131058, 131062, 131217, 131227, 131243, 131290, 131322, 131349, 131422, 131438, 131516, 131850, 131853, 131890, 132216, 132254, 132272, 132345, 132396, 132420, 132459, 132475, 132592, 132661, 132757, 132863, 132867, 132906, 132991, 133014, 133041, 133049, 133131, 133167, 133239, 133400, 133602, 133649, 133682, 133698, 133866, 133888, 133889, 133939, 134035, 134158, 134159, 134164, 134260, 134372, 134383, 134458, 134460, 134657, 134670, 134695, 134851, 135015, 135047, 135062, 135396, 135433, 135605, 135696, 135782, 135816, 135820, 135940, 135948, 135993, 136161, 136181, 136258, 136259, 136458, 136485, 136543, 136683, 136824, 136968, 137025, 137037, 137070, 137077, 137139, 137190, 137191, 137305, 137424, 137434, 137823, 138036, 138128, 138130, 138137, 138150, 138163, 138207, 138280, 138299, 138307, 138442, 138479, 138497, 138511, 138937, 139033, 139121, 139184, 139274, 139302, 139424, 139638, 139939, 140026, 140099, 140246, 140301, 140407, 140440, 140764, 140832, 140946, 141023, 141056, 141098, 141203, 141275, 141280, 141290, 141510, 141522, 141525, 141602, 141647, 141774, 141778, 141847, 141871, 141926, 141945, 142041, 142608, 142759, 142888, 142926, 142995, 143123, 143177, 143260, 143277, 143357, 143425, 143439, 143482, 143816, 143871, 144082, 144096, 144105, 144106, 144107, 144171, 144189, 144261, 144325, 144413, 144503, 144555, 144556, 144705, 144788, 144875, 144944, 145092, 145330, 145365, 145535, 145545, 145673, 145820, 145826, 145875, 145909, 146098, 146186, 146220, 146287, 146494, 146572, 146653, 146663, 146710, 146736, 146752, 146790, 146800, 146923, 146957, 147070, 147136, 147262, 147277, 147444, 147495, 147519, 147907, 147935, 147951, 147996, 148114, 148159, 148247, 148264, 148356, 148361, 148370, 148404, 148406, 148423, 148446, 148664, 148681, 148713, 148744, 148830, 149036, 149074, 149100, 149201, 149366, 149421, 149532, 149580, 149596, 149791, 149804, 149807, 149841, 149847, 150247, 150281, 150342, 150362, 150504, 150640, 150688, 150830, 150866, 151007, 151020, 151062, 151201, 152137, 153140, 153306, 153617, 153941, 154687, 154690, 155005, 155258, 155440, 155532, 155950, 156341, 156454, 156580, 156683, 156725, 156734, 157027, 157145, 157227, 157385, 157394, 157409, 157502, 157545, 157663, 157697, 157804, 157962, 157987, 158101, 158108, 158164, 158368, 158411, 158573, 158625, 158710, 158719, 158820, 158872, 158934, 159033, 159037, 159102, 159193, 159336, 159353, 159403, 159572, 159667, 159868, 159950, 160112, 160143, 160287, 160546, 160681, 160909, 161133, 161240, 161260, 161270, 161293, 161301, 161326, 161352, 161474, 161495, 161533, 161605, 161744, 162103, 162108, 162220, 162327, 162345, 162398, 162515, 162776, 162857, 162913, 163103, 163160, 163226, 163271, 163463, 163487, 163524, 163593, 163619, 163766, 163821, 163869, 163927, 163928, 164007, 164061, 164138, 164207, 164222, 164352, 164419, 164458, 164482, 164543, 164555, 164562, 164577, 164679, 164689, 164782, 164800, 164893, 164987, 165054, 165088, 165207, 165218, 165230, 165326, 165576, 165577, 165591, 165674, 165878, 165898, 165989, 166620, 166810, 166978, 167059, 167088, 167245, 167265, 167277, 167331, 167477, 167493, 167765, 167837, 167936, 168043, 168077, 168117, 168121, 168126, 168135, 168143, 168145, 168150, 168160, 168165, 168178, 168184, 168187, 168192, 168306, 168450, 168482, 168490, 168495, 168523, 168570, 168576, 168583, 168588, 168589, 168611, 168624, 168642, 168657, 168660, 168667, 168692, 168693, 168695, 168696, 168704, 168709, 168732, 168734, 168737, 168741, 168752, 168754, 168772, 168783, 168791, 168796, 168797, 168811, 168813, 168816, 168863, 168869, 168875, 168882, 168885, 168898, 168901, 168913, 168938, 168945, 168957, 168964, 168971, 168992, 169017, 169022, 169031, 169061, 169064, 169069, 169073, 169077, 169090, 169092, 169093, 169105, 169116, 169124, 169139, 169149, 169160, 169163, 169174, 169184, 169186, 169187, 169194, 169197, 169205, 169217, 169236, 169241, 169242, 169269, 169275, 169277, 169278, 169279, 169282, 169287, 169288, 169303, 169323, 169339, 169342, 169357, 169369, 169380, 169409, 169422, 169708, 169954, 170004, 170005, 170007, 170012, 170036, 170052, 170054, 170059, 170062, 170064, 170068, 170102, 170115, 170139, 170145, 170146, 170147, 170152, 170164, 170187, 170198, 170204, 170205, 170211, 170214, 170215, 170224, 170226, 170256, 170261, 170278, 170297, 170304, 170306, 170320, 170332, 170338, 170362, 170365, 170367, 170368, 170372, 170384, 170457, 170465, 170468, 170473, 170477, 170481, 170482, 170500, 170530, 170538, 170546, 170561, 170569, 170579, 170581, 170596, 170606, 170614, 170644, 170653, 170654, 170656, 170658, 170716, 170720, 170723, 170724, 170736, 170739, 170742, 170746, 170749, 170790, 170833, 170907, 170916, 170924, 170929, 170936, 170944, 170974, 170990, 171012, 171014, 171017, 171044, 171052, 171083, 171149, 171157, 171160, 171199, 171210, 171243, 171270, 171271, 171295, 171332, 171348, 171368, 171370, 171378, 171390, 171393, 171431, 171477, 171558, 171561, 171568, 171593, 171600, 171604, 171606, 171634, 171683, 171689, 171694, 171729, 171739, 171741, 171768, 171791, 171801, 171856, 171871, 171892, 171899, 171927, 171950, 172022, 172039, 172149, 172178, 172214, 172246, 172265, 172278, 172315, 172320, 172329, 172343, 172347, 172354, 172357, 172361, 172364, 172377, 172382, 172411, 172435, 172450, 172474, 172484, 172485, 172520, 172545, 172552, 172598, 172600, 172602, 172607, 172659, 172669, 172671, 172688, 172756, 172773, 172779, 172804, 172829, 172837, 172859, 172881, 172905, 172923, 172965, 172971, 172979, 172986, 172992, 172994, 173053, 173063, 173070, 173081, 173096, 173108, 173111, 173156, 173190, 173206, 173253, 173282, 173305, 173318, 173321, 173331, 173370, 173395, 173431, 173439, 173500, 173566, 173599, 173648, 173676, 173693, 173695, 173707, 173750, 173763, 173793, 173883, 173956, 173971, 173979, 173996, 174046, 174086, 174121, 174123, 174144, 174163, 174182, 174186, 174234, 174279, 174293, 174305, 174336, 174356, 174371, 174441, 174444, 174468, 174469, 174476, 174489, 174541, 174556, 174869, 174937, 175016, 175174, 175433, 175678, 176111, 176300, 176975, 177139, 177212, 177217, 177221, 177235, 177265, 177322, 177340, 177350, 177380, 177399, 177405, 177478, 177479, 177481, 177493, 177552, 177600, 177611, 177621, 177629, 177634, 177648, 177655, 177658, 177664, 177680, 177697, 177708, 177732, 177738, 177780, 177802, 177837, 177846, 177859, 177868, 177902, 177907, 177910, 177911, 177912, 177938, 177940, 177951, 177952, 177954, 177980, 177988, 178032, 178036, 178060, 178074, 178075, 178087, 178109, 178124, 178143, 178166, 178172, 178178, 178186, 178196, 178199, 178203, 178267, 178303, 178330, 178362, 178372, 178375, 178401, 178431, 178433, 178439, 178453, 178462, 178470, 178472, 178476, 178488, 178503, 178519, 178523, 178546, 178555, 178580, 178643, 178664, 178668, 178672, 178673, 178686, 178687, 178700, 178709, 178722, 178740, 178766, 178803, 178811, 178812, 178814, 178825, 178829, 178859, 178891, 178893, 178903, 178909, 179024, 179314, 179441, 179606, 179615, 179653, 179669, 179694, 179702, 179727, 179740, 179754, 179756, 179770, 179777, 179789, 179791, 179808, 179814, 179817, 179822, 179824, 179835, 179847, 179863, 179896, 179898, 179925, 179972, 180012, 180056, 180078, 180106, 180113, 180114, 180141, 180149, 180165, 180174, 180192, 180196, 180204, 180206, 180208, 180213, 180235, 180251, 180301, 180313, 180350, 180363, 180373, 180401, 180435, 180450, 180454, 180502, 180736, 181559, 181864, 182263, 182378, 182435, 182572, 182635, 182655, 182716, 182897, 183033, 183179, 183251, 183299, 183416, 183443, 183533, 183557, 183572, 183633, 183682, 183784, 183885, 183947, 183949, 183974, 184038, 184132, 184180, 184182, 184218, 184475, 184542, 184633, 184638, 184787, 184812, 184895, 184930, 184985, 185028, 185089, 185090, 185290, 185302, 185448, 186626, 186653, 186660, 187791, 187794, 187864, 188325, 188497, 188893, 189201, 189445, 189986, 190073, 190270, 190543, 190679, 190845, 191082, 191401, 191459, 191528, 191681, 192266, 193204, 193472, 193619, 194609, 194847, 195957, 197151, 197272, 198097, 198367, 199470, 199937, 200738, 201048, 202131, 203893, 203967, 205356, 206762, 208212, 208346, 208936, 211614, 212541, 212821, 213734, 214042, 214167, 214842, 216067, 216551, 217754, 220539, 222852, 224160, 225556, 226041, 226897, 226920, 228889, 229843, 233607, 233808, 239094, 239668, 240425, 243318, 243934, 244185, 245220, 246518, 249764, 253113, 253260, 255043, 256633, 257846, 257913, 259344, 260665, 267201, 269298, 270421, 270884, 271321, 271851, 274534, 274615, 279346, 281007, 282230, 282298, 284060, 284159, 284257, 285443, 285698, 285894, 286592, 286924, 287013, 289741, 290536, 291972, 292517, 294197, 296347, 297204, 297810, 299480, 299706, 299888, 299930, 300259, 300436, 300586, 300985, 301289, 301290, 301465, 301503, 301659, 301702, 302091, 302797, 302976, 303050, 303248, 303447, 303451, 303573, 304226, 304295, 305150, 305336, 305404, 305782, 305970, 306005, 306012, 306061, 306185, 306258, 306655, 307174, 307262, 307267, 307661, 307854, 308067, 308478, 308617, 309199, 309407, 309729, 310451, 310496, 310950, 310956, 310994, 311449, 311629, 311690, 311769, 311770, 311920, 311923, 311930, 311976, 311980, 312066, 312067, 312068, 312072, 312211, 312237, 312301, 312330, 312367, 312386, 312393, 312507, 312513, 312525, 312527, 312529, 312531, 312564, 312665, 312671, 312676, 312677, 312823, 312824, 312831, 312834, 312864, 312874, 312887, 312973, 312980, 312981, 312982, 313032, 313046, 313086, 313089, 313130, 313204, 313210, 313246, 313267, 313268, 313269, 313277, 313278, 313279, 313291, 313310, 313311, 313376, 313379, 313391, 313545, 313579, 313630, 313640, 313698, 313726, 313877, 314076, 314129, 314170, 314255, 314428, 314454, 314610, 314615, 314643, 314788, 314879, 314889, 314928, 314969, 314976, 315000, 315037, 315055, 315072, 315152, 315205, 315215, 315230, 315235, 315259, 315274, 315300, 315303, 315316, 315360, 315410, 315429, 315521, 315576, 315741, 315746, 315846, 315884, 315911, 315913, 315975, 316008, 316089, 316167, 316202, 316214, 316289, 316294, 316378, 316438, 316504, 316626, 316670, 316695, 316853, 316881, 316884, 316905, 317012, 317030, 317049, 317249, 317274, 317451, 317587, 317689, 317765, 317784, 317935, 318096, 318199, 318223, 318305, 318593, 318837, 318922, 318972, 319399, 319422, 319576, 319670, 319737, 319832, 319858, 319966, 320013, 320078, 320522, 320601, 320719, 320740, 320749, 320938, 320951, 320952, 320959, 321015, 321132, 321416, 321445, 321448, 321760, 321795, 321856, 322038, 322089, 322150, 322158, 322170, 322211, 322340, 322534, 322549, 322557, 322567, 322583, 322613, 322645, 322652, 322706, 322709, 322853, 322898, 322957, 323032, 323038, 323075, 323132, 323231, 323249, 323291, 323477, 323515, 323574, 323648, 323752, 323767, 323808, 323819, 323823, 323844, 323888, 323941, 323946, 323954, 323958, 324003, 324016, 324045, 324050, 324075, 324094, 324105, 324108, 324114, 324120, 324131, 324136, 324144, 324169, 324174, 324180, 324188, 324191, 324202, 324227, 324241, 324255, 324259, 324260, 324299, 324340, 324369, 324385, 324437, 324455, 324469, 324475, 324525, 324555, 324564, 324584, 324585, 324594, 324603, 324606, 324608, 324609, 324618, 324622, 324623, 324627, 324628, 324632, 324644, 324647, 324651, 324653, 324662, 324669, 324670, 324674, 324676, 324680, 324681, 324687, 324691, 324696, 324701, 324702, 324705, 324710, 324715, 324723, 324731, 324732, 324734, 324739, 324740, 324744, 324747, 324751, 324757, 324760, 324762, 324771, 324772, 324774, 324776, 324781, 324788, 324795, 324796, 324800, 324802, 324806, 324811, 324816, 324819, 324823, 324829, 324839, 324841, 324845, 324853, 324858, 324864, 324867, 324869, 324871, 324876, 324879, 324892, 324895, 324898, 324902, 324908, 324914, 324920, 324927, 324930, 324931, 324936, 324940, 324942, 324944, 324945, 324948, 324960, 324963, 324968, 324973, 324979, 324986, 324989, 324991, 324994, 324999, 325004, 325025, 325027, 325029, 325031, 325035, 325041, 325047, 325053, 325059, 325061, 325078, 325081, 325088, 325089, 325103, 325107, 325114, 325117, 325122, 325135, 325137, 325142, 325144, 325149, 325170, 325176, 325178, 325182, 325184, 325186, 325202, 325206, 325210, 325214, 325222, 325227, 325228, 325232, 325237, 325242, 325248, 325251, 325258, 325262, 325265, 325269, 325277, 325280, 325281, 325291, 325300, 325301, 325305, 325307, 325311, 325318, 325322, 325326, 325327, 325336, 325338, 325347, 325350, 325351, 325358, 325360, 325361, 325362, 325369, 325377, 325382, 325386, 325397, 325400, 325403, 325412, 325423, 325434, 325437, 325450, 325452, 325457, 325458, 325459, 325466, 325469, 325472, 325476, 325481, 325484, 325495, 325498, 325503, 325511, 325515, 325518, 325528, 325535, 325544, 325551, 325564, 325566, 325570, 325572, 325575, 325577, 325590, 325597, 325602, 325604, 325606, 325608, 325626, 325630, 325631, 325633, 325636, 325653, 325656, 325667, 325668, 325675, 325684, 325689, 325700, 325706, 325708, 325714, 325719, 325721, 325722, 325726, 325727, 325737, 325742, 325747, 325750, 325754, 325765, 325771, 325776, 325780, 325786, 325792, 325793, 325794, 325803, 325809, 325824, 325840, 325846, 325847, 325872, 325877, 325881, 325894, 325912, 325913, 325920, 325931, 325940, 325949, 325955, 325981, 325983, 326006, 326011, 326016, 326028, 326039, 326044, 326049, 326058, 326062, 326085, 326092, 326094, 326104, 326113, 326119, 326133, 326134, 326142, 326156, 326160, 326164, 326171, 326172, 326180, 326183, 326196, 326199, 326223, 326228, 326230, 326239, 326256, 326257, 326263, 326286, 326293, 326308, 326319, 326336, 326350, 326352, 326357, 326363, 326395, 326410, 326424, 326431, 326434, 326444, 326451, 326452, 326456, 326463, 326465, 326472, 326476, 326481, 326486, 326494, 326497, 326501, 326502, 326507, 326520, 326546, 326550, 326559, 326560, 326567, 326571, 326588, 326607, 326612, 326621, 326632, 326633, 326643, 326649, 326656, 326666, 326672, 326678, 326681, 326686, 326691, 326694, 326705, 326710, 326713, 326730, 326732, 326753, 326756, 326765, 326783, 326784, 326791, 326795, 326801, 326804, 326810, 326825, 326829, 326846, 326856, 326863, 326871, 326883, 326885, 326888, 326891, 326902, 326905, 326911, 326921, 326950, 326968, 326972, 326977, 326985, 326986, 326995, 326999, 327002, 327014, 327023, 327034, 327036, 327039, 327044, 327045, 327048, 327055, 327064, 327071, 327080, 327093, 327099, 327110, 327114, 327121, 327123, 327132, 327134, 327140, 327144, 327148, 327149, 327157, 327165, 327169, 327177, 327188, 327195, 327197, 327199, 327200, 327216, 327219, 327237, 327241, 327243, 327245, 327251, 327259, 327261, 327265, 327269, 327270, 327276, 327298, 327307, 327308, 327316, 327339, 327340, 327343, 327344, 327345, 327351, 327352, 327355, 327359, 327374, 327375, 327377, 327382, 327383, 327395, 327421, 327422, 327431, 327437, 327447, 327451, 327454, 327475, 327482, 327486, 327487, 327492, 327504, 327510, 327515, 327518, 327524, 327525, 327526, 327533, 327536, 327539, 327547, 327548, 327553, 327570, 327577, 327589, 327593, 327597, 327606, 327609, 327613, 327615, 327616, 327620, 327639, 327647, 327648, 327650, 327656, 327662, 327669, 327684, 327692, 327712, 327715, 327731, 327736, 327738, 327744, 327753, 327761, 327766, 327773, 327780, 327785, 327789, 327792, 327805, 327810, 327816, 327832, 327833, 327835, 327838, 327842, 327845, 327864, 327869, 327873, 327879, 327889, 327897, 327911, 327917, 327932, 327936, 327942, 327948, 327962, 327965, 327967, 327969, 327971, 327978, 327983, 327987, 327998, 328009, 328014, 328021, 328029, 328030, 328036, 328037, 328044, 328049, 328054, 328062, 328064, 328067, 328070, 328071, 328081, 328083, 328091, 328096, 328103, 328108, 328113, 328123, 328128, 328135, 328143, 328145, 328151, 328166, 328172, 328174, 328179, 328199, 328208, 328215, 328219, 328225, 328227, 328241, 328243, 328249, 328254, 328259, 328261, 328265, 328271, 328275, 328282, 328287, 328288, 328293, 328297, 328303, 328307, 328309, 328312, 328313, 328317, 328323, 328337, 328338, 328348, 328352, 328357, 328368, 328374, 328384, 328385, 328386, 328393, 328400, 328403, 328404, 328410, 328413, 328414, 328446, 328450, 328454, 328463, 328469, 328488, 328495, 328498, 328513, 328523, 328526, 328545, 328558, 328560, 328575, 328581, 328582, 328592, 328599, 328601, 328620, 328633, 328639, 328651, 328652, 328655, 328656, 328663, 328666, 328677, 328681, 328686, 328693, 328695, 328699, 328705, 328717, 328722, 328726, 328727, 328730, 328734, 328737, 328741, 328743, 328751, 328758, 328766, 328771, 328781, 328785, 328789, 328797, 328803, 328815, 328828, 328831, 328835, 328839, 328848, 328851, 328862, 328865, 328871, 328872, 328875, 328878, 328882, 328884, 328888, 328897, 328903, 328915, 328927, 328944, 328945, 328947, 328951, 328961, 328966, 328973, 328984, 328997, 328999, 329005, 329010, 329017, 329020, 329027, 329029, 329055, 329059, 329063, 329076, 329078, 329082, 329084, 329086, 329089, 329104, 329105, 329121, 329125, 329126, 329133, 329137, 329144, 329151, 329155, 329156, 329159, 329166, 329189, 329190, 329193, 329203, 329211, 329215, 329217, 329221, 329232, 329234, 329235, 329240, 329247, 329248, 329252, 329258, 329260, 329266, 329271, 329279, 329281, 329283, 329290, 329291, 329296, 329300, 329304, 329317, 329331, 329339, 329343, 329344, 329345, 329361, 329374, 329375, 329389, 329391, 329393, 329401, 329406, 329415, 329417, 329421, 329444, 329446, 329471, 329474, 329481, 329492, 329510, 329516, 329518, 329520, 329523, 329526, 329534, 329537, 329548, 329552, 329555, 329568, 329571, 329575, 329590, 329595, 329602, 329609, 329611, 329618, 329631, 329637, 329654, 329663, 329674, 329684, 329692, 329696, 329705, 329716, 329720, 329730, 329739, 329750, 329763, 329764, 329771, 329779, 329782, 329789, 329806, 329812, 329816, 329824, 329830, 329833, 329840, 329848, 329850, 329855, 329862, 329873, 329878, 329887, 329890, 329895, 329902, 329904, 329906, 329918, 329940, 329942, 329950, 329952, 329966, 329977, 329979, 329981, 329982, 329987, 329989, 329993, 329996, 330000, 330003, 330004, 330010, 330016, 330035, 330036, 330040, 330043, 330047, 330050, 330053, 330056, 330074, 330094, 330105, 330112, 330114, 330121, 330124, 330127, 330136, 330142, 330154, 330159, 330162, 330166, 330174, 330175, 330183, 330194, 330203, 330214, 330219, 330228, 330231, 330242, 330248, 330250, 330252, 330292, 330295, 330300, 330306, 330309, 330314, 330335, 330342, 330346, 330353, 330362, 330369, 330376, 330383, 330387, 330392, 330399, 330407, 330408, 330415, 330422, 330425, 330430, 330436, 330444, 330458, 330459, 330461, 330478, 330482, 330484, 330496, 330501, 330503, 330512, 330520, 330525, 330531, 330532, 330534, 330544, 330561, 330567, 330569, 330573, 330579, 330583, 330587, 330596, 330626, 330636, 330640, 330666, 330677, 330678, 330686, 330687, 330697, 330702, 330706, 330711, 330713, 330722, 330731, 330735, 330743, 330755, 330767, 330775, 330780, 330785, 330789, 330792, 330801, 330807, 330816, 330820, 330826, 330831, 330845, 330846, 330854, 330870, 330881, 330882, 330889, 330904, 330912, 330919, 330925, 330926, 330938, 330941, 330948, 330959, 330962, 330970, 330972, 330973, 330979, 330990, 330993, 330998, 331000, 331002, 331006, 331012, 331014, 331017, 331021, 331027, 331029, 331032, 331041, 331044, 331047, 331054, 331059, 331085, 331092, 331097, 331104, 331109, 331110, 331120, 331121, 331135, 331137, 331143, 331144, 331149, 331152, 331172, 331197, 331199, 331207, 331208, 331213, 331220, 331223, 331252, 331261, 331266, 331297, 331302, 331318, 331322, 331333, 331340, 331344, 331347, 331351, 331358, 331366, 331371, 331372, 331374, 331382, 331394, 331398, 331406, 331416, 331424, 331431, 331432, 331445, 331456, 331461, 331468, 331475, 331481, 331488, 331498, 331504, 331506, 331507, 331514, 331516, 331527, 331529, 331533, 331536, 331539, 331542, 331553, 331556, 331557, 331561, 331567, 331569, 331573, 331580, 331590, 331597, 331601, 331604, 331611, 331619, 331626, 331638, 331646, 331650, 331654, 331674, 331685, 331693, 331696, 331702, 331705, 331711, 331721, 331734, 331748, 331750, 331778, 331782, 331788, 331793, 331826, 331833, 331838, 331841, 331852, 331862, 331867, 331872, 331884, 331886, 331889, 331899, 331909, 331913, 331917, 331922, 331926, 331935, 331940, 331952, 331956, 331967, 331970, 331974, 331979, 331986, 331988, 331991, 331993, 332003, 332005, 332007, 332012, 332015, 332017, 332023, 332028, 332036, 332041, 332046, 332057, 332065, 332067, 332075, 332077, 332079, 332081, 332083, 332085, 332088, 332096, 332100, 332124, 332136, 332154, 332157, 332161, 332164, 332171, 332181, 332184, 332189, 332196, 332204, 332208, 332215, 332229, 332233, 332234, 332243, 332248, 332253, 332254, 332255, 332265, 332266, 332268, 332276, 332284, 332288, 332291, 332295, 332302, 332308, 332315, 332320, 332331, 332350, 332356, 332359, 332364, 332366, 332369, 332373, 332388, 332390, 332393, 332398, 332404, 332411, 332435, 332437, 332448, 332453, 332455, 332464, 332474, 332487, 332492, 332494, 332502, 332506, 332521, 332530, 332536, 332548, 332551, 332556, 332562, 332575, 332580, 332585, 332598, 332615, 332622, 332624, 332627, 332630, 332655, 332668, 332677, 332690, 332693, 332700, 332723, 332733, 332740, 332745, 332751, 332755, 332761, 332764, 332768, 332776, 332790, 332800, 332809, 332824, 332827, 332832, 332837, 332845, 332855, 332859, 332868, 332872, 332874, 332878, 332879, 332882, 332885, 332895, 332899, 332902, 332912, 332913, 332918, 332920, 332924, 332929, 332941, 332949, 332955, 332991, 333000, 333007, 333016, 333019, 333026, 333031, 333040, 333059, 333061, 333065, 333068, 333077, 333084, 333091, 333094, 333095, 333099, 333107, 333114, 333117, 333127, 333132, 333135, 333138, 333142, 333149, 333153, 333164, 333170, 333174, 333187, 333192, 333193, 333199, 333206, 333210, 333211, 333215, 333231, 333233, 333244, 333259, 333260, 333266, 333269, 333273, 333283, 333287, 333296, 333297, 333304, 333307, 333314, 333318, 333320, 333330, 333333, 333335, 333341, 333353, 333360, 333363, 333379, 333390, 333391, 333394, 333405, 333408, 333412, 333416, 333427, 333434, 333449, 333455, 333457, 333468, 333473, 333475, 333479, 333482, 333483, 333487, 333494, 333500, 333506, 333518, 333521, 333530, 333537, 333541, 333544, 333545, 333548, 333565, 333588, 333592, 333595, 333598, 333600, 333606, 333608, 333609, 333614, 333626, 333635, 333636, 333644, 333646, 333651, 333655, 333674, 333675, 333679, 333691, 333695, 333699, 333708, 333716, 333717, 333721, 333728, 333733, 333740, 333742, 333743, 333745, 333752, 333754, 333755, 333758, 333760, 333761, 333765, 333784, 333789, 333793, 333795, 333797, 333803, 333807, 333808, 333812, 333814, 333822, 333825, 333827, 333836, 333838, 333842, 333852, 333859, 333868, 333870, 333874, 333877, 333881, 333883, 333886, 333890, 333896, 333909, 333912, 333920, 333987, 333995, 334180, 334236, 334277, 334328, 334365, 334406, 334419, 334491, 334575, 334630, 334678, 334680, 334695, 334754, 334808, 334812, 334826, 334970, 335011, 335014, 335042, 335090, 335125, 335171, 335198, 335212, 335303, 335393, 335449, 335464, 335565, 335579, 335604, 335647, 335656, 335725, 335727, 335767, 335774, 335801, 335809, 335856, 335893, 335941, 335985, 336005, 336046, 336135, 336328, 336368, 336395, 336434, 336479, 336620, 336702, 336715, 336808, 336852, 337014, 337077, 337254, 337265, 337315, 337348, 337458, 337483, 337661, 337686, 337690, 337706, 337711, 337718, 337767, 337803, 337817, 337919, 337950, 338009, 338010, 338167, 338263, 338364, 338387, 338401, 338534, 338602, 338618, 338714, 338744, 338786, 338931, 338946, 338956, 339020, 339040, 339092, 339132, 339252, 339298, 339350, 339410, 339487, 339529, 339531, 339574, 339584, 339751, 339800, 339809, 339836, 339887, 339938, 339958, 340032, 340047, 340062, 340133, 340274, 340315, 340359, 340362, 340466, 340481, 340560, 340574, 340589, 340599, 340602, 340648, 340698, 340783, 340792, 340874, 340888, 340895, 340942, 340996, 341068, 341110, 341139, 341154, 341256, 341273, 341292, 341296, 341417, 341489, 341530, 341579, 341618, 341706, 341837, 341913, 341921, 341990, 342118, 342126, 342161, 342163, 342319, 342324, 342334, 342338, 342497, 342602, 342676, 342719, 342854, 342855, 342942, 343048, 343100, 343107, 343113, 343265, 343285, 343345, 343415, 343478, 343551, 343563, 343587, 345460, 345613, 345614, 345619, 345747, 345776, 345818, 345948, 345997, 346056, 346102, 346310, 346316, 346439, 346480, 346499, 346530, 346531, 346669, 346710, 346831, 346838, 346866, 346876, 346943, 347004, 347006, 347009, 347011, 347016, 347020, 347027, 347029, 347035, 347040, 347045, 347050, 347055, 347063, 347069, 347077, 347083, 347087, 347090, 347094, 347108, 347122, 347128, 347133, 347140, 347154, 347160, 347167, 347174, 347181, 347187, 347197, 347198, 347202, 347204, 347214, 347216, 347225, 347239, 347242, 347248, 347250, 347254, 347268, 347278, 347281, 347284, 347285, 347290, 347302, 347320, 347328, 347337, 347338, 347344, 347348, 347354, 347360, 347367, 347370, 347374, 347382, 347386, 347391, 347400, 347416, 347419, 347423, 347435, 347439, 347446, 347457, 347464, 347470, 347478, 347481, 347486, 347495, 347498, 347501, 347507, 347510, 347512, 347519, 347520, 347523, 347535, 347541, 347550, 347554, 347560, 347564, 347572, 347581, 347585, 347590, 347595, 347602, 347616, 347622, 347631, 347636, 347640, 347663, 347672, 347675, 347683, 347687, 347692, 347693, 347697, 347703, 347706, 347713, 347724, 347735, 347737, 347740, 347748, 347750, 347754, 347759, 347767, 347776, 347782, 347792, 347801, 347803, 347810, 347822, 347826, 347830, 347836, 347841, 347847, 347857, 347864, 347871, 347875, 347887, 347909, 347914, 347920, 347922, 347927, 347929, 347931, 347933, 347940, 347941, 347945, 347947, 347949, 347954, 347961, 347967, 347969, 347972, 347981, 347982, 347987, 347995, 348002, 348004, 348012, 348016, 348030, 348035, 348042, 348050, 348054, 348065, 348066, 348073, 348075, 348091, 348096, 348098, 348106, 348107, 348138, 348157, 348161, 348165, 348171, 348181, 348189, 348190, 348193, 348195, 348199, 348203, 348210, 348211, 348220, 348228, 348234, 348237, 348239, 348247, 348257, 348258, 348262, 348267, 348272, 348276, 348282, 348288, 348290, 348305, 348310, 348312, 348324, 348338, 348342, 348345, 348352, 348358, 348363, 348368, 348381, 348390, 348397, 348417, 348430, 348442, 348446, 348450, 348453, 348468, 348473, 348477, 348489, 348490, 348494, 348500, 348515, 348516, 348522, 348527, 348538, 348541, 348546, 348551, 348552, 348558, 348560, 348561, 348574, 348580, 348586, 348587, 348589, 348593, 348595, 348597, 348605, 348606, 348611, 348613, 348617, 348621, 348626, 348630, 348639, 348642, 348645, 348648, 348657, 348660, 348665, 348678, 348681, 348690, 348692, 348696, 348699, 348703, 348705, 348707, 348717, 348722, 348723, 348731, 348734, 348736, 348739, 348741, 348744, 348748, 348749, 348752, 348755, 348757, 348767, 348769, 348779, 348783, 348790, 348793, 348795, 348798, 348806, 348807, 348813, 348818, 348824, 348828, 348829, 348834, 348843, 348847, 348849, 348851, 348858, 348861, 348864, 348869, 348874, 348875, 348876, 348881, 348883, 348884, 348886, 348887, 348894, 348897, 348902, 348905, 348908, 348915, 348919, 348921, 348922, 348926, 348929, 348931, 348944, 348946, 348947, 348951, 348952, 348953, 348957, 348961, 348963, 348970, 348974, 348976, 348979, 348980, 348982, 348985, 348987, 348993, 348995, 348998, 349001, 349002, 349006, 349011, 349016, 349019, 349022, 349026, 349029, 349033, 349035, 349039, 349047, 349048, 349055, 349058, 349062, 349064, 349070, 349073, 349075, 349078, 349082, 349084, 349087, 349090, 349092, 349097, 349098, 349105, 349106, 349111, 349114, 349120, 349128, 349134, 349139, 349146, 349150, 349153, 349160, 349161, 349164, 349167, 349169, 349172, 349179, 349181, 349183, 349186, 349189, 349196, 349198, 349199, 349200, 349207, 349217, 349220, 349222, 349224, 349236, 349237, 349242, 349251, 349252, 349254, 349256, 349257, 349259, 349261, 349264, 349270, 349276, 349282, 349286, 349290, 349295, 349302, 349304, 349306, 349307, 349309, 349310, 349320, 349324, 349325, 349335, 349339, 349342, 349346, 349347, 349350, 349351, 349354, 349361, 349363, 349364, 349366, 349369, 349372, 349376, 349381, 349384, 349386, 349392, 349394, 349397, 349399, 349401, 349405, 349406, 349409, 349410, 349411, 349414, 349416, 349418, 349420, 349424, 349432, 349434, 349436, 349440, 349441, 349444, 349449, 349451, 349453, 349455, 349456, 349458, 349461, 349463, 349468, 349470, 349472, 349473, 349474, 349476, 349477, 349479, 349485, 349489, 349491, 349493, 349494, 349496, 349499, 349501, 349502, 349504, 349511, 349513, 349520, 349522, 349530, 349533, 349537, 349541, 349542, 349544, 349547, 349549, 349553, 349556, 349559, 349570, 349571, 349573, 349575, 349578, 349590, 349604, 349606, 349609, 349612, 349624, 349625, 349628, 349635, 349637, 349639, 349641, 349647, 349649, 349650, 349652, 349655, 349661, 349663, 349675, 349678, 349680, 349682, 349684, 349693, 349696, 349698, 349702, 349704, 349707, 349709, 349711, 349713, 349715, 349719, 349726, 349729, 349732, 349734, 349745, 349746, 349750, 349752, 349753, 349756, 349759, 349769, 349772, 349775, 349776, 349778, 349782, 349784, 349787, 349789, 349790, 349791, 349795, 349798, 349800, 349805, 349807, 349813, 349814, 349819, 349821, 349822, 349823, 349825, 349831, 349835, 349836, 349838, 349846, 349847, 349849, 349853, 349864, 349870, 349876, 349878, 349880, 349892, 349898, 349901, 349907, 349909, 349910, 349926, 349931, 349933, 349942, 349946, 349948, 349955, 349957, 349959, 349962, 349973, 349975, 349977, 349983, 349984, 349985, 349991, 349999, 350001, 350006, 350007, 350010, 350012, 350014, 350017, 350020, 350025, 350028, 350030, 350032, 350034, 350038, 350040, 350046, 350047, 350049, 350051, 350055, 350057, 350059, 350060, 350065, 350068, 350069, 350070, 350072, 350074, 350078, 350080, 350081, 350083, 350085, 350086, 350089, 350091, 350096, 350099, 350102, 350105, 350106, 350110, 350111, 350113, 350116, 350118, 350120, 350123, 350126, 350127, 350133, 350137, 350139, 350141, 350142, 350145, 350152, 350153, 350157, 350160, 350161, 350163, 350169, 350171, 350174, 350187, 350191, 350193, 350197, 350199, 350204, 350206, 350207, 350209, 350210, 350212, 350218, 350219, 350221, 350223, 350225, 350234, 350235, 350240, 350246, 350247, 350249, 350251, 350262, 350265, 350266, 350269, 350279, 350280, 350284, 350287, 350288, 350291, 350299, 350300, 350303, 350304, 350311, 350314, 350316, 350319, 350320, 350326, 350329, 350334, 350341, 350345, 350349, 350353, 350358, 350363, 350365, 350367, 350368, 350372, 350373, 350375, 350377, 350378, 350383, 350388, 350393, 350396, 350402, 350404, 350406, 350412, 350414, 350416, 350421, 350423, 350426, 350429, 350430, 350436, 350438, 350439, 350442, 350444, 350448, 350450, 350453, 350454, 350458, 350461, 350464, 350472, 350476, 350480, 350481, 350487, 350489, 350491, 350493, 350495, 350504, 350506, 350508, 350509, 350511, 350513, 350514, 350521, 350524, 350527, 350536, 350538, 350539, 350543, 350545, 350549, 350552, 350554, 350557, 350569, 350570, 350571, 350575, 350585, 350590, 350591, 350599, 350600, 350603, 350613, 350616, 350619, 350621, 350626, 350627, 350629, 350631, 350637, 350648, 350650, 350665, 350669, 350671, 350806, 350807, 350810, 350811, 350812, 350815, 350817, 350818, 350819, 350827, 350831, 350833, 350834, 350838, 350839, 350843, 350846, 350853, 350857, 350858, 350861, 350862, 350867, 350870, 350873, 350888, 350892, 350895, 350897, 350899, 350908, 350910, 350912, 350913, 350917, 350924, 350926, 350930, 350931, 350934, 350936, 350940, 350944, 350947, 350948, 350952, 350955, 350958, 350960, 350961, 350966, 350968, 350972, 350976, 350982, 350991, 351006, 351012, 351023, 351039, 351051, 351054, 351058, 351071, 351079, 351085, 351088, 351091, 351106, 351110, 351150, 351155, 351161, 351192, 351194, 351205, 351220, 351224, 351230, 351231, 351240, 351251, 351257, 351271, 351272, 351280, 351291, 351292, 351305, 351318, 351338, 351341, 351357, 351359, 351369, 351374, 351381, 351383, 351384, 351390, 351398, 351403, 351406, 351409, 351414, 351431, 351448, 351485, 351537, 351553, 351564, 351588, 351593, 351610, 351611, 351612, 351624, 351640, 351645, 351673, 351679, 351717, 351759, 351784, 351785, 351812, 351817, 351835, 351846, 351865, 351890, 351907, 351912, 351919, 351928, 351936, 351964, 351965, 351995, 352007, 352022, 352028, 352031, 352034, 352037, 352050, 352057, 352080, 352104, 352108, 352125, 352132, 352140, 352143, 352160, 352169, 352172, 352189, 352219, 352227, 352237, 352248, 352252, 352260, 352263, 352265, 352278, 352317, 352327, 352334, 352346, 352354, 352376, 352382, 352390, 352392, 352411, 352421, 352440, 352460, 352483, 352490, 352508, 352528, 352548, 352553, 352574, 352576, 352600, 352631, 352640, 352662, 352676, 352688, 352700, 352704, 352707, 352719, 352729, 352748, 352751, 352766, 352771, 352783, 352796, 352821, 352829, 352850, 352852, 352861, 352883, 352884, 352896, 352905, 352948, 352959, 352973, 352974, 352988, 353009, 353016, 353034, 353065, 353079, 353085, 353098, 353107, 353114, 353132, 353135, 353141, 353145, 353167, 353190, 353204, 353229, 353248, 353258, 353261, 353269, 353283, 353285, 353312, 353316, 353329, 353344, 353345, 353349, 353363, 353366, 353377, 353382, 353401, 353422, 353438, 353441, 353467, 353485, 353494, 353501, 353515, 353529, 353536, 353564, 353566, 353575, 353584, 353588, 353599, 353602, 353613, 353634, 353649, 353665, 353677, 353686, 353691, 353705, 353714, 353726, 353737, 353758, 353776, 353790, 353800, 353805, 353825, 353839, 353850, 353870, 353876, 353880, 353909, 353916, 353922, 353931, 353941, 353966, 353987, 353989, 354001, 354010, 354021, 354031, 354038, 354069, 354089, 354094, 354099, 354112, 354119, 354125, 354133, 354147, 354148, 354157, 354159, 354170, 354183, 354188, 354203, 354207, 354209, 354219, 354239, 354242, 354251, 354264, 354277, 354288, 354346, 354363, 354371, 354377, 354392, 354397, 354412, 354418, 354432, 354439, 354442, 354448, 354478, 354492, 354498, 354510, 354513, 354531, 354551, 354562, 354582, 354588, 354601, 354613, 354639, 354647, 354658, 354663, 354670, 354682, 354695, 354703, 354709, 354731, 354734, 354759, 354810, 354828, 354835, 354842, 354845, 354860, 354871, 354873, 354884, 354889, 354898, 354906, 354924, 354927, 354943, 354954, 354958, 354972, 354990, 355007, 355015, 355022, 355023, 355032, 355065, 355071, 355088, 355095, 355096, 355105, 355106, 355112, 355124, 355144, 355152, 355163, 355168, 355178, 355188, 355197, 355206, 355210, 355215, 355219, 355238, 355258, 355268, 355274, 355291, 355306, 355318, 355328, 355334, 355349, 355358, 355367, 355383, 355384, 355389, 355397, 355406, 355409, 355412, 355415, 355417, 355420, 355423, 355430, 355439, 355455, 355459, 355464, 355472, 355482, 355484, 355486, 355492, 355497, 355512, 355514, 355527, 355537, 355545, 355557, 355561, 355573, 355576, 355580, 355581, 355589, 355600, 355602, 355610, 355613, 355622, 355629, 355650, 355656, 355658, 355670, 355684, 355689, 355694, 355729, 355732, 355734, 355735, 355749, 355754, 355766, 355771, 355785, 355802, 355812, 355819, 355825, 355828, 355835, 355840, 355853, 355858, 355883, 355899, 355908, 355918, 355919, 355925, 355934, 355948, 355961, 355966, 355993, 355997, 356018, 356026, 356032, 356050, 356091, 356117, 356136, 356151, 356158, 356170, 356174, 356191, 356198, 356211, 356257, 356264, 356270, 356272, 356286, 356317, 356321, 356326, 356333, 356346, 356355, 356356, 356361, 356374, 356377, 356383, 356391, 356414, 356425, 356444, 356456, 356461, 356472, 356477, 356478, 356489, 356494, 356503, 356534, 356540, 356584, 356606, 356607, 356628, 356634, 356657, 356666, 356669, 356682, 356684, 356696, 356712, 356727, 356730, 356739, 356745, 356750, 356763, 356768, 356787, 356796, 356805, 356845, 356849, 356859, 356877, 356883, 356890, 356900, 356916, 356919, 356930, 356945, 356976, 356978, 357003, 357008, 357038, 357042, 357045, 357060, 357074, 357079, 357086, 357096, 357098, 357114, 357117, 357118, 357127, 357136, 357152, 357173, 357182, 357191, 357198, 357199, 357207, 357215, 357228, 357235, 357246, 357247, 357251, 357272, 357286, 357287, 357300, 357313, 357318, 357327, 357331, 357335, 357344, 357348, 357350, 357353, 357364, 357377, 357402, 357405, 357412, 357413, 357424, 357428, 357436, 357449, 357458, 357467, 357475, 357485, 357494, 357496, 357504, 357513, 357522, 357523, 357531, 357542, 357544, 357560, 357576, 357579, 357588, 357606, 357610, 357625, 357637, 357643, 357651, 357656, 357665, 357680, 357694, 357707, 357715, 357721, 357723, 357746, 357757, 357758, 357777, 357779, 357781, 357794, 357798, 357807, 357813, 357815, 357831, 357842, 357857, 357859, 357873, 357886, 357898, 357904, 357912, 357920, 357937, 357951, 357955, 357965, 357974, 357988, 357997, 357999, 358007, 358021, 358032, 358039, 358041, 358060, 358075, 358097, 358111, 358113, 358136, 358144, 358148, 358171, 358189, 358201, 358210, 358217, 358218, 358222, 358238, 358241, 358249, 358253, 358264, 358266, 358274, 358292, 358295, 358303, 358311, 358314, 358347, 358349, 358357, 358360, 358372, 358380, 358397, 358404, 358410, 358418, 358434, 358438, 358447, 358463, 358480, 358492, 358499, 358507, 358514, 358521, 358534, 358558, 358562, 358567, 358570, 358575, 358585, 358599, 358605, 358611, 358616, 358626, 358639, 358651, 358677, 358688, 358696, 358703, 358715, 358717, 358733, 358740, 358748, 358753, 358757, 358768, 358772, 358787, 358790, 358800, 358814, 358819, 358825, 358829, 358830, 358834, 358838, 358856, 358866, 358869, 358882, 358886, 358900, 358903, 358918, 358922, 358925, 358936, 358937, 358941, 358943, 358955, 358963, 358977, 358981, 358986, 358992, 358999, 359001, 359010, 359022, 359034, 359035, 359048, 359050, 359052, 359066, 359068, 359073, 359097, 359099, 359103, 359118, 359121, 359130, 359132, 359144, 359155, 359158, 359163, 359171, 359183, 359193, 359203, 359206, 359209, 359218, 359222, 359227, 359228, 359232, 359236, 359241, 359244, 359257, 359266, 359271, 359277, 359279, 359286, 359296, 359307, 359310, 359318, 359326, 359328, 359337, 359338, 359344, 359350, 359356, 359361, 359366, 359374, 359375, 359378, 359388, 359395, 359404, 359405, 359411, 359419, 359423, 359424, 359431, 359436, 359446, 359456, 359465, 359466, 359472, 359476, 359487, 359492, 359499, 359512, 359517, 359535, 359543, 359544, 359549, 359561, 359572, 359584, 359590, 359597, 359603, 359622, 359625, 359628, 359641, 359644, 359652, 359663, 359664, 359674, 359689, 359696, 359705, 359708, 359720, 359723, 359730, 359738, 359749, 359757, 359763, 359776, 359802, 359829, 359834, 359838, 359844, 359854, 359864, 359869, 359873, 359875, 359883, 359896, 359898, 359908, 359911, 359917, 359925, 359930, 359937, 359947, 359954, 359955, 359973, 359978, 359981, 359985, 359990, 360006, 360017, 360025, 360028, 360039, 360044, 360047, 360049, 360056, 360069, 360073, 360084, 360088, 360098, 360103, 360106, 360110, 360135, 360145, 360150, 360153, 360159, 360164, 360177, 360178, 360182, 360187, 360192, 360195, 360208, 360212, 360213, 360222, 360224, 360230, 360234, 360264, 360267, 360273, 360277, 360284, 360287, 360288, 360293, 360301, 360325, 360335, 360338, 360342, 360345, 360357, 360362, 360372, 360383, 360403, 360424, 360433, 360441, 360468, 360472, 360480, 360483, 360496, 360504, 360511, 360516, 360535, 360543, 360555, 360560, 360570, 360573, 360578, 360581, 360583, 360590, 360597, 360603, 360614, 360620, 360624, 360630, 360634, 360635, 360642, 360650, 360653, 360654, 360667, 360673, 360689, 360711, 360712, 360718, 360723, 360724, 360739, 360759, 360767, 360780, 360782, 360795, 360802, 360815, 360827, 360843, 360855, 360860, 360863, 360873, 360892, 360897, 360909, 360923, 360939, 360940, 360945, 360963, 360975, 360988, 361009, 361012, 361025, 361029, 361042, 361046, 361057, 361075, 361083, 361088, 361096, 361099, 361109, 361120, 361133, 361154, 361168, 361193, 361205, 361223, 361254, 361257, 361263, 361282, 361292, 361302, 361312, 361323, 361324, 361343, 361354, 361356, 361365, 361369, 361383, 361386, 361398, 361427, 361431, 361436, 361469, 361478, 361482, 361490, 361510, 361519, 361536, 361560, 361572, 361587, 361602, 361613, 361617, 361627, 361633, 361646, 361655, 361657, 361676, 361685, 361687, 361711, 361712, 361723, 361747, 361760, 361765, 361776, 361787, 361790, 361801, 361814, 361861, 361870, 361889, 361902, 361909, 361913, 361923, 361936, 361958, 361973, 361974, 362006, 362048, 362071, 362077, 362098, 362106, 362113, 362125, 362133, 362141, 362153, 362157, 362173, 362183, 362200, 362212, 362214, 362226, 362235, 362245, 362268, 362285, 362309, 362318, 362325, 362338, 362348, 362349, 362393, 362401, 362415, 362425, 362433, 362442, 362449, 362454, 362477, 362494, 362495, 362512, 362533, 362539, 362542, 362552, 362558, 362574, 362582, 362593, 362606, 362623, 362631, 362639, 362643, 362679, 362680, 362691, 362708, 362712, 362717, 362723, 362725, 362746, 362758, 362775, 362785, 362787, 362793, 362808, 362823, 362828, 362844, 362855, 362873, 362903, 362905, 362921, 362925, 362941, 362942, 362957, 362977, 362994, 363007, 363010, 363018, 363027, 363028, 363039, 363050, 363060, 363066, 363076, 363089, 363090, 363098, 363101, 363132, 363137, 363148, 363158, 363173, 363181, 363187, 363196, 363227, 363238, 363239, 363242, 363251, 363257, 363261, 363274, 363286, 363306, 363326, 363365, 363378, 363388, 363390, 363402, 363444, 363464, 363468, 363480, 363485, 363495, 363509, 363512, 363522, 363529, 363538, 363550, 363557, 363569, 363581, 363582, 363586, 363590, 363605, 363608, 363621, 363647, 363649, 363654, 363669, 363673, 363696, 363703, 363727, 363742, 363754, 363757, 363763, 363767, 363785, 363800, 363833, 363839, 363846, 363852, 363853, 363861, 363904, 363913, 363916, 363925, 363934, 363936, 363943, 363949, 363954, 363978, 363988, 363991, 363998, 364018, 364022, 364025, 364038, 364039, 364046, 364063, 364081, 364082, 364104, 364107, 364126, 364147, 364155, 364168, 364221, 364226, 364241, 364249, 364254, 364260, 364270, 364271, 364281, 364291, 364298, 364309, 364310, 364347, 364354, 364372, 364389, 364399, 364414, 364433, 364442, 364451, 364461, 364462, 364471, 364483, 364490, 364499, 364512, 364531, 364539, 364569, 364584, 364594, 364606, 364631, 364632, 364638, 364643, 364680, 364700, 364716, 364752, 364755, 364791, 364799, 364806, 364812, 364846, 364852, 364860, 364864, 364882, 364913, 364947, 364983, 364999, 365027, 365058, 365087, 365101, 365108, 365115, 365121, 365143, 365171, 365174, 365188, 365195, 365216, 365232, 365238, 365244, 365260, 365265, 365275, 365295, 365321, 365324, 365334, 365345, 365356, 365366, 365384, 365391, 365394, 365402, 365405, 365409, 365433, 365445, 365456, 365467, 365474, 365524, 365545, 365554, 365562, 365566, 365572, 365583, 365590, 365595, 365600, 365604, 365618, 365623, 365631, 365650, 365669, 365679, 365707, 365708, 365715, 365738, 365763, 365784, 365796, 365802, 365806, 365827, 365840, 365906, 365933, 365948, 365967, 365981, 366010, 366022, 366036, 366059, 366070, 366077, 366080, 366099, 366104, 366118, 366129, 366139, 366170, 366184, 366192, 366230, 366250, 366258, 366259, 366267, 366273, 366285, 366292, 366294, 366322, 366341, 366344, 366365, 366393, 366412, 366418, 366422, 366436, 366474, 366484, 366495, 366501, 366521, 366523, 366545, 366558, 366589, 366606, 366621, 366630, 366640, 366661, 366672, 366685, 366686, 366704, 366717, 366719, 366720, 366730, 366733, 366746, 366748, 366755, 366759, 366767, 366778, 366798, 366818, 366820, 366828, 366841, 366856, 366868, 366879, 366884, 366898, 366915, 366922, 366925, 366943, 366944, 366961, 366978, 366983, 366995, 367010, 367018, 367047, 367067, 367079, 367084, 367085, 367091, 367105, 367113, 367167, 367186, 367192, 367205, 367211, 367217, 367231, 367238, 367248, 367263, 367282, 367312, 367323, 367325, 367342, 367351, 367362, 367388, 367429, 367438, 367453, 367462, 367471, 367488, 367489, 367501, 367517, 367522, 367537, 367558, 367565, 367569, 367582, 367592, 367632, 367645, 367656, 367666, 367674, 367690, 367699, 367706, 367729, 367737, 367738, 367748, 367753, 367763, 367765, 367773, 367784, 367808, 367838, 367855, 367863, 367873, 367879, 367909, 367916, 367922, 367932, 367945, 367946, 367954, 367964, 367965, 367976, 367999, 368001, 368041, 368051, 368061, 368071, 368085, 368097, 368113, 368117, 368131, 368152, 368156, 368170, 368171, 368172, 368181, 368192, 368207, 368214, 368218, 368228, 368233, 368256, 368273, 368294, 368299, 368308, 368335, 368345, 368353, 368361, 368378, 368384, 368390, 368399, 368412, 368416, 368421, 368430, 368437, 368450, 368455, 368469, 368472, 368485, 368488, 368495, 368508, 368534, 368542, 368549, 368558, 368583, 368597, 368613, 368655, 368675, 368686, 368692, 368721, 368722, 368739, 368743, 368765, 368793, 368794, 368808, 368811, 368823, 368825, 368837, 368854, 368874, 368875, 368884, 368889, 368902, 368906, 368912, 368921, 368927, 368933, 368946, 368948, 368954, 369015, 369022, 369036, 369060, 369122, 369127, 369136, 369180, 369207, 369215, 369245, 369255, 369268, 369274, 369279, 369287, 369298, 369302, 369317, 369326, 369330, 369334, 369369, 369374, 369390, 369400, 369407, 369430, 369448, 369451, 369477, 369484, 369490, 369491, 369503, 369505, 369518, 369526, 369530, 369552, 369556, 369560, 369581, 369591, 369608, 369645, 369651, 369670, 369676, 369678, 369683, 369694, 369705, 369716, 369731, 369742, 369752, 369764, 369778, 369797, 369798, 369813, 369819, 369838, 369843, 369858, 369860, 369862, 369877, 369878, 369887, 369892, 369904, 369906, 369914, 369932, 369939, 369946, 369948, 369955, 369960, 369971, 369972, 370004, 370006, 370014, 370016, 370020, 370023, 370043, 370051, 370074, 370083, 370088, 370096, 370120, 370131, 370141, 370145, 370147, 370169, 370178, 370179, 370182, 370187, 370189, 370216, 370223, 370228, 370241, 370251, 370277, 370287, 370307, 370328, 370334, 370339, 370345, 370347, 370373, 370383, 370399, 370420, 370428, 370445, 370473, 370484, 370489, 370499, 370511, 370522, 370533, 370536, 370539, 370544, 370554, 370589, 370603, 370614, 370617, 370649, 370657, 370663, 370679, 370694, 370701, 370710, 370734, 370741, 370747, 370751, 370770, 370779, 370791, 370809, 370815, 370843, 370872, 370878, 370880, 370894, 370914, 370940, 370941, 370953, 370955, 370970, 370972, 370983, 370989, 371006, 371012, 371033, 371037, 371041, 371050, 371065, 371066, 371076, 371081, 371089, 371093, 371113, 371118, 371124, 371136, 371155, 371161, 371173, 371175, 371186, 371187, 371197, 371201, 371219, 371230, 371237, 371250, 371253, 371267, 371286, 371304, 371309, 371312, 371342, 371343, 371347, 371371, 371372, 371379, 371388, 371397, 371403, 371411, 371430, 371458, 371483, 371500, 371504, 371511, 371512, 371530, 371536, 371547, 371551, 371560, 371572, 371585, 371599, 371610, 371617, 371619, 371635, 371652, 371659, 371661, 371666, 371671, 371684, 371691, 371706, 371724, 371726, 371737, 371748, 371765, 371777, 371802, 371805, 371828, 371832, 371838, 371856, 371857, 371861, 371877, 371890, 371901, 371914, 371920, 371936, 371957, 371973, 371974, 371975, 371991, 371997, 372001, 372010, 372017, 372024, 372059, 372073, 372076, 372087, 372095, 372125, 372129, 372131, 372132, 372140, 372150, 372159, 372167, 372174, 372182, 372189, 372197, 372207, 372225, 372233, 372243, 372252, 372253, 372263, 372268, 372275, 372278, 372294, 372308, 372311, 372324, 372329, 372341, 372347, 372397, 372409, 372419, 372420, 372432, 372457, 372464, 372476, 372477, 372490, 372498, 372512, 372533, 372536, 372548, 372560, 372567, 372570, 372578, 372583, 372595, 372605, 372618, 372622, 372631, 372646, 372651, 372657, 372665, 372677, 372691, 372713, 372727, 372744, 372749, 372802, 372806, 372822, 372831, 372839, 372843, 372848, 372865, 372867, 372934, 372946, 372968, 372972, 372988, 372997, 373015, 373035, 373069, 373078, 373083, 373090, 373096, 373103, 373115, 373125, 373138, 373146, 373149, 373164, 373165, 373170, 373184, 373206, 373216, 373218, 373230, 373236, 373246, 373249, 373258, 373261, 373276, 373293, 373298, 373313, 373322, 373328, 373333, 373344, 373346, 373356, 373367, 373368, 373382, 373384, 373389, 373394, 373414, 373428, 373431, 373438, 373450, 373458, 373485, 373509, 373510, 373523, 373527, 373530, 373544, 373556, 373567, 373596, 373597, 373603, 373610, 373624, 373647, 373655, 373659, 373667, 373671, 373704, 373726, 373751, 373756, 373767, 373777, 373785, 373788, 373791, 373800, 373807, 373810, 373820, 373837, 373846, 373853, 373858, 373870, 373871, 373881, 373894, 373904, 373907, 373910, 373927, 373934, 373937, 373941, 373953, 373968, 374025, 374028, 374043, 374051, 374053, 374072, 374094, 374098, 374102, 374115, 374127, 374149, 374164, 374167, 374175, 374191, 374204, 374214, 374219, 374228, 374235, 374251, 374274, 374276, 374279, 374290, 374297, 374306, 374309, 374318, 374329, 374338, 374355, 374357, 374367, 374376, 374384, 374402, 374403, 374420, 374437, 374438, 374447, 374450, 374459, 374470, 374474, 374479, 374484, 374495, 374513, 374527, 374543, 374562, 374568, 374574, 374581, 374587, 374593, 374605, 374632, 374642, 374644, 374650, 374659, 374667, 374678, 374692, 374695, 374720, 374730, 374748, 374762, 374764, 374768, 374779, 374784, 374813, 374814, 374832, 374839, 374844, 374859, 374873, 374879, 374890, 374901, 374925, 374941, 374945, 374960, 374963, 374979, 374986, 374994, 374998, 375004, 375022, 375029, 375034, 375041, 375043, 375056, 375067, 375116, 375127, 375133, 375154, 375179, 375193, 375212, 375219, 375224, 375233, 375235, 375241, 375247, 375259, 375262, 375270, 375273, 375289, 375311, 375348, 375353, 375365, 375376, 375381, 375383, 375394, 375413, 375426, 375446, 375455, 375474, 375477, 375501, 375508, 375522, 375523, 375530, 375538, 375546, 375551, 375556, 375564, 375588, 375596, 375599, 375605, 375609, 375617, 375621, 375634, 375638, 375660, 375670, 375695, 375718, 375733, 375737, 375741, 375756, 375765, 375784, 375786, 375795, 375797, 375802, 375811, 375817, 375824, 375825, 375832, 375848, 375852, 375858, 375870, 375878, 375881, 375896, 375910, 375915, 375924, 375932, 375937, 375970, 375974, 375980, 375984, 375990, 375998, 376001, 376007, 376028, 376034, 376038, 376057, 376077, 376088, 376095, 376118, 376129, 376161, 376175, 376179, 376182, 376186, 376203, 376206, 376233, 376250, 376254, 376260, 376278, 376282, 376286, 376289, 376295, 376302, 376334, 376339, 376344, 376360, 376378, 376386, 376406, 376408, 376418, 376420, 376460, 376465, 376479, 376496, 376506, 376522, 376529, 376534, 376535, 376550, 376562, 376568, 376571, 376591, 376620, 376626, 376634, 376647, 376652, 376668, 376679, 376681, 376738, 376745, 376757, 376759, 376779, 376796, 376805, 376808, 376814, 376825, 376852, 376876, 376880, 376894, 376910, 376929, 376934, 376936, 376954, 376955, 376976, 376985, 376991, 377010, 377036, 377040, 377049, 377061, 377070, 377084, 377108, 377150, 377167, 377195, 377211, 377221, 377229, 377244, 377245, 377248, 377249, 377258, 377277, 377298, 377309, 377315, 377325, 377335, 377357, 377371, 377373, 377378, 377394, 377424, 377436, 377453, 377459, 377460, 377480, 377496, 377504, 377507, 377524, 377548, 377559, 377568, 377569, 377587, 377593, 377594, 377598, 377601, 377602, 377606, 377609, 377628, 377637, 377646, 377649, 377662, 377674, 377681, 377701, 377716, 377726, 377733, 377743, 377763, 377788, 377805, 377812, 377822, 377835, 377844, 377852, 377853, 377854, 377859, 377865, 377880, 377896, 377903, 377908, 377920, 377946, 377949, 377951, 377967, 377969, 377976, 378006, 378010, 378019, 378022, 378026, 378041, 378052, 378055, 378067, 378079, 378091, 378092, 378104, 378119, 378123, 378135, 378152, 378178, 378198, 378199, 378217, 378222, 378236, 378266, 378267, 378278, 378279, 378304, 378308, 378339, 378344, 378345, 378369, 378374, 378384, 378386, 378394, 378400, 378417, 378423, 378430, 378431, 378440, 378465, 378467, 378486, 378505, 378512, 378524, 378525, 378543, 378546, 378563, 378565, 378571, 378583, 378584, 378585, 378591, 378594, 378604, 378607, 378622, 378627, 378630, 378647, 378661, 378669, 378674, 378686, 378701, 378714, 378716, 378722, 378729, 378736, 378739, 378747, 378762, 378787, 378800, 378801, 378816, 378823, 378833, 378883, 378893, 378898, 378921, 378926, 378951, 378969, 378970, 378972, 378983, 378991, 378999, 379018, 379026, 379031, 379045, 379048, 379064, 379068, 379089, 379097, 379116, 379123, 379133, 379142, 379149, 379151, 379172, 379183, 379185, 379200, 379203, 379226, 379252, 379260, 379269, 379279, 379286, 379298, 379306, 379315, 379328, 379336, 379342, 379351, 379356, 379361, 379365, 379370, 379371, 379384, 379389, 379395, 379413, 379437, 379440, 379441, 379470, 379476, 379500, 379510, 379514, 379524, 379531, 379548, 379556, 379574, 379581, 379586, 379602, 379615, 379616, 379621, 379626, 379632, 379633, 379651, 379663, 379679, 379685, 379726, 379732, 379736, 379739, 379745, 379748, 379787, 379801, 379831, 379832, 379850, 379857, 379864, 379907, 379914, 379931, 379934, 379935, 379942, 379949, 379952, 379960, 379968, 379972, 379987, 380000, 380017, 380024, 380031, 380037, 380038, 380047, 380049, 380060, 380065, 380072, 380099, 380106, 380118, 380129, 380135, 380138, 380149, 380156, 380159, 380172, 380184, 380204, 380214, 380221, 380225, 380238, 380256, 380257, 380281, 380294, 380297, 380305, 380310, 380328, 380331, 380353, 380365, 380367, 380368, 380394, 380414, 380426, 380433, 380439, 380454, 380458, 380487, 380489, 380493, 380513, 380515, 380524, 380541, 380551, 380586, 380628, 380629, 380643, 380656, 380663, 380704, 380707, 380726, 380728, 380744, 380746, 380753, 380759, 380765, 380785, 380807, 380825, 380827, 380835, 380842, 380860, 380869, 380879, 380888, 380896, 380911, 380922, 380923, 380942, 380971, 380974, 380981, 380983, 381014, 381025, 381032, 381042, 381047, 381058, 381089, 381108, 381110, 381116, 381123, 381129, 381137, 381154, 381160, 381168, 381197, 381199, 381217, 381254, 381260, 381270, 381274, 381296, 381304, 381307, 381317, 381336, 381342, 381352, 381366, 381379, 381395, 381399, 381401, 381414, 381422, 381432, 381436, 381458, 381459, 381464, 381475, 381476, 381477, 381482, 381495, 381509, 381531, 381532, 381538, 381562, 381566, 381579, 381587, 381608, 381626, 381642, 381657, 381669, 381693, 381700, 381726, 381734, 381747, 381757, 381765, 381800, 381824, 381835, 381846, 381853, 381861, 381863, 381869, 381874, 381882, 381883, 381892, 381893, 381900, 381908, 381912, 381920, 381923, 381927, 381943, 381951, 381973, 381985, 381988, 381995, 381997, 382016, 382040, 382046, 382053, 382088, 382092, 382113, 382128, 382134, 382143, 382151, 382162, 382165, 382172, 382182, 382201, 382222, 382223, 382246, 382255, 382273, 382281, 382288, 382307, 382334, 382346, 382352, 382362, 382373, 382383, 382384, 382415, 382423, 382425, 382447, 382450, 382458, 382469, 382487, 382493, 382494, 382503, 382512, 382517, 382536, 382562, 382565, 382571, 382580, 382607, 382623, 382639, 382665, 382668, 382681, 382689, 382695, 382709, 382718, 382727, 382747, 382750, 382795, 382802, 382817, 382824, 382834, 382837, 382853, 382856, 382875, 382879, 382901, 382906, 382911, 382914, 382938, 382939, 382956, 382970, 382989, 383001, 383023, 383037, 383102, 383104, 383108, 383115, 383123, 383125, 383134, 383146, 383147, 383168, 383177, 383195, 383228, 383241, 383248, 383255, 383257, 383265, 383293, 383296, 383302, 383307, 383310, 383334, 383340, 383359, 383360, 383373, 383384, 383385, 383390, 383398, 383441, 383451, 383465, 383467, 383469, 383493, 383497, 383603, 383605, 383627, 383643, 383645, 383683, 383696, 383702, 383706, 383733, 383738, 383746, 383772, 383788, 383793, 383803, 383822, 383839, 383849, 383885, 383894, 383900, 383922, 383939, 383956, 383992, 384000, 384034, 384048, 384078, 384085, 384101, 384109, 384127, 384131, 384155, 384198, 384233, 384243, 384247, 384264, 384277, 384291, 384359, 384360, 384377, 384397, 384416, 384424, 384449, 384459, 384462, 384467, 384484, 384495, 384514, 384515, 384524, 384551, 384552, 384624, 384635, 384662, 384712, 384731, 384743, 384749, 384783, 384820, 384835, 384852, 384859, 384883, 384910, 384932, 384996, 385007, 385027, 385028, 385042, 385053, 385060, 385062, 385071, 385093, 385127, 385138, 385150, 385167, 385223, 385225, 385260, 385266, 385285, 385299, 385311, 385319, 385330, 385349, 385364, 385382, 385391, 385418, 385432, 385433, 385450, 385456, 385479, 385484, 385488, 385490, 385495, 385497, 385505, 385516, 385527, 385535, 385543, 385556, 385557, 385559, 385570, 385576, 385599, 385609, 385612, 385621, 385624, 385635, 385640, 385644, 385647, 385662, 385674, 385676, 385706, 385707, 385719, 385737, 385753, 385756, 385763, 385766, 385768, 385773, 385784, 385788, 385796, 385810, 385812, 385832, 385845, 385846, 385869, 385873, 385884, 385889, 385901, 385917, 385931, 385941, 385950, 385982, 385990, 385996, 386010, 386041, 386047, 386057, 386058, 386081, 386103, 386118, 386124, 386130, 386135, 386139, 386147, 386160, 386182, 386187, 386193, 386209, 386240, 386258, 386276, 386277, 386292, 386310, 386318, 386328, 386333, 386355, 386363, 386366, 386385, 386400, 386408, 386422, 386435, 386454, 386465, 386474, 386477, 386483, 386494, 386506, 386517, 386529, 386538, 386546, 386554, 386565, 386598, 386610, 386624, 386631, 386635, 386639, 386647, 386656, 386661, 386668, 386680, 386683, 386697, 386717, 386719, 386724, 386729, 386740, 386747, 386750, 386770, 386771, 386776, 386782, 386788, 386791, 386798, 386806, 386820, 386829, 386845, 386846, 386864, 386865, 386869, 386877, 386879, 386885, 386900, 386903, 386910, 386919, 386948, 386952, 386960, 386970, 386981, 386992, 387005, 387018, 387041, 387044, 387060, 387072, 387079, 387114, 387130, 387136, 387150, 387155, 387156, 387162, 387181, 387193, 387205, 387214, 387220, 387224, 387228, 387244, 387250, 387260, 387265, 387296, 387305, 387311, 387317, 387333, 387338, 387345, 387352, 387363, 387368, 387380, 387381, 387396, 387404, 387414, 387427, 387444, 387451, 387476, 387477, 387483, 387490, 387499, 387501, 387502, 387513, 387522, 387530, 387533, 387543, 387557, 387562, 387566, 387573, 387596, 387643, 387662, 387667, 387673, 387693, 387718, 387738, 387755, 387767, 387768, 387784, 387791, 387816, 387828, 387832, 387842, 387851, 387889, 387896, 387912, 387916, 387920, 387926, 387935, 387936, 387958, 387971, 387982, 387985, 388002, 388015, 388039, 388051, 388089, 388099, 388105, 388107, 388112, 388117, 388128, 388140, 388150, 388155, 388159, 388165, 388174, 388195, 388204, 388212, 388218, 388220, 388224, 388226, 388236, 388244, 388263, 388267, 388297, 388301, 388319, 388325, 388347, 388371, 388405, 388470, 388495, 388501, 388509, 388513, 388524, 388527, 388535, 388557, 388561, 388575, 388577, 388588, 388604, 388609, 388611, 388631, 388635, 388641, 388660, 388669, 388677, 388680, 388691, 388697, 388700, 388710, 388717, 388732, 388756, 388759, 388771, 388803, 388815, 388822, 388823, 388827, 388841, 388851, 388853, 388860, 388861, 388877, 388885, 388891, 388901, 388913, 388922, 388928, 388939, 388971, 388979, 388986, 388988, 389006, 389019, 389035, 389038, 389052, 389064, 389096, 389106, 389127, 389132, 389145, 389150, 389160, 389164, 389165, 389174, 389179, 389188, 389209, 389233, 389256, 389266, 389274, 389276, 389283, 389302, 389321, 389325, 389351, 389371, 389385, 389413, 389417, 389427, 389430, 389437, 389444, 389453, 389465, 389468, 389472, 389477, 389490, 389492, 389502, 389515, 389521, 389534, 389535, 389552, 389558, 389570, 389572, 389580, 389590, 389597, 389603, 389619, 389621, 389631, 389634, 389638, 389645, 389648, 389655, 389656, 389665, 389666, 389668, 389673, 389688, 389693, 389708, 389717, 389719, 389729, 389750, 389760, 389771, 389782, 389785, 389786, 389793, 389813, 389822, 389827, 389833, 389837, 389884, 389921, 389930, 389938, 389974, 389976, 389990, 390005, 390032, 390035, 390049, 390055, 390084, 390103, 390111, 390113, 390119, 390175, 390202, 390207, 390235, 390282, 390310, 390312, 390352, 390362, 390368, 390378, 390386, 390411, 390416, 390442, 390451, 390474, 390483, 390496, 390516, 390543, 390544, 390548, 390554, 390559, 390568, 390569, 390576, 390593, 390613, 390636, 390640, 390648, 390656, 390665, 390681, 390696, 390712, 390743, 390761, 390770, 390772, 390800, 390804, 390821, 390830, 390835, 390840, 390853, 390861, 390896, 390900, 390905, 390909, 390937, 390942, 390943, 390958, 390966, 390979, 390993, 391024, 391035, 391044, 391077, 391094, 391098, 391121, 391154, 391168, 391231, 391246, 391255, 391260, 391272, 391275, 391282, 391301, 391311, 391318, 391343, 391348, 391359, 391394, 391398, 391414, 391468, 391503, 391572, 391580, 391583, 391605, 391627, 391651, 391678, 391721, 391746, 391749, 391758, 391772, 391781, 391794, 391827, 391834, 391843, 391878, 391879, 391882, 391898, 391900, 391907, 391921, 391928, 391948, 391958, 391980, 392005, 392024, 392035, 392056, 392063, 392105, 392124, 392142, 392157, 392176, 392178, 392183, 392195, 392202, 392207, 392212, 392216, 392238, 392261, 392268, 392274, 392281, 392295, 392300, 392304, 392320, 392351, 392365, 392371, 392381, 392393, 392395, 392405, 392421, 392453, 392467, 392477, 392515, 392519, 392539, 392554, 392559, 392604, 392605, 392621, 392624, 392655, 392674, 392680, 392694, 392706, 392726, 392736, 392747, 392758, 392760, 392770, 392775, 392788, 392813, 392823, 392849, 392858, 392879, 392881, 392886, 392909, 392927, 392946, 392951, 392958, 392977, 392984, 392998, 393012, 393027, 393031, 393046, 393047, 393058, 393067, 393076, 393085, 393094, 393107, 393132, 393135, 393152, 393168, 393170, 393183, 393186, 393213, 393218, 393231, 393234, 393244, 393264, 393268, 393293, 393294, 393353, 393357, 393362, 393363, 393374, 393377, 393391, 393399, 393422, 393454, 393456, 393468, 393477, 393486, 393510, 393525, 393528, 393541, 393558, 393564, 393592, 393611, 393632, 393643, 393650, 393653, 393673, 393680, 393697, 393706, 393712, 393720, 393738, 393745, 393752, 393767, 393810, 393813, 393833, 393857, 393880, 393885, 393896, 393903, 393911, 393922, 393923, 393945, 393948, 393963, 393974, 393983, 393991, 394026, 394039, 394051, 394064, 394073, 394101, 394109, 394130, 394144, 394171, 394178, 394195, 394204, 394218, 394259, 394283, 394298, 394309, 394322, 394362, 394395, 394399, 394418, 394424, 394440, 394463, 394472, 394478, 394488, 394496, 394497, 394515, 394517, 394529, 394532, 394539, 394556, 394560, 394568, 394595, 394598, 394604, 394606, 394637, 394642, 394654, 394665, 394668, 394673, 394693, 394695, 394705, 394717, 394721, 394731, 394733, 394745, 394752, 394764, 394789, 394802, 394842, 394881, 394901, 394902, 394903, 394914, 394918, 394928, 394940, 394945, 394950, 394956, 394974, 394977, 394978, 394991, 395017, 395022, 395024, 395035, 395038, 395046, 395053, 395061, 395073, 395075, 395103, 395114, 395116, 395131, 395147, 395157, 395177, 395180, 395196, 395208, 395224, 395225, 395251, 395263, 395289, 395322, 395329, 395336, 395352, 395363, 395367, 395380, 395382, 395418, 395428, 395432, 395438, 395462, 395467, 395472, 395479, 395507, 395522, 395524, 395535, 395541, 395552, 395561, 395581, 395597, 395613, 395620, 395634, 395660, 395681, 395683, 395695, 395704, 395707, 395769, 395772, 395803, 395849, 395859, 395865, 395872, 395884, 395892, 395908, 395912, 395917, 395923, 395956, 395957, 395966, 395972, 395978, 395989, 396001, 396014, 396017, 396020, 396026, 396035, 396043, 396055, 396060, 396071, 396087, 396090, 396108, 396112, 396116, 396126, 396145, 396147, 396169, 396180, 396183, 396199, 396209, 396232, 396291, 396325, 396326, 396327, 396336, 396352, 396357, 396370, 396372, 396394, 396416, 396420, 396426, 396436, 396449, 396456, 396462, 396466, 396470, 396480, 396489, 396508, 396514, 396530, 396541, 396553, 396561, 396564, 396572, 396637, 396640, 396647, 396650, 396656, 396670, 396690, 396700, 396722, 396795, 396798, 396808, 396838, 396841, 396885, 396893, 396901, 396913, 396917, 396934, 396940, 396944, 396959, 396963, 396972, 396973, 396986, 396990, 396996, 397003, 397016, 397032, 397055, 397064, 397083, 397091, 397092, 397124, 397135, 397139, 397154, 397167, 397170, 397186, 397189, 397204, 397226, 397250, 397261, 397270, 397282, 397294, 397318, 397327, 397342, 397346, 397375, 397382, 397384, 397385, 397389, 397393, 397397, 397443, 397464, 397472, 397496, 397510, 397512, 397524, 397534, 397586, 397611, 397613, 397631, 397663, 397683, 397687, 397718, 397719, 397737, 397745, 397747, 397768, 397785, 397791, 397795, 397798, 397800, 397809, 397832, 397858, 397860, 397866, 397892, 397893, 397923, 397977, 397978, 397999, 398020, 398036, 398037, 398052, 398053, 398081, 398092, 398097, 398099, 398125, 398143, 398175, 398180, 398189, 398191, 398194, 398195, 398232, 398255, 398273, 398284, 398297, 398311, 398324, 398329, 398340, 398358, 398370, 398381, 398385, 398390, 398392, 398397, 398399, 398415, 398460, 398468, 398486, 398488, 398497, 398500, 398512, 398526, 398541, 398544, 398549, 398572, 398585, 398602, 398605, 398645, 398647, 398651, 398668, 398684, 398687, 398703, 398734, 398755, 398756, 398774, 398789, 398811, 398833, 398838, 398868, 398871, 398872, 398887, 398897, 398919, 398930, 398954, 398970, 398972, 398975, 398982, 398983, 398992, 399005, 399011, 399024, 399029, 399037, 399049, 399050, 399065, 399066, 399091, 399103, 399125, 399134, 399158, 399185, 399189, 399190, 399199, 399222, 399226, 399252, 399258, 399270, 399304, 399307, 399313, 399328, 399335, 399340, 399364, 399369, 399372, 399385, 399388, 399393, 399455, 399459, 399478, 399481, 399482, 399490, 399507, 399524, 399535, 399546, 399547, 399562, 399572, 399573, 399577, 399591, 399598, 399608, 399617, 399627, 399634, 399654, 399660, 399679, 399680, 399703, 399708, 399710, 399719, 399727, 399740, 399742, 399747, 399761, 399764, 399775, 399792, 399799, 399812, 399818, 399826, 399838, 399844, 399875, 399885, 399907, 399911, 399918, 399929, 399949, 399957, 399963, 399966, 399979, 399988, 399993, 399998, 400003, 400017, 400019, 400027, 400043, 400052, 400071, 400095, 400099, 400116, 400127, 400136, 400150, 400156, 400158, 400160, 400164, 400191, 400194, 400200, 400205, 400212, 400224, 400226, 400242, 400249, 400254, 400262, 400269, 400295, 400322, 400335, 400351, 400368, 400377, 400386, 400389, 400396, 400398, 400407, 400422, 400436, 400454, 400458, 400461, 400482, 400483, 400485, 400506, 400521, 400542, 400549, 400574, 400586, 400595, 400599, 400603, 400606, 400631, 400632, 400636, 400639, 400673, 400685, 400693, 400717, 400729, 400745, 400753, 400765, 400775, 400796, 400820, 400824, 400838, 400840, 400845, 400854, 400858, 400874, 400876, 400883, 400887, 400898, 400903, 400911, 400919, 400933, 400938, 400951, 400952, 400958, 400969, 400976, 400992, 400998, 401002, 401007, 401014, 401031, 401041, 401049, 401050, 401072, 401077, 401083, 401085, 401114, 401136, 401137, 401173, 401183, 401186, 401191, 401197, 401200, 401208, 401223, 401245, 401267, 401330, 401351, 401354, 401359, 401361, 401362, 401393, 401399, 401421, 401441, 401448, 401453, 401469, 401481, 401501, 401503, 401511, 401527, 401542, 401554, 401559, 401561, 401581, 401583, 401605, 401615, 401618, 401627, 401642, 401645, 401654, 401670, 401672, 401676, 401684, 401702, 401708, 401711, 401718, 401729, 401739, 401750, 401773, 401790, 401792, 401804, 401807, 401855, 401857, 401873, 401900, 401911, 401921, 401923, 401943, 401962, 401966, 401968, 401971, 401979, 401990, 402016, 402038, 402042, 402065, 402067, 402084, 402100, 402107, 402114, 402118, 402122, 402127, 402143, 402159, 402162, 402163, 402167, 402194, 402195, 402198, 402213, 402215, 402233, 402239, 402251, 402253, 402263, 402296, 402315, 402324, 402329, 402334, 402354, 402357, 402371, 402396, 402407, 402425, 402433, 402448, 402453, 402494, 402507, 402515, 402518, 402524, 402538, 402549, 402563, 402565, 402582, 402599, 402610, 402617, 402651, 402662, 402669, 402672, 402689, 402705, 402711, 402713, 402723, 402730, 402739, 402740, 402755, 402759, 402760, 402764, 402778, 402789, 402793, 402809, 402810, 402818, 402833, 402843, 402857, 402874, 402881, 402888, 402899, 402907, 402917, 402943, 402954, 402964, 402969, 402972, 402976, 402986, 403009, 403013, 403024, 403036, 403045, 403056, 403065, 403069, 403076, 403093, 403105, 403107, 403150, 403162, 403165, 403203, 403208, 403209, 403222, 403226, 403231, 403270, 403285, 403287, 403342, 403343, 403349, 403357, 403375, 403394, 403404, 403410, 403413, 403415, 403427, 403466, 403469, 403483, 403487, 403497, 403506, 403510, 403518, 403522, 403526, 403545, 403557, 403564, 403568, 403583, 403611, 403617, 403620, 403632, 403643, 403644, 403654, 403660, 403671, 403691, 403697, 403703, 403705, 403710, 403739, 403746, 403756, 403833, 403839, 403852, 403868, 403872, 403875, 403884, 403911, 403931, 403935, 403951, 403953, 403955, 403960, 403966, 403971, 403978, 403993, 404004, 404008, 404027, 404030, 404036, 404041, 404049, 404062, 404079, 404089, 404119, 404127, 404163, 404166, 404180, 404204, 404209, 404219, 404228, 404247, 404250, 404260, 404262, 404264, 404275, 404276, 404296, 404298, 404300, 404316, 404329, 404336, 404348, 404351, 404380, 404382, 404384, 404391, 404395, 404410, 404416, 404433, 404435, 404436, 404440, 404453, 404454, 404470, 404480, 404482, 404487, 404488, 404492, 404494, 404500, 404501, 404506, 404528, 404535, 404556, 404565, 404583, 404607, 404618, 404624, 404636, 404650, 404669, 404673, 404685, 404694, 404702, 404711, 404720, 404730, 404739, 404743, 404746, 404748, 404752, 404774, 404790, 404791, 404794, 404811, 404820, 404829, 404831, 404834, 404841, 404854, 404857, 404860, 404874, 404882, 404884, 404894, 404895, 404899, 404915, 404923, 404926, 404939, 404947, 404952, 404976, 404983, 404987, 404996, 404997, 405016, 405031, 405032, 405038, 405043, 405047, 405050, 405055, 405058, 405069, 405080, 405083, 405093, 405094, 405098, 405115, 405124, 405146, 405147, 405151, 405156, 405170, 405185, 405189, 405213, 405260, 405261, 405267, 405277, 405286, 405294, 405315, 405336, 405359, 405378, 405392, 405395, 405400, 405403, 405406, 405418, 405422, 405429, 405432, 405440, 405442, 405450, 405472, 405488, 405492, 405500, 405507, 405519, 405520, 405523, 405526, 405527, 405539, 405548, 405557, 405566, 405577, 405586, 405587, 405618, 405621, 405635, 405640, 405650, 405653, 405658, 405663, 405673, 405676, 405692, 405694, 405697, 405702, 405706, 405727, 405736, 405744, 405751, 405772, 405779, 405793, 405800, 405804, 405814, 405831, 405843, 405846, 405863, 405870, 405884, 405895, 405900, 405911, 405913, 405916, 405930, 405943, 405961, 405979, 405987, 405994, 406014, 406045, 406062, 406068, 406082, 406090, 406095, 406096, 406109, 406127, 406129, 406144, 406148, 406157, 406193, 406195, 406200, 406213, 406226, 406232, 406246, 406248, 406250, 406257, 406268, 406271, 406276, 406280, 406297, 406302, 406307, 406321, 406326, 406337, 406343, 406346, 406359, 406388, 406400, 406409, 406410, 406425, 406435, 406440, 406443, 406446, 406456, 406476, 406481, 406493, 406502, 406514, 406521, 406531, 406540, 406545, 406546, 406608, 406614, 406639, 406657, 406671, 406681, 406701, 406712, 406714, 406717, 406736, 406744, 406763, 406778, 406790, 406796, 406823, 406826, 406828, 406853, 406883, 406887, 406895, 406896, 406898, 406917, 406929, 406930, 406943, 406958, 406970, 406973, 406984, 406986, 407000, 407001, 407019, 407022, 407025, 407030, 407035, 407048, 407057, 407065, 407072, 407074, 407077, 407078, 407091, 407116, 407118, 407122, 407163, 407164, 407165, 407174, 407179, 407198, 407201, 407215, 407216, 407218, 407243, 407244, 407259, 407322, 407347, 407354, 407358, 407411, 407412, 407419, 407422, 407426, 407434, 407438, 407445, 407450, 407464, 407466, 407476, 407478, 407511, 407527, 407547, 407557, 407565, 407583, 407584, 407589, 407605, 407608, 407622, 407630, 407635, 407663, 407687, 407691, 407693, 407702, 407705, 407710, 407713, 407716, 407721, 407761, 407770, 407781, 407797, 407803, 407809, 407813, 407815, 407824, 407830, 407848, 407853, 407860, 407865, 407873, 407891, 407892, 407901, 407906, 407932, 407945, 407947, 407958, 407967, 407970, 407971, 407972, 407974, 407978, 407989, 407991, 407995, 407997, 408007, 408018, 408021, 408031, 408041, 408052, 408061, 408063, 408070, 408073, 408084, 408088, 408100, 408103, 408105, 408115, 408130, 408136, 408140, 408181, 408189, 408190, 408196, 408207, 408214, 408227, 408231, 408242, 408253, 408254, 408260, 408274, 408284, 408300, 408314, 408324, 408331, 408347, 408354, 408355, 408378, 408399, 408406, 408409, 408418, 408425, 408426, 408435, 408439, 408452, 408465, 408492, 408493, 408497, 408503, 408508, 408513, 408547, 408550, 408557, 408559, 408578, 408597, 408610, 408639, 408644, 408654, 408661, 408665, 408679, 408680, 408699, 408726, 408735, 408749, 408781, 408790, 408793, 408812, 408815, 408835, 408840, 408842, 408850, 408880, 408892, 408901, 408918, 408922, 408953, 408961, 408988, 409007, 409008, 409033, 409035, 409036, 409061, 409089, 409091, 409097, 409105, 409114, 409115, 409121, 409126, 409135, 409144, 409161, 409182, 409186, 409190, 409198, 409201, 409204, 409216, 409222, 409233, 409241, 409244, 409246, 409252, 409255, 409264, 409270, 409283, 409289, 409290, 409291, 409304, 409330, 409334, 409336, 409345, 409355, 409358, 409377, 409387, 409404, 409414, 409425, 409439, 409443, 409449, 409455, 409460, 409461, 409474, 409477, 409486, 409489, 409495, 409496, 409506, 409524, 409538, 409539, 409547, 409552, 409553, 409565, 409578, 409588, 409592, 409595, 409598, 409622, 409635, 409696, 409704, 409717, 409718, 409760, 409771, 409777, 409785, 409795, 409810, 409811, 409814, 409821, 409827, 409850, 409864, 409870, 409877, 409881, 409892, 409894, 409909, 409920, 409931, 409934, 409940, 409945, 409948, 409950, 409969, 409980, 410005, 410009, 410020, 410036, 410039, 410045, 410082, 410094, 410118, 410150, 410160, 410175, 410190, 410217, 410222, 410232, 410248, 410267, 410282, 410301, 410302, 410303, 410349, 410352, 410359, 410369, 410370, 410378, 410386, 410391, 410402, 410405, 410417, 410423, 410425, 410426, 410448, 410457, 410467, 410476, 410483, 410493, 410498, 410519, 410527, 410541, 410553, 410556, 410560, 410572, 410574, 410591, 410596, 410612, 410615, 410625, 410627, 410628, 410632, 410647, 410648, 410665, 410670, 410676, 410680, 410681, 410701, 410702, 410704, 410718, 410727, 410740, 410742, 410743, 410746, 410754, 410759, 410768, 410774, 410775, 410783, 410792, 410798, 410804, 410806, 410810, 410834, 410844, 410860, 410867, 410869, 410871, 410885, 410895, 410913, 410919, 410928, 410944, 410964, 410979, 411000, 411003, 411024, 411025, 411028, 411035, 411064, 411069, 411086, 411099, 411120, 411124, 411137, 411145, 411154, 411164, 411167, 411173, 411190, 411195, 411201, 411214, 411218, 411226, 411232, 411242, 411251, 411253, 411286, 411298, 411319, 411322, 411335, 411368, 411388, 411390, 411395, 411398, 411399, 411404, 411405, 411410, 411442, 411488, 411511, 411521, 411523, 411530, 411535, 411539, 411540, 411548, 411558, 411561, 411565, 411580, 411582, 411591, 411603, 411607, 411609, 411620, 411621, 411625, 411635, 411649, 411660, 411698, 411702, 411709, 411710, 411718, 411726, 411730, 411745, 411748, 411760, 411761, 411765, 411771, 411784, 411789, 411800, 411808, 411813, 411818, 411823, 411830, 411835, 411839, 411848, 411856, 411873, 411881, 411889, 411898, 411910, 411918, 411919, 411948, 411950, 411966, 411989, 412023, 412024, 412043, 412053, 412055, 412065, 412070, 412073, 412077, 412102, 412118, 412126, 412127, 412168, 412174, 412188, 412196, 412197, 412206, 412220, 412233, 412250, 412257, 412270, 412285, 412300, 412311, 412313, 412321, 412327, 412334, 412341, 412351, 412354, 412355, 412365, 412371, 412372, 412377, 412380, 412381, 412403, 412431, 412446, 412459, 412472, 412475, 412482, 412491, 412493, 412514, 412549, 412553, 412558, 412570, 412585, 412591, 412597, 412600, 412602, 412621, 412631, 412640, 412650, 412651, 412655, 412685, 412689, 412703, 412709, 412715, 412728, 412730, 412732, 412748, 412751, 412789, 412797, 412809, 412815, 412841, 412848, 412865, 412867, 412875, 412878, 412891, 412904, 412912, 412926, 412943, 412945, 412951, 412958, 412967, 412971, 412979, 412982, 413019, 413026, 413027, 413030, 413051, 413057, 413061, 413070, 413081, 413092, 413097, 413112, 413120, 413121, 413127, 413145, 413158, 413165, 413169, 413179, 413190, 413195, 413204, 413210, 413222, 413226, 413229, 413231, 413243, 413244, 413253, 413259, 413274, 413277, 413280, 413287, 413290, 413297, 413299, 413303, 413327, 413339, 413340, 413343, 413354, 413359, 413378, 413418, 413426, 413435, 413454, 413464, 413471, 413521, 413553, 413564, 413573, 413589, 413598, 413605, 413611, 413615, 413625, 413633, 413642, 413649, 413652, 413668, 413671, 413677, 413682, 413683, 413687, 413691, 413698, 413708, 413728, 413731, 413750, 413754, 413755, 413764, 413782, 413789, 413805, 413820, 413836, 413842, 413856, 413866, 413870, 413891, 413908, 413915, 413952, 413962, 413966, 413975, 413976, 413994, 414011, 414025, 414028, 414037, 414040, 414047, 414048, 414061, 414062, 414065, 414072, 414082, 414092, 414093, 414101, 414104, 414119, 414127, 414128, 414137, 414141, 414146, 414158, 414168, 414176, 414181, 414192, 414194, 414195, 414205, 414209, 414212, 414218, 414223, 414230, 414237, 414243, 414247, 414254, 414258, 414263, 414267, 414282, 414286, 414289, 414291, 414296, 414302, 414304, 414320, 414322, 414325, 414328, 414329, 414334, 414335, 414353, 414355, 414371, 414375, 414379, 414383, 414387, 414398, 414424, 414430, 414446, 414466, 414469, 414473, 414483, 414514, 414520, 414542, 414546, 414551, 414562, 414568, 414578, 414585, 414589, 414602, 414606, 414616, 414622, 414643, 414655, 414665, 414670, 414681, 414684, 414688, 414690, 414710, 414715, 414719, 414723, 414737, 414751, 414758, 414773, 414802, 414810, 414811, 414812, 414824, 414827, 414831, 414837, 414843, 414847, 414872, 414875, 414878, 414910, 414914, 414917, 414941, 414946, 414962, 414966, 414969, 414989, 414990, 415013, 415019, 415021, 415025, 415035, 415042, 415045, 415052, 415053, 415058, 415059, 415063, 415069, 415127, 415164, 415175, 415180, 415187, 415196, 415209, 415210, 415262, 415296, 415307, 415325, 415343, 415348, 415356, 415358, 415370, 415373, 415402, 415404, 415419, 415428, 415439, 415465, 415502, 415508, 415512, 415517, 415539, 415549, 415556, 415564, 415568, 415584, 415595, 415599, 415607, 415620, 415639, 415650, 415653, 415691, 415707, 415708, 415715, 415723, 415746, 415749, 415753, 415760, 415768, 415773, 415783, 415786, 415794, 415803, 415804, 415823, 415829, 415839, 415847, 415850, 415852, 415856, 415865, 415871, 415872, 415883, 415900, 415916, 415942, 415968, 415982, 415987, 415993, 415996, 416012, 416013, 416017, 416020, 416022, 416032, 416035, 416044, 416045, 416063, 416069, 416077, 416098, 416103, 416115, 416129, 416137, 416141, 416142, 416164, 416166, 416170, 416178, 416199, 416209, 416212, 416246, 416270, 416279, 416292, 416300, 416305, 416321, 416340, 416356, 416362, 416366, 416371, 416376, 416382, 416407, 416415, 416416, 416428, 416436, 416437, 416439, 416440, 416447, 416448, 416458, 416459, 416485, 416486, 416501, 416502, 416508, 416509, 416511, 416516, 416520, 416525, 416527, 416544, 416547, 416553, 416596, 416599, 416635, 416638, 416648, 416652, 416655, 416658, 416665, 416669, 416695, 416696, 416699, 416717, 416733, 416746, 416763, 416765, 416768, 416787, 416788, 416793, 416813, 416823, 416844, 416847, 416853, 416857, 416866, 416880, 416881, 416897, 416910, 416924, 416932, 416937, 416946, 416953, 416962, 416968, 416979, 417008, 417057, 417058, 417061, 417087, 417094, 417103, 417115, 417126, 417128, 417146, 417176, 417193, 417201, 417211, 417212, 417214, 417235, 417238, 417265, 417272, 417275, 417284, 417285, 417291, 417293, 417295, 417298, 417299, 417344, 417350, 417357, 417374, 417381, 417390, 417391, 417421, 417428, 417433, 417434, 417456, 417458, 417459, 417473, 417487, 417488, 417490, 417494, 417512, 417536, 417539, 417543, 417555, 417564, 417567, 417579, 417586, 417590, 417599, 417606, 417608, 417615, 417622, 417626, 417629, 417639, 417648, 417652, 417666, 417684, 417695, 417697, 417698, 417724, 417740, 417745, 417749, 417756, 417762, 417767, 417772, 417774, 417788, 417794, 417799, 417811, 417814, 417817, 417822, 417828, 417837, 417842, 417848, 417920, 417933, 417953, 417954, 417955, 417973, 418002, 418017, 418028, 418030, 418070, 418087, 418105, 418114, 418116, 418121, 418122, 418142, 418148, 418153, 418158, 418175, 418179, 418188, 418206, 418213, 418234, 418241, 418244, 418247, 418254, 418257, 418263, 418274, 418275, 418295, 418312, 418318, 418322, 418325, 418357, 418375, 418397, 418404, 418457, 418468, 418474, 418478, 418488, 418492, 418532, 418545, 418551, 418558, 418569, 418584, 418585, 418602, 418613, 418623, 418628, 418630, 418638, 418666, 418667, 418669, 418699, 418706, 418707, 418745, 418765, 418769, 418776, 418783, 418788, 418802, 418810, 418816, 418821, 418826, 418845, 418847, 418849, 418871, 418884, 418886, 418887, 418899, 418908, 418910, 418912, 418920, 418936, 418963, 418991, 419005, 419027, 419035, 419040, 419073, 419078, 419088, 419102, 419106, 419128, 419132, 419136, 419137, 419171, 419178, 419181, 419182, 419183, 419191, 419206, 419208, 419211, 419212, 419215, 419226, 419228, 419242, 419245, 419275, 419281, 419287, 419312, 419325, 419338, 419345, 419363, 419377, 419378, 419379, 419383, 419396, 419398, 419400, 419413, 419429, 419434, 419447, 419454, 419466, 419476, 419478, 419482, 419486, 419487, 419492, 419507, 419511, 419512, 419514, 419522, 419536, 419543, 419545, 419553, 419558, 419567, 419578, 419587, 419619, 419628, 419639, 419651, 419664, 419705, 419707, 419715, 419718, 419729, 419737, 419748, 419749, 419752, 419760, 419766, 419780, 419813, 419821, 419837, 419843, 419844, 419849, 419852, 419855, 419865, 419871, 419881, 419887, 419901, 419909, 419912, 419920, 419927, 419949, 419955, 419961, 419965, 419969, 419976, 419987, 419989, 420011, 420019, 420025, 420058, 420059, 420080, 420092, 420100, 420101, 420114, 420128, 420140, 420151, 420152, 420158, 420160, 420179, 420194, 420211, 420218, 420230, 420241, 420253, 420254, 420268, 420271, 420287, 420300, 420306, 420313, 420319, 420335, 420339, 420351, 420360, 420364, 420365, 420371, 420374, 420385, 420404, 420411, 420415, 420430, 420453, 420462, 420483, 420484, 420489, 420500, 420508, 420512, 420514, 420533, 420562, 420571, 420580, 420582, 420583, 420588, 420630, 420638, 420640, 420647, 420660, 420675, 420682, 420693, 420696, 420698, 420703, 420716, 420768, 420773, 420806, 420813, 420817, 420823, 420826, 420830, 420835, 420844, 420853, 420857, 420863, 420870, 420881, 420894, 420898, 420912, 420924, 420928, 420950, 420951, 420953, 420954, 420966, 420972, 420980, 420984, 420989, 420997, 421011, 421029, 421040, 421046, 421054, 421063, 421066, 421068, 421087, 421090, 421107, 421116, 421118, 421129, 421135, 421137, 421162, 421166, 421176, 421182, 421186, 421193, 421195, 421201, 421219, 421225, 421234, 421238, 421241, 421245, 421247, 421257, 421261, 421267, 421291, 421301, 421316, 421336, 421346, 421384, 421391, 421398, 421407, 421421, 421441, 421462, 421466, 421468, 421476, 421483, 421494, 421505, 421506, 421514, 421518, 421526, 421527, 421548, 421553, 421554, 421561, 421573, 421584, 421606, 421611, 421615, 421633, 421644, 421647, 421656, 421658, 421661, 421677, 421680, 421690, 421705, 421714, 421724, 421730, 421734, 421745, 421746, 421753, 421756, 421760, 421771, 421775, 421776, 421779, 421788, 421802, 421824, 421825, 421830, 421836, 421864, 421869, 421872, 421876, 421882, 421921, 421926, 421928, 421929, 421933, 421936, 421944, 421954, 421962, 421975, 421981, 422003, 422017, 422023, 422031, 422045, 422057, 422059, 422081, 422084, 422092, 422097, 422100, 422101, 422103, 422107, 422109, 422123, 422124, 422133, 422135, 422140, 422142, 422148, 422154, 422158, 422163, 422166, 422178, 422180, 422188, 422193, 422213, 422227, 422233, 422240, 422241, 422247, 422255, 422277, 422308, 422322, 422329, 422343, 422346, 422366, 422370, 422374, 422381, 422385, 422386, 422407, 422410, 422416, 422430, 422438, 422440, 422451, 422455, 422456, 422482, 422484, 422491, 422517, 422524, 422534, 422544, 422545, 422546, 422550, 422557, 422558, 422559, 422584, 422585, 422597, 422599, 422603, 422615, 422632, 422641, 422661, 422663, 422674, 422676, 422694, 422696, 422717, 422719, 422723, 422732, 422734, 422747, 422753, 422761, 422762, 422769, 422784, 422791, 422801, 422803, 422808, 422819, 422823, 422838, 422849, 422850, 422869, 422874, 422884, 422896, 422904, 422905, 422907, 422915, 422939, 422942, 422943, 422955, 422960, 422983, 422993, 422994, 423000, 423023, 423032, 423055, 423058, 423072, 423082, 423083, 423087, 423094, 423095, 423099, 423100, 423103, 423104, 423120, 423123, 423126, 423130, 423133, 423143, 423148, 423158, 423161, 423177, 423181, 423183, 423200, 423201, 423205, 423250, 423265, 423287, 423291, 423295, 423310, 423329, 423335, 423354, 423357, 423365, 423366, 423372, 423379, 423400, 423401, 423410, 423413, 423431, 423432, 423437, 423445, 423451, 423463, 423466, 423471, 423480, 423489, 423498, 423499, 423509, 423516, 423525, 423527, 423529, 423545, 423559, 423566, 423572, 423574, 423581, 423582, 423587, 423590, 423594, 423599, 423607, 423612, 423616, 423629, 423650, 423653, 423657, 423661, 423683, 423707, 423712, 423734, 423735, 423740, 423745, 423778, 423788, 423814, 423822, 423825, 423848, 423863, 423873, 423884, 423893, 423896, 423899, 423916, 423918, 423936, 423949, 423955, 423967, 423986, 424004, 424007, 424009, 424011, 424016, 424021, 424024, 424035, 424038, 424042, 424060, 424068, 424081, 424083, 424101, 424103, 424106, 424127, 424134, 424168, 424175, 424176, 424181, 424204, 424224, 424226, 424257, 424269, 424282, 424284, 424292, 424303, 424308, 424309, 424311, 424322, 424324, 424326, 424331, 424367, 424383, 424390, 424409, 424411, 424440, 424444, 424452, 424456, 424458, 424461, 424473, 424475, 424476, 424485, 424494, 424514, 424518, 424522, 424531, 424552, 424554, 424574, 424582, 424584, 424595, 424613, 424614, 424629, 424638, 424645, 424654, 424658, 424659, 424662, 424667, 424678, 424685, 424690, 424692, 424694, 424738, 424745, 424756, 424764, 424774, 424787, 424807, 424829, 424834, 424843, 424854, 424859, 424871, 424888, 424892, 424895, 424901, 424915, 424921, 424939, 424948, 424953, 424974, 424985, 424994, 425005, 425015, 425022, 425035, 425038, 425043, 425050, 425052, 425070, 425080, 425087, 425092, 425112, 425118, 425119, 425120, 425131, 425135, 425138, 425142, 425153, 425161, 425199, 425202, 425246, 425249, 425255, 425264, 425272, 425282, 425284, 425289, 425313, 425321, 425325, 425342, 425362, 425363, 425364, 425409, 425412, 425414, 425448, 425453, 425474, 425492, 425503, 425534, 425536, 425538, 425546, 425554, 425557, 425568, 425595, 425635, 425639, 425643, 425661, 425675, 425679, 425690, 425692, 425696, 425701, 425703, 425729, 425753, 425758, 425763, 425772, 425775, 425776, 425780, 425791, 425792, 425798, 425804, 425810, 425816, 425840, 425842, 425850, 425861, 425874, 425877, 425896, 425897, 425898, 425907, 425916, 425918, 425923, 425930, 425938, 425944, 425946, 425953, 425962, 425963, 425978, 425992, 425994, 426008, 426017, 426031, 426040, 426048, 426052, 426081, 426086, 426088, 426111, 426112, 426123, 426124, 426134, 426137, 426145, 426150, 426160, 426171, 426179, 426181, 426184, 426196, 426215, 426220, 426232, 426246, 426257, 426261, 426276, 426283, 426284, 426298, 426302, 426307, 426308, 426320, 426329, 426342, 426354, 426357, 426361, 426368, 426374, 426380, 426392, 426399, 426416, 426421, 426426, 426432, 426448, 426451, 426458, 426475, 426484, 426494, 426495, 426498, 426501, 426517, 426528, 426537, 426569, 426586, 426594, 426600, 426603, 426608, 426615, 426622, 426627, 426654, 426665, 426668, 426675, 426682, 426685, 426687, 426700, 426710, 426711, 426732, 426736, 426760, 426774, 426783, 426795, 426801, 426818, 426820, 426847, 426856, 426861, 426866, 426868, 426871, 426897, 426914, 426923, 426929, 426931, 426933, 426934, 426941, 426944, 426953, 426973, 426984, 426985, 426992, 426994, 426999, 427001, 427005, 427015, 427029, 427033, 427039, 427043, 427053, 427054, 427057, 427070, 427072, 427092, 427093, 427106, 427124, 427139, 427144, 427153, 427154, 427156, 427162, 427166, 427169, 427174, 427205, 427210, 427215, 427216, 427252, 427276, 427300, 427305, 427340, 427354, 427358, 427364, 427420, 427439, 427468, 427476, 427482, 427485, 427489, 427496, 427508, 427510, 427516, 427526, 427538, 427550, 427556, 427631, 427633, 427643, 427646, 427650, 427660, 427702, 427729, 427739, 427758, 427768, 427771, 427778, 427779, 427788, 427799, 427802, 427813, 427819, 427821, 427824, 427830, 427835, 427847, 427849, 427859, 427871, 427885, 427898, 427899, 427907, 427915, 427916, 427928, 427936, 427952, 427959, 427968, 427972, 427977, 427981, 427986, 427992, 428002, 428004, 428006, 428048, 428050, 428059, 428070, 428080, 428083, 428093, 428104, 428119, 428130, 428140, 428142, 428153, 428166, 428176, 428179, 428183, 428186, 428198, 428201, 428203, 428221, 428228, 428241, 428243, 428250, 428256, 428260, 428279, 428291, 428307, 428318, 428324, 428336, 428344, 428348, 428365, 428375, 428388, 428393, 428402, 428411, 428415, 428420, 428436, 428440, 428453, 428460, 428479, 428518, 428539, 428545, 428556, 428573, 428585, 428610, 428616, 428618, 428624, 428634, 428649, 428650, 428669, 428697, 428698, 428701, 428728, 428744, 428753, 428756, 428762, 428772, 428773, 428784, 428792, 428796, 428798, 428802, 428812, 428818, 428823, 428832, 428845, 428850, 428853, 428857, 428867, 428871, 428880, 428894, 428908, 428919, 428925, 428943, 428959, 428962, 428966, 428978, 428990, 428995, 429034, 429039, 429053, 429063, 429067, 429091, 429096, 429114, 429118, 429124, 429126, 429143, 429149, 429169, 429177, 429180, 429196, 429198, 429208, 429225, 429230, 429232, 429239, 429244, 429258, 429269, 429272, 429286, 429296, 429301, 429314, 429316, 429341, 429343, 429346, 429347, 429355, 429359, 429365, 429366, 429369, 429371, 429375, 429379, 429390, 429393, 429424, 429426, 429444, 429450, 429458, 429463, 429467, 429484, 429488, 429502, 429522, 429525, 429527, 429537, 429542, 429555, 429560, 429564, 429570, 429839, 429849, 429851, 429860, 429866, 429883, 429884, 429889, 429899, 429903, 429905, 429924, 429931, 429933, 429940, 429944, 429949, 429954, 429956, 429973, 429980, 429987, 429988, 429990, 429998, 430004, 430018, 430020, 430023, 430026, 430028, 430040, 430046, 430052, 430056, 430063, 430065, 430067, 430071, 430073, 430076, 430089, 430097, 430108, 430112, 430128, 430133, 430138, 430152, 430163, 430168, 430172, 430178, 430186, 430190, 430194, 430203, 430205, 430221, 430224, 430226, 430228, 430237, 430258, 430277, 430301, 430318, 430320, 430326, 430335, 430355, 430368, 430369, 430373, 430382, 430389, 430394, 430400, 430411, 430418, 430432, 430459, 430461, 430470, 430476, 430477, 430482, 430487, 430490, 430498, 430508, 430516, 430522, 430531, 430534, 430545, 430556, 430562, 430563, 430572, 430578, 430582, 430591, 430603, 430604, 430608, 430613, 430621, 430626, 430627, 430628, 430636, 430639, 430640, 430643, 430645, 430654, 430658, 430660, 430673, 430674, 430677, 430680, 430684, 430689, 430696, 430706, 430713, 430721, 430728, 430733, 430736, 430750, 430751, 430759, 430767, 430786, 430794, 430808, 430814, 430818, 430821, 430826, 430829, 430831, 430835, 430839, 430858, 430863, 430880, 430888, 430890, 430897, 430900, 430914, 430915, 430917, 430920, 430924, 430933, 430934, 430937, 430941, 430952, 430968, 430971, 430975, 430980, 430987, 430989, 430993, 431006, 431014, 431019, 431025, 431026, 431030, 431039, 431054, 431064, 431074, 431075, 431091, 431107, 431120, 431123, 431128, 431129, 431132, 431137, 431159, 431163, 431168, 431173, 431180, 431188, 431194, 431204, 431205, 431208, 431214, 431219, 431224, 431236, 431242, 431247, 431253, 431258, 431260, 431261, 431272, 431275, 431276, 431279, 431296, 431315, 431318, 431323, 431328, 431335, 431337, 431347, 431351, 431361, 431376, 431382, 431383, 431387, 431408, 431409, 431410, 431419, 431422, 431435, 431441, 431458, 431463, 431468, 431476, 431491, 431492, 431497, 431498, 431512, 431518, 431525, 431526, 431536, 431567, 431580, 431582, 431590, 431609, 431619, 431623, 431630, 431635, 431636, 431644, 431645, 431657, 431658, 431667, 431678, 431685, 431688, 431699, 431700, 431705, 431707, 431710, 431718, 431726, 431728, 431736, 431743, 431750, 431754, 431784, 431805, 431815, 431828, 431835, 431837, 431844, 431847, 431849, 431852, 431856, 431859, 431874, 431887, 431889, 431892, 431898, 431919, 431923, 431929, 431938, 431939, 431957, 431965, 431975, 431978, 432000, 432001, 432012, 432023, 432029, 432042, 432058, 432061, 432067, 432073, 432074, 432077, 432084, 432093, 432096, 432103, 432110, 432120, 432123, 432144, 432151, 432156, 432170, 432171, 432184, 432190, 432196, 432200, 432205, 432209, 432212, 432225, 432227, 432229, 432235, 432242, 432245, 432250, 432254, 432264, 432268, 432281, 432282, 432289, 432294, 432296, 432304, 432309, 432313, 432316, 432326, 432331, 432333, 432339, 432345, 432352, 432356, 432360, 432368, 432376, 432383, 432386, 432391, 432404, 432410, 432415, 432419, 432423, 432428, 432441, 432450, 432456, 432462, 432465, 432470, 432475, 432480, 432492, 432501, 432515, 432528, 432533, 432536, 432543, 432546, 432553, 432558, 432569, 432584, 432586, 432593, 432599, 432602, 432604, 432608, 432618, 432620, 432624, 432634, 432644, 432648, 432654, 432660, 432667, 432673, 432686, 432702, 432705, 432712, 432717, 432720, 432728, 432744, 432745, 432762, 432764, 432765, 432780, 432786, 432788, 432809, 432821, 432846, 432866, 432867, 432872, 432901, 432904, 432908, 432911, 432919, 432934, 432941, 432953, 432970, 432973, 432977, 432983, 432998, 433008, 433012, 433023, 433030, 433035, 433047, 433051, 433060, 433066, 433074, 433081, 433085, 433094, 433106, 433109, 433115, 433126, 433130, 433136, 433139, 433156, 433159, 433163, 433169, 433177, 433190, 433196, 433201, 433207, 433213, 433219, 433222, 433225, 433230, 433246, 433254, 433257, 433260, 433266, 433270, 433277, 433278, 433284, 433285, 433293, 433298, 433306, 433320, 433328, 433331, 433346, 433349, 433355, 433360, 433365, 433370, 433375, 433387, 433397, 433403, 433406, 433408, 433412, 433415, 433417, 433422, 433436, 433446, 433449, 433453, 433456, 433475, 433484, 433488, 433491, 433498, 433514, 433515, 433526, 433528, 433533, 433544, 433569, 433573, 433586, 433591, 433598, 433614, 433619, 433623, 433625, 433629, 433632, 433633, 433637, 433646, 433652, 433658, 433661, 433668, 433675, 433679, 433681, 433688, 433692, 433697, 433704, 433705, 433714, 433717, 433727, 433730, 433736, 433743, 433748, 433752, 433772, 433775, 433777, 433781, 433788, 433796, 433808, 433816, 433821, 433828, 433833, 433836, 433854, 433860, 433864, 433866, 433880, 433886, 433895, 433899, 433901, 433914, 433923, 433931, 433938, 433945, 433948, 433955, 433963, 433972, 433977, 433981, 433984, 433987, 433993, 434005, 434011, 434013, 434019, 434023, 434028, 434035, 434042, 434045, 434047, 434049, 434052, 434066, 434081, 434084, 434087, 434093, 434097, 434104, 434106, 434110, 434116, 434120, 434132, 434144, 434145, 434151, 434162, 434167, 434171, 434177, 434182, 434190, 434196, 434204, 434220, 434237, 434263, 434267, 434272, 434293, 434310, 434315, 434326, 434331, 434334, 434345, 434383, 434397, 434402, 434406, 434409, 434416, 434424, 434428, 434433, 434434, 434435, 434461, 434468, 434470, 434471, 434473, 434474, 434479, 434489, 434490, 434499, 434501, 434514, 434525, 434529, 434536, 434541, 434545, 434546, 434551, 434556, 434561, 434562, 434566, 434575, 434581, 434582, 434586, 434589, 434592, 434598, 434603, 434607, 434614, 434628, 434631, 434649, 434650, 434651, 434658, 434664, 434670, 434674, 434680, 434687, 434690, 434705, 434711, 434716, 434721, 434727, 434732, 434746, 434751, 434753, 434761, 434765, 434766, 434769, 434795, 434796, 434802, 434804, 434808, 434815, 434816, 434820, 434823, 434824, 434831, 434839, 434857, 434858, 434870, 434872, 434877, 434880, 434886, 434896, 434912, 434914, 434923, 434926, 434935, 434966, 434973, 434977, 434978, 434992, 434995, 434998, 435004, 435012, 435016, 435025, 435026, 435031, 435036, 435037, 435039, 435048, 435055, 435067, 435071, 435074, 435082, 435086, 435092, 435102, 435105, 435107, 435120, 435137, 435143, 435166, 435188, 435233, 435245, 435246, 435256, 435257, 435258, 435278, 435285, 435291, 435302, 435327, 435330, 435334, 435347, 435352, 435360, 435361, 435372, 435376, 435378, 435379, 435381, 435389, 435396, 435406, 435407, 435413, 435422, 435429, 435432, 435434, 435448, 435454, 435468, 435471, 435491, 435496, 435526, 435564, 435570, 435575, 435579, 435623, 435628, 435631, 435635, 435663, 435664, 435676, 435677, 435702, 435714, 435725, 435726, 435728, 435736, 435738, 435744, 435754, 435755, 435760, 435772, 435778, 435780, 435802, 435806, 435807, 435808, 435812, 435813, 435835, 435855, 435873, 435884, 435889, 435905, 435925, 435926, 435938, 435950, 435955, 435956, 435963, 435966, 435967, 435999, 436001, 436006, 436017, 436027, 436030, 436033, 436037, 436038, 436040, 436052, 436063, 436075, 436076, 436087, 436095, 436107, 436109, 436110, 436115, 436117, 436122, 436125, 436127, 436134, 436143, 436147, 436154, 436163, 436164, 436165, 436172, 436185, 436188, 436196, 436202, 436203, 436211, 436214, 436216, 436224, 436227, 436231, 436235, 436238, 436254, 436256, 436257, 436258, 436264, 436298, 436307, 436314, 436325, 436336, 436345, 436354, 436355, 436356, 436368, 436377, 436384, 436385, 436396, 436412, 436419, 436432, 436438, 436464, 436470, 436581, 436604, 436641, 436657, 436675, 436680, 436686, 436688, 436692, 436694, 436702, 436718, 436721, 436733, 436734, 436738, 436741, 436748, 436751, 436759, 436767, 436768, 436777, 436796, 436803, 436815, 436818, 436821, 436831, 436834, 436845, 436856, 436861, 436863, 436868, 436873, 436878, 436879, 436880, 436885, 436886, 436891, 436896, 436898, 436900, 436901, 436906, 436909, 436910, 436915, 436921, 436926, 436927, 436929, 436936, 436937, 436954, 436955, 436986, 436990, 436994, 437007, 437009, 437018, 437028, 437030, 437037, 437041, 437045, 437062, 437070, 437084, 437086, 437097, 437098, 437104, 437110, 437113, 437125, 437131, 437133, 437134, 437137, 437144, 437160, 437164, 437173, 437175, 437182, 437195, 437205, 437219, 437229, 437233, 437243, 437253, 437256, 437259, 437270, 437273, 437275, 437291, 437294, 437307, 437310, 437313, 437315, 437327, 437328, 437339, 437341, 437362, 437368, 437387, 437388, 437394, 437409, 437411, 437426, 437440, 437452, 437455, 437462, 437466, 437468, 437476, 437477, 437482, 437496, 437503, 437510, 437515, 437518, 437533, 437547, 437553, 437578, 437589, 437605, 437610, 437615, 437617, 437620, 437662, 437663, 437669, 437682, 437685, 437693, 437719, 437728, 437729, 437735, 437740, 437749, 437759, 437767, 437771, 437772, 437777, 437782, 437793, 437800, 437813, 437816, 437818, 437825, 437835, 437836, 437841, 437849, 437874, 437883, 437887, 437888, 437893, 437897, 437905, 437909, 437911, 437918, 437922, 437947, 437968, 437970, 437979, 437991, 437992, 437993, 437995, 438002, 438005, 438011, 438031, 438038, 438040, 438056, 438067, 438071, 438078, 438080, 438088, 438093, 438097, 438101, 438102, 438113, 438115, 438120, 438125, 438129, 438130, 438139, 438143, 438159, 438164, 438168, 438185, 438190, 438193, 438194, 438196, 438197, 438201, 438207, 438208, 438215, 438216, 438218, 438220, 438222, 438228, 438231, 438236, 438239, 438240, 438244, 438254, 438256, 438257, 438264, 438267, 438272, 438273, 438275, 438288, 438327, 438333, 438339, 438340, 438343, 438352, 438354, 438370, 438378, 438379, 438396, 438399, 438411, 438423, 438428, 438431, 438432, 438445, 438448, 438455, 438461, 438466, 438467, 438474, 438482, 438486, 438491, 438499, 438507, 438511, 438513, 438550, 438552, 438557, 438567, 438575, 438577, 438585, 438597, 438626, 438631, 438637, 438638, 438644, 438645, 438658, 438659, 438682, 438717, 438718, 438728, 438739, 438745, 438747, 438753, 438768, 438777, 438781, 438788, 438794, 438818, 438820, 438821, 438835, 438858, 438869, 438876, 438879, 438884, 438890, 438910, 438940, 438945, 438965, 438977, 438982, 438992, 438993, 438995, 439001, 439023, 439024, 439028, 439031, 439033, 439039, 439042, 439044, 439048, 439051, 439056, 439063, 439064, 439068, 439074, 439075, 439077, 439087, 439092, 439105, 439110, 439115, 439116, 439137, 439150, 439152, 439161, 439162, 439164, 439166, 439167, 439173, 439199, 439201, 439206, 439234, 439236, 439258, 439271, 439278, 439287, 439290, 439291, 439292, 439298, 439300, 439305, 439313, 439315, 439318, 439320, 439323, 439340, 439346, 439348, 439351, 439356, 439373, 439374, 439392, 439396, 439397, 439398, 439409, 439413, 439417, 439437, 439441, 439444, 439454, 439467, 439474, 439484, 439491, 439500, 439505, 439506, 439512, 439514, 439516, 439518, 439519, 439526, 439536, 439545, 439550, 439556, 439557, 439561, 439568, 439571, 439575, 439586, 439591, 439604, 439610, 439612, 439616, 439629, 439635, 439642, 439649, 439656, 439663, 439666, 439677, 439687, 439688, 439699, 439713, 439714, 439728, 439729, 439732, 439753, 439764, 439783, 439793, 439798, 439799, 439805, 439813, 439823, 439825, 439826, 439836, 439847, 439850, 439861, 439873, 439877, 439886, 439898, 439900, 439907, 439913, 439916, 439917, 439921, 439923, 439926, 439928, 439950, 439952, 439970, 440006, 440008, 440014, 440020, 440025, 440035, 440048, 440054, 440072, 440092, 440098, 440107, 440108, 440122, 440131, 440148, 440175, 440188, 440201, 440209, 440223, 440233, 440270, 440273, 440285, 440287, 440292, 440301, 440303, 440309, 440337, 440348, 440371, 440387, 440390, 440397, 440406, 440408, 440419, 440420, 440422, 440440, 440451, 440455, 440462, 440477, 440490, 440494, 440509, 440565, 440578, 440584, 440592, 440619, 440622, 440639, 440641, 440665, 440671, 440672, 440679, 440688, 440692, 440700, 440702, 440703, 440711, 440723, 440729, 440770, 440776, 440780, 440788, 440791, 440807, 440817, 440818, 440821, 440826, 440848, 440856, 440873, 440879, 440881, 440892, 440896, 440898, 440903, 440906, 440908, 440919, 440930, 440938, 440939, 440949, 440953, 440955, 440964, 440967, 440972, 440976, 440980, 440991, 441003, 441005, 441015, 441026, 441033, 441043, 441045, 441054, 441072, 441076, 441088, 441089, 441094, 441096, 441125, 441135, 441146, 441167, 441172, 441176, 441179, 441200, 441204, 441210, 441211, 441233, 441261, 441265, 441305, 441307, 441312, 441317, 441337, 441342, 441352, 441388, 441389, 441412, 441414, 441423, 441427, 441447, 441454, 441466, 441476, 441508, 441527, 441537, 441538, 441544, 441560, 441561, 441572, 441590, 441593, 441624, 441640, 441642, 441646, 441652, 441672, 441679, 441685, 441695, 441732, 441765, 441771, 441787, 441791, 441801, 441821, 441823, 441826, 441834, 441835, 441836, 441839, 441840, 441846, 441854, 441859, 441864, 441869, 441884, 441887, 441919, 441923, 441939, 441959, 441963, 441964, 441971, 441979, 441981, 441987, 441994, 441995, 441997, 441999, 442008, 442011, 442012, 442013, 442023, 442029, 442031, 442037, 442041, 442052, 442053, 442055, 442057, 442088, 442102, 442110, 442118, 442121, 442125, 442136, 442149, 442154, 442155, 442166, 442172, 442176, 442180, 442186, 442197, 442200, 442231, 442232, 442236, 442241, 442242, 442244, 442255, 442264, 442268, 442294, 442298, 442299, 442303, 442308, 442319, 442320, 442321, 442328, 442330, 442333, 442340, 442355, 442362, 442370, 442373, 442397, 442401, 442419, 442429, 442434, 442435, 442438, 442443, 442446, 442447, 442450, 442469, 442498, 442503, 442506, 442525, 442531, 442533, 442535, 442541, 442543, 442548, 442549, 442551, 442552, 442558, 442559, 442560, 442562, 442570, 442576, 442578, 442580, 442588, 442591, 442619, 442636, 442647, 442650, 442656, 442677, 442679, 442692, 442693, 442706, 442713, 442724, 442729, 442732, 442733, 442776, 442784, 442788, 442800, 442803, 442817, 442828, 442841, 442848, 442850, 442861, 442864, 442873, 442881, 442883, 442890, 442891, 442905, 442911, 442919, 442923, 442929, 442934, 442935, 442939, 442942, 442954, 442955, 442973, 442978, 442980, 442981, 442986, 442995, 442999, 443016, 443026, 443033, 443037, 443039, 443042, 443048, 443052, 443057, 443061, 443064, 443073, 443077, 443083, 443089, 443095, 443107, 443110, 443112, 443113, 443124, 443129, 443134, 443137, 443147, 443154, 443159, 443168, 443190, 443204, 443207, 443209, 443217, 443235, 443236, 443244, 443251, 443254, 443268, 443289, 443300, 443301, 443306, 443307, 443321, 443329, 443341, 443344, 443364, 443368, 443379, 443381, 443387, 443397, 443408, 443434, 443437, 443439, 443440, 443443, 443460, 443464, 443471, 443480, 443490, 443491, 443504, 443507, 443515, 443521, 443524, 443544, 443553, 443561, 443569, 443570, 443580, 443582, 443592, 443593, 443597, 443604, 443605, 443614, 443630, 443633, 443635, 443638, 443641, 443642, 443643, 443663, 443665, 443675, 443678, 443679, 443686, 443692, 443696, 443702, 443705, 443707, 443717, 443728, 443731, 443742, 443745, 443751, 443764, 443778, 443790, 443794, 443798, 443806, 443811, 443813, 443820, 443821, 443826, 443827, 443838, 443841, 443850, 443862, 443863, 443865, 443866, 443867, 443870, 443874, 443895, 443897, 443899, 443906, 443918, 443922, 443924, 443928, 443934, 443940, 443947, 443950, 443953, 443954, 443965, 443966, 443969, 443971, 443990, 443991, 443995, 444004, 444006, 444008, 444009, 444010, 444013, 444021, 444042, 444043, 444045, 444046, 444054, 444063, 444064, 444068, 444070, 444071, 444072, 444074, 444079, 444081, 444082, 444087, 444088, 444101, 444109, 444113, 444118, 444123, 444124, 444138, 444139, 444146, 444153, 444155, 444159, 444160, 444163, 444172, 444174, 444192, 444209, 444214, 444226, 444235, 444239, 444240, 444242, 444244, 444246, 444250, 444256, 444257, 444258, 444260, 444265, 444267, 444269, 444274, 444278, 444288, 444296, 444301, 444305, 444308, 444311, 444315, 444318, 444329, 444349, 444354, 444357, 444361, 444368, 444376, 444383, 444386, 444398, 444404, 444407, 444415, 444418, 444419, 444423, 444431, 444443, 444449, 444453, 444474, 444477, 444483, 444488, 444491, 444494, 444516, 444521, 444528, 444532, 444549, 444551, 444561, 444564, 444565, 444589, 444599, 444602, 444605, 444617, 444630, 444631, 444633, 444640, 444650, 444654, 444656, 444666, 444668, 444672, 444693, 444699, 444708, 444717, 444719, 444731, 444748, 444750, 444751, 444770, 444773, 444775, 444776, 444781, 444794, 444798, 444805, 444812, 444819, 444827, 444830, 444831, 444841, 444844, 444846, 444848, 444854, 444855, 444870, 444875, 444886, 444893, 444899, 444916, 444920, 444931, 444932, 444937, 444938, 444958, 444961, 444974, 444980, 444984, 444990, 444991, 444996, 445001, 445005, 445007, 445021, 445032, 445035, 445042, 445043, 445045, 445050, 445054, 445059, 445068, 445070, 445082, 445092, 445099, 445114, 445115, 445116, 445118, 445119, 445120, 445121, 445126, 445127, 445130, 445133, 445148, 445151, 445164, 445166, 445167, 445185, 445191, 445199, 445207, 445208, 445209, 445211, 445220, 445227, 445236, 445238, 445262, 445264, 445271, 445279, 445283, 445294, 445295, 445312, 445313, 445337, 445347, 445349, 445350, 445358, 445370, 445372, 445373, 445377, 445379, 445394, 445401, 445403, 445413, 445414, 445416, 445418, 445420, 445423, 445436, 445448, 445457, 445475, 445476, 445477, 445489, 445492, 445496, 445504, 445509, 445515, 445523, 445530, 445539, 445540, 445541, 445543, 445546, 445558, 445564, 445576, 445586, 445592, 445600, 445606, 445608, 445616, 445630, 445642, 445643, 445665, 445666, 445676, 445677, 445679, 445696, 445697, 445702, 445713, 445725, 445727, 445736, 445743, 445752, 445754, 445756, 445765, 445783, 445784, 445798, 445802, 445813, 445817, 445829, 445839, 445842, 445850, 445854, 445866, 445875, 445902, 445907, 445912, 445922, 445923, 445926, 445930, 445936, 445938, 445947, 445948, 445951, 445955, 445958, 445963, 445965, 445970, 446002, 446047, 446049, 446052, 446054, 446071, 446080, 446087, 446093, 446094, 446096, 446101, 446102, 446105, 446106, 446112, 446122, 446124, 446129, 446132, 446134, 446143, 446149, 446154, 446165, 446166, 446169, 446171, 446174, 446178, 446179, 446181, 446195, 446197, 446206, 446209, 446218, 446220, 446222, 446226, 446238, 446251, 446264, 446269, 446292, 446303, 446313, 446318, 446363, 446378, 446389, 446400, 446408, 446409, 446422, 446426, 446431, 446436, 446439, 446440, 446455, 446469, 446474, 446489, 446501, 446504, 446512, 446515, 446517, 446535, 446540, 446546, 446555, 446570, 446572, 446586, 446594, 446598, 446617, 446618, 446619, 446625, 446643, 446645, 446650, 446666, 446671, 446677, 446682, 446688, 446690, 446693, 446696, 446713, 446715, 446716, 446719, 446720, 446732, 446738, 446742, 446747, 446754, 446762, 446764, 446767, 446770, 446772, 446775, 446784, 446794, 446801, 446813, 446816, 446835, 446891, 446892, 446900, 446906, 446921, 446935, 446938, 446942, 446949, 446952, 446970, 446971, 446981, 446986, 446990, 447014, 447019, 447027, 447057, 447062, 447083, 447086, 447087, 447100, 447104, 447109, 447111, 447118, 447129, 447132, 447139, 447156, 447169, 447174, 447180, 447182, 447192, 447202, 447203, 447205, 447210, 447217, 447220, 447224, 447242, 447273, 447280, 447286, 447288, 447289, 447294, 447298, 447301, 447303, 447318, 447325, 447326, 447328, 447342, 447348, 447358, 447364, 447368, 447376, 447379, 447381, 447392, 447403, 447418, 447422, 447425, 447432, 447439, 447444, 447445, 447459, 447462, 447464, 447478, 447480, 447493, 447495, 447497, 447498, 447507, 447517, 447530, 447549, 447554, 447560, 447567, 447571, 447610, 447619, 447632, 447635, 447642, 447650, 447654, 447675, 447678, 447686, 447688, 447693, 447696, 447698, 447725, 447738, 447751, 447777, 447784, 447788, 447789, 447815, 447817, 447824, 447827, 447828, 447832, 447833, 447835, 447850, 447853, 447856, 447858, 447864, 447866, 447867, 447875, 447876, 447883, 447885, 447886, 447908, 447915, 447923, 447962, 447969, 447979, 447982, 447984, 448002, 448006, 448012, 448017, 448023, 448038, 448063, 448065, 448066, 448074, 448088, 448092, 448095, 448100, 448103, 448110, 448117, 448132, 448140, 448141, 448157, 448158, 448163, 448170, 448175, 448178, 448189, 448193, 448203, 448210, 448211, 448213, 448235, 448238, 448249, 448250, 448260, 448263, 448267, 448275, 448286, 448287, 448291, 448292, 448297, 448298, 448312, 448313, 448318, 448320, 448321, 448336, 448341, 448348, 448354, 448358, 448363, 448367, 448371, 448376, 448377, 448389, 448394, 448402, 448403, 448408, 448422, 448428, 448430, 448442, 448444, 448446, 448449, 448461, 448462, 448486, 448501, 448502, 448508, 448520, 448523, 448526, 448552, 448556, 448557, 448570, 448574, 448579, 448589, 448605, 448610, 448622, 448624, 448635, 448641, 448661, 448665, 448701, 448702, 448705, 448706, 448707, 448709, 448722, 448738, 448754, 448760, 448761, 448768, 448773, 448777, 448790, 448793, 448802, 448803, 448804, 448807, 448808, 448814, 448815, 448828, 448836, 448839, 448850, 448857, 448859, 448865, 448871, 448872, 448877, 448884, 448890, 448896, 448901, 448917, 448919, 448925, 448938, 448941, 448949, 448965, 448974, 448976, 448981, 448994, 448995, 448996, 449006, 449014, 449022, 449024, 449027, 449032, 449038, 449042, 449047, 449049, 449054, 449056, 449057, 449058, 449060, 449062, 449077, 449079, 449080, 449086, 449096, 449100, 449111, 449125, 449145, 449147, 449151, 449179, 449182, 449188, 449193, 449203, 449213, 449220, 449227, 449232, 449257, 449272, 449282, 449288, 449309, 449311, 449312, 449317, 449323, 449327, 449330, 449335, 449343, 449346, 449347, 449359, 449360, 449361, 449383, 449394, 449402, 449409, 449427, 449428, 449429, 449446, 449450, 449457, 449458, 449483, 449484, 449490, 449492, 449499, 449500, 449504, 449505, 449516, 449526, 449531, 449539, 449541, 449543, 449544, 449550, 449557, 449559, 449564, 449566, 449571, 449574, 449581, 449582, 449592, 449596, 449601, 449614, 449616, 449618, 449645, 449649, 449654, 449657, 449661, 449676, 449677, 449729, 449731, 449753, 449757, 449762, 449768, 449769, 449771, 449794, 449800, 449810, 449814, 449815, 449817, 449818, 449819, 449825, 449828, 449843, 449846, 449853, 449858, 449874, 449875, 449881, 449889, 449905, 449909, 449919, 449924, 449926, 449931, 449932, 449934, 449947, 449950, 449960, 449967, 449970, 449972, 449983, 449984, 449986, 449989, 449996, 450017, 450024, 450031, 450033, 450038, 450047, 450055, 450058, 450059, 450062, 450066, 450074, 450079, 450080, 450092, 450108, 450120, 450122, 450123, 450128, 450132, 450145, 450164, 450179, 450187, 450199, 450210, 450246, 450261, 450264, 450279, 450281, 450285, 450295, 450298, 450300, 450309, 450321, 450326, 450332, 450341, 450344, 450347, 450348, 450358, 450368, 450376, 450379, 450390, 450391, 450400, 450432, 450436, 450438, 450477, 450498, 450505, 450516, 450518, 450536, 450541, 450548, 450549, 450550, 450551, 450552, 450554, 450558, 450561, 450570, 450599, 450600, 450605, 450607, 450629, 450630, 450639, 450648, 450649, 450655, 450657, 450666, 450670, 450697, 450700, 450702, 450704, 450705, 450707, 450710, 450712, 450714, 450718, 450721, 450731, 450749, 450750, 450753, 450757, 450759, 450770, 450777, 450787, 450790, 450794, 450807, 450818, 450835, 450842, 450854, 450860, 450862, 450868, 450869, 450874, 450886, 450900, 450903, 450904, 450920, 450925, 450933, 450934, 450935, 450940, 450951, 450974, 450979, 450980, 450981, 450982, 450983, 450990, 450993, 450996, 451013, 451015, 451020, 451021, 451023, 451026, 451029, 451030, 451032, 451033, 451034, 451041, 451043, 451045, 451052, 451054, 451060, 451063, 451073, 451078, 451100, 451106, 451108, 451120, 451134, 451138, 451144, 451146, 451152, 451161, 451162, 451164, 451173, 451176, 451179, 451183, 451190, 451193, 451206, 451216, 451223, 451236, 451240, 451242, 451249, 451257, 451258, 451267, 451269, 451276, 451284, 451285, 451291, 451292, 451297, 451318, 451319, 451320, 451323, 451324, 451333, 451354, 451364, 451367, 451373, 451388, 451409, 451412, 451417, 451421, 451422, 451425, 451426, 451428, 451437, 451441, 451443, 451466, 451467, 451469, 451474, 451485, 451496, 451504, 451506, 451516, 451544, 451545, 451546, 451549, 451555, 451571, 451572, 451576, 451580, 451582, 451588, 451625, 451628, 451632, 451641, 451645, 451646, 451648, 451655, 451656, 451657, 451658, 451661, 451668, 451675, 451676, 451679, 451683, 451708, 451723, 451729, 451731, 451745, 451748, 451765, 451777, 451782, 451788, 451789, 451791, 451795, 451803, 451806, 451807, 451811, 451814, 451821, 451828, 451833, 451858, 451869, 451870, 451871, 451876, 451877, 451878, 451886, 451895, 451901, 451914, 451916, 451917, 451920, 451922, 451931, 451932, 451939, 451949, 451953, 451957, 451959, 451964, 451973, 451974, 451978, 451982, 451985, 451998, 452001, 452008, 452011, 452012, 452018, 452019, 452026, 452027, 452041, 452056, 452057, 452062, 452064, 452068, 452077, 452080, 452089, 452111, 452114, 452115, 452116, 452127, 452130, 452132, 452133, 452140, 452142, 452144, 452147, 452148, 452154, 452156, 452160, 452166, 452167, 452169, 452178, 452179, 452180, 452181, 452184, 452185, 452186, 452188, 452200, 452214, 452228, 452237, 452244, 452254, 452256, 452260, 452266, 452276, 452278, 452280, 452283, 452284, 452296, 452298, 452300, 452329, 452337, 452340, 452346, 452353, 452361, 452364, 452367, 452379, 452393, 452404, 452413, 452426, 452429, 452433, 452445, 452453, 452456, 452472, 452474, 452476, 452480, 452483, 452484, 452485, 452490, 452493, 452496, 452500, 452512, 452514, 452515, 452520, 452522, 452541, 452579, 452655, 452672, 452686, 452692, 452694, 452696, 452707, 452713, 452724, 452730, 452731, 452735, 452746, 452748, 452756, 452766, 452770, 452784, 452791, 452792, 452797, 452816, 452818, 452826, 452827, 452832, 452877, 452879, 452882, 452885, 452886, 452902, 452915, 452918, 452935, 452942, 452944, 452945, 452951, 452964, 452966, 452973, 452977, 452982, 452995, 453000, 453024, 453025, 453030, 453035, 453042, 453053, 453060, 453070, 453082, 453086, 453090, 453093, 453097, 453108, 453111, 453112, 453130, 453134, 453141, 453145, 453149, 453153, 453155, 453156, 453162, 453165, 453173, 453179, 453184, 453185, 453202, 453205, 453210, 453223, 453224, 453230, 453232, 453236, 453243, 453246, 453247, 453249, 453255, 453268, 453287, 453298, 453309, 453316, 453321, 453322, 453324, 453328, 453333, 453336, 453350, 453362, 453363, 453370, 453384, 453393, 453404, 453433, 453437, 453444, 453445, 453455, 453459, 453505, 453513, 453522, 453540, 453542, 453549, 453552, 453553, 453555, 453562, 453567, 453571, 453583, 453595, 453596, 453600, 453606, 453618, 453621, 453629, 453631, 453639, 453640, 453659, 453668, 453673, 453684, 453695, 453696, 453715, 453725, 453730, 453731, 453736, 453740, 453744, 453751, 453765, 453774, 453779, 453782, 453788, 453791, 453796, 453816, 453819, 453820, 453827, 453835, 453841, 453851, 453853, 453854, 453865, 453866, 453875, 453877, 453880, 453885, 453886, 453889, 453893, 453895, 453901, 453924, 453932, 453934, 453935, 453949, 453954, 453957, 453965, 453968, 453970, 453978, 453984, 453989, 453996, 454009, 454010, 454012, 454015, 454019, 454026, 454029, 454031, 454034, 454044, 454062, 454067, 454075, 454080, 454083, 454093, 454094, 454111, 454122, 454124, 454131, 454139, 454142, 454152, 454158, 454160, 454165, 454168, 454181, 454182, 454185, 454196, 454199, 454204, 454205, 454211, 454214, 454221, 454244, 454255, 454256, 454264, 454265, 454267, 454303, 454305, 454329, 454336, 454339, 454345, 454371, 454372, 454377, 454378, 454379, 454424, 454425, 454430, 454439, 454445, 454449, 454450, 454452, 454454, 454461, 454475, 454483, 454489, 454492, 454502, 454511, 454513, 454515, 454516, 454526, 454529, 454531, 454541, 454542, 454548, 454565, 454572, 454584, 454595, 454599, 454604, 454606, 454608, 454611, 454612, 454615, 454617, 454618, 454620, 454621, 454639, 454641, 454646, 454650, 454653, 454658, 454671, 454675, 454683, 454685, 454688, 454710, 454718, 454722, 454723, 454738, 454746, 454755, 454775, 454776, 454787, 454788, 454797, 454798, 454812, 454814, 454816, 454817, 454820, 454842, 454846, 454858, 454865, 454868, 454880, 454882, 454896, 454900, 454901, 454905, 454923, 454933, 454938, 454947, 454951, 454958, 454962, 454963, 454971, 454972, 454979, 454984, 455011, 455014, 455017, 455020, 455025, 455032, 455034, 455036, 455051, 455055, 455056, 455059, 455060, 455065, 455067, 455072, 455080, 455097, 455113, 455121, 455135, 455137, 455147, 455154, 455166, 455169, 455200, 455201, 455205, 455216, 455218, 455228, 455234, 455240, 455256, 455263, 455270, 455272, 455273, 455281, 455301, 455305, 455312, 455315, 455318, 455320, 455326, 455328, 455330, 455341, 455346, 455356, 455370, 455372, 455386, 455389, 455413, 455414, 455421, 455428, 455429, 455432, 455433, 455442, 455445, 455449, 455451, 455452, 455463, 455466, 455468, 455483, 455507, 455512, 455517, 455527, 455544, 455546, 455548, 455566, 455574, 455575, 455583, 455585, 455586, 455592, 455601, 455602, 455604, 455605, 455607, 455610, 455620, 455635, 455649, 455655, 455668, 455672, 455679, 455690, 455692, 455700, 455710, 455721, 455725, 455732, 455734, 455739, 455750, 455758, 455760, 455762, 455766, 455768, 455783, 455790, 455804, 455813, 455814, 455842, 455846, 455852, 455856, 455865, 455867, 455869, 455875, 455882, 455887, 455900, 455903, 455917, 455924, 455931, 455935, 455936, 455958, 455962, 455966, 455969, 455985, 456007, 456031, 456061, 456064, 456069, 456078, 456082, 456087, 456094, 456098, 456111, 456113, 456125, 456127, 456133, 456134, 456148, 456162, 456171, 456176, 456177, 456188, 456191, 456198, 456205, 456216, 456233, 456245, 456253, 456266, 456268, 456277, 456278, 456280, 456282, 456291, 456292, 456293, 456298, 456300, 456308, 456310, 456314, 456321, 456339, 456342, 456351, 456361, 456367, 456380, 456392, 456394, 456406, 456410, 456430, 456431, 456434, 456439, 456455, 456459, 456463, 456469, 456473, 456477, 456485, 456493, 456512, 456531, 456551, 456580, 456583, 456586, 456597, 456608, 456613, 456619, 456639, 456647, 456677, 456684, 456686, 456694, 456695, 456702, 456713, 456719, 456720, 456721, 456733, 456741, 456747, 456749, 456775, 456778, 456779, 456781, 456813, 456817, 456821, 456834, 456836, 456846, 456852, 456854, 456885, 456899, 456905, 456907, 456909, 456914, 456934, 456941, 456943, 456949, 456982, 456984, 457002, 457004, 457008, 457013, 457035, 457063, 457065, 457068, 457070, 457073, 457090, 457102, 457111, 457118, 457119, 457127, 457128, 457132, 457136, 457143, 457147, 457150, 457153, 457161, 457184, 457214, 457224, 457234, 457249, 457250, 457260, 457262, 457264, 457275, 457282, 457286, 457293, 457296, 457303, 457308, 457322, 457326, 457346, 457354, 457355, 457357, 457358, 457360, 457365, 457366, 457369, 457377, 457409, 457429, 457441, 457457, 457470, 457473, 457478, 457480, 457482, 457502, 457507, 457510, 457514, 457524, 457534, 457535, 457536, 457544, 457557, 457562, 457564, 457566, 457571, 457579, 457583, 457587, 457594, 457599, 457613, 457619, 457620, 457630, 457631, 457642, 457654, 457663, 457669, 457682, 457683, 457704, 457729, 457892, 457895, 457901, 457904, 457907, 457908, 457910, 457915, 457920, 457923, 457924, 457933, 457935, 457936, 457943, 457946, 457947, 457967, 457970, 457992, 458000, 458005, 458008, 458021, 458022, 458027, 458032, 458043, 458080, 458121, 458122, 458131, 458133, 458135, 458142, 458143, 458144, 458152, 458165, 458170, 458173, 458180, 458198, 458205, 458207, 458215, 458221, 458224, 458227, 458230, 458232, 458243, 458259, 458275, 458277, 458284, 458293, 458295, 458307, 458316, 458317, 458318, 458327, 458340, 458348, 458359, 458372, 458402, 458403, 458419, 458420, 458422, 458444, 458445, 458461, 458463, 458464, 458470, 458490, 458501, 458512, 458526, 458532, 458538, 458544, 458550, 458591, 458604, 458610, 458619, 458620, 458625, 458632, 458635, 458643, 458648, 458669, 458671, 458682, 458692, 458699, 458700, 458702, 458713, 458724, 458730, 458732, 458745, 458746, 458770, 458779, 458784, 458796, 458803, 458804, 458815, 458818, 458828, 458839, 458840, 458853, 458856, 458875, 458889, 458893, 458908, 458925, 458938, 458940, 458967, 458968, 458978, 458999, 459014, 459020, 459022, 459024, 459025, 459039, 459048, 459053, 459059, 459064, 459071, 459086, 459089, 459091, 459092, 459103, 459104, 459105, 459106, 459115, 459119, 459126, 459131, 459135, 459139, 459150, 459157, 459158, 459164, 459167, 459184, 459190, 459193, 459203, 459216, 459225, 459238, 459242, 459247, 459265, 459292, 459302, 459306, 459309, 459316, 459318, 459319, 459322, 459335, 459341, 459347, 459350, 459351, 459360, 459369, 459383, 459390, 459459, 459472, 459475, 459483, 459489, 459492, 459496, 459497, 459498, 459500, 459508, 459510, 459515, 459516, 459529, 459540, 459544, 459548, 459550, 459552, 459563, 459583, 459600, 459616, 459626, 459636, 459638, 459643, 459645, 459652, 459654, 459655, 459660, 459661, 459675, 459676, 459696, 459703, 459706, 459707, 459723, 459725, 459728, 459734, 459739, 459746, 459748, 459758, 459762, 459773, 459785, 459787, 459801, 459809, 459827, 459831, 459839, 459851, 459853, 459856, 459859, 459864, 459880, 459888, 459891, 459911, 459923, 459937, 459952, 459955, 459961, 459971, 459972, 459979, 459980, 459985, 459986, 459992, 459999, 460008, 460015, 460017, 460018, 460032, 460046, 460050, 460062, 460063, 460082, 460091, 460092, 460124, 460137, 460153, 460174, 460189, 460207, 460211, 460214, 460216, 460222, 460231, 460234, 460237, 460250, 460251, 460253, 460258, 460259, 460290, 460317, 460321, 460325, 460334, 460340, 460342, 460343, 460357, 460364, 460366, 460379, 460380, 460382, 460385, 460394, 460397, 460401, 460415, 460418, 460421, 460434, 460457, 460499, 460516, 460519, 460520, 460523, 460524, 460545, 460549, 460558, 460563, 460565, 460567, 460569, 460578, 460586, 460587, 460589, 460600, 460610, 460611, 460617, 460618, 460623, 460625, 460633, 460635, 460650, 460655, 460662, 460675, 460680, 460691, 460700, 460702, 460705, 460720, 460723, 460736, 460738, 460739, 460745, 460747, 460748, 460761, 460768, 460772, 460783, 460786, 460809, 460817, 460821, 460832, 460843, 460847, 460865, 460869, 460873, 460876, 460910, 460913, 460919, 460929, 460948, 460949, 460953, 460961, 460971, 460973, 460981, 460985, 460989, 460992, 460993, 460997, 461005, 461008, 461009, 461014, 461023, 461024, 461030, 461047, 461052, 461060, 461066, 461074, 461089, 461095, 461103, 461107, 461114, 461137, 461148, 461165, 461178, 461195, 461210, 461241, 461255, 461257, 461262, 461265, 461267, 461270, 461279, 461281, 461286, 461315, 461316, 461318, 461342, 461351, 461352, 461355, 461369, 461371, 461382, 461388, 461389, 461392, 461400, 461410, 461418, 461437, 461438, 461451, 461467, 461485, 461494, 461504, 461508, 461509, 461520, 461526, 461539, 461553, 461554, 461560, 461574, 461576, 461577, 461592, 461606, 461607, 461608, 461610, 461615, 461627, 461643, 461648, 461650, 461652, 461655, 461671, 461679, 461684, 461702, 461708, 461713, 461714, 461720, 461749, 461758, 461764, 461765, 461770, 461772, 461779, 461786, 461787, 461788, 461804, 461816, 461854, 461864, 461879, 461906, 461916, 461922, 461938, 461943, 461954, 461962, 461964, 461977, 461982, 461991, 462014, 462019, 462024, 462030, 462036, 462038, 462044, 462050, 462055, 462066, 462080, 462082, 462097, 462103, 462108, 462115, 462133, 462136, 462137, 462150, 462151, 462152, 462156, 462158, 462160, 462161, 462166, 462175, 462179, 462185, 462186, 462191, 462198, 462209, 462215, 462220, 462236, 462240, 462244, 462253, 462256, 462259, 462271, 462274, 462279, 462280, 462283, 462284, 462292, 462305, 462309, 462315, 462319, 462324, 462331, 462333, 462335, 462340, 462342, 462346, 462350, 462352, 462354, 462361, 462363, 462365, 462366, 462367, 462369, 462374, 462386, 462388, 462395, 462403, 462407, 462409, 462411, 462423, 462425, 462436, 462438, 462445, 462458, 462462, 462466, 462467, 462473, 462476, 462478, 462485, 462492, 462500, 462501, 462502, 462508, 462519, 462520, 462528, 462533, 462542, 462548, 462554, 462558, 462560, 462564, 462586, 462596, 462598, 462599, 462603, 462607, 462615, 462619, 462620, 462625, 462643, 462644, 462652, 462653, 462668, 462693, 462694, 462725, 462727, 462731, 462737, 462738, 462748, 462750, 462757, 462764, 462771, 462779, 462781, 462784, 462797, 462798, 462815, 462816, 462818, 462819, 462824, 462830, 462844, 462856, 462873, 462874, 462880, 462887, 462890, 462900, 462906, 462910, 462913, 462922, 462925, 462927, 462928, 462930, 462938, 462944, 462959, 462966, 462972, 462973, 462978, 462988, 462989, 463007, 463009, 463013, 463018, 463021, 463029, 463046, 463055, 463061, 463062, 463064, 463076, 463078, 463080, 463081, 463089, 463091, 463095, 463112, 463123, 463126, 463129, 463133, 463141, 463145, 463149, 463156, 463158, 463164, 463166, 463176, 463182, 463185, 463189, 463190, 463201, 463204, 463210, 463211, 463216, 463218, 463223, 463240, 463246, 463249, 463254, 463279, 463294, 463296, 463299, 463301, 463304, 463306, 463309, 463311, 463313, 463316, 463317, 463323, 463345, 463349, 463356, 463367, 463407, 463421, 463434, 463440, 463442, 463443, 463444, 463454, 463457, 463462, 463469, 463475, 463479, 463482, 463484, 463488, 463495, 463497, 463498, 463502, 463508, 463517, 463528, 463531, 463536, 463547, 463551, 463573, 463591, 463608, 463613, 463620, 463630, 463631, 463632, 463639, 463641, 463645, 463654, 463657, 463660, 463663, 463667, 463669, 463671, 463672, 463673, 463680, 463681, 463687, 463689, 463690, 463691, 463718, 463723, 463731, 463735, 463748, 463752, 463753, 463758, 463762, 463766, 463770, 463771, 463772, 463789, 463791, 463795, 463814, 463826, 463829, 463831, 463833, 463839, 463843, 463846, 463852, 463857, 463858, 463859, 463863, 463864, 463869, 463873, 463875, 463887, 463889, 463892, 463899, 463900, 463901, 463907, 463908, 463922, 463926, 463931, 463933, 463934, 463943, 463948, 463954, 463956, 463970, 463974, 463979, 463993, 463996, 463997, 464006, 464008, 464017, 464022, 464023, 464027, 464029, 464031, 464032, 464036, 464057, 464058, 464060, 464061, 464065, 464080, 464085, 464091, 464092, 464099, 464102, 464109, 464110, 464116, 464118, 464134, 464135, 464136, 464141, 464144, 464149, 464152, 464154, 464168, 464169, 464174, 464180, 464192, 464200, 464204, 464208, 464212, 464216, 464229, 464234, 464246, 464253, 464258, 464267, 464268, 464272, 464288, 464294, 464326, 464331, 464338, 464343, 464346, 464350, 464351, 464363, 464376, 464392, 464397, 464401, 464412, 464415, 464416, 464419, 464422, 464424, 464426, 464428, 464430, 464432, 464436, 464443, 464444, 464449, 464455, 464461, 464464, 464470, 464471, 464476, 464482, 464485, 464497, 464498, 464500, 464510, 464518, 464521, 464529, 464545, 464585, 464599, 464600, 464601, 464618, 464628, 464629, 464632, 464633, 464635, 464642, 464667, 464669, 464677, 464684, 464686, 464687, 464689, 464690, 464694, 464705, 464710, 464711, 464721, 464728, 464729, 464737, 464743, 464750, 464751, 464766, 464773, 464778, 464787, 464789, 464790, 464797, 464801, 464804, 464806, 464808, 464810, 464811, 464826, 464827, 464835, 464840, 464844, 464855, 464857, 464864, 464867, 464869, 464870, 464876, 464882, 464887, 464890, 464893, 464896, 464899, 464906, 464907, 464923, 464924, 464926, 464935, 464937, 464940, 464942, 464950, 464954, 464955, 464957, 464959, 464960, 464964, 464977, 464982, 464986, 464993, 464996, 465019, 465029, 465038, 465050, 465051, 465055, 465059, 465062, 465065, 465071, 465075, 465076, 465091, 465105, 465112, 465115, 465126, 465135, 465144, 465145, 465148, 465156, 465160, 465161, 465176, 465183, 465199, 465200, 465220, 465223, 465226, 465232, 465238, 465239, 465243, 465244, 465252, 465254, 465256, 465262, 465281, 465291, 465296, 465300, 465302, 465305, 465321, 465327, 465331, 465342, 465369, 465374, 465382, 465389, 465392, 465395, 465398, 465401, 465406, 465413, 465422, 465423, 465427, 465430, 465438, 465440, 465445, 465463, 465467, 465483, 465484, 465491, 465493, 465495, 465500, 465516, 465517, 465533, 465535, 465539, 465542, 465559, 465564, 465566, 465570, 465572, 465575, 465577, 465580, 465581, 465597, 465602, 465603, 465604, 465614, 465629, 465634, 465638, 465641, 465642, 465645, 465657, 465665, 465671, 465672, 465698, 465709, 465710, 465733, 465735, 465737, 465743, 465744, 465745, 465748, 465749, 465758, 465760, 465767, 465770, 465797, 465798, 465802, 465804, 465814, 465817, 465828, 465952, 465957, 465965, 465976, 465983, 465993, 466029, 466035, 466036, 466043, 466046, 466053, 466060, 466062, 466076, 466083, 466084, 466086, 466107, 466130, 466133, 466136, 466141, 466155, 466163, 466167, 466185, 466188, 466194, 466213, 466214, 466216, 466225, 466233, 466238, 466261, 466270, 466287, 466299, 466302, 466303, 466317, 466323, 466331, 466334, 466353, 466354, 466363, 466366, 466369, 466376, 466377, 466391, 466392, 466395, 466408, 466414, 466422, 466424, 466426, 466430, 466472, 466483, 466487, 466518, 466560, 466569, 466576, 466588, 466597, 466601, 466610, 466618, 466621, 466627, 466628, 466634, 466643, 466645, 466649, 466659, 466678, 466680, 466692, 466722, 466746, 466748, 466758, 466761, 466765, 466813, 466825, 466829, 466835, 466850, 466860, 466862, 466878, 466887, 466890, 466891, 466897, 466911, 466933, 466934, 466951, 466955, 466966, 466969, 466975, 466978, 466992, 467004, 467027, 467038, 467039, 467041, 467050, 467059, 467060, 467076, 467098, 467100, 467103, 467104, 467127, 467131, 467152, 467163, 467170, 467215, 467224, 467225, 467278, 467301, 467336, 467338, 467345, 467355, 467365, 467380, 467381, 467390, 467413, 467424, 467439, 467442, 467450, 467456, 467484, 467488, 467496, 467520, 467576, 467577, 467583, 467597, 467646, 467650, 467663, 467669, 467670, 467672, 467689, 467701, 467704, 467706, 467737, 467743, 467754, 467771, 467774, 467799, 467802, 467821, 467843, 467844, 467856, 467868, 467873, 467884, 467886, 467893, 467902, 467963, 467971, 467979, 467984, 468011, 468014, 468037, 468046, 468054, 468059, 468060, 468078, 468082, 468085, 468097, 468107, 468108, 468133, 468141, 468166, 468175, 468195, 468212, 468247, 468254, 468255, 468259, 468282, 468284, 468300, 468314, 468326, 468334, 468340, 468342, 468343, 468364, 468367, 468394, 468396, 468404, 468446, 468485, 468488, 468494, 468503, 468507, 468531, 468542, 468543, 468546, 468549, 468552, 468554, 468562, 468571, 468583, 468620, 468625, 468634, 468639, 468640, 468646, 468649, 468661, 468669, 468674, 468687, 468728, 468735, 468746, 468777, 468786, 468794, 468797, 468805, 468807, 468810, 468820, 468826, 468838, 468843, 468852, 468853, 468855, 468861, 468864, 468866, 468872, 468874, 468875, 468876, 468878, 468880, 468887, 468946, 468963, 468971, 468978, 468982, 468991, 469025, 469046, 469047, 469050, 469052, 469063, 469099, 469102, 469105, 469107, 469108, 469109, 469111, 469112, 469114, 469121, 469126, 469132, 469134, 469140, 469174, 469187, 469193, 469199, 469205, 469209, 469233, 469234, 469255, 469271, 469284, 469288, 469295, 469301, 469302, 469309, 469349, 469352, 469355, 469380, 469401, 469403, 469412, 469414, 469424, 469435, 469439, 469441, 469461, 469465, 469470, 469475, 469486, 469492, 469525, 469546, 469559, 469589, 469591, 469613, 469618, 469634, 469641, 469664, 469666, 469680, 469702, 469720, 469724, 469730, 469736, 469741, 469747, 469748, 469750, 469755, 469758, 469784, 469788, 469797, 469811, 469834, 469839, 469842, 469845, 469853, 469854, 469856, 469868, 469890, 469896, 469904, 469908, 469910, 469916, 469923, 469924, 469926, 469947, 469997, 469999, 470014, 470016, 470017, 470040, 470047, 470058, 470092, 470109, 470140, 470197, 470308, 470338, 470614, 470642, 470657, 470669, 470675, 470693, 470735, 470739, 470763, 470772, 470774, 470782, 470786, 470793, 470799, 470806, 470808, 470811, 470815, 470818, 470843, 470844, 470851, 470854, 470871, 470880, 470884, 470888, 470889, 470907, 470912, 470931, 470946, 470959, 470962, 470967, 470984, 471010, 471025, 471055, 471056, 471072, 471074, 471082, 471093, 471119, 471127, 471166, 471204, 471205, 471207, 471211, 471212, 471216, 471218, 471228, 471246, 471270, 471291, 471294, 471321, 471383, 471416, 471432, 471445, 471457, 471476, 471493, 471497, 471498, 471501, 471504, 471507, 471508, 471524, 471527, 471533, 471536, 471545, 471564, 471582, 471584, 471586, 471591, 471610, 471618, 471662, 471684, 471701, 471727, 471729, 471740, 471741, 471801, 471812, 471835, 471843, 471849, 471852, 471866, 471875, 471883, 471884, 471888, 471905, 471918, 471951, 471958, 471985, 472051, 472052, 472061, 472073, 472097, 472124, 472131, 472160, 472177, 472182, 472184, 472188, 472192, 472200, 472223, 472224, 472247, 472264, 472266, 472272, 472288, 472312, 472326, 472331, 472344, 472374, 472378, 472385, 472398, 472408, 472421, 472435, 472457, 472460, 472463, 472465, 472469, 472477, 472486, 472494, 472520, 472523, 472557, 472567, 472602, 472607, 472674, 472684, 472688, 472689, 472720, 472731, 472740, 472745, 472784, 472802, 472816, 472844, 472906, 472919, 472957, 472962, 472983, 472989, 473034, 473162, 473197, 473202, 473215, 473241, 473245, 473248, 473250, 473251, 473252, 473284, 473313, 473321, 473341, 473343, 473366, 473401, 473426, 473469, 473481, 473506, 473517, 473519, 473579, 473580, 473600, 473653, 473685, 473784, 473785, 473886, 473893, 473895, 473897, 473898, 473907, 473908, 473932, 473940, 473945, 473956, 473960, 473965, 473973, 473985, 474148, 474269, 474270, 474277, 474295, 474306, 474309, 474321, 474333, 474336, 474355, 474363, 474365, 474368, 474397, 474399, 474405, 474415, 474421, 474451, 474462, 474476, 474509, 474510, 474511, 474512, 474514, 474519, 474524, 474534, 474540, 474545, 474565, 474568, 474572, 474575, 474577, 474587, 474593, 474608, 474616, 474630, 474644, 474650, 474652, 474656, 474683, 474692, 474707, 474722, 474727, 474729, 474732, 474742, 474750, 474760, 474782, 474785, 474788, 474793, 474797, 474808, 474829, 474833, 474837, 474838, 474845, 474856, 474864, 474868, 474872, 474880, 474882, 474901, 474906, 474908, 474912, 474919, 474921, 474937, 474949, 474951, 474959, 474972, 474976, 474988, 474994, 475002, 475006, 475009, 475010, 475051, 475059, 475071, 475075, 475079, 475098, 475101, 475119, 475126, 475127, 475135, 475139, 475142, 475146, 475147, 475168, 475171, 475180, 475189, 475208, 475226, 475246, 475250, 475269, 475294, 475297, 475303, 475307, 475314, 475319, 475323, 475324, 475327, 475331, 475350, 475352, 475353, 475374, 475382, 475383, 475403, 475414, 475418, 475429, 475431, 475434, 475445, 475454, 475467, 475477, 475487, 475489, 475491, 475498, 475501, 475509, 475514, 475521, 475523, 475529, 475540, 475544, 475554, 475564, 475567, 475568, 475581, 475594, 475598, 475606, 475609, 475613, 475626, 475638, 475648, 475650, 475651, 475654, 475682, 475693, 475697, 475698, 475700, 475713, 475718, 475719, 475724, 475728, 475737, 475739, 475774, 475800, 475802, 475807, 475812, 475821, 475835, 475841, 475858, 475886, 475896, 475901, 475920, 475937, 475939, 475942, 475958, 475959, 475971, 475972, 475982, 475983, 475988, 475989, 476005, 476007, 476009, 476016, 476023, 476052, 476068, 476070, 476080, 476083, 476097, 476100, 476101, 476117, 476118, 476119, 476124, 476134, 476137, 476139, 476157, 476166, 476167, 476172, 476179, 476180, 476182, 476206, 476215, 476222, 476241, 476243, 476255, 476265, 476269, 476272, 476278, 476285, 476310, 476319, 476326, 476338, 476341, 476351, 476371, 476372, 476375, 476378, 476384, 476393, 476419, 476424, 476433, 476439, 476453, 476467, 476476, 476483, 476487, 476491, 476512, 476514, 476515, 476520, 476521, 476532, 476535, 476540, 476550, 476566, 476577, 476579, 476587, 476593, 476604, 476614, 476615, 476624, 476633, 476647, 476651, 476660, 476668, 476670, 476671, 476685, 476686, 476691, 476697, 476719, 476722, 476725, 476729, 476733, 476736, 476757, 476762, 476782, 476783, 476785, 476793, 476799, 476804, 476809, 476814, 476830, 476843, 476848, 476849, 476855, 476860, 476875, 476891, 476900, 476902, 476915, 476916, 476918, 476924, 476931, 476939, 476945, 476972, 477006, 477014, 477017, 477023, 477036, 477038, 477051, 477053, 477059, 477071, 477074, 477082, 477098, 477102, 477106, 477107, 477110, 477126, 477128, 477130, 477133, 477169, 477173, 477179, 477180, 477203, 477209, 477221, 477222, 477223, 477225, 477228, 477247, 477258, 477265, 477268, 477280, 477300, 477310, 477315, 477325, 477327, 477336, 477340, 477351, 477366, 477389, 477398, 477408, 477413, 477440, 477450, 477455, 477465, 477472, 477492, 477506, 477523, 477525, 477537, 477539, 477559, 477593, 477596, 477605, 477606, 477618, 477621, 477628, 477638, 477639, 477652, 477668, 477676, 477685, 477692, 477698, 477714, 477716, 477717, 477729, 477731, 477751, 477758, 477763, 477787, 477791, 477795, 477806, 477832, 477854, 477856, 477860, 477885, 477895, 477903, 477905, 477908, 477928, 477933, 477942, 477948, 477978, 477984, 477986, 477995, 478003, 478006, 478009, 478013, 478016, 478018, 478022, 478029, 478033, 478034, 478043, 478063, 478075, 478092, 478126, 478140, 478149, 478165, 478167, 478178, 478180, 478185, 478189, 478199, 478204, 478210, 478212, 478214, 478240, 478257, 478271, 478273, 478276, 478294, 478309, 478312, 478316, 478328, 478331, 478357, 478381, 478407, 478414, 478417, 478422, 478445, 478450, 478472, 478473, 478490, 478497, 478536, 478557, 478572, 478578, 478596, 478609, 478635, 478640, 478643, 478647, 478649, 478656, 478671, 478683, 478688, 478700, 478704, 478713, 478715, 478721, 478729, 478731, 478735, 478737, 478747, 478755, 478759, 478761, 478768, 478788, 478793, 478798, 478813, 478823, 478830, 478836, 478844, 478846, 478848, 478852, 478858, 478862, 478864, 478865, 478881, 478895, 478903, 478904, 478926, 478927, 478930, 478939, 478942, 478946, 478956, 478959, 478973, 478985, 478998, 479004, 479032, 479037, 479054, 479066, 479070, 479071, 479075, 479117, 479119, 479158, 479182, 479190, 479200, 479202, 479217, 479220, 479221, 479281, 479296, 479298, 479311, 479313, 479319, 479342, 479343, 479360, 479391, 479393, 479425, 479435, 479437, 479449, 479454, 479463, 479464, 479470, 479474, 479477, 479478, 479480, 479492, 479494, 479495, 479518, 479521, 479526, 479576, 479590, 479597, 479614, 479620, 479621, 479648, 479650, 479655, 479683, 479701, 479703, 479706, 479723, 479729, 479730, 479744, 479760, 479775, 479782, 479790, 479793, 479797, 479804, 479810, 479844, 479846, 479856, 479857, 479895, 479898, 479901, 479918, 479919, 479920, 479924, 479929, 479930, 479933, 479940, 479953, 479960, 479964, 479978, 479988, 479990, 479992, 479998, 480021, 480023, 480028, 480034, 480036, 480068, 480072, 480074, 480082, 480087, 480091, 480112, 480114, 480117, 480125, 480138, 480158, 480167, 480175, 480183, 480184, 480202, 480204, 480208, 480214, 480215, 480224, 480230, 480242, 480246, 480250, 480265, 480272, 480275, 480284, 480298, 480302, 480319, 480320, 480325, 480329, 480342, 480359, 480367, 480369, 480373, 480391, 480435, 480438, 480441, 480442, 480443, 480445, 480451, 480455, 480470, 480473, 480476, 480478, 480480, 480488, 480492, 480499, 480500, 480507, 480511, 480528, 480532, 480533, 480534, 480544, 480580, 480583, 480585, 480586, 480589, 480590, 480617, 480624, 480628, 480633, 480659, 480665, 480673, 480686, 480690, 480707, 480726, 480729, 480731, 480739, 480743, 480747, 480759, 480764, 480775, 480782, 480785, 480786, 480789, 480795, 480796, 480806, 480812, 480816, 480851, 480863, 480872, 480873, 480876, 480882, 480883, 480884, 480892, 480897, 480900, 480904, 480910, 480911, 480919, 480920, 480921, 480931, 480941, 480948, 480950, 480993, 481006, 481044, 481092, 481108, 481122, 481128, 481130, 481133, 481175, 481200, 481204, 481217, 481218, 481227, 481231, 481275, 481285, 481292, 481304, 481309, 481311, 481320, 481340, 481347, 481352, 481354, 481359, 481376, 481420, 481422, 481430, 481436, 481451, 481452, 481465, 481479, 481486, 481559, 481562, 481565, 481567, 481568, 481569, 481571, 481586, 481656, 481668, 481669, 481678, 481691, 481696, 481701, 481703, 481706, 481714, 481717, 481719, 481759, 481760, 481771, 481780, 481782, 481792, 481800, 481808, 481813, 481820, 481831, 481832, 481834, 481835, 481857, 481865, 481876, 481879, 481882, 481883, 481891, 481901, 481904, 481906, 481910, 481911, 481913, 481916, 481929, 481939, 481942, 481943, 481969, 481974, 481975, 481981, 481985, 482024, 482036, 482038, 482054, 482077, 482084, 482127, 482129, 482136, 482138, 482145, 482195, 482203, 482204, 482207, 482213, 482217, 482221, 482237, 482238, 482246, 482248, 482268, 482271, 482277, 482313, 482315, 482323, 482329, 482336, 482343, 482351, 482354, 482357, 482358, 482359, 482363, 482403, 482408, 482421, 482426, 482432, 482437, 482444, 482447, 482455, 482456, 482459, 482463, 482468, 482474, 482484, 482485, 482488, 482491, 482497, 482502, 482505, 482509, 482518, 482522, 482523, 482524, 482527, 482528, 482532, 482543, 482545, 482548, 482549, 482567, 482574, 482578, 482580, 482582, 482583, 482589, 482593, 482599, 482601, 482609, 482611, 482618, 482627, 482644, 482656, 482657, 482663, 482669, 482674, 482675, 482677, 482703, 482779, 482790, 483404, 483419, 483504, 483524, 483535, 483556, 483558, 483559, 483572, 483635, 483653, 483676, 483684, 483696, 483701, 483709, 483754, 483766, 483779, 483790, 483808, 483813, 483828, 483841, 483857, 483870, 483937, 483954, 483977, 483979, 483990, 484005, 484007, 484016, 484054, 484060, 484065, 484068, 484094, 484103, 484108, 484118, 484119, 484131, 484141, 484170, 484187, 484191, 484211, 484217, 484240, 484244, 484281, 484285, 484292, 484299, 484302, 484320, 484325, 484335, 484340, 484354, 484355, 484372, 484380, 484385, 484405, 484412, 484413, 484493, 484495, 484502, 484511, 484513, 484519, 484529, 484561, 484568, 484576, 484586, 484624, 484631, 484643, 484704, 484711, 484724, 484727, 484730, 484738, 484752, 484760, 484773, 484779, 484781, 484782, 484785, 484828, 484830, 484834, 484838, 484876, 484882, 484887, 484934, 484942, 484944, 484952, 484997, 485000, 485003, 485007, 485010, 485018, 485032, 485071, 485082, 485083, 485103, 485129, 485175, 485180, 485181, 485182, 485238, 485245, 485255, 485257, 485279, 485280, 485285, 485318, 485394, 485401, 485406, 485410, 485415, 485416, 485473, 485479, 485482, 486548, 486553, 486558, 486572, 486583, 486584, 486590, 486596, 486610, 486625, 486641, 486642, 486645, 486652, 486659, 486666, 486673, 486680, 486685, 486686, 486697, 486705, 486726, 486729, 486730, 486731, 486736, 486749, 486752, 486754, 486756, 486778, 486779, 486782, 486784, 486808, 486821, 486825, 486833, 486836, 486841, 486845, 486855, 486866, 486873, 486879, 486881, 486887, 486901, 486905, 486906, 486907, 486955, 486968, 486970, 486976, 486980, 486983, 486994, 487004, 487008, 487029, 487033, 487034, 487045, 487057, 487059, 487068, 487077, 487081, 487100, 487101, 487104, 487110, 487114, 487127, 487130, 487132, 487143, 487149, 487150, 487154, 487158, 487178, 487199, 487203, 487213, 487214, 487218, 487238, 487240, 487252, 487262, 487275, 487280, 487289, 487293, 487307, 487310, 487314, 487320, 487324, 487337, 487343, 487357, 487377, 487381, 487391, 487400, 487410, 487424, 487426, 487434, 487445, 487470, 487486, 487492, 487495, 487499, 487506, 487507, 487515, 487527, 487539, 487541, 487554, 487555, 487571, 487580, 487581, 487586, 487588, 487592, 487593, 487597, 487604, 487606, 487610, 487620, 487626, 487650, 487651, 487652, 487656, 487662, 487664, 487677, 487678, 487704, 487706, 487718, 487720, 487742, 487757, 487761, 487780, 487787, 487795, 487801, 487818, 487854, 487865, 487868, 487879, 487885, 487886, 487894, 487919, 487924, 487932, 487950, 487957, 487970, 487982, 487996, 488014, 488022, 488024, 488033, 488035, 488038, 488046, 488051, 488057, 488058, 488060, 488062, 488063, 488073, 488094, 488101, 488103, 488111, 488122, 488124, 488136, 488138, 488154, 488160, 488168, 488195, 488196, 488209, 488216, 488217, 488220, 488229, 488238, 488256, 488290, 488297, 488304, 488305, 488310, 488311, 488321, 488332, 488344, 488345, 488367, 488373, 488380, 488385, 488399, 488410, 488414, 488423, 488430, 488436, 488439, 488440, 488446, 488455, 488468, 488471, 488489, 488491, 488497, 488536, 488540, 488563, 488573, 488582, 488589, 488596, 488600, 488640, 488683, 488750, 488751, 488752, 488763, 488768, 488770, 488825, 488837, 488842, 488960, 488967, 489001, 489003, 489016, 489050, 489059, 489061, 489066, 489105, 489108, 489110, 489129, 489149, 489151, 489161, 489162, 489169, 489180, 489185, 489192, 489198, 489200, 489217, 489220, 489226, 489230, 489233, 489238, 489242, 489255, 489256, 489283, 489299, 489304, 489311, 489316, 489318, 489321, 489332, 489339, 489341, 489345, 489354, 489357, 489366, 489374, 489382, 489386, 489389, 489398, 489400, 489407, 489408, 489411, 489416, 489421, 489424, 489425, 489436, 489457, 489458, 489459, 489470, 489471, 489475, 489480, 489484, 489491, 489505, 489506, 489527, 489533, 489535, 489537, 489538, 489546, 489548, 489558, 489565, 489567, 489569, 489576, 489577, 489584, 489586, 489590, 489603, 489606, 489607, 489608, 489615, 489617, 489620, 489628, 489630, 489631, 489641, 489643, 489644, 489647, 489657, 489662, 489665, 489669, 489673, 489679, 489699, 489723, 489727, 489728, 489740, 489752, 489795, 489797, 489826, 489829, 489830, 489859, 489871, 489879, 489888, 489896, 489898, 489905, 489906, 489912, 489913, 489916, 489938, 489944, 489958, 489965, 489980, 489992, 489998, 490000, 490017, 490019, 490032, 490033, 490044, 490054, 490081, 490088, 490105, 490116, 490119, 490124, 490125, 490130, 490132, 490141, 490161, 490162, 490168, 490175, 490180, 490188, 490199, 490205, 490210, 490237, 490244, 490245, 490248, 490249, 490264, 490268, 490272, 490283, 490286, 490294, 490304, 490312, 490316, 490321, 490328, 490340, 490348, 490356, 490358, 490366, 490367, 490373, 490383, 490387, 490398, 490401, 490431, 490436, 490437, 490439, 490448, 490469, 490470, 490477, 490480, 490483, 490489, 490491, 490493, 490498, 490506, 490508, 490510, 490515, 490516, 490544, 490547, 490548, 490570, 490583, 490584, 490592, 490610, 490611, 490621, 490630, 490639, 490644, 490649, 490650, 490657, 490673, 490676, 490680, 490682, 490683, 490686, 490689, 490694, 490703, 490725, 490731, 490748, 490761, 490775, 490776, 490784, 490785, 490787, 490789, 490791, 490793, 490805, 490808, 490815, 490823, 490832, 490833, 490835, 490841, 490843, 490846, 490847, 490866, 490867, 490871, 490876, 490878, 490888, 490895, 490899, 490900, 490906, 490907, 490912, 490932, 490933, 490935, 490946, 490947, 490949, 490951, 490955, 490958, 490959, 490968, 490975, 490976, 490980, 491006, 491007, 491008, 491020, 491024, 491032, 491034, 491037, 491039, 491041, 491042, 491046, 491048, 491069, 491070, 491079, 491080, 491082, 491084, 491087, 491090, 491094, 491099, 491106, 491107, 491110, 491111, 491112, 491116, 491118, 491119, 491130, 491134, 491135, 491150, 491168, 491171, 491176, 491180, 491181, 491187, 491199, 491200, 491201, 491219, 491223, 491233, 491237, 491238, 491240, 491243, 491247, 491250, 491255, 491256, 491258, 491261, 491265, 491270, 491271, 491272, 491276, 491278, 491280, 491287, 491291, 491305, 491313, 491318, 491319, 491320, 491321, 491323, 491325, 491326, 491327, 491329, 491330, 491335, 491342, 491345, 491346, 491365, 491371, 491373, 491376, 491377, 491390, 491396, 491397, 491408, 491412, 491417, 491418, 491420, 491426, 491434, 491436, 491444, 491448, 491454, 491455, 491463, 491465, 491478, 491484, 491488, 491506, 491507, 491529, 491533, 491534, 491546, 491557, 491558, 491563, 491579, 491594, 491596, 491600, 491603, 491624, 491635, 491636, 491652, 491656, 491659, 491662, 491664, 491665, 491669, 491672, 491675, 491680, 491685, 491687, 491689, 491690, 491694, 491696, 491705, 491716, 491723, 491727, 491730, 491735, 491736, 491739, 491746, 491757, 491763, 491767, 491774, 491776, 491780, 491784, 491788, 491791, 491796, 491798, 491834, 491836, 491837, 491845, 491846, 491848, 491854, 491860, 491866, 491874, 491876, 491877, 491878, 491887, 491895, 491896, 491900, 491904, 491909, 491912, 491913, 491916, 491918, 491920, 491936, 491940, 491945, 491947, 491953, 491960, 491964, 491968, 491979, 491986, 491991, 491992, 492000, 492021, 492022, 492035, 492054, 492055, 492056, 492080, 492132, 492135, 492146, 492155, 492171, 492179, 492189, 492191, 492192, 492209, 492215, 492219, 492236, 492240, 492242, 492247, 492250, 492270, 492286, 492292, 492312, 492315, 492323, 492327, 492341, 492385, 492390, 492397, 492424, 492429, 492430, 492440, 492441, 492442, 492443, 492451, 492459, 492479, 492482, 492488, 492500, 492516, 492519, 492521, 492522, 492523, 492525, 492535, 492574, 492576, 492578, 492582, 492585, 492588, 492592, 492600, 492610, 492612, 492618, 492632, 492639, 492648, 492674, 492691, 492694, 492701, 492714, 492715, 492717, 492720, 492730, 492731, 492749, 492761, 492766, 492771, 492777, 492785, 492806, 492811, 492814, 492822, 492826, 492849, 492850, 492861, 492864, 492866, 492872, 492888, 492895, 492908, 492918, 492929, 492936, 492940, 492942, 492968, 492982, 493008, 493023, 493029, 493033, 493035, 493042, 493056, 493066, 493075, 493106, 493130, 493132, 493142, 493146, 493150, 493158, 493160, 493165, 493174, 493184, 493191, 493207, 493214, 493217, 493222, 493225, 493229, 493233, 493259, 493286, 493291, 493300, 493302, 493319, 493334, 493343, 493360, 493376, 493385, 493386, 493387, 493391, 493394, 493399, 493400, 493408, 493411, 493413, 493420, 493423, 493424, 493425, 493426, 493434, 493444, 493452, 493466, 493468, 493469, 493490, 493491, 493497, 493508, 493509, 493511, 493512, 493514, 493515, 493527, 493546, 493561, 493566, 493567, 493574, 493595, 493616, 493618, 493626, 493641, 493650, 493653, 493655, 493683, 493686, 493690, 493702, 493710, 493727, 493738, 493752, 493762, 493765, 493780, 493782, 493784, 493788, 493793, 493802, 493809, 493812, 493817, 493830, 493861, 493868, 493886, 493888, 493892, 493897, 493907, 493912, 493915, 493916, 493925, 493927, 493947, 493949, 493965, 493967, 493972, 493975, 493979, 493990, 493992, 494000, 494003, 494006, 494008, 494016, 494050, 494059, 494066, 494067, 494071, 494075, 494083, 494089, 494090, 494097, 494103, 494104, 494112, 494119, 494123, 494124, 494125, 494133, 494137, 494145, 494164, 494168, 494169, 494184, 494211, 494236, 494251, 494256, 494259, 494263, 494276, 494279, 494291, 494293, 494297, 494307, 494309, 494310, 494324, 494335, 494348, 494368, 494378, 494379, 494382, 494390, 494391, 494392, 494398, 494414, 494428, 494434, 494441, 494458, 494460, 494461, 494469, 494476, 494488, 494489, 494494, 494495, 494496, 494502, 494521, 494523, 494528, 494536, 494537, 494538, 494548, 494555, 494578, 494592, 494594, 494595, 494607, 494617, 494627, 494645, 494647, 494648, 494659, 494660, 494665, 494667, 494676, 494680, 494684, 494685, 494688, 494689, 494700, 494701, 494713, 494727, 494750, 494752, 494754, 494758, 494765, 494769, 494783, 494789, 494791, 494801, 494808, 494818, 494826, 494828, 494830, 494839, 494846, 494852, 494856, 494858, 494865, 494875, 494881, 494903, 494910, 494913, 494918, 494922, 494928, 494962, 494963, 494966, 494967, 494981, 494983, 494987, 494993, 495005, 495018, 495022, 495023, 495024, 495039, 495042, 495048, 495054, 495075, 495079, 495092, 495104, 495115, 495136, 495137, 495140, 495145, 495148, 495156, 495163, 495165, 495166, 495169, 495178, 495179, 495188, 495204, 495217, 495226, 495232, 495238, 495249, 495251, 495254, 495256, 495283, 495289, 495291, 495292, 495298, 495299, 495307, 495308, 495313, 495314, 495330, 495333, 495339, 495349, 495353, 495354, 495361, 495367, 495369, 495371, 495376, 495399, 495402, 495403, 495410, 495426, 495441, 495470, 495475, 495477, 495480, 495481, 495495, 495499, 495500, 495503, 495508, 495517, 495519, 495525, 495534, 495535, 495544, 495548, 495564, 495580, 495585, 495593, 495602, 495617, 495622, 495635, 495664, 495666, 495678, 495681, 495689, 495710, 495724, 495726, 495737, 495767, 495769, 495772, 495774, 495776, 495795, 495797, 495800, 495802, 495810, 495826, 495829, 495837, 495842, 495845, 495852, 495868, 495870, 495877, 495881, 495890, 495904, 496171, 496175, 496185, 496189, 496190, 496193, 496195, 496197, 496198, 496199, 496207, 496226, 496227, 496228, 496236, 496243, 496244, 496245, 496247, 496263, 496277, 496286, 496290, 496299, 496301, 496325, 496336, 496341, 496367, 496403, 496405, 496417, 496428, 496431, 496454, 496457, 496470, 496477, 496494, 496504, 496516, 496518, 496535, 496546, 496557, 496564, 496565, 496570, 496576, 496580, 496603, 496611, 496617, 496626, 496636, 496643, 496650, 496664, 496665, 496678, 496680, 496684, 496703, 496704, 496711, 496720, 496726, 496727, 496730, 496731, 496737, 496742, 496748, 496750, 496756, 496762, 496777, 496783, 496792, 496805, 496818, 496834, 496836, 496846, 496876, 496880, 496881, 496904, 496915, 496920, 496923, 496933, 496939, 496940, 496950, 496960, 496972, 496974, 496986, 497004, 497011, 497014, 497022, 497031, 497063, 497075, 497078, 497084, 497100, 497103, 497109, 497114, 497117, 497125, 497143, 497207, 497243, 497252, 497255, 497260, 497273, 497278, 497280, 497288, 497321, 497329, 497337, 497348, 497354, 497355, 497356, 497369, 497377, 497378, 497382, 497396, 497420, 497446, 497453, 497464, 497474, 497482, 497487, 497494, 497498, 497510, 497513, 497517, 497519, 497529, 497534, 497535, 497541, 497545, 497552, 497561, 497563, 497566, 497575, 497582, 497583, 497584, 497594, 497600, 497603, 497607, 497608, 497637, 497647, 497658, 497659, 497669, 497676, 497677, 497683, 497688, 497690, 497705, 497707, 497713, 497720, 497724, 497726, 497727, 497733, 497738, 497747, 497751, 497753, 497758, 497759, 497769, 497778, 497780, 497786, 497794, 497796, 497799, 497800, 497813, 497826, 497835, 497837, 497844, 497851, 497855, 497886, 497890, 497896, 497898, 497904, 497911, 497923, 497925, 497929, 497943, 497945, 497950, 497951, 497967, 497984, 497994, 497995, 497998, 498001, 498003, 498008, 498016, 498024, 498031, 498033, 498035, 498036, 498037, 498045, 498052, 498053, 498057, 498059, 498060, 498068, 498078, 498086, 498094, 498107, 498110, 498112, 498113, 498132, 498141, 498154, 498155, 498158, 498160, 498165, 498192, 498195, 498210, 498211, 498213, 498223, 498229, 498234, 498235, 498238, 498260, 498261, 498265, 498273, 498277, 498279, 498281, 498292, 498316, 498319, 498331, 498334, 498335, 498347, 498350, 498361, 498363, 498372, 498381, 498388, 498392, 498395, 498405, 498409, 498414, 498419, 498421, 498422, 498424, 498442, 498459, 498467, 498473, 498479, 498489, 498491, 498492, 498508, 498509, 498532, 498534, 498543, 498549, 498558, 498568, 498577, 498582, 498589, 498592, 498594, 498597, 498603, 498614, 498621, 498636, 498637, 498640, 498655, 498656, 498674, 498680, 498689, 498690, 498691, 498694, 498697, 498715, 498717, 498723, 498735, 498739, 498743, 498755, 498770, 498776, 498779, 498785, 498787, 498799, 498800, 498811, 498821, 498833, 498838, 498843, 498844, 498856, 498866, 498870, 498873, 498879, 498886, 498891, 498902, 498910, 498931, 498939, 498954, 498963, 498974, 498981, 498985, 499000, 499002, 499007, 499019, 499027, 499029, 499046, 499047, 499056, 499060, 499062, 499066, 499071, 499108, 499119, 499121, 499126, 499128, 499135, 499319, 499320, 499324, 499330, 499353, 499369, 499371, 499374, 499376, 499378, 499387, 499403, 499410, 499416, 499418, 499419, 499423, 499424, 499427, 499433, 499438, 499445, 499446, 499458, 499462, 499463, 499464, 499473, 499487, 499499, 499500, 499506, 499514, 499524, 499539, 499541, 499542, 499549, 499557, 499558, 499565, 499567, 499584, 499587, 499589, 499597, 499608, 499618, 499622, 499623, 499631, 499638, 499639, 499653, 499656, 499661, 499663, 499667, 499689, 499695, 499697, 499702, 499713, 499718, 499720, 499723, 499729, 499733, 499738, 499748, 499754, 499760, 499765, 499766, 499767, 499777, 499779, 499795, 499799, 499801, 499811, 499824, 499832, 499835, 499839, 499843, 499844, 499850, 499859, 499865, 499868, 499878, 499881, 499886, 499889, 499890, 499905, 499918, 499921, 499933, 499944, 499948, 499957, 499958, 499960, 499961, 499972, 499974, 499996, 500003, 500015, 500016, 500022, 500043, 500047, 500050, 500053, 500054, 500058, 500066, 500081, 500082, 500087, 500093, 500103, 500104, 500109, 500116, 500126, 500140, 500163, 500166, 500175, 500183, 500185, 500186, 500189, 500204, 500214, 500215, 500228, 500234, 500240, 500244, 500247, 500256, 500272, 500275, 500283, 500304, 500309, 500314, 500333, 500336, 500342, 500343, 500347, 500348, 500351, 500356, 500360, 500374, 500377, 500385, 500388, 500393, 500394, 500400, 500401, 500402, 500414, 500423, 500444, 500445, 500446, 500448, 500458, 500471, 500476, 500477, 500482, 500483, 500491, 500497, 500500, 500501, 500506, 500508, 500512, 500519, 500533, 500535, 500537, 500569, 500572, 500585, 500590, 500595, 500597, 500602, 500624, 500630, 500632, 500637, 500638, 500644, 500646, 500652, 500663, 500665, 500667, 500672, 500680, 500688, 500695, 500697, 500702, 500724, 500726, 500727, 500739, 500741, 500751, 500752, 500757, 500771, 500791, 500793, 500794, 500796, 500814, 500816, 500822, 500823, 500829, 500832, 500836, 500855, 500861, 500864, 500871, 500880, 500887, 500897, 500900, 500903, 500905, 500916, 500918, 500926, 500927, 500928, 500930, 500932, 500933, 500934, 500937, 500941, 500947, 500957, 500960, 500961, 500965, 500969, 500970, 500971, 500973, 500981, 500983, 500990, 500992, 500994, 500996, 500998, 501004, 501009, 501012, 501014, 501038, 501040, 501041, 501046, 501051, 501056, 501059, 501060, 501063, 501070, 501072, 501081, 501086, 501094, 501096, 501105, 501106, 501107, 501109, 501117, 501126, 501127, 501129, 501130, 501137, 501139, 501144, 501146, 501153, 501155, 501160, 501168, 501169, 501170, 501174, 501178, 501194, 501196, 501210, 501214, 501225, 501226, 501236, 501238, 501239, 501243, 501257, 501260, 501261, 501264, 501268, 501274, 501277, 501280, 501285, 501286, 501289, 501297, 501298, 501301, 501306, 501314, 501332, 501335, 501337, 501339, 501341, 501342, 501343, 501347, 501362, 501368, 501376, 501382, 501387, 501388, 501409, 501416, 501417, 501419, 501424, 501427, 501428, 501433, 501441, 501443, 501456, 501466, 501470, 501477, 501481, 501486, 501487, 501498, 501507, 501508, 501510, 501512, 501518, 501525, 501526, 501532, 501534, 501540, 501564, 501567, 501572, 501575, 501579, 501591, 501592, 501596, 501598, 501603, 501606, 501610, 501612, 501613, 501619, 501622, 501628, 501641, 501642, 501655, 501657, 501663, 501664, 501667, 501671, 501675, 501677, 501681, 501682, 501685, 501687, 501689, 501694, 501697, 501699, 501704, 501716, 501731, 501733, 501735, 501738, 501740, 501748, 501752, 501771, 501777, 501784, 501786, 501787, 501801, 501802, 501819, 501824, 501828, 501834, 501850, 501855, 501860, 501869, 501872, 501877, 501881, 501889, 501892, 501896, 501910, 501915, 501917, 501923, 501925, 501932, 501935, 501938, 501939, 501944, 501951, 501953, 501954, 501980, 501984, 501995, 501996, 502004, 502008, 502009, 502010, 502017, 502021, 502022, 502023, 502024, 502044, 502068, 502077, 502078, 502079, 502085, 502087, 502096, 502097, 502123, 502129, 502138, 502155, 502200, 502206, 502208, 502211, 502212, 502217, 502219, 502222, 502223, 502228, 502234, 502239, 502240, 502243, 502245, 502250, 502254, 502263, 502275, 502281, 502287, 502288, 502306, 502310, 502327, 502328, 502333, 502343, 502346, 502353, 502354, 502363, 502364, 502368, 502370, 502372, 502376, 502380, 502385, 502386, 502397, 502409, 502422, 502439, 502443, 502453, 502455, 502461, 502462, 502467, 502469, 502478, 502483, 502484, 502489, 502497, 502502, 502510, 502513, 502518, 502537, 502540, 502549, 502555, 502562, 502566, 502569, 502578, 502585, 502591, 502598, 502605, 502616, 502619, 502620, 502623, 502625, 502632, 502637, 502641, 502647, 502652, 502670, 502673, 502681, 502685, 502689, 502697, 502698, 502702, 502712, 502714, 502718, 502722, 502728, 502734, 502739, 502750, 502755, 502766, 502770, 502792, 502793, 502798, 502803, 502804, 502808, 502812, 502821, 502825, 502827, 502828, 502841, 502852, 502856, 502857, 502866, 502873, 502883, 502887, 502890, 502892, 502893, 502905, 502907, 502916, 502917, 502930, 502932, 502936, 502957, 502964, 502967, 502973, 502978, 502984, 502986, 502998, 503023, 503043, 503054, 503067, 503072, 503078, 503080, 503092, 503106, 503112, 503115, 503116, 503125, 503141, 503145, 503151, 503152, 503160, 503168, 503171, 503172, 503184, 503187, 503192, 503194, 503200, 503202, 503204, 503205, 503221, 503224, 503227, 503232, 503235, 503238, 503239, 503260, 503261, 503274, 503285, 503292, 503293, 503308, 503312, 503315, 503324, 503332, 503338, 503339, 503340, 503341, 503345, 503352, 503354, 503361, 503370, 503371, 503376, 503378, 503386, 503387, 503390, 503392, 503394, 503396, 503403, 503406, 503424, 503441, 503443, 503447, 503454, 503459, 503461, 503462, 503463, 503470, 503471, 503472, 503480, 503486, 503488, 503490, 503494, 503500, 503508, 503526, 503528, 503529, 503539, 503542, 503549, 503555, 503556, 503577, 503578, 503581, 503582, 503587, 503592, 503601, 503607, 503611, 503614, 503623, 503642, 503652, 503667, 503674, 503684, 503685, 503696, 503699, 503713, 503715, 503719, 503720, 503721, 503725, 503729, 503733, 503739, 503751, 503754, 503765, 503775, 503787, 503789, 503790, 503792, 503793, 503795, 503796, 503797, 503800, 503802, 503806, 503819, 503830, 503831, 503832, 503833, 503834, 503836, 503837, 503838, 503839, 503840, 503842, 503844, 503845, 503846, 503849, 503850, 503851, 503852, 503853, 503854, 503855, 503856, 503857, 503860, 503861, 503862, 503863, 503864, 503865, 503866, 503867, 503868, 503870, 503871, 503872, 503873, 503874, 503876, 503877, 503891, 503892, 503898, 503899, 503900, 503901, 503902, 503905, 503911, 503912, 503918, 503922, 503924, 503935, 503941, 503945, 503949, 503951, 503952, 503962, 503968, 503970, 503972, 503978, 503981, 503982, 503983, 503993, 503995, 503998, 504000, 504010, 504026, 504039, 504048, 504049, 504058, 504059, 504071, 504084, 504091, 504096, 504097, 504106, 504113, 504118, 504120, 504137, 504140, 504143, 504144, 504147, 504148, 504160, 504169, 504174, 504176, 504181, 504184, 504187, 504188, 504190, 504200, 504207, 504222, 504223, 504224, 504228, 504229, 504231, 504233, 504239, 504240, 504242, 504245, 504246, 504251, 504261, 504273, 504278, 504307, 504308, 504311, 504315, 504321, 504331, 504335, 504336, 504347, 504358, 504364, 504365, 504368, 504377, 504380, 504384, 504385, 504386, 504402, 504406, 504418, 504419, 504423, 504424, 504426, 504427, 504431, 504441, 504451, 504452, 504463, 504467, 504470, 504479, 504483, 504494, 504497, 504512, 504515, 504526, 504529, 504531, 504537, 504547, 504548, 504549, 504551, 504557, 504558, 504566, 504580, 504589, 504591, 504598, 504602, 504605, 504610, 504611, 504612, 504613, 504614, 504616, 504617, 504618, 504620, 504622, 504623, 504624, 504625, 504627, 504630, 504631, 504632, 504633, 504634, 504635, 504638, 504639, 504640, 504641, 504643, 504644, 504647, 504649, 504651, 504652, 504653, 504654, 504655, 504656, 504657, 504660, 504661, 504663, 504666, 504668, 504671, 504673, 504674, 504679, 504680, 504684, 504687, 504692, 504695, 504698, 504708, 504728, 504730, 504747, 504758, 504764, 504766, 504768, 504769, 504773, 504785, 504786, 504793, 504800, 504801, 504806, 504810, 504814, 504818, 504821, 504826, 504830, 504832, 504833, 504840, 504844, 504850, 504853, 504868, 504872, 504884, 504886, 504892, 504897, 504899, 504901, 504906, 504923, 504928, 504929, 504933, 504942, 504949, 504970, 504972, 504976, 504977, 504982, 504983, 504986, 505005, 505013, 505022, 505023, 505024, 505033, 505043, 505048, 505049, 505061, 505062, 505064, 505066, 505068, 505071, 505072, 505074, 505075, 505086, 505090, 505097, 505101, 505104, 505110, 505118, 505128, 505130, 505131, 505132, 505139, 505144, 505145, 505156, 505157, 505159, 505161, 505173, 505176, 505177, 505180, 505189, 505194, 505196, 505203, 505208, 505219, 505228, 505229, 505240, 505241, 505254, 505265, 505272, 505277, 505287, 505288, 505291, 505292, 505298, 505301, 505314, 505330, 505334, 505337, 505342, 505343, 505347, 505348, 505365, 505372, 505374, 505381, 505389, 505404, 505410, 505420, 505422, 505430, 505431, 505442, 505445, 505454, 505456, 505458, 505464, 505470, 505478, 505481, 505491, 505499, 505527, 505529, 505532, 505537, 505555, 505559, 505570, 505579, 505588, 505589, 505594, 505596, 505605, 505606, 505615, 505622, 505623, 505624, 505633, 505637, 505639, 505645, 505650, 505652, 505653, 505654, 505655, 505660, 505661, 505670, 505671, 505677, 505684, 505693, 505695, 505705, 505717, 505723, 505727, 505733, 505737, 505744, 505747, 505752, 505757, 505758, 505772, 505775, 505796, 505800, 505805, 505815, 505822, 505845, 505847, 505848, 505863, 505873, 505880, 505893, 505894, 505899, 505904, 505911, 505918, 505921, 505922, 505928, 505935, 505937, 505940, 505941, 505943, 505946, 505951, 505954, 505957, 505958, 505960, 505963, 505966, 505976, 505977, 505982, 505998, 505999, 506002, 506027, 506033, 506043, 506044, 506051, 506056, 506062, 506063, 506064, 506069, 506070, 506072, 506078, 506099, 506114, 506118, 506121, 506127, 506139, 506147, 506150, 506156, 506157, 506165, 506172, 506174, 506175, 506179, 506199, 506201, 506202, 506207, 506208, 506212, 506214, 506219, 506221, 506230, 506231, 506238, 506257, 506258, 506267, 506272, 506279, 506282, 506290, 506294, 506297, 506298, 506310, 506313, 506314, 506330, 506339, 506350, 506357, 506359, 506361, 506367, 506369, 506376, 506379, 506380, 506391, 506392, 506399, 506414, 506415, 506426, 506429, 506434, 506435, 506437, 506438, 506462, 506480, 506497, 506498, 506500, 506501, 506504, 506507, 506513, 506514, 506520, 506524, 506527, 506531, 506534, 506542, 506545, 506550, 506555, 506557, 506567, 506572, 506574, 506587, 506594, 506602, 506624, 506627, 506629, 506631, 506632, 506633, 506635, 506644, 506646, 506650, 506657, 506660, 506667, 506668, 506679, 506698, 506702, 506713, 506723, 506727, 506730, 506751, 506760, 506763, 506764, 506768, 506769, 506776, 506782, 506787, 506806, 506807, 506808, 506811, 506826, 506852, 506867, 506886, 506907, 506912, 506914, 506929, 506930, 506948, 506956, 506962, 506968, 506969, 506977, 506980, 506981, 507001, 507002, 507006, 507008, 507019, 507030, 507047, 507050, 507052, 507054, 507071, 507086, 507089, 507101, 507114, 507118, 507120, 507125, 507127, 507148, 507151, 507155, 507168, 507193, 507216, 507227, 507233, 507235, 507241, 507248, 507257, 507260, 507275, 507294, 507298, 507302, 507319, 507343, 507349, 507357, 507358, 507376, 507387, 507398, 507408, 507415, 507432, 507436, 507441, 507443, 507447, 507472, 507482, 507487, 507517, 507519, 507524, 507525, 507537, 507550, 507554, 507559, 507560, 507562, 507564, 507574, 507581, 507583, 507585, 507587, 507593, 507602, 507615, 507633, 507634, 507635, 507641, 507649, 507664, 507671, 507674, 507675, 507690, 507691, 507698, 507705, 507707, 507719, 507728, 507745, 507753, 507761, 507773, 507787, 507791, 507801, 507806, 507812, 507813, 507817, 507821, 507826, 507830, 507836, 507841, 507844, 507869, 507871, 507874, 507875, 507880, 507886, 507893, 507909, 507920, 507923, 507926, 507928, 507937, 507948, 507952, 507968, 507980, 507987, 507988, 507993, 507996, 507999, 508009, 508014, 508024, 508030, 508058, 508060, 508064, 508070, 508079, 508081, 508086, 508092, 508098, 508116, 508131, 508134, 508147, 508151, 508161, 508168, 508176, 508182, 508189, 508197, 508200, 508203, 508231, 508235, 508253, 508258, 508262, 508266, 508273, 508281, 508297, 508298, 508303, 508308, 508317, 508332, 508343, 508349, 508353, 508356, 508360, 508363, 508367, 508371, 508377, 508382, 508399, 508411, 508435, 508448, 508454, 508459, 508485, 508486, 508489, 508492, 508494, 508507, 508511, 508519, 508520, 508525, 508541, 508548, 508564, 508565, 508569, 508573, 508575, 508596, 508597, 508605, 508606, 508621, 508622, 508628, 508631, 508632, 508641, 508643, 508644, 508650, 508655, 508660, 508672, 508678, 508679, 508698, 508705, 508734, 508748, 508752, 508755, 508763, 508767, 508783, 508797, 508798, 508808, 508815, 508823, 508834, 508864, 508889, 508909, 508912, 508916, 508922, 508924, 508926, 508933, 508947, 508949, 508950, 508954, 508959, 508961, 508967, 508972, 509033, 509045, 509046, 509064, 509071, 509083, 509117, 509120, 509136, 509137, 509143, 509145, 509154, 509156, 509159, 509168, 509175, 509177, 509185, 509191, 509206, 509228, 509238, 509242, 509243, 509246, 509253, 509261, 509264, 509268, 509276, 509280, 509281, 509289, 509313, 509317, 509333, 509336, 509337, 509340, 509346, 509351, 509376, 509379, 509391, 509400, 509407, 509410, 509414, 509424, 509425, 509428, 509433, 509445, 509451, 509463, 509485, 509496, 509501, 509512, 509515, 509533, 509537, 509544, 509566, 509574, 509579, 509585, 509589, 509593, 509602, 509605, 509616, 509619, 509627, 509642, 509661, 509668, 509673, 509683, 509687, 509700, 509702, 509703, 509705, 509710, 509715, 509721, 509723, 509724, 509726, 509729, 509730, 509749, 509773, 509774, 509777, 509779, 509794, 509798, 509804, 509805, 509814, 509815, 509822, 509836, 509845, 509850, 509857, 509866, 509878, 509888, 509889, 509893, 509904, 509913, 509917, 509919, 509928, 509933, 509940, 509942, 509956, 509965, 509970, 509978, 509982, 509985, 509993, 510008, 510015, 510026, 510035, 510036, 510043, 510044, 510048, 510054, 510071, 510086, 510089, 510101, 510107, 510112, 510133, 510136, 510140, 510141, 510175, 510178, 510198, 510205, 510207, 510208, 510212, 510230, 510235, 510237, 510240, 510244, 510245, 510247, 510255, 510261, 510263, 510265, 510286, 510296, 510305, 510310, 510326, 510332, 510333, 510335, 510342, 510345, 510352, 510373, 510375, 510376, 510386, 510391, 510394, 510418, 510424, 510427, 510436, 510440, 510448, 510471, 510475, 510484, 510487, 510492, 510494, 510496, 510499, 510506, 510510, 510525, 510533, 510545, 510547, 510551, 510555, 510557, 510559, 510565, 510568, 510591, 510616, 510619, 510623, 510640, 510660, 510665, 510666, 510668, 510670, 510673, 510677, 510682, 510696, 510708, 510721, 510727, 510738, 510759, 510784, 510801, 510810, 510812, 510815, 510819, 510832, 510834, 510835, 510841, 510846, 510852, 510854, 510866, 510869, 510873, 510882, 510908, 510914, 510917, 510920, 510921, 510927, 510928, 510940, 510957, 510960, 510961, 510963, 510985, 510986, 510988, 510993, 510994, 511013, 511018, 511019, 511029, 511031, 511034, 511036, 511037, 511040, 511053, 511054, 511058, 511072, 511086, 511122, 511130, 511148, 511151, 511154, 511162, 511167, 511168, 511170, 511183, 511197, 511210, 511216, 511223, 511244, 511249, 511252, 511255, 511258, 511266, 511273, 511279, 511285, 511290, 511312, 511314, 511316, 511317, 511320, 511327, 511332, 511369, 511375, 511377, 511381, 511409, 511410, 511423, 511433, 511442, 511443, 511447, 511455, 511460, 511470, 511476, 511500, 511503, 511514, 511516, 511517, 511525, 511549, 511550, 511551, 511568, 511577, 511581, 511589, 511607, 511611, 511624, 511636, 511650, 511655, 511671, 511672, 511707, 511712, 511722, 511744, 511754, 511757, 511758, 511760, 511767, 511773, 511793, 511794, 511817, 511818, 511837, 511839, 511848, 511852, 511874, 511875, 511878, 511885, 511891, 511900, 511909, 511917, 511921, 511925, 511936, 511939, 511945, 511954, 511961, 511962, 511967, 511982, 511994, 512001, 512005, 512028, 512031, 512047, 512059, 512062, 512063, 512064, 512076, 512077, 512082, 512089, 512092, 512093, 512102, 512107, 512108, 512118, 512127, 512139, 512157, 512162, 512173, 512176, 512178, 512183, 512191, 512195, 512201, 512202, 512210, 512215, 512221, 512244, 512245, 512250, 512261, 512262, 512277, 512285, 512292, 512300, 512306, 512319, 512322, 512333, 512336, 512341, 512370, 512382, 512385, 512387, 512389, 512399, 512402, 512407, 512413, 512428, 512461, 512463, 512474, 512475, 512476, 512478, 512481, 512483, 512489, 512505, 512508, 512511, 512513, 512542, 512554, 512555, 512558, 512559, 512569, 512574, 512595, 512598, 512601, 512613, 512617, 512620, 512633, 512652, 512655, 512662, 512670, 512671, 512674, 512682, 512685, 512689, 512694, 512696, 512697, 512702, 512704, 512707, 512709, 512714, 512722, 512726, 512732, 512734, 512746, 512749, 512752, 512753, 512772, 512774, 512782, 512789, 512815, 512839, 512849, 512852, 512857, 512861, 512866, 512869, 512873, 512887, 512895, 512897, 512899, 512903, 512923, 512926, 512933, 512947, 512963, 512975, 512985, 513000, 513006, 513010, 513014, 513029, 513031, 513034, 513040, 513055, 513057, 513072, 513077, 513082, 513091, 513100, 513106, 513107, 513110, 513113, 513116, 513117, 513119, 513125, 513127, 513146, 513157, 513161, 513172, 513182, 513185, 513216, 513218, 513226, 513228, 513242, 513245, 513246, 513249, 513258, 513267, 513268, 513286, 513287, 513294, 513301, 513302, 513305, 513313, 513317, 513321, 513333, 513340, 513344, 513367, 513372, 513383, 513385, 513402, 513403, 513406, 513425, 513429, 513440, 513446, 513448, 513449, 513469, 513470, 513473, 513478, 513484, 513502, 513524, 513535, 513559, 513602, 513610, 513629, 513634, 513652, 513654, 513656, 513667, 513672, 513689, 513703, 513706, 513713, 513715, 513718, 513720, 513725, 513732, 513733, 513736, 513750, 513761, 513774, 513777, 513779, 513783, 513791, 513797, 513803, 513811, 513816, 513828, 513831, 513839, 513845, 513847, 513856, 513860, 513878, 513886, 513890, 513893, 513897, 513900, 513912, 513917, 513928, 513937, 513967, 513989, 513995, 514005, 514008, 514019, 514022, 514041, 514044, 514049, 514058, 514074, 514082, 514093, 514110, 514111, 514148, 514160, 514217, 514248, 514272, 514278, 514332, 514357, 514397, 514409, 514430, 514503, 514512, 514522, 514527, 514533, 514534, 514542, 514548, 514558, 514568, 514583, 514620, 514625, 514635, 514652, 514668, 514669, 514673, 514693, 514723, 514724, 514779, 514794, 514800, 514867, 514926, 515029, 515173, 515175, 515185, 515186, 515189, 515190, 515196, 515197, 515208, 515209, 515211, 515214, 515216, 515231, 515249, 515256, 515259, 515262, 515269, 515270, 515274, 515276, 515280, 515281, 515300, 515301, 515311, 515318, 515319, 515325, 515333, 515339, 515342, 515343, 515345, 515351, 515354, 515355, 515358, 515359, 515360, 515361, 515363, 515372, 515374, 515376, 515380, 515388, 515390, 515407, 515408, 515414, 515436, 515445, 515451, 515455, 515457, 515460, 515466, 515474, 515475, 515476, 515488, 515491, 515500, 515501, 515510, 515511, 515516, 515527, 515543, 515555, 515579, 515591, 515597, 515606, 515609, 515616, 515622, 515623, 515626, 515633, 515649, 515666, 515679, 515682, 515687, 515690, 515703, 515711, 515713, 515727, 515737, 515764, 515772, 515773, 515775, 515778, 515784, 515802, 515814, 515819, 515821, 515823, 515824, 515828, 515829, 515830, 515833, 515842, 515856, 515859, 515860, 515871, 515873, 515874, 515877, 515884, 515893, 515897, 515900, 515901, 515907, 515910, 515914, 515918, 515922, 515937, 515945, 515947, 515951, 515952, 515962, 515974, 515978, 516007, 516011, 516013, 516016, 516030, 516040, 516044, 516055, 516057, 516060, 516067, 516075, 516076, 516086, 516097, 516098, 516099, 516104, 516109, 516120, 516122, 516125, 516133, 516143, 516146, 516147, 516175, 516180, 516186, 516193, 516214, 516229, 516271, 516272, 516276, 516278, 516282, 516291, 516295, 516300, 516304, 516324, 516334, 516335, 516337, 516339, 516351, 516356, 516359, 516362, 516363, 516369, 516384, 516391, 516421, 516428, 516439, 516445, 516448, 516467, 516468, 516475, 516480, 516484, 516488, 516490, 516498, 516500, 516503, 516507, 516511, 516512, 516514, 516516, 516519, 516529, 516533, 516534, 516537, 516540, 516544, 516573, 516576, 516596, 516602, 516620, 516629, 516636, 516643, 516648, 516655, 516677, 516681, 516689, 516709, 516719, 516725, 516734, 516735, 516753, 516759, 516777, 516798, 516800, 516805, 516809, 516817, 516819, 516827, 516836, 516842, 516843, 516854, 516866, 516873, 516876, 516877, 516881, 516898, 516906, 516907, 516915, 516920, 516925, 516926, 516938, 516940, 516948, 516953, 516955, 516956, 516957, 516958, 516965, 516968, 516970, 516971, 516974, 516976, 517001, 517007, 517011, 517014, 517016, 517017, 517028, 517030, 517036, 517037, 517038, 517045, 517060, 517061, 517062, 517066, 517069, 517077, 517080, 517083, 517086, 517087, 517090, 517093, 517096, 517099, 517100, 517104, 517108, 517111, 517127, 517131, 517133, 517140, 517146, 517157, 517179, 517183, 517184, 517187, 517196, 517197, 517198, 517203, 517204, 517222, 517225, 517231, 517233, 517239, 517241, 517256, 517278, 517279, 517292, 517300, 517319, 517328, 517331, 517332, 517333, 517337, 517340, 517341, 517346, 517348, 517350, 517352, 517353, 517354, 517359, 517362, 517364, 517366, 517371, 517373, 517376, 517377, 517380, 517394, 517396, 517400, 517405, 517406, 517412, 517414, 517417, 517427, 517432, 517438, 517441, 517448, 517449, 517451, 517452, 517453, 517461, 517463, 517470, 517479, 517481, 517482, 517495, 517496, 517498, 517508, 517509, 517519, 517520, 517536, 517544, 517550, 517557, 517562, 517565, 517568, 517574, 517586, 517592, 517599, 517606, 517611, 517616, 517619, 517623, 517628, 517635, 517639, 517647, 517649, 517651, 517654, 517656, 517661, 517662, 517666, 517671, 517676, 517677, 517679, 517684, 517685, 517687, 517689, 517696, 517705, 517709, 517714, 517732, 517739, 517741, 517742, 517746, 517750, 517752, 517759, 517763, 517767, 517770, 517773, 517774, 517777, 517781, 517787, 517792, 517794, 517795, 517798, 517806, 517808, 517810, 517812, 517815, 517820, 517825, 517830, 517836, 517840, 517842, 517851, 517861, 517864, 517870, 517873, 517876, 517878, 517880, 517887, 517890, 517891, 517892, 517899, 517902, 517922, 517929, 517931, 517937, 517946, 517947, 517958, 517961, 517970, 517983, 517984, 517986, 517994, 518006, 518011, 518012, 518026, 518029, 518034, 518035, 518041, 518049, 518051, 518061, 518063, 518075, 518083, 518085, 518093, 518097, 518104, 518110, 518115, 518122, 518126, 518131, 518134, 518141, 518142, 518158, 518165, 518185, 518211, 518214, 518219, 518224, 518225, 518235, 518239, 518240, 518244, 518271, 518283, 518290, 518296, 518299, 518306, 518309, 518320, 518330, 518331, 518356, 518358, 518361, 518363, 518365, 518371, 518373, 518397, 518403, 518404, 518412, 518418, 518420, 518424, 518429, 518432, 518446, 518456, 518460, 518477, 518480, 518482, 518491, 518495, 518500, 518503, 518507, 518509, 518510, 518514, 518516, 518525, 518526, 518533, 518535, 518539, 518544, 518550, 518557, 518564, 518567, 518570, 518572, 518575, 518586, 518590, 518597, 518598, 518600, 518602, 518605, 518607, 518611, 518616, 518618, 518628, 518631, 518638, 518640, 518642, 518662, 518664, 518665, 518667, 518681, 518693, 518695, 518702, 518707, 518713, 518715, 518718, 518725, 518728, 518729, 518735, 518736, 518739, 518753, 518754, 518761, 518763, 518770, 518780, 518800, 518804, 518825, 518831, 518843, 518844, 518846, 518854, 518856, 518860, 518861, 518875, 518882, 518883, 518886, 518887, 518888, 518900, 518908, 518911, 518917, 518919, 518923, 518931, 518935, 518952, 518957, 518958, 518973, 518981, 518986, 519040, 519041, 519056, 519080, 519082, 519104, 519131, 519133, 519141, 519145, 519147, 519183, 519206, 519207, 519212, 519217, 519230, 519232, 519233, 519256, 519257, 519263, 519264, 519277, 519281, 519282, 519301, 519306, 519310, 519319, 519323, 519332, 519333, 519334, 519343, 519344, 519374, 519398, 519400, 519402, 519427, 519431, 519442, 519454, 519462, 519468, 519475, 519478, 519490, 519491, 519502, 519505, 519520, 519527, 519539, 519542, 519548, 519550, 519551, 519565, 519570, 519574, 519577, 519603, 519606, 519621, 519622, 519631, 519644, 519647, 519659, 519680, 519690, 519694, 519698, 519704, 519713, 519715, 519731, 519734, 519736, 519737, 519748, 519760, 519762, 519765, 519786, 519787, 519809, 519832, 519833, 519835, 519888, 519894, 519895, 519905, 519927, 519938, 519951, 519953, 519955, 519966, 519970, 519984, 519986, 520001, 520009, 520035, 520038, 520057, 520081, 520086, 520090, 520093, 520111, 520119, 520120, 520127, 520147, 520166, 520171, 520174, 520198, 520200, 520221, 520244, 520253, 520262, 520266, 520277, 520287, 520296, 520312, 520323, 520324, 520344, 520348, 520352, 520359, 520363, 520367, 520376, 520381, 520395, 520398, 520399, 520405, 520409, 520417, 520418, 520429, 520444, 520446, 520447, 520454, 520457, 520459, 520460, 520486, 520488, 520496, 520500, 520504, 520506, 520508, 520531, 520532, 520535, 520544, 520573, 520593, 520597, 520623, 520624, 520647, 520650, 520680, 520683, 520687, 520692, 520693, 520700, 520704, 520711, 520712, 520732, 520741, 520742, 520745, 520747, 520759, 520782, 520790, 520802, 520808, 520813, 520817, 520821, 520847, 520849, 520853, 520856, 520861, 520863, 520872, 520881, 520887, 520890, 520893, 520894, 520919, 520921, 520926, 520930, 520932, 520951, 520964, 520973, 521002, 521007, 521009, 521010, 521014, 521025, 521041, 521044, 521051, 521061, 521063, 521065, 521070, 521076, 521098, 521112, 521125, 521127, 521130, 521140, 521141, 521149, 521168, 521176, 521182, 521201, 521204, 521205, 521216, 521223, 521231, 521238, 521241, 521243, 521257, 521258, 521264, 521267, 521277, 521284, 521290, 521358, 521360, 521365, 521377, 521384, 521387, 521393, 521399, 521402, 521404, 521411, 521416, 521422, 521430, 521431, 521439, 521444, 521446, 521469, 521471, 521490, 521523, 521533, 521543, 521559, 521562, 521572, 521578, 521589, 521609, 521610, 521611, 521617, 521621, 521630, 521640, 521656, 521657, 521671, 521675, 521680, 521690, 521692, 521702, 521709, 521712, 521741, 521744, 521750, 521756, 521767, 521784, 521785, 521808, 521833, 521835, 521840, 521848, 521855, 521865, 521866, 521896, 521929, 521931, 521945, 521952, 521953, 521957, 521960, 521965, 521966, 521969, 521972, 521980, 521985, 521992, 521997, 522005, 522006, 522009, 522014, 522017, 522020, 522023, 522045, 522059, 522063, 522079, 522082, 522087, 522094, 522099, 522133, 522144, 522152, 522154, 522155, 522158, 522191, 522197, 522201, 522204, 522210, 522215, 522220, 522233, 522237, 522278, 522301, 522313, 522315, 522332, 522336, 522346, 522359, 522362, 522366, 522419, 522454, 522458, 522463, 522484, 522491, 522492, 522498, 522502, 522531, 522561, 522565, 522566, 522568, 522582, 522592, 522600, 522607, 522638, 522652, 522668, 522694, 522706, 522713, 522718, 522725, 522735, 522789, 522791, 522793, 522808, 522820, 522825, 522827, 522845, 522849, 522857, 522862, 522875, 522883, 522896, 522902, 522919, 522923, 522927, 522936, 522937, 522942, 522944, 522945, 522956, 522962, 522967, 522970, 522975, 522982, 522984, 522992, 522993, 523016, 523021, 523022, 523033, 523036, 523042, 523045, 523048, 523065, 523072, 523077, 523078, 523082, 523087, 523088, 523097, 523101, 523103, 523117, 523118, 523120, 523143, 523152, 523159, 523210, 523213, 523215, 523224, 523227, 523239, 523244, 523247, 523249, 523252, 523256, 523262, 523267, 523271, 523289, 523290, 523303, 523306, 523323, 523324, 523325, 523326, 523343, 523348, 523364, 523366, 523375, 523398, 523423, 523434, 523448, 523451, 523452, 523456, 523458, 523485, 523488, 523511, 523518, 523527, 523533, 523534, 523542, 523543, 523555, 523560, 523567, 523568, 523578, 523581, 523591, 523594, 523601, 523603, 523608, 523627, 523631, 523635, 523636, 523641, 523644, 523657, 523668, 523670, 523671, 523707, 523713, 523714, 523717, 523730, 523743, 523745, 523754, 523799, 523804, 523812, 523819, 523820, 523827, 523830, 523842, 523859, 523863, 523897, 523911, 523921, 523922, 523926, 523927, 523935, 523949, 523956, 523973, 523974, 523988, 524008, 524018, 524053, 524074, 524084, 524088, 524097, 524136, 524138, 524143, 524151, 524158, 524160, 524169, 524177, 524203, 524215, 524219, 524225, 524228, 524236, 524238, 524241, 524247, 524252, 524268, 524269, 524272, 524282, 524283, 524295, 524300, 524302, 524307, 524311, 524322, 524326, 524332, 524345, 524355, 524363, 524364, 524368, 524391, 524396, 524399, 524419, 524424, 524427, 524440, 524447, 524454, 524461, 524801, 524804, 524808, 524822, 524840, 524854, 524857, 524905, 524915, 524916, 524935, 524959, 524971, 524979, 524983, 524987, 524991, 524996, 525003, 525008, 525012, 525015, 525022, 525030, 525031, 525049, 525070, 525073, 525083, 525107, 525108, 525120, 525126, 525129, 525136, 525142, 525144, 525156, 525178, 525197, 525199, 525212, 525230, 525232, 525233, 525234, 525235, 525242, 525244, 525268, 525274, 525275, 525288, 525292, 525295, 525297, 525298, 525306, 525316, 525329, 525352, 525358, 525365, 525366, 525367, 525372, 525382, 525396, 525442, 525445, 525457, 525465, 525472, 525483, 525486, 525509, 525514, 525544, 525581, 525604, 525605, 525606, 525621, 525629, 525632, 525635, 525653, 525673, 525678, 525679, 525685, 525689, 525699, 525730, 525749, 525752, 525757, 525769, 525771, 525772, 525784, 525794, 525822, 525824, 525828, 525833, 525840, 525845, 525862, 525872, 525878, 525890, 525905, 525912, 525928, 525934, 525949, 525955, 525961, 525965, 525988, 525993, 526006, 526013, 526016, 526020, 526026, 526036, 526050, 526051, 526078, 526080, 526110, 526131, 526142, 526151, 526161, 526167, 526173, 526176, 526180, 526191, 526195, 526205, 526211, 526220, 526223, 526231, 526232, 526233, 526249, 526261, 526271, 526276, 526285, 526287, 526293, 526296, 526307, 526309, 526318, 526347, 526351, 526361, 526362, 526379, 526389, 526399, 526407, 526412, 526417, 526418, 526422, 526435, 526438, 526452, 526461, 526462, 526466, 526470, 526480, 526489, 526492, 526502, 526506, 526508, 526513, 526521, 526522, 526534, 526551, 526562, 526564, 526581, 526593, 526600, 526621, 526640, 526652, 526655, 526673, 526676, 526678, 526683, 526706, 526716, 526718, 526720, 526737, 526738, 526739, 526751, 526755, 526771, 526776, 526784, 526799, 526804, 526806, 526820, 526829, 526834, 526842, 526844, 526855, 526858, 526876, 526883, 526885, 526893, 526901, 526905, 526922, 526937, 526942, 526944, 526951, 526952, 526966, 526990, 526993, 526995, 527013, 527021, 527022, 527029, 527031, 527037, 527040, 527042, 527052, 527053, 527055, 527057, 527058, 527060, 527062, 527068, 527099, 527103, 527106, 527113, 527115, 527132, 527133, 527152, 527162, 527180, 527183, 527191, 527195, 527209, 527216, 527224, 527233, 527248, 527252, 527255, 527257, 527272, 527316, 527325, 527327, 527357, 527367, 527373, 527391, 527395, 527410, 527434, 527444, 527484, 527503, 527507, 527508, 527513, 527517, 527537, 527539, 527542, 527551, 527554, 527556, 527558, 527571, 527573, 527589, 527590, 527596, 527609, 527610, 527611, 527622, 527625, 527633, 527637, 527643, 527651, 527652, 527654, 527681, 527686, 527706, 527730, 527738, 527758, 527766, 527771, 527782, 527801, 527805, 527815, 527817, 527818, 527820, 527832, 527835, 527837, 527838, 527842, 527843, 527852, 527859, 527860, 527862, 527871, 527873, 527879, 527881, 527884, 527891, 527898, 527910, 527921, 527922, 527929, 527934, 527935, 527936, 527941, 527944, 527945, 527947, 527948, 527952, 527953, 527957, 527958, 527959, 527960, 527961, 527966, 527969, 527973, 527978, 527982, 527990, 528001, 528008, 528009, 528015, 528016, 528021, 528026, 528041, 528046, 528048, 528059, 528066, 528068, 528074, 528077, 528086, 528087, 528090, 528091, 528114, 528115, 528118, 528122, 528124, 528129, 528137, 528138, 528139, 528141, 528143, 528145, 528159, 528168, 528183, 528187, 528188, 528198, 528205, 528218, 528226, 528228, 528242, 528245, 528250, 528252, 528259, 528262, 528268, 528288, 528306, 528310, 528313, 528322, 528330, 528340, 528347, 528348, 528349, 528357, 528358, 528366, 528374, 528376, 528377, 528379, 528383, 528387, 528390, 528392, 528399, 528411, 528422, 528424, 528433, 528445, 528446, 528448, 528455, 528466, 528468, 528472, 528476, 528485, 528490, 528498, 528500, 528508, 528511, 528518, 528523, 528527, 528528, 528530, 528534, 528546, 528547, 528559, 528564, 528574, 528579, 528584, 528594, 528600, 528602, 528603, 528623, 528624, 528631, 528632, 528642, 528648, 528657, 528660, 528661, 528665, 528667, 528677, 528679, 528709, 528712, 528714, 528727, 528730, 528731, 528734, 528738, 528739, 528742, 528744, 528753, 528764, 528765, 528770, 528779, 528780, 528781, 528784, 528794, 528800, 528805, 528809, 528812, 528815, 528830, 528836, 528852, 528857, 528866, 528871, 528878, 528881, 528883, 528885, 528890, 528892, 528894, 528898, 528901, 528919, 528920, 528921, 528922, 528925, 528927, 528942, 528947, 528959, 528969, 528970, 528972, 528978, 528988, 528990, 529005, 529007, 529016, 529018, 529066, 529070, 529093, 529112, 529122, 529127, 529136, 529137, 529145, 529150, 529155, 529160, 529181, 529183, 529193, 529194, 529201, 529204, 529230, 529236, 529239, 529243, 529250, 529285, 529289, 529299, 529300, 529304, 529330, 529332, 529342, 529381, 529420, 529422, 529434, 529437, 529464, 529484, 529493, 529514, 529524, 529527, 529528, 529535, 529543, 529550, 529565, 529597, 529602, 529611, 529621, 529635, 529660, 529662, 529667, 529682, 529684, 529694, 529697, 529700, 529721, 529722, 529737, 529762, 529775, 529805, 529818, 529830, 529839, 529859, 529868, 529891, 529903, 529914, 529915, 529921, 529929, 529945, 529952, 529954, 529955, 529972, 529976, 530007, 530010, 530024, 530029, 530031, 530038, 530041, 530053, 530055, 530059, 530071, 530072, 530088, 530099, 530107, 530117, 530122, 530128, 530129, 530141, 530149, 530150, 530165, 530170, 530179, 530183, 530201, 530214, 530216, 530219, 530221, 530244, 530250, 530257, 530275, 530278, 530288, 530300, 530310, 530316, 530318, 530319, 530333, 530342, 530348, 530359, 530364, 530373, 530394, 530412, 530417, 530431, 530432, 530433, 530436, 530442, 530451, 530454, 530458, 530464, 530476, 530483, 530498, 530529, 530541, 530552, 530554, 530570, 530572, 530579, 530585, 530589, 530604, 530607, 530611, 530613, 530615, 530628, 530632, 530635, 530638, 530641, 530647, 530652, 530681, 530686, 530689, 530702, 530714, 530718, 530729, 530753, 530763, 530769, 530776, 530784, 530803, 530804, 530811, 530847, 530870, 530882, 530888, 530891, 530899, 530906, 530911, 530924, 530925, 530926, 530930, 530937, 530943, 530969, 530973, 530974, 530981, 530990, 530991, 530992, 530998, 530999, 531005, 531007, 531027, 531031, 531036, 531061, 531092, 531100, 531123, 531132, 531133, 531139, 531140, 531144, 531153, 531163, 531174, 531189, 531190, 531191, 531192, 531193, 531208, 531248, 531260, 531261, 531265, 531267, 531280, 531285, 531294, 531300, 531306, 531307, 531308, 531310, 531312, 531314, 531338, 531339, 531353, 531366, 531373, 531374, 531376, 531407, 531415, 531419, 531422, 531431, 531438, 531449, 531475, 531501, 531509, 531525, 531527, 531529, 531542, 531551, 531558, 531567, 531585, 531598, 531600, 531605, 531616, 531617, 531618, 531629, 531632, 531637, 531647, 531671, 531677, 531681, 531691, 531693, 531705, 531710, 531721, 531729, 531767, 531781, 531803, 531813, 531816, 531838, 531846, 531847, 531848, 531851, 531855, 531894, 531897, 531906, 531907, 531917, 531918, 531919, 531951, 531960, 531967, 531975, 531979, 531981, 531984, 531988, 531991, 531994, 531996, 532002, 532003, 532012, 532023, 532026, 532028, 532030, 532043, 532053, 532070, 532085, 532094, 532114, 532130, 532134, 532136, 532140, 532143, 532151, 532159, 532160, 532170, 532185, 532186, 532187, 532191, 532201, 532203, 532224, 532243, 532244, 532247, 532250, 532251, 532256, 532265, 532266, 532273, 532275, 532281, 532282, 532290, 532295, 532315, 532341, 532450, 532522, 532576, 532709, 532826, 532850, 532894, 532912, 532917, 532927, 532942, 532965, 532971, 532973, 532974, 532975, 532987, 532998, 533001, 533015, 533025, 533027, 533043, 533053, 533061, 533092, 533093, 533101, 533107, 533114, 533118, 533145, 533157, 533164, 533201, 533219, 533238, 533269, 533299, 533301, 533313, 533325, 533342, 533344, 533349, 533352, 533353, 533381, 533383, 533384, 533387, 533395, 533407, 533416, 533417, 533419, 533429, 533430, 533431, 533434, 533441, 533443, 533444, 533445, 533451, 533453, 533455, 533461, 533475, 533480, 533481, 533483, 533487, 533508, 533511, 533514, 533516, 533533, 533535, 533550, 533559, 533562, 533569, 533579, 533591, 533595, 533601, 533624, 533638, 533640, 533656, 533681, 533685, 533687, 533688, 533709, 533723, 533728, 533740, 533747, 533748, 533754, 533762, 533768, 533779, 533783, 533784, 533811, 533814, 533828, 533829, 533840, 533852, 533855, 533857, 533858, 533859, 533874, 533879, 533884, 533886, 533898, 533907, 533915, 533922, 533928, 533944, 533946, 533956, 533963, 533967, 533978, 533980, 533994, 534012, 534025, 534033, 534036, 534040, 534057, 534059, 534060, 534062, 534064, 534067, 534068, 534074, 534086, 534090, 534091, 534119, 534122, 534158, 534181, 534183, 534187, 534190, 534195, 534199, 534203, 534204, 534214, 534220, 534234, 534242, 534244, 534246, 534260, 534271, 534272, 534274, 534276, 534278, 534279, 534282, 534287, 534294, 534305, 534306, 534309, 534323, 534327, 534342, 534351, 534352, 534357, 534374, 534383, 534387, 534388, 534393, 534403, 534407, 534423, 534431, 534435, 534437, 534448, 534449, 534452, 534459, 534477, 534482, 534484, 534493, 534502, 534505, 534510, 534527, 534532, 534536, 534545, 534551, 534557, 534561, 534570, 534584, 534590, 534593, 534613, 534618, 534619, 534623, 534626, 534628, 534630, 534631, 534639, 534650, 534654, 534656, 534670, 534678, 534679, 534687, 534691, 534692, 534699, 534703, 534705, 534710, 534724, 534726, 534740, 534741, 534742, 534743, 534744, 534747, 534748, 534755, 534763, 534764, 534767, 534779, 534781, 534784, 534796, 534805, 534807, 534825, 534835, 534841, 534846, 534847, 534851, 534853, 534854, 534864, 534868, 534870, 534871, 534878, 534895, 534896, 534898, 534902, 534905, 534907, 534908, 534913, 534922, 534932, 534937, 534938, 534955, 534972, 534975, 534978, 534992, 534993, 534996, 534999, 535013, 535018, 535019, 535023, 535033, 535052, 535053, 535054, 535060, 535062, 535082, 535083, 535089, 535097, 535123, 535129, 535147, 535148, 535150, 535161, 535174, 535176, 535178, 535186, 535197, 535199, 535205, 535208, 535209, 535222, 535224, 535225, 535230, 535238, 535244, 535246, 535249, 535252, 535266, 535268, 535269, 535279, 535280, 535282, 535286, 535297, 535299, 535304, 535308, 535318, 535333, 535339, 535351, 535352, 535354, 535360, 535376, 535397, 535398, 535409, 535416, 535440, 535448, 535457, 535467, 535470, 535475, 535494, 535495, 535500, 535506, 535508, 535512, 535514, 535516, 535535, 535539, 535546, 535553, 535556, 535559, 535568, 535574, 535575, 535580, 535582, 535584, 535585, 535588, 535590, 535591, 535593, 535595, 535613, 535624, 535633, 535640, 535647, 535650, 535656, 535659, 535670, 535672, 535676, 535684, 535685, 535686, 535691, 535714, 535722, 535728, 535740, 535749, 535750, 535755, 535773, 535776, 535791, 535811, 535814, 535819, 535827, 535829, 535832, 535834, 535836, 535837, 535838, 535845, 535861, 535868, 535874, 535884, 535890, 535892, 535901, 535918, 535926, 535934, 535943, 535944, 535962, 535983, 535984, 535999, 536016, 536019, 536029, 536040, 536041, 536044, 536052, 536056, 536058, 536067, 536068, 536072, 536096, 536099, 536104, 536107, 536118, 536119, 536121, 536141, 536143, 536144, 536170, 536177, 536182, 536184, 536187, 536188, 536203, 536204, 536208, 536226, 536228, 536231, 536232, 536246, 536247, 536255, 536256, 536263, 536266, 536280, 536303, 536307, 536310, 536325, 536333, 536337, 536338, 536342, 536348, 536355, 536377, 536378, 536385, 536393, 536403, 536411, 536415, 536417, 536420, 536423, 536436, 536438, 536442, 536445, 536452, 536454, 536462, 536484, 536498, 536499, 536544, 536553, 536573, 536580, 536583, 536590, 536603, 536630, 536637, 536641, 536681, 536689, 536706, 536709, 536721, 536728, 536730, 536731, 536733, 536737, 536746, 536754, 536763, 536767, 536783, 536801, 536803, 536815, 536834, 536836, 536846, 536873, 536898, 536918, 536931, 536939, 536963, 536979, 536981, 536983, 536986, 537026, 537034, 537064, 537100, 537118, 537121, 537136, 537147, 537151, 537163, 537169, 537173, 537175, 537180, 537199, 537208, 537209, 537217, 537221, 537226, 537234, 537239, 537240, 537266, 537272, 537276, 537277, 537286, 537294, 537302, 537305, 537319, 537326, 537334, 537353, 537357, 537369, 537376, 537380, 537391, 537406, 537418, 537441, 537442, 537448, 537467, 537482, 537492, 537514, 537557, 537565, 537575, 537576, 537582, 537585, 537586, 537599, 537603, 537613, 537628, 537631, 537671, 537685, 537689, 537724, 537732, 537733, 537740, 537744, 538039, 538157, 538637, 538696, 538831, 539209, 539314, 539441, 539474, 539722, 539952, 539961, 540560, 540562, 540584, 540902, 541196, 541993, 542015, 542034, 542040, 542041, 542042, 542046, 542050, 542056, 542065, 542066, 542071, 542072, 542076, 542078, 542087, 542091, 542092, 542099, 542100, 542105, 542181, 542255, 542382, 542556, 542624, 542713, 542740, 542799, 542898, 542985, 543026, 543124, 543155, 543177, 543189, 543222, 543322, 543345, 543418, 543482, 543635, 543721, 543723, 543869, 543971, 544093, 544100, 544208, 544236, 544279, 544302, 544410, 544470, 544651, 544657, 544754, 544835, 544967, 545051, 545351, 545387, 545461, 545465, 545472, 545480, 545481, 545492, 545513, 545519, 545541, 545543, 545548, 545551, 545568, 545569, 545574, 545625, 545632, 545648, 545670, 545693, 545702, 545706, 545712, 545716, 545726, 545761, 545768, 545774, 545775, 545819, 545820, 545830, 545836, 545855, 545964, 545974, 545987, 545995, 545998, 546000, 546006, 546014, 546015, 546016, 546022, 546032, 546044, 546067, 546070, 546077, 546079, 546081, 546082, 546087, 546090, 546099, 546103, 546108, 546110, 546112, 546135, 546136, 546141, 546169, 546173, 546189, 546196, 546201, 546203, 546219, 546226, 546231, 546234, 546239, 546248, 546256, 546257, 546274, 546285, 546293, 546298, 546309, 546329, 546335, 546336, 546353, 546362, 546368, 546370, 546376, 546384, 546386, 546395, 546410, 546412, 546424, 546447, 546450, 546469, 546471, 546483, 546484, 546499, 546514, 546516, 546520, 546539, 546541, 546545, 546561, 546576, 546628, 546629, 546640, 546645, 546656, 546731, 546732, 546734, 546759, 546784, 546797, 546833, 546834, 546846, 546857, 546861, 546867, 546871, 546885, 546892, 546893, 546909, 546916, 546928, 546938, 546949, 546956, 546957, 546982, 546990, 547016, 547048, 547051, 547052, 547059, 547083, 547086, 547098, 547105, 547110, 547114, 547138, 547146, 547169, 547173, 547181, 547184, 547186, 547215, 547222, 547224, 547227, 547234, 547237, 547239, 547247, 547255, 547271, 547277, 547280, 547282, 547283, 547286, 547298, 547310, 547311, 547317, 547322, 547326, 547342, 547343, 547349, 547353, 547395, 547412, 547452, 547466, 547485, 547494, 547505, 547530, 547551, 547556, 547561, 547587, 547588, 547596, 547598, 547602, 547610, 547637, 547638, 547664, 547678, 547683, 547698, 547701, 547722, 547745, 547782, 547790, 547799, 547811, 547820, 547864, 547883, 547893, 547919, 547944, 547950, 547994, 548014, 548036, 548037, 548052, 548077, 548099, 548103, 548136, 548162, 548191, 548203, 548207, 548210, 548215, 548219, 548243, 548265, 548268, 548277, 548283, 548290, 548301, 548325, 548327, 548357, 548369, 548391, 548401, 548411, 548423, 548424, 548436, 548471, 548499, 548500, 548502, 548504, 548521, 548531, 548575, 548577, 548595, 548616, 548621, 548627, 548628, 548651, 548665, 548669, 548674, 548697, 548704, 548708, 548711, 548732, 548743, 548754, 548773, 548781, 548785, 548811, 548817, 548827, 548851, 548857, 548866, 548878, 548899, 548904, 548905, 548911, 548932, 548937, 548952, 548957, 548990, 548993, 548998, 549098, 549107, 549114, 549115, 549116, 549119, 549124, 549125, 549126, 549139, 549149, 549156, 549167, 549171, 549172, 549186, 549199, 549203, 549214, 549241, 549244, 549260, 549279, 549289, 549315, 549317, 549330, 549344, 549345, 549359, 549422, 549427, 549432, 549435, 549440, 549447, 549448, 549452, 549469, 549470, 549506, 549520, 549539, 549555, 549560, 549561, 549572, 549580, 549600, 549614, 549633, 549654, 549655, 549661, 549664, 549666, 549674, 549677, 549684, 549695, 549698, 549705, 549706, 549708, 549731, 549733, 549735, 549745, 549773, 549782, 549789, 549801, 549820, 549830, 549841, 549846, 549850, 549855, 549871, 549872, 549926, 549936, 549944, 549947, 549948, 550009, 550014, 550020, 550032, 550048, 550061, 550065, 550087, 550102, 550108, 550123, 550127, 550131, 550141, 550183, 550197, 550201, 550219, 550231, 550244, 550278, 550283, 550306, 550323, 550331, 550345, 550349, 550352, 550355, 550359, 550360, 550403, 550404, 550432, 550453, 550464, 550468, 550476, 550480, 550483, 550523, 550531, 550574, 550587, 550593, 550595, 550596, 550606, 550615, 550623, 550635, 550657, 550667, 550668, 550686, 550688, 550699, 550701, 550702, 550703, 550707, 550712, 550718, 550743, 550756, 550798, 550800, 550804, 550831, 550834, 550840, 550864, 550869, 550904, 550913, 550914, 550928, 550936, 550938, 550948, 550965, 550982, 550985, 550986, 550996, 551000, 551010, 551024, 551026, 551032, 551045, 551048, 551052, 551058, 551061, 551072, 551076, 551111, 551113, 551129, 551136, 551147, 551149, 551176, 551178, 551197, 551199, 551264, 551289, 551308, 551328, 551335, 551352, 551372, 551389, 551400, 551450, 551463, 551473, 551478, 551493, 551499, 551524, 551549, 551575, 551576, 551611, 551656, 551680, 551688, 551695, 551697, 551714, 551757, 551805, 551814, 551819, 551842, 551865, 551870, 551871, 551879, 551892, 551896, 551897, 551903, 551904, 551914, 551940, 551943, 551945, 551950, 551952, 551956, 551960, 551965, 551977, 551980, 552009, 552013, 552018, 552045, 552048, 552053, 552054, 552092, 552101, 552103, 552114, 552115, 552121, 552122, 552147, 552175, 552188, 552191, 552209, 552221, 552237, 552255, 552264, 552285, 552304, 552308, 552327, 552374, 552384, 552411, 552432, 552433, 552463, 552498, 552502, 552520, 552523, 552561, 552574, 552582, 552616, 552621, 552638, 552658, 552660, 552663, 552664, 552672, 552677, 552694, 552699, 552713, 552723, 552724, 552729, 552756, 552797, 552800, 552813, 552818, 552824, 552827, 552840, 552851, 552872, 552878, 552884, 552901, 552906, 552914, 552929, 552941, 552954, 552960, 552984, 552996, 553004, 553008, 553029, 553032, 553041, 553043, 553045, 553052, 553069, 553078, 553089, 553130, 553169, 553175, 553185, 553197, 553201, 553237, 553242, 553262, 553271, 553288, 553334, 553357, 553408, 553410, 553419, 553425, 553440, 553447, 553470, 553551, 553563, 553689, 553690, 553727, 553743, 553781, 553789, 553808, 553885, 553931, 553934, 553970, 553975, 553976, 553986, 554003, 554031, 554104, 554158, 554262, 554281, 554288, 554290, 554299, 554331, 554349, 554373, 554400, 554414, 554420, 554430, 554451, 554513, 554633, 554642, 554705, 554708, 554717, 554722, 554800, 554810, 554812, 554849, 554876, 554920, 554930, 554948, 554960, 554997, 555131, 555136, 555141, 555159, 555166, 555191, 555200, 555207, 555265, 555269, 555271, 555274, 555300, 555302, 555303, 555306, 555314, 555316, 555318, 555336, 555344, 555347, 555357, 555367, 555376, 555413, 555420, 555424, 555427, 555437, 555455, 555466, 555471, 555476, 555479, 555480, 555503, 555543, 555547, 555567, 555577, 555579, 555584, 555595, 555607, 555617, 555619, 555654, 555655, 555661, 555666, 555673, 555692, 555705, 555706, 555712, 555715, 555721, 555743, 555747, 555758, 555759, 555764, 555796, 555799, 555806, 555825, 555829, 555863, 555871, 555872, 555874, 555883, 555896, 555897, 555909, 555917, 555925, 555926, 555932, 555948, 555970, 556000, 556005, 556026, 556029, 556037, 556043, 556056, 556060, 556064, 556070, 556086, 556103, 556107, 556112, 556136, 556138, 556139, 556149, 556163, 556169, 556175, 556178, 556183, 556187, 556193, 556195, 556203, 556205, 556208, 556213, 556215, 556229, 556251, 556253, 556257, 556259, 556268, 556270, 556275, 556277, 556280, 556287, 556313, 556318, 556330, 556339, 556353, 556375, 556380, 556381, 556382, 556426, 556427, 556428, 556431, 556432, 556433, 556437, 556443, 556447, 556452, 556457, 556462, 556495, 556511, 556519, 556523, 556536, 556554, 556574, 556582, 556590, 556605, 556609, 556610, 556616, 556622, 556639, 556650, 556651, 556653, 556712, 556719, 556736, 556745, 556757, 556765, 556767, 556769, 556786, 556789, 556802, 556804, 556807, 556814, 556822, 556828, 556829, 556831, 556833, 556834, 556848, 556851, 556855, 556858, 556863, 556874, 556879, 556883, 556891, 556901, 556918, 556943, 556944, 556945, 556947, 556964, 556966, 556985, 556994, 556995, 556997, 557017, 557021, 557039, 557044, 557056, 557060, 557071, 557086, 557089, 557098, 557102, 557106, 557109, 557140, 557152, 557162, 557165, 557168, 557175, 557184, 557199, 557211, 557213, 557231, 557248, 557249, 557278, 557281, 557285, 557299, 557303, 557308, 557310, 557320, 557323, 557335, 557348, 557351, 557368, 557373, 557404, 557409, 557412, 557420, 557428, 557445, 557451, 557486, 557498, 557522, 557540, 557543, 557544, 557578, 557605, 557610, 557629, 557645, 557646, 557673, 557675, 557692, 557729, 557751, 557762, 557768, 557781, 557784, 557788, 557808, 557811, 557814, 557822, 557825, 557840, 557852, 557861, 557865, 557895, 557905, 557915, 557928, 557934, 557941, 557942, 557945, 557948, 557953, 557968, 557992, 557997, 558031, 558034, 558048, 558054, 558058, 558062, 558070, 558079, 558081, 558086, 558096, 558104, 558118, 558124, 558132, 558134, 558146, 558147, 558150, 558172, 558177, 558183, 558195, 558209, 558215, 558218, 558220, 558233, 558236, 558251, 558255, 558260, 558262, 558281, 558294, 558303, 558330, 558338, 558342, 558364, 558376, 558379, 558387, 558392, 558417, 558426, 558429, 558430, 558464, 558469, 558471, 558504, 558526, 558528, 558538, 558553, 558569, 558570, 558573, 558577, 558581, 558584, 558588, 558597, 558598, 558601, 558611, 558622, 558624, 558632, 558634, 558642, 558651, 558661, 558668, 558678, 558681, 558697, 558730, 558733, 558737, 558750, 558774, 558801, 558805, 558809, 558810, 558817, 558820, 558823, 558835, 558837, 558841, 558848, 558869, 558871, 558875, 558876, 558887, 558890, 558892, 558895, 558902, 558927, 558949, 558951, 558959, 558964, 558970, 558985, 559016, 559020, 559026, 559027, 559028, 559029, 559054, 559062, 559077, 559082, 559084, 559111, 559118, 559122, 559166, 559192, 559200, 559206, 559215, 559221, 559236, 559237, 559256, 559267, 559270, 559275, 559282, 559285, 559303, 559312, 559316, 559319, 559322, 559329, 559336, 559344, 559380, 559381, 559415, 559423, 559441, 559447, 559468, 559474, 559475, 559484, 559487, 559488, 559490, 559502, 559504, 559505, 559507, 559517, 559527, 559529, 559542, 559548, 559549, 559561, 559582, 559589, 559590, 559599, 559609, 559626, 559640, 559675, 559683, 559690, 559695, 559696, 559699, 559703, 559705, 559710, 559712, 559719, 559720, 559747, 559751, 559760, 559761, 559768, 559772, 559791, 559796, 559800, 559803, 559810, 559812, 559850, 559863, 559875, 559877, 559879, 559889, 559906, 559907, 559908, 559944, 559958, 559969, 559970, 559983, 559987, 560014, 560017, 560032, 560035, 560037, 560050, 560061, 560083, 560084, 560103, 560117, 560121, 560134, 560142, 560144, 560150, 560151, 560157, 560171, 560191, 560199, 560210, 560214, 560216, 560217, 560222, 560236, 560244, 560247, 560250, 560256, 560265, 560274, 560276, 560278, 560285, 560291, 560292, 560299, 560301, 560309, 560328, 560341, 560351, 560361, 560366, 560378, 560386, 560403, 560409, 560412, 560435, 560447, 560450, 560451, 560456, 560466, 560491, 560496, 560503, 560505, 560520, 560536, 560538, 560554, 560564, 560567, 560569, 560607, 560619, 560632, 560665, 560670, 560682, 560698, 560701, 560705, 560709, 560710, 560717, 560722, 560733, 560740, 560743, 560754, 560756, 560762, 560763, 560765, 560773, 560776, 560785, 560788, 560794, 560822, 560832, 560836, 560838, 560846, 560870, 560875, 560879, 560880, 560882, 560884, 560891, 560892, 560897, 560901, 560907, 560909, 560911, 560913, 560923, 560930, 560937, 560942, 560944, 560962, 560978, 561000, 561014, 561019, 561034, 561036, 561037, 561072, 561075, 561077, 561081, 561093, 561096, 561105, 561128, 561143, 561155, 561156, 561160, 561171, 561181, 561188, 561190, 561206, 561217, 561226, 561242, 561247, 561256, 561323, 561328, 561329, 561348, 561412, 561431, 561458, 561473, 561485, 561500, 561548, 561580, 561584, 561628, 561672, 561676, 561688, 561701, 561702, 561736, 561741, 561841, 561873, 561880, 561884, 561885, 561896, 561972, 561979, 561997, 562004, 562005, 562012, 562079, 562162, 562172, 562284, 562294, 562334, 562339, 562341, 562355, 562356, 562540, 562574, 562575, 562587, 562645, 562695, 562735, 562740, 562747, 562764, 562766, 562771, 562803, 562883, 562905, 562934, 562935, 562948, 562972, 562977, 562979, 562980, 562982, 563019, 563025, 563027, 563041, 563045, 563047, 563057, 563073, 563077, 563094, 563108, 563113, 563120, 563127, 563128, 563138, 563140, 563157, 563164, 563166, 563188, 563202, 563206, 563214, 563219, 563232, 563236, 563237, 563245, 563250, 563271, 563278, 563279, 563311, 563312, 563318, 563322, 563335, 563346, 563352, 563371, 563375, 563391, 563400, 563412, 563418, 563427, 563435, 563438, 563441, 563477, 563478, 563491, 563494, 563498, 563509, 563543, 563551, 563575, 563583, 563593, 563594, 563600, 563610, 563611, 563612, 563640, 563652, 563665, 563674, 563679, 563680, 563699, 563702, 563764, 563784, 563797, 563824, 563830, 563837, 563844, 563851, 563853, 563868, 563870, 563873, 563879, 563882, 563891, 563902, 563910, 563912, 563921, 563946, 563963, 563988, 563993, 564054, 564061, 564064, 564065, 564073, 564077, 564084, 564103, 564105, 564107, 564121, 564156, 564160, 564165, 564166, 564168, 564188, 564199, 564200, 564204, 564212, 564246, 564283, 564285, 564289, 564323, 564335, 564351, 564371, 564373, 564417, 564433, 564454, 564455, 564487, 564531, 564553, 564580, 564593, 564603, 564607, 564643, 564656, 564690, 564692, 564700, 564743, 564749, 564774, 564847, 564852, 564861, 564867, 564884, 564886, 564888, 564890, 564892, 564902, 564926, 564938, 564945, 564953, 564957, 564971, 564978, 564990, 565003, 565008, 565042, 565071, 565074, 565094, 565099, 565148, 565151, 565165, 565171, 565172, 565176, 565177, 565187, 565188, 565194, 565195, 565206, 565207, 565210, 565216, 565239, 565240, 565241, 565243, 565249, 565253, 565259, 565266, 565288, 565295, 565297, 565300, 565310, 565321, 565333, 565366, 565370, 565376, 565381, 565386, 565392, 565402, 565403, 565408, 565410, 565414, 565415, 565418, 565422, 565440, 565442, 565463, 565464, 565465, 565466, 565474, 565492, 565494, 565496, 565497, 565502, 565515, 565518, 565525, 565533, 565539, 565560, 565564, 565571, 565579, 565583, 565586, 565587, 565594, 565596, 565610, 565614, 565615, 565616, 565618, 565623, 565626, 565635, 565644, 565650, 565652, 565653, 565659, 565665, 565666, 565685, 565693, 565695, 565696, 565707, 565710, 565724, 565729, 565738, 565740, 565742, 565744, 565748, 565750, 565758, 565764, 565765, 565784, 565789, 565812, 565820, 565829, 565832, 565869, 565879, 565887, 565891, 565910, 565914, 565920, 565922, 565933, 565936, 565938, 565940, 565948, 565951, 565954, 565959, 565963, 565978, 565979, 565987, 565989, 565992, 566001, 566013, 566029, 566030, 566048, 566052, 566053, 566054, 566058, 566060, 566064, 566066, 566068, 566072, 566078, 566086, 566092, 566095, 566105, 566106, 566113, 566114, 566116, 566120, 566126, 566127, 566134, 566137, 566141, 566145, 566151, 566159, 566166, 566187, 566190, 566191, 566194, 566195, 566199, 566205, 566211, 566216, 566221, 566230, 566232, 566233, 566235, 566237, 566239, 566240, 566257, 566261, 566262, 566269, 566274, 566278, 566282, 566293, 566294, 566297, 566304, 566305, 566319, 566323, 566330, 566332, 566333, 566346, 566350, 566355, 566364, 566368, 566374, 566380, 566386, 566401, 566418, 566426, 566432, 566433, 566437, 566457, 566461, 566463, 566487, 566489, 566497, 566517, 566524, 566525, 566539, 566547, 566550, 566554, 566562, 566582, 566603, 566616, 566623, 566624, 566632, 566637, 566644, 566652, 566655, 566670, 566675, 566696, 566697, 566707, 566720, 566721, 566724, 566740, 566749, 566754, 566758, 566764, 566766, 566781, 566794, 566796, 566804, 566808, 566820, 566828, 566835, 566855, 566858, 566863, 566885, 566892, 566899, 566903, 566915, 566921, 566923, 566932, 566934, 566940, 566943, 566944, 566946, 566953, 566971, 566974))) AND "video"."x" < 180 AND "video"."y" < 160 AND "video"."duration" > 300 AND "video"."x" > 90 AND "video"."y" > 80 ) ORDER BY "video"."id" DESC
 
</pre>
<p>Toujours faire gaffe au SQL que genère son ORM :)</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/on-avait-un-de-nos-sites-qui-ramait-quand-soudain/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2015/07/N4kRcPp.jpg" length="17736" type="image/jpg" />	</item>
		<item>
		<title>The User is dead 18</title>
		<link>http://sametmax.com/the-user-is-dead/</link>
		<comments>http://sametmax.com/the-user-is-dead/#comments</comments>
		<pubDate>Tue, 14 Jul 2015 12:27:42 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Philo et culture]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=16615</guid>
		<description><![CDATA[L&#8217;authentification de mémé (enfin, mémé&#8230;) n&#8217;a plus de sens, et pourtant, on continue de la montrer en exemple dans tous les tutos : Un compte utilisateur. Un email. Un mot de passe. Boom, on vérifie le mot de passe (avec un peu de chance sur une version sainement hachée), on identifie l&#8217;utilisateur, et c&#8217;est plié. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>L&#8217;authentification de mémé (enfin, mémé&#8230;) n&#8217;a plus de sens, et pourtant, on continue de la montrer en exemple dans tous les tutos :</p>
<ul>
<li>Un compte utilisateur.</li>
<li>Un email.</li>
<li>Un mot de passe.</li>
</ul>
<p>Boom, on vérifie le mot de passe (avec un peu de chance sur une version sainement hachée), on identifie l&#8217;utilisateur, et c&#8217;est plié.</p>
<p>C&#8217;est simple, c&#8217;est beau, ça marche.</p>
<p>Mais ça ne représente pas du tout la réalité.</p>
<p>Une des plus grosses erreurs de design de frameworks comme Django est justement la classe <code>User</code>.</p>
<p>En soit, la classe <code>User</code> n&#8217;est pas un problème, mais son omniprésence dans toutes les couches du framework et sa promotion au rang d&#8217;unité de référence dans les apps tierces parties ont gardé la vision de l&#8217;authentification très monolithique.</p>
<p>C&#8217;est que le Web n&#8217;a plus du tout la forme qu&#8217;il avait il y a 10 ans, et aujourd&#8217;hui, vous pouvez vous connecter via un service (facebook, twitter, github&#8230;), utiliser une authentification à double facteur (sms, email, yubikey&#8230;) ou avoir un compte unique qui unifie plusieurs fournisseurs (ah, le fameux compte Google qui fait gmail, youtube, calendar, play, saucisseland&#8230;).</p>
<p>Les gens ont plusieurs identités, plusieurs comptes, plusieurs modes d&#8217;authentification, plusieurs points d&#8217;entrées. Ce modèle ne marche plus :</p>
<pre>USER <-- Profile </pre>
<p>Si vous créez un service aujourd'hui et que vous souhaitez prendre en compte cette réalité, le schéma en base de données va plutôt ressembler à un truc du genre :</p>
<pre>                      +-------+
                      |Session|
                      +----+--+
                           |
                           |
                           |
                           |
+-----------+         +----v---+         +--------+
|  Identity | <-------+ Account| <-------+Profile |
+-----------+         +--------+         +--------+
                 +------^   ^--------+
                 |                   |
                 |                   |
                 |                   |
                 |                   |
         +-------+-----+      +------+----+
         | Credential  |      |  Service  |
         +-------------+      +-----------+
</pre>
<p>Et encore, je n'ai pas mis les permissions, les devices, les comptes multi-utilisateurs, la vérification des comptes (lien email, sms, etc), les niveaux d'offre commerciale... Ca rend le truc vraiment compliqué.</p>
<p>Ce qui est important ici, c'est que la notion de compte devient centrale, mais que seule l'identité est unique. Une identité peut avoir plusieurs comptes. Et un compte peut être chez votre service ou un service externe. Et l'authentification peut très bien avoir lieu ailleurs : ldap, OAuth, Mozilla Personna, Open ID...</p>
<p>Si votre utilisateur a un compte chez Facebook et un compte chez vous, les deux sont des comptes, avec leurs profils, reliés à la même identité, servant à vous donner des informations, permettant de se loguer... Et vous devez garder une trace de tout ça. Le fait que l'API d'un service tape sur votre serveur et l'autre non n'a en fait aucune importance pour l'utilisateur, qui utilise tout ça comme un gros blob comme si internet était un tout.</p>
<p>La nouvelle génération ne fait pas la différence avec un site Web et un app, ne sait pas ce qu'est une URL ou un cookie et ne veut pas rentrer trop de mots de passe, mais veut par contre utiliser 5000 services.</p>
<p>Ainsi on voit que les archis basées sur des microservices (hello crossbar :)) commencent à avoir la côte, faisant abstraction de la notion de "ceci est mon app, ceci est ton app" dans la structure de son projet. Bien entendu, la distinction est importante d'un point de vue humain, mais du point de vue du workflow d'authentification, non.</p>
<p>Par contre, forcément, ça fait beaucoup plus qu'une table <code>User</code> et une table <code>Profile</code> en base de données, et c'est pourquoi toutes les apps pluggables des frameworks actuellement ont leurs propres structures bizarres, incompatibles et torturées pour faire tenir toute cette logique. Parce qu'on code sur des frameworks qui vivent encore dans les années 2000, qui passent à votre vue un objet <code>User</code> en paramètre avec ses attributs <code>username</code> et <code>email</code>.</p>
<p>Mais ce que vous avez en face de vous, ce n'est pas un utilisateur.</p>
<p>C'est une session d'utilisation.</p>
<p>D'un service (le votre). Liée à un compte. Qui peut-être (surement) possède un profil avec un username.</p>
<p>Cette session s'est initiée par une authentification avec une méthode parmi 100 auprès d'un service également, lié à un compte, avec un profil. Peut-être le même service que celui qui est utilisé, peut-être pas.</p>
<p>Et cette authentification a pu être demandée par un utilisateur, ou encore un autre service, ou un logiciel client complètement automatiquement. Souvenez-vous : la session n'a peut-être aucun humain derrière.</p>
<p>Ce qui est en face de vous n'est pas un utilisateur. L'utilisateur est mort il y a des années.</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/the-user-is-dead/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2015/07/Qokothr.jpg" length="88567" type="image/jpg" />	</item>
		<item>
		<title>Je n&#8217;expliquerai plus les CBV 17</title>
		<link>http://sametmax.com/je-nexpliquerai-plus-les-cbv/</link>
		<comments>http://sametmax.com/je-nexpliquerai-plus-les-cbv/#comments</comments>
		<pubDate>Mon, 11 May 2015 11:42:49 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[cbv]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=16221</guid>
		<description><![CDATA[ Avant, les vues génériques étaient sous forme de fonction, simples, pratiques, c'était parfait. Et ça a été retiré du framework pour des versions OO sous prétexte que c'était plus flexible.

Maintenant, ce sont ces gros tas immondes, avec un ordre d'appel de méthodes complexes, des mixins dans tous les sens et une chaine d'héritage velue. ]]></description>
				<content:encoded><![CDATA[<p>Les <a href="http://sametmax.com/des-vues-normales-aux-vues-generiques-django/">Class Based Views</a> sont des vues génériques réutilisables qui permettent de faire automatiquement des tâches courantes dans Django comme :</p>
<ul>
<li>Récupérer et afficher une ou plusieurs entrées en base de données.</li>
<li>Afficher et valider un formulaire.</li>
<li>Faire un mix des deux pour modifier des entrées en base.</li>
</ul>
<p><a href="http://sametmax.com/des-annees-plus-tards-je-naime-toujours-pas-les-cbv/">Je ne les ai jamais aimées</a>. Avant, les vues génériques étaient sous forme de fonction, simples, pratiques, c&#8217;était parfait. Et ça a été retiré du framework pour des versions OO sous prétexte que c&#8217;était plus flexible.</p>
<p>Maintenant, ce sont ces gros tas immondes, avec un ordre d&#8217;appel de méthodes complexes, des mixins dans tous les sens et une chaine d&#8217;héritage velue. </p>
<p>Je pense que c&#8217;est une bonne occasion pour rappeler que la POO n&#8217;est pas faite pour être utilisée partout, tout le temps. Aucun putain de paradigme de programmation n&#8217;est fait pour être utilisé partout, tout le temps. C&#8217;est pour ça qu&#8217;il y en a plusieurs.</p>
<p>Dans notre cas des CBV, la conséquence est que c&#8217;est <a href="http://sametmax.com/explication-de-code-des-mixins-et-des-decorateurs-de-methode-pour-django/">un enfer</a> pour expliquer tout usage qui ne soit pas un hello world, ce que la doc se garde bien de faire.</p>
<p>Après il y a toujours un malin pour dire &#8220;mais si tu vois tu fais ça, et ça, ça prend 5 lignes, c&#8217;est pas si dur&#8221;. Ouai, maintenant va expliquer ça à un stagiaire, et donne lui un exercice avec une form view qui doit modifier un objet, le lier à un user seulement si il a la permission de le faire. Juste pour voir en combien de temps il trouve. Je vais en WE à Barcelone en attendant. Je prévoie une extension à Rome pour quand il devra relire son code le trimestre prochain.</p>
<p>Et si encore c&#8217;était pour un gain de productivité évident, je fermerais les yeux. Mais c&#8217;est pas le cas. Même moi qui sait utiliser ces&#8230; ces choses&#8230; je dois regarder dans la doc à chaque fois que j&#8217;en utilise une. Et ensuite quand je relis mon code quelques mois plus tard, je chope de pattes d&#8217;oies aux coins des yeux.</p>
<blockquote><p>If you have to refer to the documentation every time you use a module, find (or build) a new module.</p></blockquote>
<p>Dixit Kenneth Reitz, le mec qui a pondu <a href="https://github.com/kennethreitz/requests">requests</a>. Donc on va user something else que les CBV, si vous le voulez bien.</p>
<p>Un lecteur m&#8217;a (encore) pointé du doigt qu&#8217;un schéma du MRO et de l&#8217;ordre d&#8217;appel des méthodes serait utile. Vous vous rendez compte du truc ? On peut comprendre l&#8217;ORM sans schéma alors que c&#8217;est une machine de guerre, et il faut une carte pour comprendre comment faire un listing un peu custo avec une CBV ? J&#8217;ai évalué la somme de travail pour faire ledit schéma, et elle est énorme : trop de classes, trop de méthodes, trop de subtilités.</p>
<p>Bref, je jette le tablier, fuck les CBV. Je ne les inclurai plus dans mes formations, mes tutos, mes aides sur les forums, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/je-nexpliquerai-plus-les-cbv/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2015/05/9cbXVwS.gif" length="202631" type="image/jpg" />	</item>
		<item>
		<title>Django, une app à la fois passe à Python 3 8</title>
		<link>http://sametmax.com/django-une-app-a-la-fois-passe-a-python-3/</link>
		<comments>http://sametmax.com/django-une-app-a-la-fois-passe-a-python-3/#comments</comments>
		<pubDate>Sun, 12 Apr 2015 08:53:55 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=16062</guid>
		<description><![CDATA[Beaucoup de nos projets ne sont pas encore compatibles Python 3 : 0bin, batbelt... La raison n'est pas technique, mais purement humaine, liée à notre monopilosité intramanuelle.]]></description>
				<content:encoded><![CDATA[<p>Beaucoup de nos projets ne sont pas encore compatibles Python 3 : 0bin, batbelt&#8230; La raison n&#8217;est pas technique, mais purement humaine, liée à notre monopilosité intramanuelle.</p>
<p>Néanmoins ayant posté sur reddit dernièrement le projet <a href="https://github.com/sametmax/Django--an-app-at-a-time/tree/fran%C3%A7ais">Django, une app à la fois</a>, on m&#8217;a demandé de le rafraichir.</p>
<p>Je l&#8217;ai donc up à Django 1.8, il est maintenant compatible avec Python 3 et gagne une licence MIT.</p>
<p>Et boom, just like that, un projet qui existe depuis 2 ans est passé dans <a href="https://github.com/trending">la liste des trending repositories de github</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/django-une-app-a-la-fois-passe-a-python-3/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2015/04/ykP0jFn.jpg" length="172667" type="image/jpg" />	</item>
		<item>
		<title>Un petit dashboard de monitoring avec Django et WAMP 7</title>
		<link>http://sametmax.com/un-petit-dashboard-de-monitoring-avec-django-et-wamp/</link>
		<comments>http://sametmax.com/un-petit-dashboard-de-monitoring-avec-django-et-wamp/#comments</comments>
		<pubDate>Sat, 07 Feb 2015 10:58:43 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[autobahn]]></category>
		<category><![CDATA[crossbar.io]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[wamp]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=15872</guid>
		<description><![CDATA[Crossbar.io vient avec un service "HTTP Pusher" qui permet d'envoyer une requête POST qui va se transformer en véritable publish WAMP.

Histoire d'illustrer tout ça, je vais vous montrer comment construire un petit service de monitoring avec Crossbar.io et Django.]]></description>
				<content:encoded><![CDATA[<p><em>Cet article est écrit dans le cadre de ma <a href="http://sametmax.com/full-disclosure/">collaboration</a> avec Tavendo.</em></p>
<p>On a déjà vu que <a href="http://sametmax.com/crossbar-le-futur-des-applications-web-python/">WAMP c&#8217;est cool</a>, mais c&#8217;est asynchrone et nos frameworks Web chéris WSGI <a href="http://sametmax.com/wamp-et-les-outils-de-dev-web-python-existants/">sont synchrones</a>.</p>
<p>J&#8217;ai donné une solution de contournement avec la lib <a href="http://sametmax.com/les-managers-le-detestent-faites-tourner-wamp-dans-django-avec-cette-astuce-insolite/">crochet</a> qui permet de faire tourner du twisted de manière synchrone dans son projet.</p>
<p>Néanmoins, beaucoup sont, j&#8217;en suis certain, à la recherche d&#8217;un truc plus simple. En effet, le bénéfice le plus immédiat de WAMP sont les notifications en temps réel. Et pour ça, crossbar vient avec le <a href="https://github.com/crossbario/crossbar/wiki/HTTP%20Pusher%20Service">HTTP PUSHER service</a> : quelques lignes de JSON dans le fichier de config de crossbar et zou, on peut publier sur un topic WAMP avec une simple requête POST :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"> <span style="color: #3366CC;">&quot;transports&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #009900;">&#123;</span>
       <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;web&quot;</span><span style="color: #339933;">,</span>
       <span style="color: #3366CC;">&quot;endpoint&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tcp&quot;</span><span style="color: #339933;">,</span>
          <span style="color: #3366CC;">&quot;port&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">8080</span>
       <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
       <span style="color: #3366CC;">&quot;paths&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
          ...
          <span style="color: #3366CC;">&quot;notify&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
             <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pusher&quot;</span><span style="color: #339933;">,</span>
             <span style="color: #3366CC;">&quot;realm&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;realm1&quot;</span><span style="color: #339933;">,</span>
             <span style="color: #3366CC;">&quot;role&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;anonymous&quot;</span>
          <span style="color: #009900;">&#125;</span>
       <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#93;</span></pre></td></tr></table></div>

<p>Et derrière, pour publier un event sur le sujet &#8220;super_sujet&#8221;, on peut faire :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> requets
requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://ip_du_router/pusher&quot;</span><span style="color: #66cc66;">,</span>
                  json<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span>
                      <span style="color: #483d8b;">'topic'</span>: <span style="color: #483d8b;">'super_sujet'</span>
                      <span style="color: #483d8b;">'args'</span>: <span style="color: black;">&#91;</span>queques<span style="color: #66cc66;">,</span> params<span style="color: #66cc66;">,</span> a<span style="color: #66cc66;">,</span> passer<span style="color: #66cc66;">,</span> si<span style="color: #66cc66;">,</span> on veut<span style="color: black;">&#93;</span>
                  <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ceci va envoyer une requête POST à un service de crossbar qui va transformer ça en véritable publish WAMP.</p>
<p>Histoire d&#8217;illustrer tout ça, je vais vous montrer comment construire un petit service de monitoring avec Crossbar.io et Django. Pour suivre le tuto vous aurez besoin :</p>
<ul>
<li>De connaissances de base en JS.</li>
<li>De connaître le principe de WAMP.</li>
<li>De savoir installer des bibliothèques Python avec extensions sur votre machine. <a href="https://duckduckgo.com/l/?kh=-1&#038;uddg=http%3A%2F%2Fsametmax.com%2Fvotre-python-aime-les-pip%2F">pip</a> et <a href="http://sametmax.com/les-environnement-virtuels-python-virtualenv-et-virtualenvwrapper">virtualenv</a> sont vos amis.</li>
<li>De connaître Django. Même si le concept peut s&#8217;appliquer à Flask, Pyramid, ou autre.</li>
</ul>
<p><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='1170' height='689' src='http://www.youtube.com/embed/e9Xtl22x5Sg?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0' allowfullscreen='true'></iframe></span></p>
<h2>Premiers pas</h2>
<p>Le but du jeu est d&#8217;avoir un petit client WAMP qu&#8217;on lance sur chaque machine qu&#8217;on veut monitorer. Celui-ci va, toutes les x secondes, récupérer l&#8217;usage CPU, RAM et disque et faire un publish WAMP.</p>
<div id="attachment_15876" style="width: 600px" class="wp-caption aligncenter"><a href="http://sametmax.com/wp-content/uploads/2015/02/architecture.png" class="grouped_elements" rel="tc-fancybox-group15872"><img src="http://sametmax.com/wp-content/uploads/2015/02/architecture.png" alt="Chaque machine possède un client WAMP" width="590" height="654" class="size-full wp-image-15876" /></a><p class="wp-caption-text">Chaque machine possède un client WAMP</p></div>
<p>A l&#8217;autre bout, on a un site Django qui a un modèle pour chaque machine monitorée, avec des valeurs pour dire si on est intéressé par le CPU, la RAM ou le disque et la valeur de x.</p>
<p>Une page affiche en temps réel tous les relevés pour toutes les machines. Si dans l&#8217;admin de Django on change un modèle, la page reflète ce changement.</p>
<div id="attachment_15877" style="width: 710px" class="wp-caption aligncenter"><a href="http://sametmax.com/wp-content/uploads/2015/02/dashboard.gif" class="grouped_elements" rel="tc-fancybox-group15872"><img src="http://sametmax.com/wp-content/uploads/2015/02/dashboard.gif" alt="Si je déclique &quot;CPU&quot; dans l&#039;admin Django, les CPUs ne sont plus affichés" width="700" height="650" class="size-full wp-image-15877" /></a><p class="wp-caption-text">Si je déclique &#8220;CPU&#8221; dans l&#8217;admin Django, les CPUs ne sont plus affichés</p></div>
<p> On aura donc besoin de django (<code>pip install Django</code>, ça c&#8217;est pas trop dur), requests (<code>pip install requests</code>, jusqu&#8217;ici tout va bien), et <a href="pythonhosted.org/psutil/">psutil</a>.</p>
<p>psutil est la lib Python qui va nous permettre de récupérer toutes le valeurs pour la RAM, le disque et le CPU. Elle utilise des extensions en C, il faut donc un compilateur et les headers Python. Sous Ubuntu, il faut donc faire :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> <span style="color: #c20cb9; font-weight: bold;">gcc</span> python-dev</pre></td></tr></table></div>

<p>Sous CentOS ça donne :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">yum groupinstall</span> <span style="color: #ff0000;">&quot;Development tools&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">yum install</span> python-devel</pre></td></tr></table></div>

<p>Sous Mac, les headers Python devraient être inclus, mais il vous faut aussi GCC. Si vous avez xcode, vous avez déjà un compilateur, sinon, il existe un installeur <a href="https://github.com/kennethreitz/osx-gcc-installer#readme">plus léger</a>.</p>
<p>Sous windows, c&#8217;est un wheel donc rien à faire normalement.</p>
<p>Et reste plus qu&#8217;à <code>pip install psutil</code>.</p>
<p>Enfin il nous faudra, logique, <a href="http://crossbar.io/docs/Local-Installation/">installer crossbar</a>. <code>pip install crossbar</code>, sachant que <a href="http://crossbar.io/docs/Installation-on-Windows/">sous Windows</a> vous aurez besoin de <a href="http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/">PyWin32</a> et comme toujours, d&#8217;avoir les dossiers <code>C:\Python27\</code> and <code>C:\Python27\Scripts</code> dans votre <a href="http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/">PATH</a>.</p>
<h2>Le HTML</h2>
<p>On a besoin que d&#8217;une page. Afin de rendre le tuto agnostique, je l&#8217;ai fait en pur JS, pas de jQuery, pas d&#8217;Angular. Donc c&#8217;est verbeux :)</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
&nbsp;
    &lt;!-- De quoi cacher un bloc facilement --&gt;
    &lt;style type=&quot;text/css&quot;&gt;
        .hide {display:none;}
    &lt;/style&gt;
&nbsp;
    &lt;!--
        La lib JS qui permet de parler WAMP .
&nbsp;
        Ici je suppose qu'on utilise un navigateur qui support websocket.
        Il est possible de faire du fallback sur flash ou long poll, mais
        ce sont des dépendances en plus.
    --&gt;
    &lt;script src=&quot;https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz&quot;
           type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&nbsp;
&nbsp;
    &lt;!-- Tout notre code client, inline pour faciliter votre lecture --&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
&nbsp;
      /* Connexion à notre serveur WAMP */
      window.addEventListener(&quot;load&quot;, function(){
        var connection = new autobahn.Connection({
           url: 'ws://127.0.0.1:8080/ws',
           realm: 'realm1'
        });
&nbsp;
        /* Quand la connexion est ouverte, exécuter ce code */
        connection.onopen = function(session) {
&nbsp;
          var clients = document.getElementById(&quot;clients&quot;);
&nbsp;
          /* Quand on reçoit l'événement clientstats, lancer cette fonction */
          session.subscribe('clientstats', function(args){
            var stats = args[0];
            var serverNode = document.getElementById(stats.ip);
&nbsp;
            /*
                 Créer un li contenant un h2 et un dl pour ce client si
                 il n'est pas encore dans la page.
            */
            if (!serverNode){
                serverNode = document.createElement(&quot;li&quot;);
                serverNode.id = stats.ip;
                serverNode.appendChild(document.createElement(&quot;h2&quot;));
                serverNode.appendChild(document.createElement(&quot;dl&quot;));
                serverNode.firstChild.innerHTML = stats.name + &quot; (&quot; + stats.ip + &quot;)&quot;;
                clients.appendChild(serverNode);
&nbsp;
                // Cacher les infos du serveur si il est désactivé.
                session.subscribe('clientconfig.' + stats.ip, function(args){
                    var config = args[0];
                    if (config.disabled){
                        var serverNode = document.getElementById(config.ip);
                        serverNode.className = &quot;hide&quot;;
                    }
                });
&nbsp;
            }
&nbsp;
            // Remettre à zéro le contenu du li du serveur.
            serverNode.className = &quot;&quot;;
            var dl = serverNode.lastChild;
            while (dl.hasChildNodes()) {
                dl.removeChild(dl.lastChild);
            }
&nbsp;
            // Si on a des infos sur le CPU, les afficher
            if (stats.cpus){
                var cpus = document.createElement(&quot;dt&quot;);
                cpus.innerHTML = &quot;CPUs:&quot;;
                dl.appendChild(cpus);
                for (var i = 0; i &lt; stats.cpus.length; i++) {
                    var cpu = document.createElement(&quot;dd&quot;);
                    cpu.innerHTML = stats.cpus[i];
                    dl.appendChild(cpu);
                };
            }
&nbsp;
            // Si on a des infos sur l'espace disque, les afficher
            if (stats.disks){
                var disks = document.createElement(&quot;dt&quot;);
                disks.innerHTML = &quot;Disk usage:&quot;;
                dl.appendChild(disks);
                for (key in stats.disks) {
                    var disk = document.createElement(&quot;dd&quot;);
                    disk.innerHTML = &quot;&lt;strong&gt;&quot; + key + &quot;&lt;/strong&gt;: &quot; + stats.disks[key];
                    dl.appendChild(disk);
                };
            }
&nbsp;
            // Si on a des infos sur l'usage mémoire, les afficher.
            if (stats.memory){
                var memory = document.createElement(&quot;dt&quot;);
                memory.innerHTML = &quot;Memory:&quot;;
                dl.appendChild(memory);
                var memVal = document.createElement(&quot;dd&quot;);
                memVal.innerHTML = stats.memory;
                dl.appendChild(memVal);
            }
&nbsp;
          });
&nbsp;
        };
&nbsp;
        // Ouvrir la connexion avec le routeur WAMP.
        connection.open();
&nbsp;
      });
    &lt;/script&gt;
&nbsp;
    &lt;title&gt; Monitoring&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt; Monitoring &lt;/h1&gt;
    &lt;ul id=&quot;clients&quot;&gt;&lt;/ul&gt;
&lt;/body&gt;
&nbsp;
&lt;/html&gt;</pre></td></tr></table></div>

<p>Comme vous pouvez le voir, c&#8217;est beaucoup de JS ordinaire et du DOM. Les seules parties spécifiques à WAMP sont :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> connection <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> autobahn.<span style="color: #660066;">Connection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
           url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'ws://127.0.0.1:8080/ws'</span><span style="color: #339933;">,</span>
           realm<span style="color: #339933;">:</span> <span style="color: #3366CC;">'realm1'</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
connection.<span style="color: #660066;">onopen</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>session<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
connection.<span style="color: #660066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Pour se connecter au serveur.</p>
<p>Et :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">session.<span style="color: #660066;">subscribe</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'nom_du_sujet'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Pour réagir à la publication d&#8217;un sujet WAMP.</p>
<h2>Le client de monitoring</h2>
<p>C&#8217;est la partie qui va aller sur chaque machine qu&#8217;on veut surveiller.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">__future__</span> <span style="color: #ff7700;font-weight:bold;">import</span> division
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">socket</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> requests
<span style="color: #ff7700;font-weight:bold;">import</span> psutil
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> autobahn.<span style="color: black;">twisted</span>.<span style="color: black;">wamp</span> <span style="color: #ff7700;font-weight:bold;">import</span> Application
<span style="color: #ff7700;font-weight:bold;">from</span> autobahn.<span style="color: black;">twisted</span>.<span style="color: black;">util</span> <span style="color: #ff7700;font-weight:bold;">import</span> sleep
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span>.<span style="color: black;">defer</span> <span style="color: #ff7700;font-weight:bold;">import</span> inlineCallbacks
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> to_gib<span style="color: black;">&#40;</span><span style="color: #dc143c;">bytes</span><span style="color: #66cc66;">,</span> factor<span style="color: #66cc66;">=</span><span style="color: #ff4500;">2</span>**<span style="color: #ff4500;">30</span><span style="color: #66cc66;">,</span> suffix<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;GiB&quot;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Converti un nombre d'octets en gibioctets.
&nbsp;
        Ex : 1073741824 octets = 1073741824/2**30 = 1GiO
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;%0.2f%s&quot;</span> % <span style="color: black;">&#40;</span><span style="color: #dc143c;">bytes</span> / factor<span style="color: #66cc66;">,</span> suffix<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_infos<span style="color: black;">&#40;</span>filters<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Retourne la valeur actuelle de l'usage CPU, mémoire et disque.
&nbsp;
        Ces valeurs sont retournées sous la forme d'un dictionnaire :
&nbsp;
            {
                'cpus': ['x%', 'y%', etc],
                'memory': &quot;z%&quot;,
                'disk':{
                    '/partition/1': 'x/y (z%)',
                    '/partition/2': 'x/y (z%)',
                    etc
                }
            }
&nbsp;
        Le paramètre filter est un dico de la forme :
&nbsp;
            {'cpus': bool, 'memory':bool, 'disk':bool}
&nbsp;
        Il est utilisé pour décider d'inclure ou non les résultats des mesures
        pour les 3 types de ressource.
&nbsp;
    &quot;&quot;&quot;</span>
&nbsp;
    results <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>filters.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'show_cpus'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">True</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        results<span style="color: black;">&#91;</span><span style="color: #483d8b;">'cpus'</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s%%&quot;</span> % x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> psutil.<span style="color: black;">cpu_percent</span><span style="color: black;">&#40;</span>percpu<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>filters.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'show_memory'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">True</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        memory <span style="color: #66cc66;">=</span> psutil.<span style="color: black;">phymem_usage</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        results<span style="color: black;">&#91;</span><span style="color: #483d8b;">'memory'</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'{used}/{total} ({percent}%)'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>
            used<span style="color: #66cc66;">=</span>to_gib<span style="color: black;">&#40;</span>memory.<span style="color: black;">active</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
            total<span style="color: #66cc66;">=</span>to_gib<span style="color: black;">&#40;</span>memory.<span style="color: black;">total</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
            percent<span style="color: #66cc66;">=</span>memory.<span style="color: black;">percent</span>
        <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>filters.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'show_disk'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">True</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        disks <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> device <span style="color: #ff7700;font-weight:bold;">in</span> psutil.<span style="color: black;">disk_partitions</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            usage <span style="color: #66cc66;">=</span> psutil.<span style="color: black;">disk_usage</span><span style="color: black;">&#40;</span>device.<span style="color: black;">mountpoint</span><span style="color: black;">&#41;</span>
            disks<span style="color: black;">&#91;</span>device.<span style="color: black;">mountpoint</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'{used}/{total} ({percent}%)'</span>.<span style="color: black;">format</span><span style="color: black;">&#40;</span>
                used<span style="color: #66cc66;">=</span>to_gib<span style="color: black;">&#40;</span>usage.<span style="color: black;">used</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
                total<span style="color: #66cc66;">=</span>to_gib<span style="color: black;">&#40;</span>usage.<span style="color: black;">total</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
                percent<span style="color: #66cc66;">=</span>usage.<span style="color: black;">percent</span>
            <span style="color: black;">&#41;</span>
        results<span style="color: black;">&#91;</span><span style="color: #483d8b;">'disks'</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> disks
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> results
&nbsp;
<span style="color: #808080; font-style: italic;"># On créé le client WAMP.</span>
app <span style="color: #66cc66;">=</span> Application<span style="color: black;">&#40;</span><span style="color: #483d8b;">'monitoring'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Ceci est l'IP publique de ma machine puisque</span>
<span style="color: #808080; font-style: italic;"># ce client doit pouvoir accéder à mon serveur</span>
<span style="color: #808080; font-style: italic;"># depuis l'extérieur.</span>
SERVER <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'172.17.42.1'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># D'abord on utilise une astuce pour connaître l'IP publique de cette</span>
<span style="color: #808080; font-style: italic;"># machine.</span>
s <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_DGRAM</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;8.8.8.8&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># On attache un dictionnaire à l'app, ainsi</span>
<span style="color: #808080; font-style: italic;"># sa référence sera accessible partout.</span>
app._params <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'name'</span>: <span style="color: #dc143c;">socket</span>.<span style="color: black;">gethostname</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'ip'</span>: s.<span style="color: black;">getsockname</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span>
s.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>app.<span style="color: #dc143c;">signal</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'onjoined'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">@</span>inlineCallbacks
<span style="color: #ff7700;font-weight:bold;">def</span> called_on_joinded<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Boucle envoyant l'état de cette machine avec WAMP toutes les x secondes.
&nbsp;
        Cette fonction est exécutée quand le client &quot;joins&quot; le router, c'est
        à dire qu'il est connecté et authentifié, prêt à envoyer des messages
        WAMP.
    &quot;&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># Ensuite on fait une requête post au serveur pour dire qu'on est</span>
    <span style="color: #808080; font-style: italic;"># actif et récupérer les valeurs de configuration de notre client.</span>
    app._params.<span style="color: black;">update</span><span style="color: black;">&#40;</span>requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://'</span> + SERVER + <span style="color: #483d8b;">':8080/clients/'</span><span style="color: #66cc66;">,</span>
                                    data<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'ip'</span>: app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>.<span style="color: black;">json</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #808080; font-style: italic;"># Puis on boucle indéfiniment</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #808080; font-style: italic;"># Chaque tour de boucle, on récupère les infos de notre machine</span>
        infos <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'ip'</span>: app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'name'</span>: app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'name'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span>
        infos.<span style="color: black;">update</span><span style="color: black;">&#40;</span>get_infos<span style="color: black;">&#40;</span>app._params<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Si les stats sont a envoyer, on fait une publication WAMP.</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'disabled'</span><span style="color: black;">&#93;</span>:
            app.<span style="color: black;">session</span>.<span style="color: black;">publish</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientstats'</span><span style="color: #66cc66;">,</span> infos<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Et on attend. Grâce à @inlineCallbacks, utiliser yield indique</span>
        <span style="color: #808080; font-style: italic;"># qu'on ne bloque pas ici, donc pendant ce temps notre client</span>
        <span style="color: #808080; font-style: italic;"># peut écouter les événements WAMP et y réagir.</span>
        <span style="color: #ff7700;font-weight:bold;">yield</span> sleep<span style="color: black;">&#40;</span>app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'frequency'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># On dit qu'on est intéressé par les événements concernant clientconfig</span>
<span style="color: #66cc66;">@</span>app.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientconfig.'</span> + app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> update_configuration<span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Met à jour la configuration du client quand Django nous le demande. &quot;&quot;&quot;</span>
    app._params.<span style="color: black;">update</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># On démarre notre client.</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:
    app.<span style="color: black;">run</span><span style="color: black;">&#40;</span>url<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;ws://%s:8080/ws&quot;</span> % SERVER<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Le plus gros du code est <code>get_infos()</code> qui n&#8217;a rien à voir avec WAMP. C&#8217;est nous, manipulant <code>psutil</code> pour obtenir les relevés de cette machine. Je ne recommande bien évidement pas de faire ça en prod : une grosse fonction monolithique qui prend un dico en param. Mais c&#8217;est pour une démo, et ça me permet de grouper les instructions qui vont ensemble pour faciliter votre compréhension.</p>
<p>La partie qui concerne WAMP :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">app <span style="color: #66cc66;">=</span> Application<span style="color: black;">&#40;</span><span style="color: #483d8b;">'monitoring'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>app.<span style="color: #dc143c;">signal</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'onjoined'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">@</span>inlineCallbacks
<span style="color: #ff7700;font-weight:bold;">def</span> called_on_joinded<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    ...
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
&nbsp;
        ...
        <span style="color: black;">app</span>.<span style="color: black;">session</span>.<span style="color: black;">publish</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientstats'</span><span style="color: #66cc66;">,</span> infos<span style="color: black;">&#41;</span>
        ...
        <span style="color: #ff7700;font-weight:bold;">yield</span> sleep<span style="color: black;">&#40;</span>app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'frequency'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><code>app = Application('monitoring')</code> créé un client WAMP, et <code>@app.signal('onjoined')</code> nous dit de lancer la fonction quand notre client est connecté et prêt à envoyer des événements. <code>@inlineCallbacks</code> est une spécificité de Twisted qui nous permet d&#8217;écrire du code asynchrone sans avoir à mettre des callback partout : à la place on met des <code>yield.</code></p>
<p>Tout le boulot de notre client a lieu dans la boucle : <code>app.session.publish('clientstats', infos)</code> publie les nouvelles mesures de CPU/RAM/Disque via WAMP, puis attend un certain temps (<code>yield sleep(app._params['frequency'])</code>) avant de le faire à nouveau. L&#8217;attente n&#8217;est pas bloquante car elle se fait avec le <code>sleep</code> de Twisted.</p>
<p>N&#8217;oublions pas :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">@</span>app.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientconfig.'</span> + app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> update_configuration<span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span>:
    app._params.<span style="color: black;">update</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>La fonction <code>update_configuration()</code> sera appelée à chaque fois qu&#8217;une publication WAMP sera faite sur le sujet <code>clientconfig.&lt;ip_du_client&gt;</code>. Notre fonction ne fait que mettre à jour la configuration du client, qui est un dico de la forme :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: black;">&#123;</span><span style="color: #483d8b;">'cpus'</span>: <span style="color: #008000;">True</span><span style="color: #66cc66;">,</span>
    <span style="color: #483d8b;">'memory'</span>: <span style="color: #008000;">False</span><span style="color: #66cc66;">,</span>
    <span style="color: #483d8b;">'disk'</span>: <span style="color: #008000;">True</span><span style="color: #66cc66;">,</span>
    <span style="color: #483d8b;">'disabled'</span>: <span style="color: #008000;">False</span><span style="color: #66cc66;">,</span>
    <span style="color: #483d8b;">'frequency'</span>: <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span></pre></td></tr></table></div>

<p>C&#8217;est ce dico qui est utilisé par <code>get_infos()</code> pour choisir quelles mesures récupérer, et aussi par <code>sleep()</code> pour savoir combien de secondes attendre avant la prochaine mesure.</p>
<p>La valeur initiale de ce dico est récupérée au lancement du client, en faisant :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">app._params.<span style="color: black;">update</span><span style="color: black;">&#40;</span>requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://'</span> + SERVER + <span style="color: #483d8b;">':8080/clients/'</span><span style="color: #66cc66;">,</span>
                                    data<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'ip'</span>: app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>.<span style="color: black;">json</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><code>requests.post(url_du_serveur, data={'ip': app._params['ip']}).json()</code> fait en effet une requête POST vers une URL de django qui nous allons voir plus loin, et qui retourne la configuration du client portant cette IP sous forme de JSON.</p>
<p>On utilise donc une fois HTTP pour obtenir les valeurs de départs, et ensuite WAMP pour les mises à jours des futures valeurs. WAMP et HTTP ne s&#8217;excluent pas : ils sont complémentaires.</p>
<p>Petite parenthèse sur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">SERVER <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'172.17.42.1'</span>
&nbsp;
s <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_DGRAM</span><span style="color: black;">&#41;</span>
s.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;8.8.8.8&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
app._params <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'name'</span>: <span style="color: #dc143c;">socket</span>.<span style="color: black;">gethostname</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'ip'</span>: s.<span style="color: black;">getsockname</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span>
s.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>D&#8217;une part, j&#8217;ai mis l&#8217;IP du serveur qui va contenir Crossbar.io et Django en dur car je suis, je pense que maintenant vous le savez, une grosse feignasse. Mais en prod, vous me faites un paramètre, on est d&#8217;accord ? Ensuite, il faut que j&#8217;identifie mon client, ce que je fais avec l&#8217;adresse IP. Il me faut donc son adresse IP externe, et je l&#8217;obtiens avec une astuce consistant à me connecter à l&#8217;IP 8.8.8.8 (les DNS google \o/) et en fermant la connexion juste derrière. Ce me permet de voir comment les autres machines me voit depuis l’extérieur.</p>
<h2>Le site Django</h2>
<p>Puisque le prérequis de l&#8217;article et de connaître Django, ça va pas être trop dur.</p>
<p>On créé son projet et son app :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">django-admin startproject django_project
.<span style="color: #000000; font-weight: bold;">/</span>manage.py startapp django_app</pre></td></tr></table></div>

<p>On se rajoute un petit modèle qui contient la configuration de chaque client (vous vous souvenez, le fameux dico) :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> requests
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> models
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span>.<span style="color: black;">models</span>.<span style="color: black;">signals</span> <span style="color: #ff7700;font-weight:bold;">import</span> post_save
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">dispatch</span> <span style="color: #ff7700;font-weight:bold;">import</span> receiver
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> model_to_dict
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Client<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Configuration de notre client. &quot;&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Pour l'identifier.</span>
    ip <span style="color: #66cc66;">=</span> models.<span style="color: black;">GenericIPAddressField</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Quelles données envoyer à notre dashboard</span>
    show_cpus <span style="color: #66cc66;">=</span> models.<span style="color: black;">BooleanField</span><span style="color: black;">&#40;</span>default<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    show_memory <span style="color: #66cc66;">=</span> models.<span style="color: black;">BooleanField</span><span style="color: black;">&#40;</span>default<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    show_disk <span style="color: #66cc66;">=</span> models.<span style="color: black;">BooleanField</span><span style="color: black;">&#40;</span>default<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Arrêter d'envoyer les données</span>
    disabled <span style="color: #66cc66;">=</span> models.<span style="color: black;">BooleanField</span><span style="color: black;">&#40;</span>default<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Fréquence de rafraîchissement des données</span>
    frequency <span style="color: #66cc66;">=</span> models.<span style="color: black;">IntegerField</span><span style="color: black;">&#40;</span>default<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">ip</span>
&nbsp;
&nbsp;
<span style="color: #66cc66;">@</span>receiver<span style="color: black;">&#40;</span>post_save<span style="color: #66cc66;">,</span> sender<span style="color: #66cc66;">=</span>Client<span style="color: #66cc66;">,</span> dispatch_uid<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;server_post_save&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> notify_server_config_changed<span style="color: black;">&#40;</span>sender<span style="color: #66cc66;">,</span> instance<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Notifie un client que sa configuration a changé.
&nbsp;
        Cette fonction est lancée quand on sauvegarde un modèle Client,
        et fait une requête POST sur le bridge WAMP-HTTP, nous permettant
        de faire un publish depuis Django.
    &quot;&quot;&quot;</span>
    requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://127.0.0.1:8080/notify&quot;</span><span style="color: #66cc66;">,</span>
                  json<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span>
                      <span style="color: #483d8b;">'topic'</span>: <span style="color: #483d8b;">'clientconfig.'</span> + instance.<span style="color: black;">ip</span><span style="color: #66cc66;">,</span>
                      <span style="color: #483d8b;">'args'</span>: <span style="color: black;">&#91;</span>model_to_dict<span style="color: black;">&#40;</span>instance<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
                  <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>La partie modèle est connue. L&#8217;astuce est dans :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">@</span>receiver<span style="color: black;">&#40;</span>post_save<span style="color: #66cc66;">,</span> sender<span style="color: #66cc66;">=</span>Client<span style="color: #66cc66;">,</span> dispatch_uid<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;server_post_save&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> notify_server_config_changed<span style="color: black;">&#40;</span>sender<span style="color: #66cc66;">,</span> instance<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
    requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://127.0.0.1:8080/notify&quot;</span><span style="color: #66cc66;">,</span>
                  json<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span>
                      <span style="color: #483d8b;">'topic'</span>: <span style="color: #483d8b;">'clientconfig.'</span> + instance.<span style="color: black;">ip</span><span style="color: #66cc66;">,</span>
                      <span style="color: #483d8b;">'args'</span>: <span style="color: black;">&#91;</span>model_to_dict<span style="color: black;">&#40;</span>instance<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
                  <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On utilise ici les signaux Django, une fonctionnalité du framework qui nous permet de lancer une fonction quand quelque chose se passe. Ici on dit &#8220;lance cette fonction quand le modèle <code>Client</code> est modifié&#8221;.</p>
<p>Donc <code>notify_server_config_changed</code> va se lancer quand la config d&#8217;un client est modifiée, par exemple dans l&#8217;admin, et recevoir l&#8217;objet modifié via son paramètre <code>instance</code>.</p>
<p>On fait alors une petite requête POST sur <code>http://127.0.0.1:8080/notify</code>, l&#8217;URL sur laquelle on configurera plus loin notre service de push. En faisant une requête dessus, on va demander à Crossbar.io de transformer la requête HTTP en message publish WAMP, ici sur le sujet &#8216;clientconfig.&lt;ip_du_client&gt;&#8217;. On publie donc un message WAMP, depuis Django.</p>
<p>Ca marche depuis n&#8217;importe où, pas juste Django. Depuis le shell, depuis Flask, n&#8217;importe où on peut faire une requête HTTP vers le service de push de crossbar.</p>
<p>Ce message va être récupéré par notre client, où qu&#8217;il soit, puisqu&#8217;il est aussi connecté au routeur WAMP. Comme, je vous le rappelle, notre client fait ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">@</span>app.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientconfig.'</span> + app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> update_configuration<span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span>:
    app._params.<span style="color: black;">update</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Il va recevoir ce message, et donc le contenu de <code>'args': [model_to_dict(instance)]</code>, c&#8217;est à dire la nouvelle configuration qu&#8217;on a changé en base de donnée. Il se met ainsi à jour immédiatement. La boucle est bouclée.</p>
<p>Comme on veut profiter de notre boucle toute bouclée, on rajoute le modèle dans l&#8217;admin :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin
&nbsp;
<span style="color: #808080; font-style: italic;"># Register your models here.</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django_app.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Client
&nbsp;
admin.<span style="color: #dc143c;">site</span>.<span style="color: black;">register</span><span style="color: black;">&#40;</span>Client<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ainsi, les configs des clients seront éditables dans l&#8217;admin, et quand on cliquera sur &#8220;save&#8221;, ça va lancer notre publish WAMP qui mettra à jour le bon client.</p>
<p>Le reste, c&#8217;est du fignolage. Une petite vue pour créer ou récupérer notre configuration de client au démarrage :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> json
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponse
<span style="color: #ff7700;font-weight:bold;">from</span> django_app.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Client
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">views</span>.<span style="color: black;">decorators</span>.<span style="color: black;">csrf</span> <span style="color: #ff7700;font-weight:bold;">import</span> csrf_exempt
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> model_to_dict
&nbsp;
&nbsp;
<span style="color: #66cc66;">@</span>csrf_exempt
<span style="color: #ff7700;font-weight:bold;">def</span> clients<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Récupère la config d'un client en base de donnée et lui envoie.&quot;&quot;&quot;</span>
    client<span style="color: #66cc66;">,</span> created <span style="color: #66cc66;">=</span> Client.<span style="color: black;">objects</span>.<span style="color: black;">get_or_create</span><span style="color: black;">&#40;</span>ip<span style="color: #66cc66;">=</span>request.<span style="color: black;">POST</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponse<span style="color: black;">&#40;</span>json.<span style="color: black;">dumps</span><span style="color: black;">&#40;</span>model_to_dict<span style="color: black;">&#40;</span>client<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> content_type<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'application/json'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On désactive la protection CSRF pour la démo, mais encore une fois, en prod, faites ça proprement, avec une jolie authentification pour protéger la vue, et tout, et tout.</p>
<p>Donc, cette vue récupère la configuration d&#8217;un client avec cette IP (la créant au besoin), et la retourne en JSON. Souvenez-vous, cela permet à notre client de faire :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    app._params.<span style="color: black;">update</span><span style="color: black;">&#40;</span>requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://'</span> + SERVER + <span style="color: #483d8b;">':8080/clients/'</span><span style="color: #66cc66;">,</span>
                                    data<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'ip'</span>: app._params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'ip'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>.<span style="color: black;">json</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Au démarrage et se déclarer dans la base de données, tout en récupérant sa config.</p>
<p>On branche tout ça via <code>urls.py</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span> <span style="color: #ff7700;font-weight:bold;">import</span> patterns<span style="color: #66cc66;">,</span> include<span style="color: #66cc66;">,</span> url
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">views</span>.<span style="color: black;">generic</span> <span style="color: #ff7700;font-weight:bold;">import</span> TemplateView
&nbsp;
urlpatterns <span style="color: #66cc66;">=</span> patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^admin/'</span><span style="color: #66cc66;">,</span> include<span style="color: black;">&#40;</span>admin.<span style="color: #dc143c;">site</span>.<span style="color: black;">urls</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^clients/'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'django_app.views.clients'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^$'</span><span style="color: #66cc66;">,</span> TemplateView.<span style="color: black;">as_view</span><span style="color: black;">&#40;</span>template_name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'dashboard.html'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>L&#8217;admin, notre vue toute fraiche, et de quoi servir le HTML du début de l&#8217;article.</p>
<p>Y plus qu&#8217;à :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>manage.py syncdb</pre></td></tr></table></div>

<h2>Crossbar.io</h2>
<p>Finalement, tout ce qu&#8217;il reste, c&#8217;est notre bon crossbar :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">crossbar init</pre></td></tr></table></div>

<p>Ceci nous pond le dossier <code>.crossbar</code> dans lequel on a le fichier <code>config.json</code> qu&#8217;on édite pour qu&#8217;il ressemble à ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;workers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
      <span style="color: #009900;">&#123;</span>
         <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;router&quot;</span><span style="color: #339933;">,</span>
         <span style="color: #3366CC;">&quot;realms&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #009900;">&#123;</span>
               <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;realm1&quot;</span><span style="color: #339933;">,</span>
               <span style="color: #3366CC;">&quot;roles&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
                  <span style="color: #009900;">&#123;</span>
                     <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;anonymous&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;permissions&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
                        <span style="color: #009900;">&#123;</span>
                           <span style="color: #3366CC;">&quot;uri&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;*&quot;</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;publish&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;subscribe&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;call&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;register&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span>
                        <span style="color: #009900;">&#125;</span>
                     <span style="color: #009900;">&#93;</span>
                  <span style="color: #009900;">&#125;</span>
               <span style="color: #009900;">&#93;</span>
            <span style="color: #009900;">&#125;</span>
         <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
         <span style="color: #3366CC;">&quot;transports&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #009900;">&#123;</span>
               <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;web&quot;</span><span style="color: #339933;">,</span>
               <span style="color: #3366CC;">&quot;endpoint&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                  <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tcp&quot;</span><span style="color: #339933;">,</span>
                  <span style="color: #3366CC;">&quot;port&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">8080</span>
               <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
               <span style="color: #3366CC;">&quot;paths&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                  <span style="color: #3366CC;">&quot;/&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                     <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;wsgi&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;module&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;django_project.wsgi&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;object&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application&quot;</span>
                  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                  <span style="color: #3366CC;">&quot;ws&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                     <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;websocket&quot;</span>
                  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                  <span style="color: #3366CC;">&quot;notify&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                     <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pusher&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;realm&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;realm1&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;role&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;anonymous&quot;</span>
                  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                  <span style="color: #3366CC;">&quot;static&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                     <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;static&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;directory&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;../static&quot;</span>
                  <span style="color: #009900;">&#125;</span>
               <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
         <span style="color: #009900;">&#93;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La partie du haut c&#8217;est un peu l&#8217;équivalent du <code>chmod 777</code> de crossbar :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">         <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;router&quot;</span><span style="color: #339933;">,</span>
         <span style="color: #3366CC;">&quot;realms&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #009900;">&#123;</span>
               <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;realm1&quot;</span><span style="color: #339933;">,</span>
               <span style="color: #3366CC;">&quot;roles&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
                  <span style="color: #009900;">&#123;</span>
                     <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;anonymous&quot;</span><span style="color: #339933;">,</span>
                     <span style="color: #3366CC;">&quot;permissions&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
                        <span style="color: #009900;">&#123;</span>
                           <span style="color: #3366CC;">&quot;uri&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;*&quot;</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;publish&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;subscribe&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;call&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                           <span style="color: #3366CC;">&quot;register&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span>
                        <span style="color: #009900;">&#125;</span>
                     <span style="color: #009900;">&#93;</span>
                  <span style="color: #009900;">&#125;</span>
               <span style="color: #009900;">&#93;</span>
            <span style="color: #009900;">&#125;</span>
         <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>&#8220;Met moi en place un router avec un accès nommé realm1 qui autorise à tous les anonymes de tout faire&#8221;. Un realm est une notion de sécurité dans Crossbar.io qui permet de cloisonner les clients connectés, nous on va tout mettre sur le même realm, c&#8217;est pour une démo je vous dis.</p>
<p>Ensuite on rajoute les transports pour chaque techno qui nous intéresse. On va tout regrouper sur le port 8080 car Twisted peut écouter en HTTP et Websocket sur le même port :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #3366CC;">&quot;transports&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;web&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;endpoint&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tcp&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;port&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">8080</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>A la racine, on sert notre app Django :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #3366CC;">&quot;/&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;wsgi&quot;</span><span style="color: #339933;">,</span>
     <span style="color: #3366CC;">&quot;module&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;django_project.wsgi&quot;</span><span style="color: #339933;">,</span>
     <span style="color: #3366CC;">&quot;object&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application&quot;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>Car oui, crossbar peut servir votre app django en prod. Pas besoin de gunicorn. En fait même pas besoin d&#8217;nginx pour un site simple, car ça tient très bien la charge. On a juste à lui indiquer quelle variable (<code>application</code>) de quel fichier WSGI (<code>django_project/wsgi.py</code>) charger, et il s&#8217;occupe du reste.</p>
<p>Sur &#8216;/ws&#8217;, on écoute en Websocket :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #3366CC;">&quot;ws&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;websocket&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>WAMP passe par là, et c&#8217;est pour ça que nos clients se connectent en faisant <code>app.run(url="ws://%s:8080/ws" % SERVER)</code> et <code>autobahn.Connection({url: 'ws://127.0.0.1:8080/ws', realm: 'realm1'});</code>.</p>
<p>&#8216;/notify&#8217; va recevoir le bridge WAMP-HTTP :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #3366CC;">&quot;notify&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pusher&quot;</span><span style="color: #339933;">,</span>
     <span style="color: #3366CC;">&quot;realm&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;realm1&quot;</span><span style="color: #339933;">,</span>
     <span style="color: #3366CC;">&quot;role&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;anonymous&quot;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Tous les anonymes du <code>realm1</code> peuvent l&#8217;utiliser. Grâce à ça, on a pu faire depuis notre signal Django :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    requests.<span style="color: black;">post</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://127.0.0.1:8080/notify&quot;</span><span style="color: #66cc66;">,</span>
                  json<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span>
                      <span style="color: #483d8b;">'topic'</span>: <span style="color: #483d8b;">'clientconfig.'</span> + instance.<span style="color: black;">ip</span><span style="color: #66cc66;">,</span>
                      <span style="color: #483d8b;">'args'</span>: <span style="color: black;">&#91;</span>model_to_dict<span style="color: black;">&#40;</span>instance<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
                  <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Et donc publier un message WAMP, via un POST HTTP.</p>
<p>Enfin, on sert les fichiers statiques Django avec Crossbar (oui, il fait aussi ça :):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"> <span style="color: #3366CC;">&quot;static&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;static&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;directory&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;../static&quot;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>N&#8217;oubliez pas le de spécifier <code>STATIC_ROOT</code> dans le fichier settings et lancer <code>./manage.py collecstatic</code>.</p>
<p>Tout ça en place, on lance notre routeur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PYTHONPATH</span>=<span style="color: #000000; font-weight: bold;">/</span>chemin<span style="color: #000000; font-weight: bold;">/</span>vers<span style="color: #000000; font-weight: bold;">/</span>votre<span style="color: #000000; font-weight: bold;">/</span>project
crossbar start</pre></td></tr></table></div>

<p>(Remplacer <code>export</code> par <code>set</code> sous Windows></p>
<p>La modification de <code>PYTHONPATH</code> est nécessaire pour que crossbar trouve votre fichier WSGI.</p>
<p>On visite <a href="http:127.0.0.1:8080/">http:127.0.0.1:8080/</a>, qui va charger notre template Django <code>dashboard.html</code>.</p>
<p>Chaque machine qui lance un client via <code>python client.py</code> va déclencher l&#8217;apparition des stats sur notre dashboard, qui seront mises à jour en temps réel.</p>
<p>Si on va sur <a href="http:127.0.0.1:8080/admin/">http:127.0.0.1:8080/admin/</a> et qu&#8217;on change la config d&#8217;un client, notre client s&#8217;adapte, et notre dashboard se met à jour automatiquement.</p>
<h2>Conclusion</h2>
<p>Notre projet ressemble à ceci au final :</p>
<pre>
.
├── client.py
├── .crossbar
│   ├── config.json
├── db.sqlite3
├── django_app
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── dashboard.html
│   └── views.py
├── django_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── static
└── manage.py

</pre>
<p>Vous pouvez récupérer le code <a href="https://github.com/sametmax/codes-des-articles/tree/master/2015/fevrier/tudo_django_wamp">ici</a>.</p>
<p>Finalement, très peu de code WAMP : un peu dans le JS, un peu dans le client. Et la seule chose qui lie WAMP à Django est la config crossbar qui ajoute le service HTTP PUSHER et notre requête POST dans <code>models.py</code></p>
<p>Cette technique n&#8217;est pas limitée à Django, et fonctionne bien pour toutes techno synchrones qui ne peut pas lancer un client WAMP directement en son sein. Pour le moment, le bridge HTTP-WAMP ne propose que PUB, pas de SUB, de pas de RPC. C&#8217;est déjà assez sympa pour avoir les notifications en temps réel un peu partout, et ça Tobias m&#8217;a dit qu&#8217;il ajoutera les autres actions dans un future proche.</p>
<p>En attendant, vous voyez le deal : on peut mélanger allègrement HTTP, WAMP, Python, JS, Client, Serveur, et monter sa petite architecture comme on le souhaite. Crossbar permet de démarrer du WSGI, mais aussi les clients WAMP sur la même machine et même n&#8217;importe quel process en ligne de commande (par exemple NodeJS) si besoin. C&#8217;est Mac Gyver ce truc.</p>
<p>On aurait pu écrire le client en Python 3 puisqu&#8217;il est sur une autre machine. Et en fait, si on lance Django en dehors de crossbar, aussi la partie Django en Python 3. Le code de crossbar n&#8217;est jamais modifié, on touche juste la configuration JSON.</p>
<p>Personnellement j&#8217;ai lancé plusieurs images <a href="http://sametmax.com/le-deploiement-par-conteneurs-avec-docker/">dockers</a> avec un client dedans à chaque fois, et c&#8217;est vraiment sympas de voir les machines se rajouter sur le dashboard en temps réel. On a une super sensation d&#8217;interactivité quand on change une valeur dans l&#8217;admin et qu&#8217;on voit le dashboard bouger.</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/un-petit-dashboard-de-monitoring-avec-django-et-wamp/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2015/02/eded53891380c2bb5fd43858688b0554.jpg" length="246633" type="image/jpg" />	</item>
		<item>
		<title>Les managers le détestent : faites tourner WAMP dans Django avec cette astuce insolite 11</title>
		<link>http://sametmax.com/les-managers-le-detestent-faites-tourner-wamp-dans-django-avec-cette-astuce-insolite/</link>
		<comments>http://sametmax.com/les-managers-le-detestent-faites-tourner-wamp-dans-django-avec-cette-astuce-insolite/#comments</comments>
		<pubDate>Sun, 04 Jan 2015 19:45:07 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[autobahn]]></category>
		<category><![CDATA[crochet]]></category>
		<category><![CDATA[crossbar]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[flask]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[twisted]]></category>
		<category><![CDATA[wamp]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=15665</guid>
		<description><![CDATA[On peut utiliser WAMP, <code>directement</code> dans Django.]]></description>
				<content:encoded><![CDATA[<p>Il existe une lib appelée <a href="https://pypi.python.org/pypi/crochet">crochet</a> qui permet de faire marcher des API de twisted entre deux bouts de code bloquants. Certes, ça ne marche qu&#8217;en 2.7 et c&#8217;est pas hyper performant, mais on peut faire des trucs mignons du genre cette démo qui <a href="https://github.com/tavendo/AutobahnPython/tree/master/examples/twisted/wamp/app/crochet/example1">mélange flask et WAMP</a>.</p>
<p>C&#8217;est du pur Python, pas de process externe à gérer, c&#8217;est presque simple.</p>
<p>Bref, si on veut utiliser WAMP avec une app synchrone comme flask, c&#8217;est un bon moyen de s&#8217;y mettre. On aura jamais des perfs fantastiques, mais on peut pusher vers le browser.</p>
<p>Du coup je me suis demandé si on pouvait faire ça avec Django.</p>
<p>Évidement, ça a été un peu plus compliqué car par défaut <code>runserver</code> lance plusieurs workers et fait un peu de magie avec les threads. Mais après un peu de bidouillage, ça marche !</p>
<p>On peut utiliser WAMP, <code>directement</code> dans Django.</p>
<h2>Suivez le guide</h2>
<p>D&#8217;abord, on installe tout le bouzin (python 2.7, souvenez-vous) :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> crossbar crochet django</pre></td></tr></table></div>

<p>Il vous faudra un Django 1.7, le tout dernier, car il possède <a href="https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready">une fonctionnalité</a> qui nous permet de lancer du code quand tout le framework est chargé.</p>
<p>Vous vous faites votre projet comme d&#8217;hab, et vous ouvrez le fichier de settings et au lieu de mettre votre app dans <code>INSTALLED_APPS</code>, vous rajoutez ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">INSTALLED_APPS <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>
    <span style="color: #483d8b;">'...'</span><span style="color: #66cc66;">,</span>
    <span style="color: #483d8b;">'votreapp.app.VotreAppConfig'</span>
<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Puis dans le module de votre app, vous créez un fichier app.py, qui va contenir ça:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> crochet
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">apps</span> <span style="color: #ff7700;font-weight:bold;">import</span> AppConfig
&nbsp;
<span style="color: #808080; font-style: italic;"># On charge l'objet contenant la session WAMP définie dans la vue</span>
<span style="color: #ff7700;font-weight:bold;">from</span> votreapp.<span style="color: black;">views</span> <span style="color: #ff7700;font-weight:bold;">import</span> wapp
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> VotreAppConfig<span style="color: black;">&#40;</span>AppConfig<span style="color: black;">&#41;</span>:
    name <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'votreapp'</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> ready<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># On dit a crochet de faire tourner notre app wamp dans sa popote qui</span>
        <span style="color: #808080; font-style: italic;"># isole le reactor de Twisted</span>
        <span style="color: #66cc66;">@</span>crochet.<span style="color: black;">run_in_reactor</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> start_wamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
           <span style="color: #808080; font-style: italic;"># On démarre la session WAMP en se connectant au serveur</span>
           <span style="color: #808080; font-style: italic;"># publique de test</span>
           wapp.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;wws://demo.crossbar.io/ws&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;realm1&quot;</span><span style="color: #66cc66;">,</span> start_reactor<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
        start_wamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On passe à urls.py dans lequel on se rajoute des vues de démo :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^ping/'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'votreapp.views.ping'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^$'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'votreapp.views.index'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Puis dans notre fichier views.py, on met :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> uuid
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">shortcuts</span> <span style="color: #ff7700;font-weight:bold;">import</span> render
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> crochet
&nbsp;
<span style="color: #808080; font-style: italic;"># Crochet se démerde pour faire tourner le reactor twisted de</span>
<span style="color: #808080; font-style: italic;"># manière invisible. A lancer avant d'importer autobahn</span>
crochet.<span style="color: black;">setup</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> autobahn.<span style="color: black;">twisted</span>.<span style="color: black;">wamp</span> <span style="color: #ff7700;font-weight:bold;">import</span> Application
&nbsp;
<span style="color: #808080; font-style: italic;"># un objet qui contient une session WAMP</span>
wapp <span style="color: #66cc66;">=</span> Application<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># On enrobe les primitives de WAMP pour les rendre synchrones</span>
<span style="color: #66cc66;">@</span>crochet.<span style="color: black;">wait_for</span><span style="color: black;">&#40;</span>timeout<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> publish<span style="color: black;">&#40;</span>topic<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
   <span style="color: #ff7700;font-weight:bold;">return</span> wapp.<span style="color: black;">session</span>.<span style="color: black;">publish</span><span style="color: black;">&#40;</span>topic<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>crochet.<span style="color: black;">wait_for</span><span style="color: black;">&#40;</span>timeout<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> call<span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
   <span style="color: #ff7700;font-weight:bold;">return</span> wapp.<span style="color: black;">session</span>.<span style="color: black;">call</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #66cc66;">@</span>crochet.<span style="color: black;">run_in_reactor</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> decorator<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>:
        wapp.<span style="color: black;">register</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> decorator
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> subscribe<span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #66cc66;">@</span>crochet.<span style="color: black;">run_in_reactor</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> decorator<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>:
        wapp.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> decorator
&nbsp;
<span style="color: #808080; font-style: italic;"># Et hop, on peut utiliser nos outils WAMP !</span>
&nbsp;
<span style="color: #66cc66;">@</span>register<span style="color: black;">&#40;</span><span style="color: #483d8b;">'uuid'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> get_uuid<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> uuid.<span style="color: black;">uuid4</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #008000;">hex</span>
&nbsp;
<span style="color: #66cc66;">@</span>subscribe<span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> onping<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'test'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Et à côté, quelques vues django normales</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> index<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># pub et RPC en action côté Python</span>
    publish<span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> call<span style="color: black;">&#40;</span><span style="color: #483d8b;">'uuid'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'test'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'index.html'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> ping<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'ping.html'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Après, un peu de templating pour que ça marche&#8230;</p>
<p>Index.html :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html" style="font-family:monospace;">{% load staticfiles %}
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;title&gt;
       UUID
    &lt;/title&gt;
&nbsp;
    &lt;script src=&quot;{% static 'autobahn.min.js' %}&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      var connection = new autobahn.Connection({
         url: &quot;ws://localhost:8080/ws&quot;,
         realm: &quot;realm1&quot;
      });
&nbsp;
     connection.onopen = function (session) {
&nbsp;
        session.call(&quot;uuid&quot;).then(function (uuid) {
          var p = document.getElementById('uuid');
          p.innerHTML = uuid;
        });
     };
&nbsp;
     connection.open();
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h2&gt;UUID&lt;/h2&gt;
&lt;p id=&quot;uuid&quot;&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>ping.html :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#123;</span>% load staticfiles %<span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&lt;!</span>DOCTYPE html<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>head<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>meta charset<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;utf-8&quot;</span> /<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>title<span style="color: #66cc66;">&gt;</span>
       Ping
    <span style="color: #66cc66;">&lt;</span>/title<span style="color: #66cc66;">&gt;</span>
&nbsp;
    <span style="color: #66cc66;">&lt;</span>script src<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;{% static 'autobahn.min.js' %}&quot;</span><span style="color: #66cc66;">&gt;&lt;</span>/script<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>script <span style="color: #008000;">type</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;text/javascript&quot;</span><span style="color: #66cc66;">&gt;</span>
      var connection <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">new</span> autobahn.<span style="color: black;">Connection</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
         url: <span style="color: #483d8b;">&quot;ws://localhost:8080/ws&quot;</span><span style="color: #66cc66;">,</span>
         realm: <span style="color: #483d8b;">&quot;realm1&quot;</span>
      <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
&nbsp;
     connection.<span style="color: black;">onopen</span> <span style="color: #66cc66;">=</span> function <span style="color: black;">&#40;</span>session<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
&nbsp;
        session.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ping&quot;</span><span style="color: #66cc66;">,</span> function <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
          var ul <span style="color: #66cc66;">=</span> document.<span style="color: black;">getElementById</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
          var li <span style="color: #66cc66;">=</span> document.<span style="color: black;">createElement</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'li'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
          li.<span style="color: black;">innerHTML</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'Ping !'</span>
          ul.<span style="color: black;">appendChild</span><span style="color: black;">&#40;</span>li<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
     <span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span>
&nbsp;
     connection.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
    <span style="color: #66cc66;">&lt;</span>/script<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/head<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>body<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Ping me <span style="color: #66cc66;">!&lt;</span>/h2<span style="color: #66cc66;">&gt;</span>
&nbsp;
<span style="color: #66cc66;">&lt;</span>ul <span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;ping&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/ul<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/body<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/html<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>On ouvre la console, on lance son routeur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">    crossbar init
    crossbar start</pre></td></tr></table></div>

<p>On lance dans une autre console son serveur Django :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>manage.py runserver</pre></td></tr></table></div>

<p>Et si on navigue sur <code>http://127.0.0.1:8000</code>, on récupère un UUID tout frais via RCP.</p>
<p>On peut aussi voir dans le shell que ça marche côté Python :</p>
<pre>94cfccf0899d4c42950788fa655b65ed
ping</pre>
<p>D’ailleurs un fichier nommé &#8220;test&#8221; est créé à la racine du projet.</p>
<p>Et si on navigue sur <code>http://127.0.0.1:8000/ping/</code> et qu&#8217;on refresh <code>http://127.0.0.1:8000</code> plusieurs fois, on voit la page se mettre à jour.</p>
<p>Achievement unlock : use WAMP and Django code in the same file.</p>
<h2>A partir de là</h2>
<p>Il y a plein de choses à faire.</p>
<p>On pourrait faire une lib qui wrap tout ça pour pas à avoir à le mettre dans son fichier de vue et qui utilise settings.py pour la configuration.</p>
<p>Il faut tester ça avec des setups plus gros pour voir comment ça se comporte avec gunicorn, plusieurs workers, le logging de Django, etc. Je suis à peu près sûr que les callbacks vont être registrés plusieurs fois et ça devrait faire des erreurs dans les logs (rien de grave ceci dit).</p>
<p>On pourrait aussi adapter le RPC pour qu&#8217;il utilise les cookies d&#8217;authentification Django, et pouvoir les protéger avec @login_required.</p>
<p>Mais un monde d&#8217;opportunités s&#8217;offrent à vous à partir de là.</p>
<p>Moi, ça fait 6 h que je taffe dessus, je vais me pieuter.</p>
<hr />
<p><a href="https://github.com/sametmax/codes-des-articles/tree/master/2015/janvier/wamp_et_django">Télécharger le code de l&#8217;article</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/les-managers-le-detestent-faites-tourner-wamp-dans-django-avec-cette-astuce-insolite/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2015/01/index.jpeg" length="10867" type="image/jpg" />	</item>
		<item>
		<title>Prendre le contrôle d&#8217;internet ? C&#8217;est possible ! Dégainez &amp; Tirez avec Trigger Happy 4</title>
		<link>http://sametmax.com/prendre-le-controle-dinternet-cest-possible-degainez-tirez-avec-trigger-happy/</link>
		<comments>http://sametmax.com/prendre-le-controle-dinternet-cest-possible-degainez-tirez-avec-trigger-happy/#comments</comments>
		<pubDate>Sun, 28 Dec 2014 06:45:36 +0000</pubDate>
		<dc:creator><![CDATA[foxmask]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=12972</guid>
		<description><![CDATA[Ceci est un post invité de foxmask posté sous licence creative common 3.0 unported. &#8220;C&#8217;est l&#8217;histoire d&#8217;un mec qu&#8217;est su&#8217;l&#8217;pont de l&#8217;Alma et regarde dans&#8221; &#8230; le python, et comme il débute, se demande mais putain de bordel, des projets à la con à pondre pour se lancer à l&#8217;assaut d&#8217;un langage, c&#8217;est toujours les [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><em><small>Ceci est un post invité de <a href="http://sametmax.com/author/foxmask/">foxmask</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/">creative common 3.0 unported</a>.</small></em></p>
<p>&#8220;C&#8217;est l&#8217;histoire d&#8217;un mec qu&#8217;est su&#8217;l&#8217;pont de l&#8217;Alma et regarde dans&#8221; &#8230; le python, et comme il débute, se demande mais putain de bordel, des projets à la con à pondre pour se lancer à l&#8217;assaut d&#8217;un langage, c&#8217;est toujours les mêmes trucs chiants que plus personne n&#8217;a envie de voir tels : forum, blog, wiki, cms. Alors comment être novateur un poil plus que ces projets sans (plus aucun) défit technique ?</p>
<p>A cette question je me suis dit, pourquoi ne pas produire &#8220;simplement&#8221; (toute proportion gardée) un équivalent libre au célébrissime <a href="https://www.ifttt.com">IFTTT</a> ?</p>
<h2>Mais qu&#8217;est-ce ? </h2>
<p>IFTTT est un service qui vous permet de brancher entre eux, les services internet où vous possédez un compte, comme Twitter, Facebook pour ne citer qu&#8217;eux (parce que la liste est longue comme un python au moins;) Et donc quand un évènement défini se produit sur votre compte twitter, genre un tweet de votre poto tombe, le service réagit au quart de tour pour rebalancer les données ailleurs, sur Facebook, un blog et n&#8217;importe quoi qui vous chante.</p>
<p>Hé bien cet équivalent libre est <a href="https://github.com/foxmask/django-th">Trigger Happy</a>, et ce &#8220;principe&#8221; décrit ci-dessus défini un ESB (Entreprise Service Bus, très connu du monde Java), un BUS qui récupère des données de droite et vous les expédie à gauche.</p>
<p>Wikipedia le défini ainsi :</p>
<blockquote="wikipedia"><p>
L&#8217;enterprise service bus (ESB) est une technique informatique intergicielle. Son but est avant tout de permettre la communication des applications qui n&#8217;ont pas été conçues pour fonctionner ensemble</p></blockquote>
<h2>Pourquoi un tel projet ?</h2>
<p>3 aspects :</p>
<ul>
<li>Avec ce projet je me suis lancé le défit d&#8217;arriver à cerner au mieux Django et abordé au mieux Python.</li>
<li>Comme tout ce que j&#8217;entreprends, se produit par pur réaction allergique à un truc qui m&#8217;a gonflé, explications les zamis :<br />
Au début on fait (plus ou moins) comme tout le monde, sa veille techno à partir de flux RSS de sites web choisis, avec un lecteur de flux RSS moins bien choisi comme iGoogle à une certaine époque ou encore &#8230; Google Reader.<br />
Là le truc qui m&#8217;a pris le chou, ce fut d&#8217;avoir dans Evernote, le résultats des flux RSS de mes sites favoris complètement atrophiés.<br />
Du genre &#8220;il a été à l&#8217;école&#8221; devenait &#8220;il a t l&#8217;cole&#8221;. Or le problème ne vient pas d&#8217;Evernote qui affiche parfaitement nos chers caractères latins, mais de IFTTT qui les bouffait au passage. Outre IFTTT il existe des versions payantes de services mais qui sont vite très vite limitées dans le nombre de triggers déclenchés que sont Zapier et CloudWork.
</li>
<li>
Le dernier aspect concerne sa chère vie privé.<br />
Oui en effet, pour que IFTTT puisse récupérer des donnés d&#8217;un service à l&#8217;autre, il faut que vous ayez un compte sur chaque service comme Twitter et Facebook. Pourquoi IFTTT en a besoin ? Pour que, &#8220;en votre nom&#8221;, avec les accréditations que vous leur octroyez, puisse lire/écrire les informations de part et d&#8217;autre.<br />
Mais pourquoi faire confiance à IFTTT / Cloudwork / Zapier ? Pourquoi leur offrir NOS accréditations les yeux fermés ?<br />
Trigger Happy repond à la question puisque l&#8217;application vous appartient, les accréditations obtenues de Twitter, Facebook etc, sont stockées dans VOTRE application Trigger Happy. Et personne n&#8217;ira les exploiter pour voir ce que vous faites sur vos comptes.
</li>
</ul>
<h2>Comment fonctionne le projet ?</h2>
<p>Dans la version simplifiée ceci donne :<br />
<div id="attachment_5019" style="width: 420px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger-happy-working.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger-happy-working.png" alt="Trigger Happy wokring process" width="410" height="351" class="size-full wp-image-5019" /></a><p class="wp-caption-text">Image tirée de ma main &#8220;gauche&#8221; gauche, enfin la gauche pas adroite</p></div><br />
De part et d&#8217;autres (dans les nuages) on a les services qui nous intéressent<br />
Les éclairs oranges sont les connecteurs qui permettent de dialoguer avec les services<br />
Au milieu .. (non ne coule pas une rivière) le moteur Trigger Happy qui gère, via les connecteurs, l&#8217;échange des données.</p>
<p>Dans la version complète ceci donne :<br />
<div id="attachment_5018" style="width: 567px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/th_esb.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/th_esb.png" alt="Trigger Happy Micro ESB" width="557" height="347" class="size-full wp-image-5018" /></a><p class="wp-caption-text">Trigger Happy Micro ESB</p></div></p>
<p>On a au milieu un &#8220;tube&#8221; (pipeline) qui va permettre, via des &#8220;command&#8221; &#038; settings &#038; url &#038; service provider, d&#8217;identifier les services &#8220;django th 1, 2, 3, 4&#8243;.<br />
A un moment donné, à l&#8217;entrée du tube, arrive un &#8220;flux&#8221; de donnés identifié pour admettons &#8220;django th 1&#8243; aka un flux RSS (au pif) puis on identifie une destination, admettons &#8220;django th 2&#8243; aka &#8220;twitter&#8221;, et les données collectées repartent donc du tube vers twitter, comme le service s&#8217;attend à les recevoir.</p>
<h2>Dans la vraie vie comment ça se passe  ?</h2>
<p>Ça se passe bien mon zami : je m&#8217;en va (la fote est volontaire tout comme l&#8217;reste;) vous montrer la création d&#8217;un trigger, permettant d&#8217;extraire les billets du flux de mon blog et de les renvoyer sur Twitter en 5 étapes :</p>
<p>Ici en premier lieu vous pouvez voir la liste des services que Trigger Happy gere pour l&#8217;utilisateur courant (mézigues)</p>
<div id="attachment_5023" style="width: 614px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_services.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_services-1024x539.png" alt="Trigger Happy : services activés" width="604" height="318" class="size-large wp-image-5023" /></a><p class="wp-caption-text">Trigger Happy : services activés</p></div>
<p>Puis l&#8217;accueil de l&#8217;appli où on remarquera que je suis radin en nombre de trigger affichés par page parce que &#8230; je me sers de l&#8217;appli via un browser sur mon smartphone m&#8217;sieur &#8216;dames :<br />
<div id="attachment_5022" style="width: 614px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_home.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_home-1024x595.png" alt="Trigger Happy : Accueil" width="604" height="351" class="size-large wp-image-5022" /></a><p class="wp-caption-text">Trigger Happy : Accueil</p></div></p>
<p>Etape 1:<br />
<div id="attachment_5024" style="width: 621px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step1.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step1.png" alt="Trigger Happy : Etape 1 de la création d&#039;un trigger" width="611" height="315" class="size-full wp-image-5024" /></a><p class="wp-caption-text">Choix du service fournissant les données</p></div></p>
<p>Etape 2:<br />
<div id="attachment_5025" style="width: 709px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step2.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step2.png" alt="Trigger Happy : Etape 2 de la création d&#039;un trigger" width="699" height="329" class="size-full wp-image-5025" /></a><p class="wp-caption-text">nommage du service et fourniture de l&#8217;origine des données</p></div></p>
<p>Etape 3:<br />
<div id="attachment_5026" style="width: 602px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step3.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step3.png" alt="Trigger Happy : Etape 3 de la création d&#039;un trigger" width="592" height="310" class="size-full wp-image-5026" /></a><p class="wp-caption-text">Choix du service accueillant les données</p></div></p>
<p>Etape 4:<br />
<div id="attachment_5027" style="width: 670px" class="wp-caption aligncenter"><a href="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step4.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step4.png" alt="Trigger Happy : Etape 4 de la création d&#039;un trigger" width="660" height="351" class="size-full wp-image-5027" /></a><p class="wp-caption-text">Trigger Happy : Etape 4 de la création d&#8217;un trigger</p></div></p>
<p>Ensuite le moment venu, se déclenche ce trigger, et pour en voir le résultat, on peut consulter <a href="http://www.foxmask.bzh/post/2014/11/27/django-paris-numa-novembre-2014-demo-live/">le billet</a> que j&#8217;avais préparé le mois dernier pour une présentation Django Paris. Et qui au moment de la publication du billet, à 19h15 pétantes, est tombé sur <a href="https://twitter.com/foxmask/status/538033340155432960">twitter</a> directement et <a href="https://www.evernote.com/pub/foxmask1/Django#st=p&#038;n=e47e8324-ad7e-4b4a-bf4e-0823642b9d3a">Evernote</a> dans la foulée.</p>
<p>Voilà ! </p>
<p>Le défit est parti et n&#8217;attend plus qu&#8217;à ce que le nombre de services croissent. Pour cela rien de plus simple, j&#8217;ai fait une doc expliquant comment pondre un module django qui exploite le service de votre choix tel Buffer, Trello, Dropbox et j&#8217;en passe et des meilleurs. Tout ce dont on a besoin : l&#8217;API du service visé en python, créer un compte pour avoir accès au service et suivre le howto sur <a href="http://trigger-happy.readthedocs.org/en/latest/new_module.html">readthedoc</a>  </p>
<p>Last but not least aux dev : ca tourne avec django 1.7 / Python 2.7 et 3.4</p>
<p>Dernier détail: comme je suis sûr que vous vous demandez pourquoi ce nom de projet ? <a href="http://trigger-happy.eu/static/django-paris-novembre-2014/trigger-happy.png" class="grouped_elements" rel="tc-fancybox-group12972">C&#8217;est un perso de la franchise Skylander</a> auquel joue mon fils et comme le projet &#8220;trigger&#8221; à tirelarigot sur l&#8217;net, ca collait pile poil :)</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/prendre-le-controle-dinternet-cest-possible-degainez-tirez-avec-trigger-happy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Django pleure &#8216;MySQL server has gone away&#8217; 1</title>
		<link>http://sametmax.com/django-pleure-mysql-server-has-gone-away/</link>
		<comments>http://sametmax.com/django-pleure-mysql-server-has-gone-away/#comments</comments>
		<pubDate>Mon, 13 Oct 2014 08:52:19 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=12424</guid>
		<description><![CDATA[
Dans certaines circonstances, par exemple une transaction ouverte pendant trop longtemps, MySQL ferme la connexion avec son client. ]]></description>
				<content:encoded><![CDATA[<p>Dans certaines circonstances, par exemple une transaction ouverte pendant trop longtemps, MySQL ferme la connexion avec son client. </p>
<p>Cela arrive par exemple quand on l&#8217;utilise comme broker pour celery. On a des tâches qui plantent, et quand on met du debug, on lit un <code>(2006, 'MySQL server has gone away')</code> bien cryptique.</p>
<p>Généralement je recommande de changer de backend ici. Passer à redis pour cet usage par exemple.</p>
<p>Mais parfois on ne peut pas. La solution est alors de forcer Django à réinitialiser la connexion en la fermant. Il faut le faire au niveau où on a remarqué que la requête échouait. Dans notre cas, au début de chaque tâche celery :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> connection 
&nbsp;
<span style="color: #66cc66;">@</span>task
<span style="color: #ff7700;font-weight:bold;">def</span> do_stuff<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    connection.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># le reste du code</span></pre></td></tr></table></div>

<p>Voyant la connexion fermée, Django va en ouvrir une nouvelle à la prochaine requête automatiquement.</p>
<p>Cela a, évidement, un impact sur les performances, donc choisissez bien entre mettre une rustine et changer la roue.</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/django-pleure-mysql-server-has-gone-away/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2014/10/keep-calm-cause-im-gone-away.png" length="38892" type="image/jpg" />	</item>
		<item>
		<title>Accélérer les listings de l&#8217;admin Django avec beaucoup de ForeignKeys 3</title>
		<link>http://sametmax.com/accelerer-les-listings-de-ladmin-django-avec-beaucoup-de-foreignkeys/</link>
		<comments>http://sametmax.com/accelerer-les-listings-de-ladmin-django-avec-beaucoup-de-foreignkeys/#comments</comments>
		<pubDate>Sun, 28 Sep 2014 07:32:29 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[perf]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=12251</guid>
		<description><![CDATA[Je pensais que ces astuces étaient très connues, mais quand j'en ai eu besoin, j'ai galéré pour mettre la main dessus. Du coup blogage, blogation, blogitude.]]></description>
				<content:encoded><![CDATA[<p>Je pensais que ces astuces étaient très connues, mais quand j&#8217;en ai eu besoin, j&#8217;ai galéré pour mettre la main dessus. Du coup blogage, blogation, blogitude.</p>
<p>L&#8217;admin Django permet de faire automatiquement un listing des objets voulus afin de les modifier. Si un modèle a une ForeignKey et qu&#8217;on définit le champ en <code>list_editable</code>, Django va pondre un drop down pour choisir parmi les relations possibles.</p>
<p>Or, le framework fait une requête <strong>pour chaque objet de la liste</strong>. Si vous avez deux ForeignKeys sur votre modèle et 20 objets (valeur par défaut) dans la liste, ça vous fait donc 40 queries, juste pour afficher ces deux drop down. Doh.</p>
<p>On peut néanmoins forcer Django à cacher le résultat de la première requête, réduisant ainsi le compte à 1, avec cette étrange astuce d&#8217;une mère au foyer (consultants hate her !) :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> VotreClasseAdmin<span style="color: black;">&#40;</span>admin.<span style="color: black;">ModelAdmin</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Cette méthode est appelée pour créer le champ de formulaire de pour</span>
    <span style="color: #808080; font-style: italic;"># chaque objet</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> formfield_for_dbfield<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> db_field<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
&nbsp;
        request <span style="color: #66cc66;">=</span> kwargs<span style="color: black;">&#91;</span><span style="color: #483d8b;">'request'</span><span style="color: black;">&#93;</span>
        formfield <span style="color: #66cc66;">=</span> <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>ProductPageAdmin<span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">formfield_for_dbfield</span><span style="color: black;">&#40;</span>db_field<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Si le champ est editable dans la liste</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> db_field.<span style="color: black;">name</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">list_editable</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>formfield<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'choices'</span><span style="color: black;">&#41;</span>:
&nbsp;
            <span style="color: #808080; font-style: italic;"># On tente de récupérer la query en cache</span>
            cache_attr_name <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'_%s_cache'</span> % db_field.<span style="color: black;">name</span>
            choices_cache <span style="color: #66cc66;">=</span> <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> cache_attr_name<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> choices_cache <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
                formfield.<span style="color: black;">choices</span> <span style="color: #66cc66;">=</span> choices_cache
&nbsp;
            <span style="color: #808080; font-style: italic;"># Pas de cache, on force Django à faire la query en accédant</span>
            <span style="color: #808080; font-style: italic;"># au descripteur .choices et on met le resultat</span>
            <span style="color: #808080; font-style: italic;"># en cache</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> cache_attr_name<span style="color: #66cc66;">,</span> formfield.<span style="color: black;">choices</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># On retourne le champ de notre formulaire avec sa valeur mise</span>
        <span style="color: #808080; font-style: italic;"># en cache</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> formfield</pre></td></tr></table></div>

<p>Malheureusement, il peut arriver qu&#8217;il y ait tellement d&#8217;objets que c&#8217;est votre navigateur qui panique. En effet, si vous avez un modèle <code>Promotion</code> avec un lien vers un modèle <code>Produit</code> et que vous avez 5000 produits en base, vous allez créer 20 <code>&lt;select&gt;</code> avec 5000 <code>&lt;options&gt;</code> dedans. 100000 balises dans une page, ça peut faire mal.</p>
<p>Dans ce cas, il vaut mieux désactiver la possibilité de faire un drop down, et mettre un champ text à la place dans lequel on entre un ID en utilisant :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> VotreClasseAdmin<span style="color: black;">&#40;</span>admin.<span style="color: black;">ModelAdmin</span><span style="color: black;">&#41;</span>
&nbsp;
     raw_id_fields <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'nom_de_votre_champ'</span><span style="color: #66cc66;">,</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Django n&#8217;est pas chien, et vous mettra un petit bouton en forme de loupe pour chercher l&#8217;ID dont vous avez besoin.</p>
<p>Si vous avez beaucoup de ForeignKey <strong>non éditables</strong> (<code>readonly_fields</code>), vous pouvez aussi vous fendre d&#8217;un <code>select_related</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> VotreClasseAdmin<span style="color: black;">&#40;</span>admin.<span style="color: black;">ModelAdmin</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> queryset<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> request<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># On filtre le queryset que Django va utiliser pour populer la liste</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>MyAdmin<span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">queryset</span><span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>.<span style="color: black;">select_related</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'myfield'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ça ne marche que sur les non éditables, car pour eux Django ne créé pas de champ de formulaire.</p>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/accelerer-les-listings-de-ladmin-django-avec-beaucoup-de-foreignkeys/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2014/09/501854_d01f_1024x2000.jpg" length="103754" type="image/jpg" />	</item>
		<item>
		<title>WAMP et les outils de dev Web Python existants 8</title>
		<link>http://sametmax.com/wamp-et-les-outils-de-dev-web-python-existants/</link>
		<comments>http://sametmax.com/wamp-et-les-outils-de-dev-web-python-existants/#comments</comments>
		<pubDate>Wed, 02 Jul 2014 05:21:09 +0000</pubDate>
		<dc:creator><![CDATA[Sam]]></dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[wamp]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://sametmax.com/?p=11259</guid>
		<description><![CDATA[C'est tout naturellement qu'on a fini par me poser (par mail), ze question.]]></description>
				<content:encoded><![CDATA[<p>Même si on peut créer un site Web en utilisant uniquement des libs WAMP, tout comme on peut le faire en utilisant uniquement flask ou tornado, il arrive immanquablement le moment où on veut mélanger, intégrer, faire cohabiter les techos ensemble. D&#8217;abord parce qu&#8217;il y a des sites existants, et qu&#8217;on va pas les jeter à la poubelle. Ensuite parce que ce sont des techos qu&#8217;on connaît et pour lesquelles ils y a beaucoup d&#8217;outils, que l&#8217;on veut mettre à profit.</p>
<p>C&#8217;est tout naturellement qu&#8217;on a fini par me poser (par mail), ze question :</p>
<blockquote><p>Subject: crossabar et autobahn</p>
<p>Message Body:<br />
Ha bah oui vous l&#8217;avez cherché à nous parler de truc comme ça: ça interroge !</p>
<p>Je m&#8217;interroge donc sur la manière d&#8217;intégrer WAMP à django. Pour la perstistence des données (l&#8217;ORM qui simplifie la création des tables tout de même), pour l&#8217;authentication et l&#8217;authorization, pour la robustesse et versatilité apportée par django&#8230;</p>
<p>J&#8217;ai pour habitude de mettre pas mal de logique dans mes modèles et je me demandais si il n&#8217;y aurait pas moyen de pluguer WAMP dans ceux ci&#8230; exposer une méthode update en RPC avec passage de JSON ? Avec namespace automatique à partir de la classe ? </p>
<p>En fait remplacer: Angular+tastypie+django+nginx par Angular+WAMP+django+crossbar avec du coup le bonus de WAMP pour le pubsub que n&#8217;a pas AJAX.</p>
<p>Comment vous verriez un (petit &#8211; après relecture ça parait dur) mixin WAMP pour des modèles django auto-détectés, auto-exposés en RPC ?</p>
<p>J&#8217;ai du mal à voir quelle tactique utiliser. J&#8217;ai peur que ça finisse en refaire tout le travail que fait déjà (très bien) tastypie/RESTframework.</p>
<p>Comment modulariser (là ou est sensé briller WAMP) les services déjà offerts par django: celery, authentication, etc ?<br />
Ces services sont tous très dépendant du système de persistance des données (check des users, permissions, query) et donc l&#8217;approche plus monolithique de django n&#8217;est pas mauvaise car tout est lié et donc facilement manipulable au même endroit&#8230; où est le gain de WAMP dans ce cas, pour une application assez classique en fait ?</p>
<p>Merci encore pour cette découverte dans tous les cas. C&#8217;est top.</p>
<p>Du coup je me relis et ça part un peu dans tous les sens&#8230; désolé.</p>
</blockquote>
<p>Comme je me suis fendu d&#8217;une réponse bien longue, je vais la paster verbatim :</p>
<blockquote><p>
Bonjour,</p>
<p>C&#8217;est une très bonne question.</p>
<p>D&#8217;abord, il faut savoir qu&#8217;on ne peut pas faire tourner un routeur WAMP dans un process Django (ou tout autre app WSGI) car Django est synchrone. En plus, l&#8217;ORM de django est bloquant, donc même sans utiliser django, utiliser son ORM au sein de WAMP va bloquer la boucle d&#8217;événements et on perdra tout l&#8217;interêt d&#8217;avoir une techno temps réel.</p>
<p>(Note a posteriori : y a surement un truc à faire avec gevent ou des threads ici, mais je sais pas encore quoi)</p>
<p>Ici on a donc 3 problèmes à résoudre :</p>
<p>&#8211; comment faire communiquer django et son app WAMP ?<br />
&#8211; comment utiliser un ORM bloquant avec WAMP ?<br />
&#8211; comment auto générer une API WAMP ?</p>
<p>Ces 3 questions n&#8217;ont pas encore de réponse définitive puisque, comme je l&#8217;ai précisé, WAMP est une techno jeune, et donc il y a beaucoup à faire. Mes articles sont précisément là pour tenter de générer un enthousiasme et pousser les gens à améliorer les outils autour de WAMP.</p>
<p>Prenons les problèmes un par un :</p>
<p>Comment faire communiquer django et son app WAMP ?<br />
====================================</p>
<p>C&#8217;est le problème le plus facile à mon sens. Il faut coder une app WAMP qui fasse le bridge entre HTTP et WAMP. Quand on register côté app HTTP, on fait un post sur l&#8217;app WAMP (qui écoute aussi sur HTTP du coup) en fournissant une URL de callback. L&#8217;app WAMP fait le register, et quand on l&#8217;appelle, elle fait l&#8217;appel à l&#8217;app HTTP via l&#8217;url de callback, et retourne le résultat. On peut faire ça pour register, subscribe, call et publish, c&#8217;est le même principe.</p>
<p>(Note a posteriori : en me relisant moi-même je m&#8217;aperçois à quel point c&#8217;est pas clair. De toute façon il faudra que je le code un jour où l&#8217;autre, et avec un bon tuto pratique, la pilule passera mieux).</p>
<p>Ce faisant, on pourra appeler du WAMP côté app HTTP, et taper dans l&#8217;app HTTP côté client WAMP.</p>
<p>Une amorce de travail  a été fait pour coder un tel bridge. Pour le moment il n&#8217;y a que le publish :</p>
<p>https://groups.google.com/forum/#!searchin/autobahnws/http/autobahnws/SbobAnoWVlQ/FnGhdYXj9aIJ</p>
<p>Ce n&#8217;est pas très dur à coder, c&#8217;est juste un boulot chiant à faire.</p>
<p>Cela dit, ça ne résout pas le problème de l&#8217;authentification, qu&#8217;il faudra à un moment on un autre, se poser. Je pense qu&#8217;on va se diriger vers une authentification hybride, qui va utiliser le session ID en cookie, mais l&#8217;envoyer via un token. Encore un truc à travailler.</p>
<p>De même, on voudra sûrement créer quelques facilités pour intégrer ça dans les frameworks les plus connus en proposant une app prêt à plugger. Rien d&#8217;insurmontable donc, mais pas mal de taff.</p>
<p>Par contre, pour ce qui est des tasks queues, à mon avis une solution de task queue WAMP sera bien plus intéressante qu&#8217;une solution type celery car on peut envoyer des messages WAMP depuis les tâches et donc avertir en temps réel de l&#8217;avancement du process. Je voterais donc pour coder soi-même une alternative.</p>
<p>Comment utiliser un ORM bloquant avec WAMP ?<br />
===============================</p>
<p>Idéalement, il faudrait avoir des ORM non bloquant, mais on Python, on en a pas. On a quelques drivers non bloquant, notamment pour PostGres et Mongo, mais pas d&#8217;ORM, et ils demandent une forme de compilation d&#8217;extension C.</p>
<p>C&#8217;est là qu&#8217;on voit qu&#8217;on se traine la culture de l&#8217;API synchrone en Python, car côté NodeJS, ils commencent à avoir pas mal de solutions.</p>
<p>En l’occurrence, on a 3 solutions :</p>
<p>&#8211; utiliser le bridge dont je viens de parler pour garder les appels dans l&#8217;app HTTP.  Ca veut dire que quand on veut faire un appel à de la base de données, ça fait WAMP => HTTP => connexion à la base, aller-retour. C&#8217;est pas idéal.<br />
&#8211; créer une app WAMP pour héberger les appels bloquants et taper dedans en RPC. Une bonne solution à mon avis. Mais assez peu intuitive.<br />
&#8211; faire tous les appels dans un threads à part. Le plus simple. Un peu verbeux par contre.</p>
<p>Dans les deux derniers cas, on à quand même le problème des querysets qui sont lazy, notamment au niveau des foreign keys. Il faudra faire particulièrement attention à ne pas accidentellement faire des appels bloquant, par exemple dans le rendu du template. Une solution viable est de créer un wrapper qui fait le rendu du template dans un threads.</p>
<p>Bref, encore pas mal d&#8217;outils à developper.</p>
<p>On peut aussi se lancer dans l&#8217;écriture d&#8217;un ORM non bloquant. Une bonne année de travail avant d&#8217;avoir quelque chose qui soit compétitif.</p>
<p>Comment auto générer une API WAMP ?<br />
==========================</p>
<p>Là tu m&#8217;en poses une bonne.</p>
<p>C&#8217;est la suite logique, évidement, mais je n&#8217;avais jamais réfléchi aussi loin. C&#8217;est un taff énorme, surtout que ça dépend de l&#8217;outil derrière. La solution la plus simple c&#8217;est encore de faire un mapper dans le bridge HTTP-WAMP qui va traduire directement un appel WAMP en un appel JSON vers l&#8217;API générée par django-rest-framework ou autre.</p>
<p>Mais bon, je suis pas certains de la valeur ajoutée.</p>
<p>Je pense qu&#8217;il est difficile pour moi de répondre à cette question pour le moment car :</p>
<p>&#8211; je ne suis pas certain que WAMP soit un bon remplacement pour les API REST. Je pense plutôt que c&#8217;est un complément.<br />
&#8211; il y a toute la question de l&#8217;authentification. Encore et toujours.<br />
&#8211; il va falloir pas mal d&#8217;essais avec plusieurs architectures en prod (séparées, mixtes, mono culture&#8230;) pour pouvoir déterminer ce qui rend le mieux.</p>
<p>Mon intuition est qu&#8217;on utilise généralement 10% de l&#8217;API générée par les frameworks, et que la partie dont on a besoin à peut très bien se faire à la main. La raison pour laquelle les trucs comme django-rest-framework sont si pratiques, c&#8217;est qu&#8217;ils gèrent des problématiques comme l&#8217;authentification, la sérialisation et la pagination.</p>
<p>Je serais plutôt d&#8217;avis de s&#8217;attaquer à ça pour WAMP, et je pense qu&#8217;on s’apercevra que finalement, pour ses propres besoins, un API complète est overkill. Par contre, pour exposer une API au monde, c&#8217;est une autre histoire. J&#8217;ai eu récemment une discussion à propos de faire des APIs WAMP :) Il y a des possibilités fascinantes. Mais c&#8217;est peut être encore un peu loin tout ça.</p>
<p>Je pense que je vais publier cette réponse sur le blog, car tu soulèves des points très importants.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://sametmax.com/wamp-et-les-outils-de-dev-web-python-existants/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	<enclosure url="http://sametmax.com/wp-content/uploads/2014/07/tumblr_n3pyweC7q71r539hzo1_500.png" length="804621" type="image/jpg" />	</item>
	</channel>
</rss>