diff --git a/assets/mcmc_samples.json b/assets/mcmc_samples.json new file mode 100644 index 0000000..64e5d3f --- /dev/null +++ b/assets/mcmc_samples.json @@ -0,0 +1 @@ +{"EV":[[881.2,0.177,2.58,1.91],[862.7,0.198,2.86,2.01],[514.4,0.208,11.92,1.19],[509.9,0.218,6.16,1.2],[639.5,0.224,3.03,1.6],[304.6,0.308,10.33,0.86],[426,0.245,6.34,1.1],[575.4,0.234,3.22,1.56],[626,0.205,12.96,1.45],[651.8,0.212,3.49,1.63],[788.5,0.2,2.64,1.85],[542.6,0.208,5.2,1.4],[529,0.229,4.98,1.32],[521.8,0.233,4.88,1.39],[235.2,0.364,10.7,0.67],[341.2,0.271,13.95,0.93],[521,0.199,8.33,1.23],[627.5,0.219,4.05,1.44],[570.3,0.224,4.52,1.46],[339.9,0.282,7.38,0.98],[670.4,0.228,3.06,1.65],[517.3,0.233,3.46,1.42],[374.5,0.246,14.46,1],[761.1,0.222,2.71,1.91],[697.2,0.218,2.92,1.68],[641.6,0.214,2.95,1.6],[466.2,0.228,9.95,1.17],[675.2,0.245,1.98,1.81],[473.3,0.238,6.12,1.21],[454.1,0.225,7.47,1.21],[743.2,0.207,3.26,1.84],[663.2,0.237,2.28,1.75],[509.1,0.223,4.49,1.33],[451.4,0.23,42.12,1.18],[579.1,0.23,2.6,1.56],[547,0.241,3.2,1.44],[757.5,0.201,2.55,1.8],[459.8,0.272,4.13,1.26],[852.5,0.213,2.23,2.17],[398.4,0.272,5.91,1.11],[415.2,0.234,18.89,1.03],[941.7,0.191,3.32,2.34],[564.8,0.252,2.52,1.6],[543.5,0.215,4.97,1.29],[475.8,0.218,8.92,1.19],[835,0.2,2.29,2.04],[575.4,0.232,5.34,1.39],[423.8,0.246,10.75,1.08],[373.6,0.272,8.51,1.04],[608.6,0.189,6.01,1.42],[515.5,0.25,4.81,1.41],[459.3,0.244,4.57,1.24],[341.7,0.269,4.73,0.98],[687,0.193,3.67,1.68],[854.9,0.208,2.23,2.09],[928.8,0.202,2.5,2.21],[454.2,0.21,7.11,1.13],[429.5,0.255,11.53,1.17],[434.2,0.216,7.07,1.12],[830,0.188,2.65,1.95],[740.5,0.189,2.92,1.65],[580.3,0.234,2.98,1.54],[325.4,0.295,7.09,0.88],[531.6,0.241,3.23,1.45],[391.9,0.231,10.47,0.99],[750.1,0.218,2.67,1.81],[795,0.186,4.22,1.9],[572.6,0.252,4.05,1.57],[644.7,0.252,2.26,1.75],[363,0.263,8.56,0.98],[407.5,0.241,7.98,1.08],[616.8,0.214,4.48,1.49],[440.6,0.244,9.07,1.2],[335.9,0.285,18.49,0.96],[623,0.209,5.29,1.53],[359.9,0.255,23.75,0.91],[565.1,0.205,5.45,1.38],[445.8,0.22,7.03,1.16],[385.1,0.261,10.51,1.01],[370.9,0.32,6.56,1.11],[591,0.219,3.89,1.46],[327.4,0.277,7.81,0.95],[449.3,0.246,6.04,1.22],[594.3,0.236,2.77,1.53],[391,0.259,16.26,1.11],[542,0.211,4.41,1.38],[566.4,0.204,5.42,1.33],[608.8,0.237,2.65,1.62],[805,0.201,3.71,1.83],[286.1,0.325,21.79,0.8],[484.2,0.24,5.16,1.27],[690.9,0.222,3.32,1.75],[781.2,0.219,2.12,1.91],[965.2,0.211,3.05,2.4],[401.8,0.237,8.77,1.01],[491.4,0.228,8.16,1.25],[900.7,0.205,2.29,2.11],[618.9,0.207,2.76,1.39],[428.9,0.23,21.47,1.09],[392.1,0.234,28.31,1.01],[756.5,0.213,2.61,1.88],[469.6,0.23,4,1.28],[359.2,0.267,15.39,0.99],[587.5,0.232,2.2,1.59],[517.9,0.247,3.55,1.39],[568,0.237,3.65,1.48],[445.2,0.233,20.38,1.15],[670,0.225,2.46,1.61],[550.8,0.211,4.67,1.31],[555.4,0.24,3.82,1.54],[657.4,0.217,3.78,1.68],[401.5,0.258,7.13,1.07],[536.3,0.233,3.98,1.32],[383.7,0.275,6.06,1.04],[455,0.236,5.19,1.27],[563.5,0.214,8.39,1.34],[484.2,0.239,5.44,1.3],[679,0.233,2.79,1.76],[380.7,0.275,6.86,1.1],[399.8,0.272,4.63,1.09],[457.7,0.239,5.01,1.16],[490.6,0.222,7.48,1.27],[784.9,0.219,2.43,1.95],[295.1,0.309,7.66,0.88],[965.3,0.2,2.51,2.31],[438.4,0.233,8.3,1.19],[477.6,0.208,16.31,1.12],[517.4,0.229,3.76,1.26],[749.3,0.2,2.63,1.79],[695.4,0.183,4.33,1.47],[366.4,0.248,15.67,1],[437.5,0.25,5.3,1.18],[475.3,0.228,6.81,1.26],[701.8,0.182,4.22,1.58],[435.3,0.244,5.12,1.15],[407.4,0.247,10.69,1.07],[353,0.243,20.43,0.92],[362.3,0.271,8.58,0.97],[577.8,0.211,3.71,1.4],[379.7,0.262,13.79,0.96],[483.6,0.247,3.79,1.3],[659,0.24,4.01,1.75],[565.2,0.239,3.12,1.55],[628,0.189,5.19,1.49],[639.5,0.202,3.32,1.53],[498.4,0.234,3.94,1.34],[401.9,0.26,49.43,1.05],[374.6,0.272,7.93,1.01],[580.4,0.281,2.5,1.54],[488.9,0.224,10.88,1.23],[326.7,0.262,48.29,0.87],[414.4,0.275,7.9,1.11],[674.4,0.215,3.37,1.64],[556.3,0.199,9.88,1.33],[844.5,0.189,4.27,2.01],[415.1,0.26,6.76,1.11],[455.9,0.227,8.84,1.07],[523.1,0.229,4.55,1.33],[600.9,0.204,5.31,1.36],[480.7,0.234,12.68,1.24],[317.2,0.312,7.11,0.91],[376.5,0.271,25.19,1.05],[801.8,0.179,4.17,1.71],[427.7,0.223,4.74,1.13],[685,0.201,3.43,1.69],[292.2,0.306,21.63,0.85],[550.4,0.205,4,1.39],[464.6,0.219,12.46,1.13],[281.5,0.314,28.14,0.81],[349.2,0.264,11.5,0.96],[308.2,0.28,14.43,0.85],[341.4,0.25,19.02,0.87],[742.2,0.252,2.66,1.99],[509.1,0.226,5.87,1.35],[419.2,0.225,33.37,1.07],[579,0.24,2.77,1.49],[462.4,0.233,6.57,1.18],[502.2,0.218,4.98,1.23],[317.8,0.311,12.21,0.96],[456.5,0.217,9.1,1.08],[420.9,0.279,6.48,1.15],[401.2,0.271,7.67,1.18],[505.3,0.233,5.4,1.28],[506.5,0.273,3.03,1.38],[328.3,0.261,11.74,0.88],[392.6,0.252,12.23,1.05],[689.8,0.234,2.62,1.85],[648.4,0.224,3.3,1.57],[426.4,0.233,13.69,1.12],[423.6,0.228,8.71,1.09],[660.9,0.221,2.94,1.7],[542.9,0.239,3.33,1.49],[496,0.237,5.12,1.3],[642.1,0.189,5.05,1.5],[642.1,0.206,3.38,1.6],[476.6,0.231,6.76,1.23],[345.6,0.272,17.87,0.93],[390.7,0.252,14.64,1.04],[226.7,0.375,27.43,0.66],[478.9,0.239,4.26,1.24],[828.4,0.216,2.22,2.03],[799.4,0.207,2.69,1.99],[654.3,0.217,2.68,1.61],[831.9,0.229,2.4,2.09],[289.5,0.3,11.23,0.8],[580.4,0.232,4.03,1.43],[723.8,0.204,4.55,1.69],[430.6,0.277,3.27,1.18],[490.6,0.221,12.38,1.18],[485.6,0.203,12.11,1.17],[586.4,0.228,3.83,1.42],[707,0.223,2.89,1.77],[411,0.273,4.13,1.18],[410.1,0.29,3.56,1.17],[493.1,0.222,6.57,1.24],[622.3,0.227,2.83,1.56],[892.3,0.221,2.26,2.21],[451.3,0.22,17.39,1.06],[642.4,0.225,3.06,1.64],[599.1,0.212,4.3,1.5],[302.2,0.296,5.57,0.9],[451.9,0.251,8.91,1.25],[377.6,0.286,7.72,1.11],[420.9,0.265,5.39,1.18],[487.6,0.224,4.39,1.18],[813.5,0.204,3.36,1.94],[405.3,0.256,11.01,1.1],[487.8,0.275,3.57,1.35],[441.2,0.249,5.29,1.18],[442,0.205,18.31,1.03],[693,0.207,3.14,1.63],[426.9,0.246,10.63,1.17],[487,0.24,2.85,1.21],[478,0.236,4.85,1.24],[478.3,0.187,26.66,1.16],[412.8,0.237,26.25,1.05],[310.8,0.296,10,0.9],[866.9,0.191,2.59,1.94],[649.5,0.189,5.52,1.5],[422.3,0.24,23.08,1.04],[457.7,0.225,19.29,1.13],[341.5,0.253,9.07,0.9],[720.4,0.215,2.94,1.9],[761.8,0.244,2.25,2.02],[500.5,0.216,6.91,1.22],[493.7,0.225,7.5,1.21],[575.9,0.211,4.53,1.39],[599.9,0.233,4.29,1.52],[534.7,0.231,4.36,1.4],[461.5,0.24,12.33,1.18],[501,0.223,5.96,1.3],[562.4,0.228,3.2,1.43],[895.3,0.215,2.57,2.24],[471.3,0.219,7.64,1.17],[648.2,0.206,3.14,1.57],[741.6,0.211,2.68,1.88],[630.7,0.185,7.04,1.41],[472.9,0.256,5.01,1.3],[434.2,0.261,26.85,1.08],[384.2,0.256,46.26,0.99],[371.4,0.258,15.05,1],[330.9,0.291,9.99,0.96],[567.2,0.213,3.65,1.43],[611.1,0.279,2.64,1.66],[609.4,0.238,2.87,1.63],[564.8,0.244,3.36,1.49],[519.1,0.215,6.36,1.31],[352,0.275,7.87,0.94],[475.9,0.209,16.84,1.15],[718.2,0.179,3.85,1.54],[394.9,0.239,12.58,0.98],[505.3,0.253,3.08,1.31],[341.8,0.279,28.09,0.97],[521.2,0.225,4.62,1.33],[798.3,0.173,4.51,1.76],[806.1,0.207,2.5,1.87],[437.2,0.225,18.26,1.07],[963.8,0.203,2.42,2.39],[349.5,0.259,21.06,0.93],[411.3,0.252,22.71,1.08],[387.4,0.263,9.38,1.05],[547,0.247,2.96,1.51],[632.7,0.202,4.67,1.51],[643.1,0.202,3.52,1.58],[795.8,0.214,2.98,2.03],[463.3,0.217,13.61,1.13],[746.9,0.215,2.46,1.91],[484.9,0.26,4.61,1.36],[897,0.21,2.31,2.25],[975.5,0.193,2.32,2.29],[494.9,0.233,3.43,1.22],[525.2,0.221,5.25,1.33],[299.3,0.311,11.99,0.91],[667.4,0.201,4.36,1.78],[446.1,0.236,4.8,1.22],[447.8,0.22,8.54,1.06],[449.9,0.25,3.32,1.27],[391.2,0.254,8.63,1.06],[630.9,0.208,3.18,1.47],[500.4,0.237,4.18,1.35],[718.7,0.213,3.35,1.8],[836.2,0.187,3.5,1.98],[423.1,0.238,14.33,1.05],[549.2,0.193,11.16,1.27],[402.6,0.236,22.9,1.04],[340.1,0.292,9.25,0.95],[833.2,0.184,5.34,1.87],[704.5,0.185,7.23,1.62],[575.6,0.235,3.09,1.55],[585.8,0.214,5,1.47],[260.9,0.345,7.31,0.79],[509.4,0.214,5.95,1.27],[497.8,0.223,5.54,1.21]],"EU":[[213.28,0.03122,7.942,1.565],[183.07,0.02819,20.323,1.334],[198.44,0.04313,32.624,1.963],[239.24,0.03109,11.828,1.89],[59.41,0.03921,9.922,0.537],[2486.41,0.0048,9.173,3.567],[507.35,0.01423,10.32,2.02],[210.69,0.02583,15.3,1.452],[326.74,0.03264,22.283,2.619],[465.99,0.01924,4.606,2.391],[704.2,0.0138,6.049,2.587],[196.21,0.03774,4.523,1.723],[259.14,0.0222,45.771,1.635],[161.44,0.0347,5.315,1.293],[718.52,0.01676,4.228,3.432],[483,0.0148,7.717,1.948],[661.97,0.00992,26.896,2.044],[98.8,0.03951,39.241,0.979],[678.68,0.01605,13.888,2.989],[580.87,0.01241,11.598,2.106],[849.1,0.01159,15.434,2.916],[199.94,0.03085,7.339,1.323],[243.06,0.02872,9.709,1.793],[186.12,0.02966,5.059,1.423],[179.38,0.03302,18.768,1.599],[214.15,0.02717,17.043,1.52],[1361.01,0.00696,6.105,2.771],[265.23,0.02159,3.832,1.541],[682.12,0.01276,8.6,2.497],[1211.11,0.00748,4.543,2.565],[991.91,0.0107,4.186,3.421],[1355.26,0.00652,7.197,2.339],[261.57,0.01914,17.939,1.395],[546.77,0.02596,14.07,3.637],[270.77,0.02597,8.034,1.929],[177.25,0.0257,11.989,1.143],[216.66,0.04504,4.81,2.357],[915.35,0.0136,11.76,3.494],[176.64,0.03235,3.495,1.365],[4061.69,0.00186,7.833,2.273],[190.88,0.02593,3.986,1.529],[149.93,0.03889,40.951,1.297],[288.72,0.0342,10.156,2.311],[211.58,0.02081,13.848,1.198],[657.59,0.01011,25.904,1.928],[162.85,0.03234,11.284,1.179],[120.16,0.04265,19.133,1.217],[6478.64,0.00148,6.72,2.785],[62.34,0.06761,13.917,1.015],[346.99,0.02651,3.648,2.655],[272.92,0.01771,11.589,1.372],[567.8,0.01195,16.813,2.075],[441.28,0.02962,10.936,3.51],[301.3,0.02717,8.828,2.006],[165.46,0.02553,9.457,1.195],[409.53,0.00994,18.444,1.079],[350.46,0.02536,6.2,2.293],[699.64,0.00912,4.052,1.903],[518.02,0.01929,3.072,2.618],[208.7,0.02555,17.051,1.368],[367.39,0.01294,9.138,1.26],[239.02,0.02357,10.935,1.451],[202.58,0.03734,6.506,1.866],[627.34,0.01948,8.965,3.357],[176.35,0.03326,10.733,1.596],[224.71,0.04028,25.292,2.088],[119.78,0.03652,21.754,1.046],[588.77,0.01775,25.268,2.926],[295.78,0.02811,47.071,2.143],[413.47,0.02239,3.458,2.554],[101.3,0.05038,19.29,1.462],[290.95,0.03265,8.571,2.221],[202.12,0.03565,4.84,1.621],[618.37,0.01954,4.685,3.287],[307.39,0.01304,16.094,1.071],[456.89,0.01446,4.926,1.72],[159.51,0.02004,12.634,0.788],[304.28,0.03745,2.96,2.681],[995.06,0.00524,8.256,1.508],[515.74,0.01586,7.305,2.086],[476.87,0.02031,4.862,2.673],[292.34,0.03545,15.102,2.859],[263.13,0.0186,19.609,1.244],[256.28,0.02065,7.917,1.409],[241.98,0.02156,4.658,1.396],[191.93,0.0314,3.438,1.57],[548.11,0.01802,3.365,2.722],[264.41,0.0372,5.302,2.31],[550.04,0.01319,7.126,1.979],[883.35,0.01085,8.852,2.769],[543.18,0.02491,49.754,3.58],[226.95,0.02796,20.775,1.697],[67.69,0.05193,13.668,0.7],[542.13,0.01734,4.476,2.437],[514.25,0.01251,13.457,1.758],[365.34,0.02255,9.424,2.16],[267.17,0.02693,8.26,1.803],[386.08,0.02469,6.485,2.555],[458.41,0.01144,4.408,1.278],[614.85,0.0196,3.947,3.224],[68.29,0.06043,18.96,0.822],[239.23,0.0089,26.063,0.596],[4733.55,0.00157,5.496,1.973],[443.55,0.01741,6.631,1.877],[765.96,0.01502,10.226,3.713],[328.29,0.01158,7.476,1.023],[568.12,0.0167,8.388,2.727],[1325.91,0.00806,5.801,2.929],[2581.3,0.00405,13.097,3.152],[349.88,0.01826,18.646,1.737],[212.6,0.02596,25.541,1.535],[599.26,0.01757,17.738,2.524],[237.96,0.03624,13.648,1.86],[471.48,0.01336,15.038,1.809],[732.87,0.01174,12.18,2.52],[490.08,0.01518,4.281,1.892],[126.45,0.03226,4.018,0.975],[700.35,0.02739,11.971,4.354],[2453.31,0.00377,12.303,2.686],[74.92,0.06187,23.62,0.905],[68.35,0.08335,3.076,1.135],[229.13,0.03455,63.501,1.801],[2991.44,0.0045,18.094,4.084],[160.52,0.02704,11.734,1.097],[140.83,0.03365,12.017,1.161],[622.54,0.01886,9.003,3.253],[117.66,0.02492,6.31,0.767],[300.54,0.02566,28.151,2.016],[318.02,0.03635,4.026,2.663],[344.58,0.03326,3.329,2.383],[254.96,0.03306,8.868,1.991],[78.8,0.05793,9.758,0.948],[512.65,0.02007,26.056,2.974],[94.78,0.04582,10.046,1.093],[344.22,0.01579,39.528,1.562],[754.54,0.00957,19.035,2.001],[857.03,0.01282,10.543,3.411],[900.72,0.00998,16.62,2.557],[603.72,0.01546,44.974,2.69],[206.88,0.02709,8.227,1.591],[112.26,0.03868,10.981,0.978],[579.68,0.01307,16.766,2.031],[382.63,0.01693,6.668,1.98],[755.73,0.01109,6.707,2.417],[338.38,0.02875,11.58,2.272],[216.61,0.03084,21.161,1.699],[725.64,0.01934,4.089,3.893],[100.33,0.03873,5.103,0.959],[758.17,0.01704,11.177,3.709],[120.79,0.03065,6.075,0.718],[417.95,0.00901,22.95,1.035],[154.02,0.03643,4.767,1.314],[332.64,0.03288,16.974,2.636],[146.74,0.03623,7.301,1.338],[643.87,0.01466,11.831,2.75],[624.68,0.01835,9.887,3.093],[361.05,0.02737,2.838,2.785],[16693.74,0.00055,15.309,2.964],[31.11,0.08967,16.897,0.423],[176.32,0.02616,17.15,1.347],[94.95,0.06209,14.02,1.163],[164.19,0.01715,49.023,0.712],[342.39,0.03119,27.612,2.917],[164.82,0.02527,29.811,1.025],[164.9,0.03521,19.532,1.306],[640.43,0.00854,6.34,1.592],[615.94,0.01913,16.562,3.152],[135.08,0.02931,4.136,1.131],[83.16,0.06685,1.477,1.158],[1126.09,0.01178,18.859,4.002],[656.62,0.01026,8.078,1.784],[16.6,0.11474,9.925,0.224],[115.87,0.02529,11.255,0.757],[148.77,0.02757,2.873,1.072],[326.27,0.02589,5.739,2.115],[274.1,0.02468,7.976,1.544],[313.9,0.01503,18.553,1.395],[231.36,0.03595,10.697,2.189],[515.74,0.01147,5.818,1.947],[277.57,0.02337,5.996,1.523],[179.66,0.03421,30.626,1.503],[637.64,0.0087,8.493,1.579],[647.04,0.0074,76.477,1.538],[929.21,0.00497,20.162,1.552],[1796.36,0.00359,14.782,1.895],[2169.23,0.0048,7.716,3.1],[243.51,0.03074,7.542,1.887],[429.14,0.02069,6.932,2.439],[240.49,0.03255,6.026,1.917],[322.13,0.02129,12.352,1.846],[416.57,0.02171,8.893,2.421],[241.82,0.02378,7.444,1.557],[446,0.01754,7.246,2.218],[218.45,0.0268,12.988,1.5],[883.53,0.01279,15.304,3.102],[647.27,0.01126,20.552,2.237],[457.98,0.01746,56.574,2.147],[260.33,0.03407,23.712,2.329],[140.32,0.03429,17.606,1.315],[352.68,0.03078,13.999,2.728],[213.08,0.02664,8.01,1.332],[490.99,0.0146,11.952,2.01],[116.12,0.04888,17.808,1.3],[136.74,0.04601,14.658,1.411],[194.17,0.04154,2.584,1.849],[283.48,0.01856,6.612,1.458],[1016.02,0.01032,18.879,3.128],[145.32,0.0375,5.916,1.491],[589.18,0.01212,6.234,2.321],[487.16,0.01063,5.996,1.584],[504.57,0.02613,9.804,3.398],[218.82,0.03762,8.214,2.043],[345.65,0.02806,33.24,2.646],[495.6,0.02369,3.813,2.695],[665.06,0.01295,9.778,2.567],[41.19,0.06215,11.858,0.515],[490.41,0.02078,30.35,2.704],[276.06,0.03083,42.893,1.933],[363.14,0.04134,4.123,3.857],[147.43,0.02692,9.48,1.024],[206.41,0.02619,6.876,1.338],[202.88,0.02707,9.081,1.462],[712.22,0.01193,6.782,2.414],[845.47,0.00546,14.132,1.338],[189.94,0.04425,25.058,1.869],[321.56,0.0276,36.743,2.283],[53.06,0.05303,16.932,0.649],[63.91,0.04651,10.447,0.605],[317.13,0.0145,8.612,1.296],[297.58,0.02267,9.805,1.691],[481.91,0.01934,21.526,2.342],[493.65,0.01292,6.265,1.764],[144.42,0.02171,10.114,0.88],[150.37,0.0211,9.016,0.777],[60.37,0.03682,9.153,0.45],[355.57,0.02307,7.321,2.004],[2087.53,0.00412,7.329,2.648],[234.28,0.0258,17.372,1.668],[167.65,0.0402,6.717,1.67],[29.54,0.09246,1.814,0.375],[22.58,0.093,37.665,0.314],[593.78,0.0117,23.549,1.874],[96.39,0.03208,23.675,0.732],[60.71,0.05381,3.091,0.754],[173.88,0.0328,19.352,1.529],[176.64,0.03632,14.195,1.45],[224.74,0.0291,3.125,1.56],[703.85,0.01378,8.666,2.709],[382.52,0.02616,6.658,2.468],[468.82,0.01988,7.375,2.398],[448.92,0.02808,6.557,3.171],[860.66,0.01072,5.299,2.606],[412.78,0.02513,13.818,2.721],[381.98,0.01621,8.74,1.639],[136.36,0.03377,6.771,1.195],[298.22,0.03547,9.94,2.518],[517.55,0.01531,5.409,2.082],[291.1,0.02223,4.053,1.852],[471.06,0.01139,32.452,1.466],[194.59,0.05029,5.102,2.534],[1790.68,0.01036,6.973,5.386],[199.36,0.02459,7.187,1.231],[358.93,0.0172,2.479,1.92],[2336.02,0.00612,11.047,4.079],[140.88,0.0577,8.486,1.771],[249.86,0.01711,2.935,1.151],[1049.25,0.00536,11.259,1.673],[467.05,0.01322,58.104,1.958],[295.3,0.03094,18.18,2.572],[217.3,0.02609,16.368,1.622],[177.54,0.01907,20.631,0.856],[322.97,0.02607,8.418,2.102],[198.07,0.02236,1.971,1.166],[1597.63,0.00366,2.256,1.476],[1898.06,0.00516,8.496,2.732],[242.65,0.02566,3.834,1.717],[1195.85,0.00842,16.001,2.954],[265.1,0.01334,8.944,0.962],[1513.46,0.00593,2.69,2.56],[99.87,0.03372,10.032,0.876],[319.43,0.02301,18.207,1.93],[487.24,0.00956,32.358,1.155],[260.59,0.03367,13.043,1.993],[11.08,0.12553,48.891,0.185],[1082.74,0.00816,4.74,2.543],[611.64,0.00727,8.651,1.282],[307.94,0.01762,6.506,1.652],[677.41,0.01108,12.811,2.295],[76.34,0.04303,4.354,0.735],[359.49,0.01674,7.475,1.599],[712.03,0.0122,5.177,2.529],[314.71,0.02557,28.776,2.012],[268.1,0.00889,15.632,0.78],[286.36,0.02474,4.436,1.757],[117.41,0.03797,32.435,1.02],[275.28,0.03297,5.773,2.173],[186.74,0.02584,1.861,1.268],[879.12,0.00715,5.656,1.956],[472.88,0.0132,8.506,1.673],[134.17,0.05625,3.129,1.781],[485.38,0.01307,8.669,1.664],[478.31,0.02348,6.72,2.689],[645.83,0.01418,5.188,2.343],[175.19,0.03678,15.366,1.742],[162.8,0.03509,5.875,1.318],[836.39,0.00465,6.672,1.067],[895.67,0.01953,17.841,4.522],[131.73,0.03457,15.922,1.137],[498.75,0.02615,7.787,3.441],[298.42,0.01803,6.433,1.589],[328.58,0.01961,11.472,1.658],[349.19,0.01651,4.472,1.631],[204.68,0.02531,13.752,1.299]],"EEn":[[107.7,0.163,0.779,0.249],[255.2,0.111,0.535,0.514],[154,0.119,1.029,0.309],[177.2,0.123,0.619,0.381],[220.9,0.127,0.587,0.501],[140,0.13,1.161,0.29],[100.8,0.149,2.718,0.199],[92.4,0.161,3.972,0.184],[128.2,0.145,0.743,0.295],[217.2,0.112,0.678,0.451],[86,0.203,0.952,0.206],[113.5,0.171,0.768,0.275],[151.3,0.141,0.571,0.348],[101.6,0.152,1.862,0.212],[98.4,0.159,0.825,0.211],[139.9,0.129,1.202,0.302],[128.6,0.142,0.732,0.286],[97.1,0.152,2.965,0.187],[168.1,0.13,0.662,0.361],[89.5,0.172,1.409,0.194],[201.2,0.114,0.688,0.424],[85.6,0.188,1.163,0.2],[86.4,0.158,1.622,0.169],[85.7,0.183,0.98,0.186],[117.3,0.135,1.176,0.233],[196.5,0.118,0.676,0.405],[159.5,0.13,0.845,0.358],[96.8,0.168,1.12,0.215],[177.2,0.114,0.792,0.363],[89.7,0.184,0.899,0.206],[118.7,0.149,0.892,0.272],[108.9,0.151,1.375,0.229],[194.9,0.118,0.655,0.411],[145.2,0.125,1.012,0.304],[99.6,0.151,1.575,0.201],[237.5,0.111,0.534,0.481],[92.5,0.159,1.618,0.191],[115.4,0.135,1.826,0.231],[108.4,0.134,11.625,0.207],[124.8,0.134,1.125,0.243],[252.3,0.094,0.652,0.552],[96.8,0.161,15.378,0.202],[166.3,0.122,1.003,0.348],[102.8,0.161,1.406,0.228],[99.9,0.149,3.795,0.202],[158.5,0.138,0.675,0.364],[133.3,0.123,1.541,0.268],[231.7,0.116,0.593,0.483],[131.9,0.126,1.205,0.26],[207.9,0.113,0.676,0.426],[108.7,0.151,1.152,0.237],[87.4,0.165,3.245,0.173],[106.3,0.145,1.935,0.216],[136.9,0.126,0.808,0.285],[189.6,0.132,0.505,0.434],[142.3,0.12,1.362,0.282],[100.1,0.165,1.673,0.223],[113.2,0.139,1.058,0.24],[85,0.16,3.606,0.164],[226.8,0.115,0.548,0.476],[194.6,0.117,0.779,0.412],[195.6,0.111,0.798,0.396],[90.3,0.169,1.945,0.186],[153.6,0.119,0.993,0.305],[248.3,0.115,0.561,0.526],[206.7,0.115,0.639,0.418],[136,0.129,1.288,0.284],[105.3,0.153,1.03,0.229],[205.5,0.12,0.571,0.423],[131.4,0.131,1.179,0.276],[118.3,0.162,1.293,0.28],[98.1,0.159,1.175,0.205],[150,0.127,1.084,0.316],[261,0.121,0.585,0.571],[193.6,0.126,0.643,0.432],[208.1,0.116,0.696,0.441],[98.8,0.163,1.66,0.217],[163.8,0.124,0.779,0.351],[140.7,0.133,0.847,0.294],[93.4,0.157,1.899,0.178],[180.6,0.132,0.645,0.408],[139.4,0.135,0.801,0.306],[141.5,0.128,0.805,0.306],[88.2,0.163,2.701,0.174],[88.4,0.178,1.589,0.191],[152,0.122,1.029,0.306],[86.6,0.174,2.022,0.179],[121.7,0.138,1.29,0.258],[213.2,0.13,0.525,0.474],[104.6,0.17,0.729,0.244],[152.9,0.119,0.955,0.305],[97.1,0.145,1.768,0.176],[140.2,0.119,1.369,0.279],[187.5,0.111,0.752,0.363],[219.4,0.124,0.594,0.485],[168,0.132,0.697,0.375],[146.5,0.121,1.216,0.301],[133.9,0.12,1.33,0.266],[135.7,0.152,0.736,0.32],[126,0.123,2.067,0.258],[89,0.171,1.628,0.188],[124.4,0.154,0.785,0.287],[124.1,0.125,3.501,0.252],[180.1,0.116,1.025,0.374],[105.2,0.148,1.666,0.218],[173.1,0.115,0.845,0.345],[209,0.127,0.486,0.457],[93.8,0.153,7.832,0.191],[116,0.134,2.735,0.231],[179.8,0.114,0.721,0.363],[112.2,0.145,2.043,0.234],[189.7,0.122,0.758,0.411],[99.7,0.153,1.233,0.207],[130.3,0.127,0.923,0.251],[178.6,0.116,0.794,0.369],[110.5,0.145,1.733,0.234],[187.8,0.114,0.78,0.385],[163.5,0.157,0.563,0.407],[141.3,0.116,1.507,0.273],[119.9,0.14,1.979,0.253],[116,0.132,2.352,0.231],[157,0.133,0.81,0.356],[105.9,0.138,2.216,0.208],[170.2,0.117,1.137,0.334],[213.3,0.11,0.731,0.437],[116.6,0.132,1.816,0.227],[101.4,0.144,1.163,0.204],[120.1,0.145,0.78,0.267],[91.8,0.167,1.889,0.192],[94.4,0.162,1.679,0.201],[91.3,0.154,10.47,0.181],[146,0.113,6.124,0.306],[99.2,0.143,6.394,0.196],[130.4,0.128,1.361,0.265],[108.7,0.14,1.273,0.222],[96.7,0.157,1.903,0.2],[141.2,0.122,1.207,0.285],[137.3,0.126,1.31,0.267],[172.2,0.122,0.682,0.358],[227.1,0.112,0.615,0.463],[177.6,0.12,0.627,0.382],[228.7,0.11,0.625,0.471],[104.6,0.145,2.29,0.215],[142.5,0.123,1.079,0.287],[232.8,0.109,0.687,0.487],[126.5,0.138,1.024,0.27],[90.3,0.168,1.102,0.196],[93.7,0.156,2.769,0.188],[101.3,0.14,2.562,0.194],[197.4,0.116,0.688,0.411],[99.2,0.156,1.638,0.209],[109,0.138,1.155,0.22],[147.4,0.157,0.513,0.357],[174.4,0.115,0.818,0.342],[165.5,0.115,0.972,0.336],[126.3,0.143,1.405,0.278],[186.9,0.139,0.551,0.439],[179,0.112,0.988,0.37],[119.3,0.13,1.777,0.235],[93.7,0.175,0.844,0.213],[165.9,0.127,0.586,0.356],[120.9,0.14,0.748,0.25],[180,0.115,0.841,0.371],[101.8,0.14,1.925,0.205],[111.3,0.135,2.335,0.223],[128.1,0.139,1.364,0.278],[87.2,0.175,1.678,0.186],[238.7,0.109,0.66,0.471],[163,0.118,1.049,0.336],[111.1,0.158,2.101,0.247],[112.5,0.146,1.129,0.238],[100,0.163,1.083,0.224],[109.2,0.141,3.02,0.219],[166.8,0.117,0.973,0.345],[91.5,0.164,1.896,0.193],[111.7,0.141,1.232,0.232],[175.1,0.112,0.934,0.351],[148,0.122,1.027,0.304],[132.8,0.13,1.84,0.277],[172.5,0.13,0.9,0.382],[148.7,0.141,0.707,0.33],[93.4,0.157,2.727,0.18],[262.8,0.106,0.601,0.537],[245.3,0.114,0.555,0.501],[109.4,0.14,1.884,0.223],[91.4,0.164,3.359,0.177],[111.2,0.14,1.151,0.218],[122.7,0.147,0.773,0.276],[179.6,0.108,0.712,0.359],[93.3,0.157,7.356,0.188],[204.6,0.116,0.653,0.424],[141.5,0.132,1.148,0.306],[103.8,0.147,1.802,0.198],[98.2,0.154,1.882,0.201],[105,0.139,2.643,0.207],[96.8,0.147,2.976,0.197],[90.6,0.164,1.544,0.191],[106.8,0.14,2.978,0.208],[165.7,0.123,0.639,0.356],[97.9,0.147,1.226,0.193],[91.6,0.149,1.95,0.178],[119.1,0.152,1.255,0.269],[128.4,0.143,1.226,0.284],[95.2,0.147,6.599,0.184],[120.3,0.142,1.059,0.262],[86.7,0.167,3.21,0.172],[103.7,0.14,3.074,0.212],[140,0.129,1.315,0.294],[88.2,0.154,5.401,0.174],[113.9,0.151,1.348,0.25],[201,0.112,0.699,0.407],[97.6,0.177,0.902,0.22],[88.8,0.159,5.456,0.167],[214.8,0.115,0.67,0.455],[100,0.145,3.57,0.196],[93.2,0.156,6.131,0.184],[107.6,0.137,2.004,0.21],[115.6,0.134,1.726,0.227],[102.1,0.148,1.617,0.213],[118,0.135,1.415,0.228],[98.7,0.16,1.349,0.214],[100,0.147,1.508,0.202],[172.7,0.11,1.227,0.349],[104.3,0.173,0.717,0.243],[223,0.107,0.997,0.495],[173.5,0.123,0.813,0.369],[117.7,0.137,1.584,0.246],[211.3,0.109,0.714,0.438],[167.4,0.133,0.539,0.374],[164.8,0.12,0.979,0.34],[241.3,0.117,0.485,0.47],[130,0.124,1.118,0.259],[87.6,0.162,6.888,0.17],[118,0.142,1.192,0.255],[230.9,0.113,0.548,0.455],[185.1,0.125,0.636,0.404],[127.4,0.137,1.109,0.278],[108.5,0.151,1.233,0.235],[204.7,0.112,0.678,0.415],[123.6,0.141,1.149,0.27],[132.1,0.152,0.89,0.3],[156.6,0.125,0.872,0.326],[100.2,0.16,1.405,0.216],[85.6,0.187,1.635,0.192],[214.9,0.119,0.645,0.456],[110.6,0.135,2.725,0.234],[163.1,0.122,0.845,0.33],[101.8,0.149,5.287,0.204],[177.1,0.121,1.013,0.377],[101.1,0.145,10.361,0.196],[84.6,0.168,3.033,0.172],[167.6,0.114,0.873,0.334],[99.7,0.169,1.12,0.225],[109.7,0.137,2.163,0.211],[267,0.11,0.561,0.55],[138.1,0.14,0.893,0.301],[86.3,0.165,1.478,0.171],[95.8,0.153,2.344,0.186],[107.1,0.178,1.443,0.252],[136.2,0.14,0.724,0.297],[140.4,0.126,1.064,0.28],[252.3,0.108,0.6,0.517],[133.9,0.131,0.918,0.284],[249.2,0.11,0.532,0.494],[121.5,0.136,1.378,0.236],[119.6,0.135,1.263,0.261],[133.5,0.123,1.403,0.262],[117.2,0.132,2.64,0.243],[86.5,0.174,3.297,0.184],[237.5,0.106,0.58,0.469],[193.5,0.134,0.588,0.445],[92.8,0.155,2.715,0.184],[97.5,0.148,3.035,0.186],[120,0.143,0.976,0.26],[147.8,0.148,0.656,0.347],[232.8,0.109,0.711,0.489],[143.7,0.132,0.85,0.309],[136.5,0.14,0.804,0.304],[144.1,0.118,1.126,0.282],[193.1,0.122,0.643,0.399],[96.3,0.165,1.318,0.207],[121.3,0.143,1.185,0.267],[196,0.129,0.686,0.435],[90.7,0.16,5.377,0.185],[203.4,0.118,0.825,0.436],[155.6,0.137,0.587,0.353],[100.8,0.17,1.065,0.235],[172.9,0.125,0.806,0.372],[101.7,0.144,2.353,0.2],[139.3,0.124,1.102,0.274],[96,0.158,1.351,0.2],[141.9,0.133,1.06,0.309],[209,0.125,0.612,0.465],[114.8,0.141,1.455,0.242],[97.1,0.167,0.992,0.218],[88.5,0.178,1.383,0.194],[116.7,0.177,0.513,0.285],[112.1,0.144,3.674,0.229],[94.1,0.148,5.325,0.186],[133.3,0.13,0.838,0.278],[159.6,0.132,0.69,0.349],[119.2,0.134,0.935,0.24],[183,0.121,0.801,0.383],[107.9,0.147,1.525,0.226],[157.7,0.117,1.114,0.322],[145.6,0.121,1.202,0.289],[130.3,0.129,1.163,0.261],[99.7,0.154,2.466,0.21],[105.4,0.139,3.171,0.207],[140,0.151,0.603,0.327],[152,0.118,1.212,0.308],[136.7,0.138,0.938,0.297],[109.3,0.138,2.572,0.214]],"EC":[[632.3,0.0808,6.29,1.712],[260.5,0.083,13.11,0.71],[280.9,0.0903,3.16,0.692],[312.1,0.0867,4.23,0.813],[148.3,0.1004,22.72,0.441],[316.2,0.0772,6.77,0.773],[345.6,0.0703,3.4,0.837],[512.5,0.0795,1.55,1.383],[405.9,0.0827,1.94,1.068],[187.9,0.0876,8.98,0.56],[913.5,0.0676,4.17,2.175],[498.8,0.075,1.79,1.26],[234.5,0.0971,1.79,0.688],[302,0.0833,12.27,0.821],[628.3,0.068,1.72,1.548],[350.1,0.0688,3.71,0.895],[312.7,0.0862,1.9,0.899],[556,0.069,6.91,1.357],[550.9,0.068,2.04,1.355],[224.7,0.0957,5.93,0.652],[276.4,0.0729,18.92,0.724],[215.9,0.0798,3.59,0.535],[349.1,0.0737,1.67,0.86],[132.6,0.1183,6.76,0.435],[232.7,0.0787,28.07,0.602],[220.1,0.0815,25.58,0.566],[289,0.0781,2.78,0.749],[604,0.0804,24.84,1.556],[309.2,0.0749,1.37,0.894],[883.7,0.0805,2.67,2.491],[840.6,0.0697,2.62,1.983],[529.6,0.0726,10.23,1.37],[156.1,0.0815,6.78,0.442],[526.5,0.0683,2.21,1.251],[278.4,0.0773,5.75,0.727],[442.1,0.0625,2.84,1.159],[359.4,0.0698,2.82,0.923],[226.9,0.0982,6.63,0.619],[392.7,0.0607,9.79,1.067],[397.4,0.0789,2.6,1.063],[380.9,0.0764,9.86,1.004],[282.1,0.0686,11.64,0.725],[333.4,0.0849,6.86,0.853],[1224.7,0.0552,3.54,2.805],[288.9,0.0782,2.07,0.903],[322.5,0.0686,3.86,0.911],[276.4,0.0754,21.99,0.718],[299.4,0.0823,5.45,0.803],[252,0.0806,11.6,0.706],[396.6,0.0816,3.75,1.106],[300.3,0.0931,1.5,0.979],[367,0.0877,1.28,1],[313.1,0.0779,7.89,0.84],[328.6,0.0901,1.21,1.034],[287.5,0.0853,27.68,0.857],[475.9,0.0733,4,1.162],[268.5,0.0936,3.91,0.875],[195.6,0.0907,3,0.518],[386.7,0.0742,2.94,0.961],[298.5,0.0761,2.44,0.8],[192.1,0.0794,19.51,0.474],[1900.4,0.0773,6.66,4.787],[392.9,0.0733,1.53,1.025],[352.4,0.0809,9.51,0.967],[365.5,0.0879,1.27,1.122],[158.8,0.0978,4.28,0.432],[285.6,0.0889,1.5,0.889],[230,0.0759,2.75,0.653],[694.2,0.0757,2.28,1.743],[546.5,0.0761,1.7,1.365],[366.6,0.0778,4.92,0.998],[392.6,0.0721,4.34,1.008],[333.8,0.0816,4.29,0.886],[311.5,0.0803,5.3,0.934],[224.7,0.0987,5.77,0.553],[346.8,0.0922,1.46,0.966],[321.4,0.0885,1.21,0.871],[178.1,0.1031,46.31,0.533],[551,0.0645,3.4,1.391],[287.4,0.0789,9.32,0.784],[182.5,0.0937,10.31,0.522],[182.9,0.0938,3.58,0.501],[504.4,0.0789,1.38,1.324],[200.2,0.0846,5,0.675],[316.1,0.0765,19.26,0.853],[363.3,0.0818,3.14,0.898],[389.6,0.0746,2.29,1.03],[385.8,0.086,1.36,1.071],[395.4,0.0759,15.47,0.975],[233.3,0.0893,17.53,0.692],[603.4,0.069,8.27,1.521],[331.9,0.0798,2.63,0.889],[247.4,0.0937,4.21,0.693],[270.5,0.0695,7.64,0.681],[304.2,0.0825,15.53,0.867],[413.9,0.0791,2.82,1.087],[535.7,0.0698,1.67,1.388],[310.9,0.0738,2.15,0.797],[226.8,0.084,3.15,0.639],[258.1,0.0841,8.45,0.685],[314.7,0.0864,1.28,0.986],[365.5,0.0723,4.68,0.913],[196.4,0.0876,11.3,0.562],[451.7,0.0785,3.74,1.185],[320.1,0.0748,6.3,0.749],[314.5,0.0765,13,0.815],[176,0.0979,3.44,0.525],[555.8,0.0813,2.85,1.465],[181.2,0.0967,3.93,0.589],[329.5,0.0761,5.12,0.82],[359.4,0.0653,2.5,0.89],[591.8,0.0656,2.25,1.445],[252.7,0.0906,2.61,0.705],[281.8,0.0898,1.37,0.78],[374.5,0.0748,1.77,1.004],[405.7,0.0789,1.38,1.086],[364.3,0.0783,2.12,0.942],[365.8,0.08,4.13,0.943],[290.8,0.0811,25.98,0.737],[295.9,0.0972,2.26,0.897],[256.7,0.0833,20.47,0.743],[163.6,0.0873,9.66,0.452],[258.9,0.081,28.77,0.794],[478.4,0.0738,1.35,1.309],[328.1,0.0782,14.32,0.822],[279.6,0.082,36.21,0.776],[250.5,0.0825,3.77,0.624],[188.9,0.0789,7.94,0.507],[267.8,0.0893,4.1,0.767],[427.7,0.0664,14.98,0.996],[891.1,0.0726,3.45,2.133],[517.1,0.0754,1.39,1.243],[212.6,0.0892,3.13,0.595],[237.6,0.0803,3.89,0.637],[241.1,0.0882,1.95,0.73],[488,0.0652,6.31,1.287],[539.1,0.0803,1.58,1.293],[317.1,0.0683,3.12,0.785],[214.6,0.0885,6.18,0.605],[501.8,0.0665,1.8,1.19],[670.1,0.0678,2.71,1.701],[711.8,0.0748,2.3,1.869],[342.7,0.0716,3.12,0.864],[244.4,0.0865,5.65,0.693],[698.4,0.0741,3.04,2.039],[303.7,0.0784,1.43,0.869],[455.4,0.0694,1.56,1.079],[282.7,0.087,2.66,0.719],[478.5,0.0703,2.47,1.154],[371.1,0.081,1.17,1.06],[246.4,0.0744,3.04,0.751],[248.5,0.0896,1.9,0.73],[392.7,0.0899,1.69,1.132],[919,0.0774,18.92,2.204],[454.1,0.0745,3.31,1.251],[142.7,0.0937,10.92,0.397],[308.4,0.0753,3.64,0.82],[322.4,0.0744,1.86,0.766],[386.6,0.081,6.18,1.066],[509.1,0.0728,2.39,1.303],[456.3,0.0707,2.16,1.155],[344.8,0.0811,18.78,0.882],[416.3,0.0742,43.22,0.963],[506.3,0.0691,2.08,1.242],[228.8,0.082,53,0.669],[524.1,0.0669,2.23,1.331],[295.1,0.0755,11.83,0.806],[532.9,0.0711,1.34,1.333],[231,0.0734,16.77,0.625],[212,0.0784,1.51,0.605],[331.9,0.084,2.32,0.963],[346.6,0.0708,9.41,0.874],[466.2,0.0707,1.44,1.167],[315.5,0.0823,1.98,0.877],[372.2,0.0728,6.12,0.963],[324,0.0817,1.56,0.854],[299.6,0.0814,1.34,0.913],[321.7,0.0841,1.64,0.937],[118.3,0.1044,9.24,0.334],[317.6,0.0745,7.67,0.756],[402.7,0.0873,2.07,1.254],[163.5,0.0955,9.76,0.452],[426.7,0.0825,3.07,1.098],[310.4,0.0781,1.5,0.842],[302.2,0.076,2.42,0.776],[338.9,0.0808,1.1,0.987],[326,0.077,4.97,0.815],[169.6,0.0874,8.53,0.463],[330,0.0764,7.11,0.95],[501,0.0674,15.19,1.294],[442.7,0.0861,1.49,1.243],[211.1,0.081,14.22,0.607],[199.9,0.082,6,0.554],[357.2,0.0747,1.88,0.981],[550.7,0.0836,1.82,1.654],[256.9,0.0873,3.88,0.697],[261.6,0.078,2.03,0.721],[358.1,0.0809,6.74,0.976],[271.8,0.0834,3.44,0.736],[300.2,0.0762,24.19,0.762],[424.7,0.0756,1.67,1.084],[215.7,0.0859,8.82,0.592],[426.6,0.0804,2.02,1.161],[205.8,0.0924,21.74,0.586],[121.4,0.103,41.86,0.402],[214.1,0.0801,6.84,0.592],[473.8,0.0799,1.86,1.285],[302.1,0.0803,2.17,0.815],[211.2,0.0893,9.37,0.597],[446.4,0.0754,4.09,1.256],[294.4,0.0871,9.97,0.775],[266.8,0.0738,3.13,0.652],[415.5,0.0777,6.15,1.078],[697.4,0.0717,2.03,1.862],[378.8,0.0745,1.69,1.042],[719.5,0.0763,5.76,1.87],[236.6,0.0758,30.69,0.663],[348.6,0.0735,4.88,0.964],[208,0.0849,2.91,0.561],[388.5,0.0786,2.3,1.005],[329.3,0.0718,4.35,0.797],[208.3,0.0932,1.01,0.636],[372.8,0.078,9,0.971],[406.3,0.0833,3.09,1.16],[156.5,0.1048,15.9,0.469],[333.2,0.0705,3.65,0.937],[299.7,0.0894,1.8,0.759],[346.5,0.0891,1.86,0.953],[619.3,0.063,8.01,1.507],[592.3,0.0665,1.91,1.493],[589,0.0746,1.82,1.476],[392.7,0.0817,1.3,1.155],[270.5,0.0646,9.62,0.693],[499.2,0.0787,1.34,1.326],[409.5,0.0782,1.93,1.146],[210.9,0.0916,1.89,0.622],[350.8,0.0823,2.79,0.989],[499.1,0.0626,5.2,1.159],[775.5,0.0813,4.11,1.984],[1293.7,0.0764,3.87,3.52],[584.2,0.0713,1.49,1.366],[251.8,0.0779,5.26,0.635],[283.3,0.0895,1.14,0.822],[258.8,0.077,2.14,0.691],[317.9,0.0684,9.22,0.863],[257.7,0.0862,2.48,0.798],[474.9,0.0755,1.27,1.232],[644.3,0.0667,11.88,1.663],[312.7,0.0828,4.33,0.875],[508.3,0.0747,5,1.27],[277.5,0.0826,2.6,0.733],[359.2,0.0673,4.6,0.864],[160.9,0.0915,9.09,0.445],[245.3,0.0811,7.5,0.672],[431.8,0.0746,8.04,1.189],[622.7,0.0767,3.66,1.571],[362.9,0.0812,1.15,1.05],[222.2,0.0809,4.19,0.596],[264.9,0.0861,5.6,0.725],[362.7,0.076,4.5,0.963],[395.4,0.0788,1.66,1.04],[456.6,0.0678,6.38,1.071],[241.6,0.0848,9.26,0.641],[393.9,0.07,1.23,1.072],[668.7,0.0631,2.29,1.585],[332.8,0.0721,3.78,0.913],[211.9,0.0791,13.44,0.506],[415.1,0.0836,4.03,1.091],[372.4,0.0845,2.03,0.975],[237.2,0.0868,12.1,0.669],[399.4,0.0766,3.11,1.119],[319.6,0.0809,1.32,0.88],[252.6,0.0843,5.85,0.677],[254.2,0.084,2.39,0.631],[396.2,0.0775,2.46,1.045],[530.8,0.0846,3.06,1.507],[662.3,0.0691,3.62,1.526],[208.5,0.0848,3.85,0.591],[228,0.0887,4.58,0.62],[411,0.0807,14.87,1.053],[377.7,0.0862,4.06,0.968],[528.7,0.0757,1.92,1.381],[290.1,0.089,1.18,0.982],[259.1,0.0846,2.34,0.701],[319.5,0.0841,3.47,0.877],[161.3,0.0915,9.26,0.454],[347.4,0.0733,1.47,1.041],[247.3,0.0986,19.9,0.68],[349.5,0.0765,6.66,0.961],[194.3,0.103,2.93,0.75],[514.6,0.0573,5.75,1.17],[506.1,0.0817,9.44,1.277],[484.7,0.0801,1.51,1.347],[423.4,0.0787,1.61,1.124],[294,0.0792,4.16,0.831],[255.9,0.0919,8.88,0.747],[283.2,0.093,1.05,0.896],[395.4,0.0731,6.24,0.995],[318.1,0.0891,1.02,0.898],[461.5,0.0671,5.8,1.118],[471,0.0788,2.2,1.219],[288.5,0.0606,41.21,0.702],[614.1,0.0657,1.95,1.565],[207.7,0.0928,6.67,0.576],[345.4,0.0799,5.36,0.858],[394.2,0.0883,1.53,1.052],[249.8,0.0823,10.93,0.688],[357.4,0.0797,3.73,0.959],[715,0.0717,1.99,1.675],[281.4,0.0816,1.71,0.759],[559.2,0.0771,13.75,1.359],[617.8,0.0613,8.85,1.514],[417.2,0.0742,8.16,1.138]],"EB":[[1013.9,0.777,39.3,2.64],[1514.1,0.759,57.8,3.82],[1364.2,0.672,40.5,3.54],[2236.3,0.679,52.1,5.36],[1439.6,0.687,29.2,3.5],[2103.4,0.615,32.5,4.41],[2347.5,0.669,126.7,5.14],[1139.3,0.77,51.4,2.84],[1535.1,0.869,38,4.2],[1599.3,0.769,27.2,3.83],[2037.4,0.715,45,4.69],[2045.2,0.629,40.5,4.51],[2338.7,0.664,76.9,5.17],[1888.5,0.724,25.4,4.71],[1002.9,0.82,69.4,2.83],[1788.6,0.702,70.4,4.13],[1675.9,0.736,23.8,3.89],[1529.6,0.741,95.5,3.76],[2301.3,0.589,27.4,4.69],[2115.9,0.641,26.6,4.45],[2595.6,0.693,62.6,5.66],[2317.2,0.655,32.1,5.34],[3384.2,0.713,78.2,8.7],[2772.9,0.78,89.6,7.35],[2055.6,0.733,56.3,5.3],[1704.7,0.708,72.8,4.24],[2609,0.601,71.3,5.46],[2079.6,0.674,125.7,5.29],[3500.9,0.725,65.7,9.02],[3457.4,0.658,114,8.59],[3023.4,0.748,65.7,8.26],[1307.5,0.724,36.5,3.26],[1398.4,0.773,28.2,3.48],[1363.8,0.696,56.8,3.38],[1802.2,0.665,47.7,4.2],[1531.4,0.719,37.5,3.82],[1809.1,0.726,62.1,4.28],[2307.8,0.623,69.3,4.73],[2365.5,0.612,52.5,5.02],[2565.9,0.663,18.2,5.63],[1852.5,0.632,42.9,3.96],[1287.9,0.769,43.9,3.18],[1814.1,0.695,22.9,4.38],[2172.1,0.685,33.6,4.83],[1825.3,0.62,32.3,3.83],[2048.6,0.641,48.6,4.41],[1791.2,0.666,44.7,3.92],[1364.2,0.789,20,3.47],[1499.2,0.714,65.3,3.52],[2086.9,0.598,31.9,4.46],[2667,0.582,14.3,5.41],[1377.2,0.832,81,3.42],[1569.1,0.67,43.7,3.45],[2140.8,0.607,56.4,4.52],[2064.2,0.615,23.2,4.26],[2212.5,0.582,50.3,4.53],[2348.5,0.611,40.5,4.82],[2411,0.616,41,4.91],[2463.7,0.621,42.2,5.05],[2442.1,0.615,42.1,5.01],[1630.7,0.717,58.3,3.67],[3082.3,0.681,56.2,6.79],[3269.7,0.713,70.6,8.92],[2583.8,0.708,50.2,6.7],[2294.5,0.659,55,5.1],[2763.7,0.604,53.4,5.82],[2243.1,0.683,52.7,5],[1575.7,0.656,26.7,3.5],[1796.4,0.612,46.4,3.71],[1707.1,0.758,56.7,3.92],[1620.8,0.734,15.1,4.1],[1719.2,0.64,49,3.82],[2397.2,0.654,40.1,5.26],[1496.4,0.851,56.5,3.66],[2075.5,0.666,76.9,4.35],[2243,0.682,58.3,5.15],[1436.4,0.727,46.1,3.52],[3307,0.668,99.9,7.79],[3284.2,0.702,79.7,8.62],[2026.7,0.649,27.6,4.4],[2065.2,0.684,29.3,4.82],[2908.8,0.647,58.3,6.34],[1916.7,0.708,23,4.61],[2488.2,0.681,40.1,5.44],[2467.6,0.68,35.1,5.27],[2661.6,0.641,35.2,5.47],[1984.5,0.608,48,4.17],[1180.5,0.776,75.5,3.08],[1135,0.752,65.5,2.98],[2081.1,0.686,45,4.81],[1878.9,0.707,78.1,4.11],[2461.4,0.638,58.1,5.11],[3213.4,0.62,17.8,6.53],[3972.8,0.662,44.1,9.21],[2328.4,0.679,73.8,5.41],[1967.3,0.625,78,4.11],[3319.3,0.625,53,6.57],[1383.8,0.687,40,3.33],[1931.9,0.759,72.9,4.47],[2392.3,0.654,75,5.17],[1667.9,0.784,111.4,4.01],[2838.3,0.667,55.8,6.36],[1565.3,0.693,20.4,3.62],[1727.9,0.687,90.7,3.99],[2281.5,0.645,52,5.17],[1406.7,0.766,70.4,3.48],[1613.8,0.707,72.9,3.99],[1598.1,0.778,43.4,3.99],[1968.8,0.706,88.9,4.91],[1918.2,0.628,62.1,4.22],[1813,0.705,23.7,4.01],[1714.3,0.783,50.7,4.03],[2020.7,0.804,21,5.13],[2159.9,0.607,68,4.55],[1700.1,0.686,45.8,3.8],[1026.6,0.816,28.1,2.88],[2749.3,0.603,19.8,5.66],[1969.8,0.637,36.2,4.26],[2547.5,0.625,29.7,5.26],[2958,0.618,36.8,6.29],[2136.4,0.618,35.7,4.47],[1958,0.672,41.5,4.32],[1841.1,0.679,51.6,4.23],[2014.7,0.599,55.7,4.25],[1712.1,0.698,16.4,4.26],[1835,0.695,47.8,4.4],[1952.5,0.681,66.2,4.52],[1900.4,0.714,49.4,4.36],[2301.3,0.628,48.6,4.86],[2001.3,0.702,88.6,4.75],[1986.5,0.677,33,4.57],[2615.6,0.746,45.4,6.76],[988.1,0.803,66.1,2.73],[2048.8,0.64,74.5,4.3],[2782.4,0.586,64.5,5.53],[2405.4,0.663,81.1,5.3],[2693.2,0.657,50.1,6.08],[1818,0.749,57.3,4.21],[1778.4,0.749,41.9,4.26],[3004.1,0.636,57.5,6.45],[2331.8,0.636,50.3,5],[1964.9,0.661,53.9,4.49],[2928.3,0.614,69.4,5.83],[2042.2,0.681,30.4,4.74],[2041.6,0.639,25.2,4.67],[2565,0.582,43.6,5.11],[1749.5,0.676,24.3,3.77],[3283.4,0.572,18.3,6.62],[2759.3,0.587,44.8,5.67],[1541.1,0.726,13.2,3.77],[1537.5,0.881,36.2,3.91],[1396.4,0.745,58.8,3.42],[2612.4,0.594,25.3,5.25],[1774.5,0.666,31.2,3.96],[1824.9,0.676,84.4,4.31],[1522,0.672,23.3,3.48],[1585.7,0.747,53.5,4.05],[1167.9,0.649,128.7,2.89],[1800.4,0.727,42.8,4.22],[1867.5,0.644,61.7,4.03],[3487.6,0.65,27.4,7.4],[1826.7,0.647,49.2,3.95],[1520.5,0.708,71.7,3.67],[1184.6,0.804,60.9,3.06],[2551.6,0.645,18.8,5.45],[1963.7,0.701,52.7,4.83],[3847.7,0.7,71.6,9.57],[2347.1,0.654,31,5.23],[1386.8,0.7,62.8,3.15],[1867.2,0.68,106.1,4.17],[1805.3,0.715,45.8,4.34],[2370.4,0.684,48.9,5.58],[2071.6,0.727,117.7,4.99],[4295.8,0.678,51.8,10.01],[1711.4,0.763,127.8,4.35],[1852.3,0.651,29.8,3.88],[1787.4,0.626,31.3,3.76],[1765.2,0.636,31.7,3.75],[1717.3,0.625,30.5,3.64],[1865.3,0.631,29.9,3.92],[1866.2,0.628,29.8,3.91],[1831.7,0.623,30.1,3.88],[1932.9,0.614,30.3,3.99],[1900.4,0.617,29.9,4.01],[1929.9,0.637,29,4.09],[2058.5,0.624,30.9,4.31],[2026,0.642,30.2,4.29],[2051.4,0.626,31.2,4.28],[2039.5,0.644,31.9,4.27],[2105.1,0.634,31.2,4.37],[2112.2,0.601,32.2,4.36],[2179.5,0.61,31.7,4.47],[2150.5,0.616,31.5,4.44],[2155.8,0.622,31.4,4.45],[2243.3,0.609,32.3,4.58],[2220.8,0.607,32.6,4.55],[2129.3,0.628,33.9,4.46],[2145,0.614,33.7,4.44],[2188.2,0.625,33.6,4.51],[2172.9,0.62,33.8,4.51],[2161.1,0.616,34,4.49],[2221.8,0.601,32.9,4.55],[2267.5,0.587,33.2,4.63],[2248,0.595,32.6,4.58],[2210.3,0.596,32.4,4.53],[2249.9,0.603,32.6,4.57],[2198.5,0.589,33.5,4.46],[2207.3,0.583,33.6,4.47],[2219.7,0.582,33.9,4.48],[2254.8,0.595,33.8,4.58],[2229.5,0.594,33.8,4.53],[2205.2,0.595,33.7,4.47],[2284.7,0.576,33.7,4.61],[2235.5,0.576,33.2,4.52],[2237.2,0.594,33.2,4.56],[2205,0.607,32.8,4.52],[2223.1,0.605,33,4.55],[2255.9,0.581,33.7,4.51],[2251.7,0.569,34.9,4.58],[2287.3,0.564,35.3,4.65],[2251.3,0.621,33.2,4.68],[2228.5,0.609,33.5,4.62],[2205.7,0.621,34.5,4.6],[2206.4,0.589,34.3,4.56],[2179,0.603,35,4.42],[2211.2,0.583,34.8,4.5],[2244.2,0.602,32.6,4.67],[2290.6,0.617,32,4.7],[2959.5,0.734,85.5,7.73],[1765.8,0.664,61.6,3.84],[2345.2,0.592,43.1,4.91],[2722.8,0.595,36.9,5.46],[2429.5,0.594,8.3,5.18],[2284.5,0.613,30.5,4.87],[1941.7,0.645,54.1,4.2],[2298.1,0.645,54.1,5.21],[1558.5,0.753,34.2,3.64],[1002.6,0.836,47.1,2.7],[1651.1,0.69,29.8,3.68],[2052.2,0.686,53.4,4.47],[2714.8,0.719,76.2,6.76],[2042.3,0.618,45.9,4.36],[1777.4,0.63,42.1,3.71],[2143,0.626,40.8,4.56],[1315.3,0.689,24.2,3.3],[2264.7,0.668,19.6,4.93],[2104.4,0.687,22.9,4.77],[2390.3,0.619,44.4,4.89],[1945.9,0.674,47,4.32],[1569.3,0.777,55,3.83],[1542.3,0.712,36.2,3.92],[1603.8,0.716,31.9,3.9],[2265.7,0.714,74.4,5.29],[1776.1,0.743,61.5,4.04],[2459.6,0.699,26.2,5.47],[1603.3,0.759,44,3.82],[1830.6,0.697,65.1,4.16],[2057.9,0.678,82.9,4.54],[1374.2,0.688,84.2,3.26],[1532.3,0.772,80,3.62],[2694.7,0.653,66.8,5.91],[1149.4,0.734,82.2,2.88],[1477,0.726,77.2,3.66],[2572.5,0.609,40.6,5.15],[2816.9,0.667,44.3,6.16],[1928,0.679,28.9,4.39],[1489,0.738,35.6,3.46],[2184.9,0.68,29.7,4.88],[1530.5,0.681,53.7,3.63],[1841.9,0.617,31.7,3.89],[2168.6,0.651,50.2,5.08],[2120.4,0.682,57.8,4.72],[2112.5,0.733,51.6,5.06],[1348.8,0.701,32.5,3.34],[2066,0.674,39.3,4.95],[1667.7,0.737,43.8,3.71],[1342.2,0.747,64.1,3.38],[2412,0.61,41.7,5.09],[1859.5,0.648,83.7,3.91],[1952.6,0.705,46.8,4.24],[2001.9,0.613,65.7,4.44],[1875.6,0.671,22.1,4.15],[1877.1,0.632,29.1,3.99],[1721.3,0.643,54,3.72],[2475.5,0.641,82.9,5.22],[989.9,0.829,41.6,2.68],[1635.1,0.729,39.6,3.84],[2659.2,0.641,65.5,5.81],[2816.2,0.633,37.7,5.82],[2342.2,0.721,34.9,5.47],[1979.5,0.635,65.7,4.3],[2124.6,0.663,24,5.11],[1641.1,0.631,46.3,3.59],[1994.1,0.634,27.8,4.56],[2076.2,0.667,24.6,4.57],[1969.8,0.637,30.1,4.27],[3567.9,0.678,41.4,7.9],[2182.9,0.665,58,4.67],[2123.9,0.613,107.9,4.34],[2168.3,0.668,51.2,4.69],[2497.6,0.667,68.8,5.4],[1520,0.678,30.6,3.47],[1685.4,0.71,52.7,3.74],[962.2,0.77,45.9,2.66],[2085.7,0.634,41.3,4.39],[2224.9,0.622,41.7,4.61],[1602,0.65,18.6,3.63],[1031.4,0.893,36.2,2.78],[1913.5,0.701,42.2,4.37],[2498.6,0.615,32.2,5.37],[2525.8,0.632,26.2,5.39],[1564,0.688,40,3.62],[1541.2,0.763,41,3.78]],"EUCS":[[14.988,0.061,0.031,0.112],[15.7,0.054,0.02,0.107],[20.142,1.476,0.008,0.095],[11.983,0.047,0.033,0.088],[20.954,0.02,0.023,0.1],[13.205,0.077,0.023,0.093],[12.038,0.074,0.034,0.087],[13.162,0.038,0.028,0.085],[14.578,0.049,0.027,0.098],[12.463,0.076,0.023,0.098],[27.825,0.011,0.029,0.108],[13.17,1.413,0.014,0.08],[15.927,0.042,0.034,0.111],[16.095,0.031,0.033,0.102],[21.081,3.262,0.012,0.131],[18.623,0.043,0.023,0.12],[13.461,0.05,0.038,0.11],[31.378,0.256,0.005,0.106],[15.952,2.322,0.015,0.102],[12.669,0.047,0.043,0.097],[14.11,0.046,0.031,0.097],[25.63,0.261,0.006,0.099],[8.187,4.51,0.023,0.088],[20.341,0.017,0.026,0.097],[20.123,0.018,0.025,0.096],[18.969,0.024,0.02,0.095],[18.467,0.022,0.022,0.094],[17.92,0.022,0.023,0.094],[18.213,0.02,0.028,0.095],[18.016,0.018,0.027,0.095],[17.358,0.021,0.026,0.095],[14.855,0.069,0.024,0.105],[13.403,1.132,0.024,0.097],[13.56,0.872,0.022,0.103],[12.84,0.516,0.038,0.097],[18.806,0.022,0.022,0.09],[12.462,0.046,0.034,0.094],[21.764,2.22,0.008,0.096],[13.753,0.126,0.026,0.103],[13.413,3.583,0.016,0.098],[16.774,0.807,0.009,0.097],[24.617,4.535,0.006,0.087],[16.033,0.558,0.017,0.104],[16.087,0.034,0.025,0.098],[29.355,2.322,0.005,0.108],[28.738,1.234,0.007,0.133],[30.224,3.837,0.005,0.098],[22.338,0.429,0.006,0.089],[22.303,5.113,0.008,0.104],[33.77,4.332,0.005,0.12],[15.671,0.188,0.012,0.088],[18.455,0.021,0.024,0.1],[12.94,0.059,0.025,0.092],[13.757,0.206,0.035,0.109],[13.066,1.52,0.034,0.106],[18.042,4.195,0.026,0.133],[11.745,3.212,0.023,0.106],[10.489,0.123,0.026,0.095],[13.386,0.073,0.028,0.098],[11.132,1.153,0.037,0.086],[16.936,0.121,0.024,0.126],[11.536,3.603,0.023,0.091],[26.869,0.112,0.007,0.108],[30.423,1.991,0.005,0.101],[28.588,0.379,0.006,0.108],[15.859,0.095,0.013,0.092],[11.502,4.007,0.03,0.087],[16.909,0.019,0.035,0.093],[27.717,3.016,0.008,0.125],[25.508,3.707,0.007,0.113],[15.636,3.237,0.028,0.127],[13.862,3.023,0.025,0.098],[19.799,0.783,0.01,0.105],[23.79,4.069,0.009,0.114],[22.636,0.216,0.008,0.103],[12.81,0.064,0.048,0.107],[21.913,3.434,0.007,0.096],[12.209,5.006,0.021,0.1],[27.721,0.326,0.005,0.094],[13.036,0.037,0.035,0.095],[19.349,0.017,0.028,0.092],[51.672,0.705,0.005,0.158],[9.718,2.676,0.029,0.095],[11.551,2.204,0.035,0.098],[13.799,0.038,0.036,0.094],[11.935,0.352,0.021,0.09],[14.833,4.155,0.016,0.097],[11.069,1.248,0.033,0.092],[24.274,1.269,0.008,0.097],[10.525,0.124,0.024,0.09],[11.62,4.912,0.026,0.094],[13.753,2.85,0.029,0.103],[11.972,5.133,0.035,0.09],[12.746,0.043,0.033,0.09],[12.895,0.048,0.028,0.088],[24.496,4.318,0.006,0.097],[14.497,0.073,0.028,0.109],[13.662,0.04,0.028,0.09],[20.214,2.071,0.008,0.104],[12.437,3.262,0.032,0.099],[17.77,0.033,0.029,0.113],[14.673,0.055,0.045,0.105],[13.598,0.04,0.029,0.09],[14.561,0.038,0.025,0.092],[19.215,0.024,0.023,0.1],[16.479,0.028,0.031,0.096],[16.199,0.031,0.024,0.098],[21.942,2.313,0.007,0.099],[14.023,0.071,0.028,0.101],[15.109,0.245,0.023,0.11],[16.392,0.044,0.028,0.114],[14.362,0.946,0.015,0.096],[9.792,4.172,0.034,0.084],[26.557,5.088,0.006,0.102],[16.433,0.107,0.016,0.099],[30.793,2.89,0.005,0.108],[18.695,5.783,0.011,0.105],[19.216,0.299,0.009,0.093],[24.167,5.855,0.006,0.092],[14.097,2.19,0.032,0.101],[12.859,0.081,0.026,0.095],[17.197,0.032,0.026,0.102],[17.617,0.043,0.025,0.115],[13.161,0.045,0.027,0.087],[16.435,0.039,0.025,0.1],[8.068,3.971,0.029,0.095],[10.362,4.786,0.027,0.112],[15.401,3.107,0.014,0.098],[11.246,0.29,0.026,0.086],[14.504,1.834,0.027,0.109],[19.237,0.02,0.023,0.097],[15.395,0.037,0.026,0.101],[15.048,0.043,0.024,0.097],[16.107,0.026,0.029,0.096],[11.428,4.87,0.035,0.092],[17.475,4.242,0.012,0.1],[24.829,1.825,0.007,0.109],[25.376,4.484,0.007,0.104],[15.796,0.135,0.012,0.087],[15.273,2.345,0.011,0.088],[29.983,4.647,0.005,0.098],[10.894,0.339,0.029,0.094],[14.786,0.032,0.026,0.089],[22.007,0.022,0.02,0.113],[12.345,0.099,0.034,0.097],[20.947,0.026,0.022,0.11],[23.839,0.014,0.028,0.11],[14.626,0.053,0.023,0.099],[33.362,5.544,0.006,0.117],[17.002,0.085,0.031,0.135],[22.318,0.016,0.027,0.106],[17.435,0.051,0.014,0.088],[14.166,0.078,0.028,0.104],[16.368,0.027,0.024,0.1],[12.001,0.045,0.024,0.078],[11.402,0.14,0.03,0.087],[28.256,2.037,0.006,0.108],[30.776,2.95,0.005,0.115],[13.383,3.65,0.015,0.098],[15.929,0.035,0.032,0.107],[34.29,5.691,0.007,0.127],[15.874,0.041,0.027,0.106],[12.981,0.053,0.047,0.09],[12.853,5.731,0.023,0.103],[24.779,1.478,0.006,0.095],[19.832,0.527,0.007,0.083],[26.97,5.188,0.006,0.102],[23.215,4.436,0.014,0.141],[15.958,3.171,0.012,0.092],[17.429,0.029,0.023,0.101],[14.188,0.084,0.027,0.102],[14.529,0.037,0.026,0.094],[17.911,0.026,0.021,0.096],[14.322,0.063,0.029,0.105],[10.648,3.927,0.019,0.089],[17.019,1.823,0.022,0.111],[10.891,5.544,0.027,0.092],[12.366,0.096,0.025,0.088],[13.764,0.034,0.029,0.093],[29.047,0.564,0.007,0.113],[14.321,0.019,0.119,0.095],[12.18,5.703,0.026,0.106],[11.824,0.829,0.028,0.105],[25.789,0.764,0.005,0.094],[18.062,5.93,0.008,0.094],[24.666,1.988,0.006,0.091],[23.742,5.551,0.007,0.099],[20.341,0.873,0.012,0.128],[12.62,4.93,0.028,0.099],[14.594,2.036,0.011,0.09],[12.937,0.357,0.029,0.096],[9.905,0.513,0.022,0.088],[16.655,0.023,0.028,0.093],[14.187,4.847,0.017,0.099],[23.755,2.353,0.007,0.093],[16.612,0.061,0.016,0.098],[22.974,0.233,0.008,0.094],[16.395,1.696,0.016,0.115],[14.215,0.038,0.033,0.101],[28.575,0.005,0.133,0.099],[19.32,0.008,3.734,0.081],[22.152,0.008,3.811,0.098],[13.891,0.031,0.035,0.103],[18.021,0.032,0.027,0.118],[14.329,0.034,0.03,0.092],[15.598,0.034,0.026,0.096],[12.6,0.364,0.016,0.093],[14.869,0.038,0.028,0.102],[12.908,0.05,0.038,0.098],[17.308,0.038,0.021,0.1],[16.058,0.049,0.019,0.095],[21.763,0.018,0.03,0.112],[11.005,0.057,0.028,0.077],[11.985,2.386,0.021,0.104],[13.847,1.659,0.011,0.089],[22.65,3.121,0.008,0.106],[16.54,0.714,0.009,0.084],[17.057,4.939,0.018,0.133],[12.825,1.656,0.034,0.096],[15.315,0.051,0.025,0.104],[26.865,0.559,0.007,0.106],[23.707,4.806,0.006,0.114],[20.256,1,0.01,0.105],[28.925,2.964,0.006,0.119],[18.912,5.998,0.008,0.088],[21.227,0.013,0.091,0.119],[20.868,2.979,0.013,0.116],[16.727,0.407,0.015,0.101],[12.644,2.667,0.026,0.111],[13.018,0.056,0.037,0.095],[12.676,5.508,0.035,0.108],[13.246,0.059,0.028,0.096],[23.552,3.264,0.009,0.113],[12.863,0.039,0.032,0.089],[13.814,0.044,0.028,0.098],[15.187,0.336,0.017,0.114],[20.694,1.605,0.008,0.097],[22.772,4.757,0.006,0.097],[32.423,1.436,0.005,0.105],[29.24,5.147,0.005,0.099],[11.94,5.214,0.019,0.105],[24.51,0.659,0.007,0.103],[17.403,2.577,0.011,0.096],[16.222,1.173,0.009,0.089],[15.365,0.033,0.027,0.099],[26.007,5.528,0.008,0.118],[31.846,4.469,0.005,0.101],[27.195,3.016,0.005,0.099],[25.637,5.758,0.005,0.094],[26.211,1.555,0.005,0.085],[14.986,0.036,0.035,0.097],[29.139,2.141,0.005,0.085],[23.254,2.397,0.007,0.101],[23.393,1.661,0.009,0.111],[20.087,0.172,0.01,0.101],[18.574,0.034,0.024,0.112],[21.924,0.052,0.01,0.102],[26.049,0.014,0.028,0.113],[15.342,0.039,0.028,0.102],[28.634,2.271,0.005,0.1],[15.927,0.034,0.021,0.091],[21.283,2.395,0.008,0.089],[22.041,0.021,0.02,0.103],[17.543,0.028,0.027,0.104],[15.17,0.032,0.03,0.102],[16.217,0.039,0.026,0.106],[12.46,0.074,0.028,0.094],[17.618,0.026,0.032,0.106],[14.859,3.706,0.017,0.108],[14.554,0.036,0.028,0.095],[19.042,0.375,0.024,0.151],[20.343,4.754,0.01,0.102],[28.8,1.901,0.006,0.106],[28.722,4.7,0.005,0.095],[31.006,2.696,0.005,0.107],[12.738,2.795,0.028,0.098],[20.011,5.86,0.026,0.146],[17.098,3.336,0.026,0.133],[10.847,2.636,0.027,0.088],[13.656,2.225,0.021,0.107],[18.241,0.031,0.034,0.119],[16.247,0.023,0.033,0.099],[23.286,3.053,0.008,0.107],[27.148,3.133,0.005,0.087],[15.462,5.781,0.013,0.088],[17.039,5.645,0.015,0.112],[14.427,5.209,0.012,0.085],[15.613,0.03,0.028,0.101],[15.251,0.037,0.021,0.096],[14.149,4.424,0.032,0.114],[14.579,0.628,0.032,0.115],[12.853,0.055,0.027,0.092],[14.082,0.041,0.028,0.093],[15.934,0.042,0.025,0.103],[19.65,3.913,0.01,0.111],[11.594,0.036,0.05,0.099],[15.234,4.866,0.023,0.113],[31.828,0.409,0.005,0.104],[13.225,3.299,0.03,0.102],[10.683,4.506,0.034,0.096],[16.149,0.053,0.024,0.114],[16.409,0.044,0.021,0.103],[19.716,3.412,0.008,0.091],[16.11,0.043,0.029,0.109],[14.625,0.121,0.023,0.107],[26.315,5.836,0.005,0.095],[16.411,1.387,0.012,0.095],[33.44,3.397,0.005,0.119],[17.291,2.868,0.012,0.1],[32.648,1.249,0.005,0.102],[26.801,5.876,0.005,0.089],[14.011,4.926,0.018,0.096],[13.792,4.562,0.037,0.104]]} \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index edc0fd9..22797a3 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -5,6 +5,30 @@ > section la plus récente EN PREMIER ; ce fichier est lu par le dialog > « Nouveautés » de l'app web (fetch `docs/CHANGELOG.md`). +## [1.9.0] — 2026-09-18 + +### Modèle Estrannaise ANALYTIQUE + nuage d'incertitude (portage Android v1.9.0, versions sync) + +- **Le modèle ESE n'est plus les tables horaires ODS** : il est désormais la + **forme close 3C publiée par estrannaise.js** (les sources originelles + dont l'ODS n'était que l'échantillonnage horaire) — fidélité épinglée : + RMS 0,00 vs les tables sur 0→200 j, écart de pic ≤ 0,1 %. Les tables ne + sont plus fetchées au démarrage (−550 Ko, démarrage plus rapide) ; + `pk_profiles.json` reste uniquement comme référence des tests. +- **6 esters injectables couverts** (EV, EU, EEn, EC, EB + **EUCS**, undécylate + suspension cristalline, exclusif à ce fit) — l'ancien ESE n'en couvrait + que 3. +- **NUAGE D'INCERTITUDE (exclusif ESE)** : Estrannaise publie le posterior + MCMC de ses paramètres (313 échantillons/ester) — chip `Nuage` + (off par défaut, activable à volonté, actif SEULEMENT si ESE est affiché) + → nuage diffus de courbes montrant la plage d'imprécision du modèle, + comme sur le site estrannaise. TFS/WHSAH ne publient pas de posterior → + pas de nuage pour eux. +- t½ terminale ESE désormais **analytique** (ln2/min(k1,k2,k3)) — la + recommandation de prise de sang n'estime plus la t½ par pente de table. +- **Tests** : fidélité (RMS, pics), cas dégénérés, MCMC (313 × 6), nuage + (32 courbes, dispersion, exclusivité ESE), t½ analytique. + ## [1.8.1] — 2026-09-17 ### Corrigé — la stabilisation ignorait les changements récents (dose/ester/intervalle) diff --git a/js/pk/estrannaise-cloud.js b/js/pk/estrannaise-cloud.js new file mode 100644 index 0000000..df00e03 --- /dev/null +++ b/js/pk/estrannaise-cloud.js @@ -0,0 +1,103 @@ +/** + * NUAGE D'INCERTITUDE (v1.9.0, miroir fidèle de `pk/EstrannaiseCloud.kt`) — + * feature **exclusive au modèle ESE**. + * + * SOURCE : Estrannaise publie le **posterior MCMC** de ses paramètres + * (313 échantillons `(d, k1, k2, k3)` par ester injectable — cf + * js/pk/estrannaise-models.js). Le graphique dessine un **nuage diffus** : + * M courbes (une par échantillon échelonné) qui montrent la plage + * d'imprécision possible du modèle — l'affichage du site estrannaise. + * TFS/WHSAH ne publient pas de posterior → pas de nuage (choix confirmé). + * + * QU'EST-CE QUE LE NUAGE REPRÉSENTE : la superposition des doses des + * traitements E2 **à profil ESE** évaluée avec UN échantillon MCMC par + * courbe. Les contributions des autres traitements ne sont PAS incluses + * (pas d'incertitude publiée pour eux — limite documentée §12). + * + * DÉTERMINISME : échantillons **échelonnés** (stride, pas d'aléatoire) — + * le nuage est identique à chaque affichage et testable en Node. + * + * PUR (aucun DOM) → testable en Node (tests/estrannaise-cloud.test.js). + */ + +import * as EstrannaiseModels from './estrannaise-models.js'; +import { usesProfileModel } from './pk-engine.js'; + + +/** Nombre de courbes du nuage (compromis étendue visuelle / coût ×32). */ +export const DEFAULT_NB_CURVES = 32; + +/** Un creux à moins de 6 h n'est pas exploitable (réutilisé pour l'horizon). */ +export const MIN_HORIZON_HOURS = 6; + +/** + * Calcule le nuage d'incertitude. + * + * @param {object[]} treatments TOUS les traitements (actifs ET inactifs, §6.bis) + * @param {object[]} doseLogs toutes les doses réelles + * @param {number} startMs fenêtre demandée (celle du graphique) + * @param {number} endMs + * @param {number} stepMs pas de la grille (stepForRange) + * @param {number} nowMs « maintenant » + * @param {number} [nbCurves=32] + * @returns {Array>} M courbes — + * **vide** si rien n'est calculable : aucun traitement E2 actif à profil + * ESE couvert, aucune dose, ou MCMC non chargé. + */ +export function compute( + treatments, doseLogs, startMs, endMs, stepMs, nowMs, nbCurves = DEFAULT_NB_CURVES, +) { + if (startMs >= endMs || stepMs <= 0 || nbCurves < 2) return []; + + // Porteurs : traitements E2 actifs à profil ESE avec ester couvert + const carriers = treatments.filter((t) => + t.type === 'ESTRADIOL' + && t.isActive + && usesProfileModel(t) + && t.pkModel === 'ESE' + && EstrannaiseModels.hasModel(t.esterType)); + if (carriers.length === 0) return []; + + const carrierIds = new Set(carriers.map((t) => t.id)); + const carrierDoses = doseLogs.filter((d) => carrierIds.has(d.treatmentId) && d.timestamp <= endMs); + if (carrierDoses.length === 0) return []; + + // Échantillons échelonnés du posterior (déterministes) + const samplesByEster = new Map( + carriers.map((t) => [t.esterType, EstrannaiseModels.mcmcSamples(t.esterType)]), + ); + if ([...samplesByEster.values()].some((s) => s.length === 0)) return []; + const maxSamples = Math.min(...[...samplesByEster.values()].map((s) => s.length)); + const stride = Math.max(1, Math.trunc(maxSamples / Math.min(nbCurves, maxSamples))); + + // Grille : de max(start, 1ʳᵉ dose du porteur) à endMs — rien avant la 1ʳᵉ dose + const firstDoseMs = Math.min(...carrierDoses.map((d) => d.timestamp)); + const t0 = Math.max(startMs, firstDoseMs); + if (t0 > endMs) return []; + + // ── M courbes ────────────────────────────────────────────────────────────── + const cloud = []; + for (let m = 0; m < nbCurves; m++) { + const sampleIdx = Math.min(m * stride, maxSamples - 1); + const paramsByEster = new Map( + [...samplesByEster.entries()].map(([ester, samples]) => [ + ester, samples[Math.min(sampleIdx, samples.length - 1)], + ]), + ); + const curve = []; + for (let t = t0; t <= endMs; t += stepMs) { + let e2 = 0.0; + for (const dose of carrierDoses) { + if (dose.timestamp > t) continue; + const dtH = (t - dose.timestamp) / 3600000; + const tr = carriers.find((x) => x.id === dose.treatmentId); + e2 += EstrannaiseModels.sampleWithParams( + tr.esterType, dtH, paramsByEster.get(tr.esterType), + ) * dose.doseAmount; + } + curve.push({ timestamp: t, e2, t: 0.0 }); + } + if (curve.length >= 2) cloud.push(curve); + } + return cloud; +} diff --git a/js/pk/estrannaise-models.js b/js/pk/estrannaise-models.js new file mode 100644 index 0000000..270c20b --- /dev/null +++ b/js/pk/estrannaise-models.js @@ -0,0 +1,141 @@ +/** + * ───────────────────────────────────────────────────────────────────────────── + * Modèle **Estrannaise analytique** (v1.9.0, miroir fidèle de + * `pk/EstrannaiseModels.kt`) — remplace définitivement les tables horaires + * ODS pour le modèle ESE. + * + * SOURCE ORIGINELLE : https://github.com/WHSAH/estrannaise.js/ — le modèle 3 + * compartiments avec les paramètres d'ajustement **publiés par Estrannaise** + * (t en JOURS, dose en mg → pg/mL) : + * + * C(t) = dose · d · k1·k2 · [ e^(−k1·t)/((k1−k2)(k1−k3)) + * − e^(−k2·t)/((k1−k2)(k2−k3)) + * + e^(−k3·t)/((k1−k3)(k2−k3)) ] + * + * FIDÉLITÉ (épinglée par EstrannaiseModelsTest) : cette forme close + * reproduit les anciennes tables ODS à l'identique (RMS 0,00 sur 0→200 j, + * écart de pic ≤ 0,1 %) — l'ODS n'était que l'échantillonnage horaire de + * ces formules. Décision v1.9.0 : « tous les modèles ont maintenant leurs + * sources originelles — on abandonne complètement les liens avec le + * fichier ODS ». + * + * NUAGE D'INCERTITUDE (v1.9.0, exclusif ESE) : Estrannaise publie le + * **posterior MCMC** de ses paramètres (313 échantillons par ester — + * `assets/mcmc_samples.json`, 48 Ko, fetché au démarrage). Le graphique + * peut dessiner un nuage diffus de courbes montrant la plage + * d'imprécision du modèle. TFS/WHSAH ne publient pas de posterior. + * + * PUR sauf [init] (fetch de l'asset MCMC) — la formule est testable en + * Node (tests/estrannaise-models.test.js). + * ───────────────────────────────────────────────────────────────────────────── + */ + +// ── Paramètres d'ajustement publiés par Estrannaise (src/modeldata.js) ────── +// Clés = clés esters de l'app. Mapping depuis le repo : « EV im »→EV, +// « EUn im »→EU, « EEn im »→EEn, « EC im »→EC, « EB im »→EB, +// « EUn casubq »→EUCS (nouveau code ester v1.9.0). +const PK_PARAMETERS = { + EV: [478.0, 0.236, 4.85, 1.24], + EU: [471.5, 0.01729, 6.528, 2.285], + EEN: [191.4, 0.119, 0.601, 0.402], + EC: [246.0, 0.0825, 3.57, 0.669], + EB: [1893.1, 0.67, 61.5, 4.34], + EUCS: [16.15, 0.046, 0.022, 0.101], +}; + +let mcmc = null; // posterior MCMC (chargé via init()) — { ester: [[d,k1,k2,k3] × 313] } + +/** + * Fetch de l'asset `assets/mcmc_samples.json` (48 Ko) puis init — appelé au + * démarrage par app.js (remplace l'ancien fetch des tables ODS, 550 Ko). + * Silencieux en cas d'échec (le nuage restera simplement vide — les courbes + * nommées ne dépendent pas du posterior). + */ +export async function init() { + try { + const resp = await fetch('assets/mcmc_samples.json'); + if (resp.ok) initWithJson(await resp.text()); + } catch (_e) { + // best-effort : sans MCMC, pas de nuage — les courbes restent calculables + } +} + +export function hasModel(ester) { + return Object.prototype.hasOwnProperty.call(PK_PARAMETERS, String(ester).toUpperCase()); +} + +/** Les paramètres de l'ester, ou null (lookup insensible à la casse). */ +export function model(ester) { + const key = String(ester).toUpperCase(); + if (!hasModel(key)) return null; + const [d, k1, k2, k3] = PK_PARAMETERS[key]; + return { + d, k1, k2, k3, + /** t½ terminale ANALYTIQUE : la phase la plus lente domine la queue. */ + get terminalHalfLifeDays() { + return Math.log(2) / Math.min(k1, k2, k3); + }, + }; +} + +/** Forme close 3C (t en JOURS) — cas général + 3 cas dégénérés (taux égaux). */ +function curveDays(t, dose, m) { + if (t < 0) return 0.0; + let ret = 0.0; + if (dose > 0 && m.d > 0) { + const { k1, k2, k3 } = m; + if (k1 === k2 && k2 === k3) { + ret += dose * m.d * k1 * k1 * t * t * Math.exp(-k1 * t) / 2; + } else if (k1 === k2 && k2 !== k3) { + ret += dose * m.d * k1 * k1 * (Math.exp(-k3 * t) - Math.exp(-k1 * t) * (1 + (k1 - k3) * t)) / (k1 - k3) / (k1 - k3); + } else if (k1 !== k2 && k1 === k3) { + ret += dose * m.d * k1 * k2 * (Math.exp(-k2 * t) - Math.exp(-k1 * t) * (1 + (k1 - k2) * t)) / (k1 - k2) / (k1 - k2); + } else if (k1 !== k2 && k2 === k3) { + ret += dose * m.d * k1 * k2 * (Math.exp(-k1 * t) - Math.exp(-k2 * t) * (1 - (k1 - k2) * t)) / (k1 - k2) / (k1 - k2); + } else { + ret += dose * m.d * k1 * k2 * ( + Math.exp(-k1 * t) / (k1 - k2) / (k1 - k3) + - Math.exp(-k2 * t) / (k1 - k2) / (k2 - k3) + + Math.exp(-k3 * t) / (k1 - k3) / (k2 - k3) + ); + } + } + return Number.isNaN(ret) ? 0.0 : ret; +} + +/** + * Réponse normalisée (pg/mL PAR mg) à dtHours — t converti en jours ici. + * dtHours ≤ 0 → 0. + */ +export function sample(ester, dtHours) { + const m = model(ester); + if (!m || dtHours <= 0) return 0.0; + return curveDays(dtHours / 24, 1.0, m); +} + +/** Courbe avec un jeu de paramètres DONNÉ (échantillon MCMC) — nuage. */ +export function sampleWithParams(ester, dtHours, p) { + if (dtHours <= 0) return 0.0; + return curveDays(dtHours / 24, 1.0, p); +} + +/** + * Charge le posterior MCMC depuis `assets/mcmc_samples.json` (appelé au + * démarrage par app.js — remplace le fetch des tables ODS). + * @param {string} json contenu JSON brut + */ +export function initWithJson(json) { + const raw = JSON.parse(json); + // Mapper vers des objets {d, k1, k2, k3} (miroir du Param Kotlin) — les + // tableaux bruts du JSON ne portent pas les noms de champs + const parsed = {}; + for (const [ester, arr] of Object.entries(raw)) { + parsed[ester.toUpperCase()] = arr.map(([d, k1, k2, k3]) => ({ d, k1, k2, k3 })); + } + mcmc = parsed; +} + +/** Les échantillons MCMC d'un ester (vide si non chargé / inconnu). */ +export function mcmcSamples(ester) { + return (mcmc && mcmc[String(ester).toUpperCase()]) || []; +} diff --git a/js/pk/index.js b/js/pk/index.js index 6cf9e3e..f68a6f5 100644 --- a/js/pk/index.js +++ b/js/pk/index.js @@ -11,10 +11,12 @@ export * from './pk-extrema.js'; export * as LabTrajectoryModel from './lab-trajectory-model.js'; export { computeLabAnchoredCurve, ratioAt, extensionHorizonEndMs } from './lab-trajectory-model.js'; export * as LabTiming from './lab-timing.js'; +export * as EstrannaiseModels from './estrannaise-models.js'; +export { sample as estrannaiseSample, hasModel as estrannaiseHasModel } from './estrannaise-models.js'; export { nextBloodDrawRecommendation, shouldSuggestPosology } from './lab-timing.js'; +export { compute as computeEstrannaiseCloud, DEFAULT_NB_CURVES } from './estrannaise-cloud.js'; export * from './chart-helpers.js'; export * as Alerts from './alerts.js'; -export * as PKProfileStore from './pk-profile-store.js'; export * as TransfemScienceModels from './transfem-science-models.js'; export * as WhsahModels from './whsah-models.js'; export * as PKPresets from './presets.js'; diff --git a/js/pk/lab-timing.js b/js/pk/lab-timing.js index 14da394..ce88404 100644 --- a/js/pk/lab-timing.js +++ b/js/pk/lab-timing.js @@ -35,6 +35,7 @@ */ import { computeCurve, generateForecastDoses, TConfig, usesProfileModel, doseEster } from './pk-engine.js'; +import * as EstrannaiseModels from './estrannaise-models.js'; import { model as tfsModel } from './transfem-science-models.js'; import { model as whsahModel } from './whsah-models.js'; import * as pkProfileStore from './pk-profile-store.js'; @@ -77,7 +78,8 @@ export function nextBloodDrawRecommendation(treatments, doseLogs, labs, nowMs = let tHalfDays = null; if (carrier.pkModel === 'TFS') tHalfDays = tfsModel(carrier.esterType)?.terminalHalfLifeDays ?? null; else if (carrier.pkModel === 'WHS') tHalfDays = whsahModel(carrier.esterType)?.terminalHalfLifeDays ?? null; - else if (carrier.pkModel === 'ESE') tHalfDays = pkProfileStore.terminalHalfLifeDays(carrier.esterType, 'ESE'); + // v1.9.0 : ESE analytique (estrannaise.js) — t½ terminale analytique + else if (carrier.pkModel === 'ESE') tHalfDays = EstrannaiseModels.model(carrier.esterType)?.terminalHalfLifeDays ?? null; if (tHalfDays === null || tHalfDays === undefined) return null; // ── 3) Début du régime courant + date de stabilisation ──────────────────── diff --git a/js/pk/pk-engine.js b/js/pk/pk-engine.js index d6cbb50..a7015cb 100644 --- a/js/pk/pk-engine.js +++ b/js/pk/pk-engine.js @@ -26,7 +26,7 @@ import * as TransfemScienceModels from './transfem-science-models.js'; import * as WhsahModels from './whsah-models.js'; -import * as PKProfileStore from './pk-profile-store.js'; +import { sample as estrannaiseSample, hasModel as estrannaiseHasModel, model as estrannaiseModel } from './estrannaise-models.js'; /** Une heure en ms. */ export const HOUR_MS = 3600000; @@ -140,7 +140,7 @@ export function doseEster(treatment, dose) { * 1. traitement à PROFIL PK (injection + ester ≠ NONE) : * - TFS + ester couvert par le V3C → TransfemScienceModels ; * - WHSAH + ester couvert par le fit Mona → WhsahModels ; - * - sinon → tables ODS via PKProfileStore (ester sans modèle → 0) ; + * - ESE → forme close estrannaise.js (v1.9.0, analytique) ; ester sans modèle → 0 ; * 2. sinon → Bateman (gel / patch / oral / custom). * * `modelOverride` force ESE/TFS/WHS pour CE calcul (le graphique dessine les @@ -173,7 +173,10 @@ export function concentrationOfDose(treatment, dose, queryTimeMs, bateman = null if (mod === PKModels.WHSAH && WhsahModels.hasModel(ester)) { return WhsahModels.sample(ester, dtH) * mg; } - return PKProfileStore.sample(ester, mod, dtH) * mg; + if (mod === 'ESE' && estrannaiseHasModel(ester)) { + return estrannaiseSample(ester, dtH) * mg; + } + return 0.0; // ester sans modèle (ni TFS ni WHSAH ni ESE analytique) } } @@ -207,7 +210,9 @@ export function cutoffHours(treatment) { } else if (mod === PKModels.TRANSFEM_SCIENCE && TransfemScienceModels.hasModel(treatment.esterType)) { profileH = TransfemScienceModels.model(treatment.esterType).terminalHalfLifeDays * 24.0 * 10.0; } else { - profileH = PKProfileStore.profileLength(treatment.esterType, mod); + // v1.9.0 : ESE analytique → t½ terminale analytique (comme TFS/WHS), + // plus la longueur de table ODS + profileH = 10 * 24 * estrannaiseModel(treatment.esterType).terminalHalfLifeDays; } } const batemanH = usesProfileModel(treatment) ? 0.0 : 30.0 * treatment.eliminationHalfLifeHours; diff --git a/js/ui/app.js b/js/ui/app.js index 386c727..feabb5d 100644 --- a/js/ui/app.js +++ b/js/ui/app.js @@ -3,7 +3,7 @@ * HormoneTrack Web — shell applicatif (portage de HormoneTrackApp.kt + * MainActivity.kt + HormoneTrackRoot.kt). * - * - attend l'initialisation de PKProfileStore (fetch de l'asset) ; + * - attend l'initialisation de l'asset MCMC (nuage d'incertitude ESE, v1.9.0) ; * - routing par hash (#home/#chart/#doses/#labs/#treatments/#settings/ * #treatment-edit/{id}) — permet la navigation headless et le lien profond ; * - NavigationBar 5 onglets (barre masquée sur settings/éditeur, miroir @@ -20,7 +20,7 @@ * ───────────────────────────────────────────────────────────────────────────── */ -import * as PKProfileStore from '../pk/pk-profile-store.js'; +import * as EstrannaiseModels from '../pk/estrannaise-models.js'; import { store } from '../data/store.js'; import * as AppLog from '../util/app-log.js'; import { isVersionNewer, sectionsSince } from '../util/changelog.js'; @@ -57,7 +57,9 @@ async function main() { // 4) Asset PK (équivalent de PKProfileStore.init(context) dans // HormoneTrackApp.onCreate) — les courbes ne sont calculées qu'après ; // le re-rendu ci-dessous remplace le « Chargement… » par les données. - await PKProfileStore.init(); + // v1.9.0 : l'asset MCMC (nuage ESE, 48 Ko) remplace le fetch des tables + // ODS (550 Ko) — démarrage plus rapide, runtime 100 % sources analytiques + await EstrannaiseModels.init(); // 5) Langue au démarrage (miroir MainActivity : setApplicationLocales) document.documentElement.lang = resolveLocale(store.getSettings().language); @@ -154,14 +156,6 @@ function renderRoute() { const preserveChartState = route === 'chart' && lastRoute === 'chart'; lastRoute = route; - // Écran de chargement tant que l'asset PK n'est pas chargé (les écrans - // afficheraient « aucune donnée » à tort — les profils valent 0 avant init). - if (!PKProfileStore.isInitialized()) { - contentEl.textContent = ''; - contentEl.appendChild(el('p', { class: 'hint', style: 'padding:24px 0;' }, t('loading'))); - return; - } - // Marqueur E2E : l'app est prête (asset chargé, écran rendu) — utilisé par // scripts/e2e.mjs pour attendre la fin du rendu (plus de course au screenshot). document.body.setAttribute('data-ready', '1'); @@ -364,6 +358,41 @@ function maybeLoadDemoData() { notes: isLastPair ? 'DHT : 12 ng/dL' : null, }); }); + // v1.9.0 : un 2ᵉ traitement E2 à modèle ESE (EV) avec 2 doses — permet + // de démontrer/tester le nuage d'incertitude ESE et la couverture + // multi-esters sans toucher au traitement EEn (TFS) principal. + const evId = store.upsertTreatment({ + name: 'EV — Estrannaise (démo)', + type: 'ESTRADIOL', + route: 'INJECTION_IM', + doseAmount: 4.0, + doseUnit: 'mg', + isActive: true, + notes: null, + esterType: 'EV', + pkModel: 'ESE', + absorptionHours: 45, + eliminationHalfLifeHours: 70, + bioavailabilityFraction: 1, + scaleFactor: 1.0, + forecastIntervalDays: null, + reminderHour: null, + reminderMinute: null, + reminderEnabled: false, + calendarEventId: null, + createdAt: now - 60 * DAY, + }); + // doses vieilles de 10-24 j : contribution résiduelle au présent (la + // courbe EV/SE fait partie du mini-chart sans saturer le niveau actuel) + for (const k of [24, 17, 10]) { + store.upsertDoseLog({ + treatmentId: evId, + timestamp: now - k * DAY, + doseAmount: 4.0, + notes: null, + esterType: null, + }); + } AppLog.log('demo', 'données de démonstration chargées (?demo=1)'); } diff --git a/js/ui/chart.js b/js/ui/chart.js index 160fd84..6ce0275 100644 --- a/js/ui/chart.js +++ b/js/ui/chart.js @@ -31,7 +31,7 @@ import { computeCurve, generateForecastDoses, autoCalibrated, TConfig, - computeLabAnchoredCurve, + computeLabAnchoredCurve, computeEstrannaiseCloud, } from '../pk/index.js'; import { stepForRange, defaultModelToggles, panDeltaHours, clampPanHours, @@ -124,6 +124,12 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { // demandée explicitement ; le chip n'est actif que si Lab track est ON // (miroir ChartScreen.kt). showLabTrackExtend: false, + // v1.9.0 : NUAGE D'INCERTITUDE du modèle ESE (posterior MCMC de + // estrannaise.js) — OFF par défaut, activable à volonté, ACTIVABLE + // SEULEMENT si le modèle ESE est affiché (exclusif à ce modèle — les + // fits TFS/WHSAH ne publient pas de posterior). Éteindre ESE coupe le + // nuage automatiquement (miroir ChartScreen.kt). + showCloud: false, panResidualHours: 0.0, // résiduel fractionnaire du pan (fix #62) togglesInitialized: false, }; @@ -253,7 +259,13 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { // Rangée 3 : toggles modèles superposables modelRow.textContent = ''; - modelRow.appendChild(filterChip(t('model_ese'), state.showEse, () => { state.showEse = !state.showEse; redraw(); })); + modelRow.appendChild(filterChip(t('model_ese'), state.showEse, () => { + state.showEse = !state.showEse; + // v1.9.0 : le nuage est exclusif à ESE — éteindre ESE éteint le nuage + // (sinon il flotterait sans sa courbe) + if (!state.showEse) state.showCloud = false; + redraw(); + })); modelRow.appendChild(filterChip(t('model_tfs'), state.showTfs, () => { state.showTfs = !state.showTfs; redraw(); })); modelRow.appendChild(filterChip(t('model_whs'), state.showWhs, () => { state.showWhs = !state.showWhs; redraw(); })); // v1.5.0 : courbe hybride ancrée sur les labs (off par défaut) @@ -262,6 +274,9 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { // défaut, SANS EFFET — donc désactivé — tant que Lab track est off : // la prolongation n'existe que comme extension de CETTE courbe) modelRow.appendChild(filterChip(t('show_lab_track_extend'), state.showLabTrackExtend, () => { state.showLabTrackExtend = !state.showLabTrackExtend; redraw(); }, !state.showLabTrack)); + // v1.9.0 : nuage d'incertitude (off par défaut, activable à volonté, + // SEULEMENT si ESE est affiché — même pattern que Prolonger/Tracé labs) + modelRow.appendChild(filterChip(t('show_cloud'), state.showCloud, () => { state.showCloud = !state.showCloud; redraw(); }, !state.showEse)); // ── Courbes par modèle sélectionné ───────────────────────────────────── const curves = []; @@ -277,8 +292,8 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { // ⚠️ Les DEUX clés doivent être SKIPPÉES par la boucle de légende // (leçon #63 Android : sinon le catchall imprime la légende TFS en // doublon) et avoir leurs entrées dédiées plus bas. + const step = stepForRange(state.rangeHours); // partagé : LAB + modèles (v1.9.0) if (state.showLabTrack) { - const step = stepForRange(state.rangeHours); const labCurve = computeLabAnchoredCurve( treatments, doseLogs, labResults, startMs, endMs, step, null, state.showLabTrackExtend, @@ -292,6 +307,16 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { curves.push(['LAB', labCurve.points]); } } + // v1.9.0 : NUAGE D'INCERTITUDE ESE — INDÉPENDANT du tracé labs (il ne + // dépend que de showCloud && showEse) : M courbes du posterior MCMC, cf + // EstrannaiseCloud. Clé 'CLOUD' skippée des légendes (leçon #63 miroir) + // et dessinée en alpha faible. + if (state.showCloud) { + const cloud = computeEstrannaiseCloud( + treatments, doseLogs, startMs, endMs, step, nowMs, + ); + if (cloud.length > 0) curves.push(['CLOUD', cloud.flat()]); + } if (state.showEse || state.showTfs || state.showWhs) { // Home utilise le modèle stocké ; le graphique calibre chaque modèle // avec SA prédiction (fix #60). Référence = auto du modèle TFS (les @@ -307,7 +332,6 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { const allDoses = doseLogs.concat(forecastDoses); // Pas d'échantillonnage adaptatif au zoom (v1.2.9) - const step = stepForRange(state.rangeHours); const addCurve = (model) => { const autoM = autoByModel.get(model); curves.push([model, computeCurve( @@ -354,6 +378,14 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { drawChart( canvas, curves.map(([model, pts]) => { + if (model === 'CLOUD') { + // v1.9.0 : nuage MCMC — chaque courbe individuelle est tracée + // en alpha faible ; PAS de labels/extrema (incertitude, pas des + // courbes nommées). Ne participe pas aux échelles via allPoints + // ? Si : allPoints inclut CLOUD — les échelles s'adaptent donc + // au nuage (cohérent : le nuage montre le range réel possible). + return { points: pts, e2Style: { color: 'rgba(194,24,91,0.12)', dashed: true }, tStyle: null, showExtrema: false }; + } if (model === 'LAB') { // v1.5.0 : Tracé labs = E2 rose foncé pointillé, PAS de courbe T // (série E2-only) et hors pics/creux (showExtrema=false) @@ -396,7 +428,7 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { // ⚠️ Les clés 'LAB' (v1.5.0) et 'LABX' (v1.6.0) sont SKIPPÉES // (légendes dédiées plus bas, fix #63 Android-miroir : sinon le // catchall imprime la légende TFS en doublon) - if (model === 'LAB' || model === 'LABX') continue; + if (model === 'LAB' || model === 'LABX' || model === 'CLOUD') continue; const st = seriesStyles(model); if (model === 'ESE') { legend.appendChild(legendLine(t('legend_ese_e2'), st.e2.color)); @@ -423,6 +455,12 @@ export function renderChart(container, ctx, { preserveState = false } = {}) { // si la série "LABX" existe (chip Prolonger actif ET horizon atteint // dans la fenêtre visible). Même condition pour les deux (factorisée) : // il ne peut jamais y avoir de courbe prolongée sans son avertissement. + // v1.9.0 : légende du nuage d'incertitude (ESE) — visible tant que + // le nuage est affiché (l'alpha faible le rend nettement secondaire) + if (state.showCloud && state.showEse + && curves.some(([m, pts]) => m === 'CLOUD' && pts.length >= 2)) { + legend.appendChild(el('div', { class: 'legend-muted' }, t('legend_cloud'))); + } const labExtendVisible = state.showLabTrack && state.showLabTrackExtend && curves.some(([m, pts]) => m === 'LABX' && pts.length >= 2); if (labExtendVisible) { diff --git a/js/ui/settings.js b/js/ui/settings.js index 077d1b2..a6fc2db 100644 --- a/js/ui/settings.js +++ b/js/ui/settings.js @@ -31,7 +31,7 @@ import { el, showDialog, field, switchRow, filterChip, toast } from './component * (APK + web au MÊME numéro, tags appariés `vX.Y.Z` + `vX.Y.Z-web`). * v1.4.10 = portage initial de l'Android v1.4.10. */ -export const WEB_VERSION = '1.8.1'; +export const WEB_VERSION = '1.9.0'; /** Parse un champ numérique FR (virgule → point) ; null si vide/invalide. */ function parseNumOrNull(text) { diff --git a/js/util/i18n.js b/js/util/i18n.js index 1decaa1..7004e23 100644 --- a/js/util/i18n.js +++ b/js/util/i18n.js @@ -194,6 +194,10 @@ const EN = { // v1.6.0 : prolongation du tracé labs au-delà du dernier lab (opt-in, // actif seulement quand Lab track est ON — miroir strings.xml Android) show_lab_track_extend: 'Extend', + // v1.9.0 : nuage d'incertitude du modèle ESE (posterior MCMC de + // estrannaise.js) — exclusif à ESE, off par défaut + show_cloud: 'Cloud', + legend_cloud: 'Dotted cloud = Estrannaise MCMC parameter uncertainty (ESE model only)', lab_track_extend_warning: '⚠ Simulation only, with no guarantee of matching reality: the extension extrapolates your model from your lab results — which can themselves be inaccurate. Trust your next blood test, not this curve.', back_to_present: 'Back to present', legend_ese_e2: 'E2 — Estrannaise (blue)', @@ -387,6 +391,8 @@ const FR = { // v1.6.0 : prolongation du tracé labs au-delà du dernier lab (opt-in, // actif seulement quand Tracé labs est ON — miroir strings.xml Android) show_lab_track_extend: 'Prolonger', + show_cloud: 'Nuage', + legend_cloud: 'Nuage pointillé = incertitude des paramètres MCMC de l\'Estrannaise (modèle ESE seul)', lab_track_extend_warning: '⚠ Simple simulation, sans garantie de correspondre au réel : la prolongation extrapole ton modèle à partir de tes résultats de laboratoire — qui peuvent eux-mêmes être erronés. Fie-toi à ta prochaine prise de sang, pas à cette courbe.', back_to_present: 'Revenir à maintenant', legend_ese_e2: 'E2 — Estrannaise (bleu)', diff --git a/scripts/e2e.mjs b/scripts/e2e.mjs index ac93ab3..88cac77 100644 --- a/scripts/e2e.mjs +++ b/scripts/e2e.mjs @@ -131,7 +131,7 @@ async function main() { ok(dialog !== null, 'dialog « Nouveautés » au premier lancement (markdown rendu)'); if (dialog) { const dlgText = await dialog.textContent(); - ok(dlgText.includes('Version 1.8.1'), 'dialog : section de la version courante'); + ok(dlgText.includes('Version 1.9.0'), 'dialog : section de la version courante'); const hasRenderedMd = await dialog.$('.md-body h3, .md-body strong'); ok(hasRenderedMd !== null, 'dialog : markdown RENDU (titres/gras), pas de brut'); await page.click('.dialog .actions button'); @@ -183,24 +183,25 @@ async function main() { } await page.waitForTimeout(400); // 1) Le chip « Prolonger » est DÉSACTIVÉ tant que « Tracé labs » est off - const extendDisabledBefore = await page.evaluate((lbl) => { - const b = [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === lbl); + const chipDisabled = (lbl) => page.evaluate((label) => { + const b = [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === label); return b ? /opacity:\s*0\.4/.test(b.getAttribute('style') || '') : null; - }, 'Prolonger'); + }, lbl); + const clickChip = (lbl) => page.evaluate((label) => { + [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === label)?.click(); + }, lbl); + const extendDisabledBefore = await chipDisabled('Prolonger'); ok(extendDisabledBefore === true, 'chip « Prolonger » désactivé tant que Tracé labs est off'); // 2) Active Tracé labs → la légende ancrée apparaît (sans avertissement) - await page.evaluate((lbl) => { - [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === lbl)?.click(); - }, 'Tracé labs'); + await clickChip('Tracé labs'); + await page.waitForTimeout(400); await page.waitForTimeout(400); const labTrackText = await page.textContent('main.content'); ok(labTrackText.includes('E2 ancrée sur tes labs'), 'légende « Tracé labs » (ancrée) affichée'); ok(!labTrackText.includes('Simple simulation, sans garantie'), 'pas d\'avertissement tant que la prolongation est off'); // 3) Active « Prolonger » → légende prolongée + AVERTISSEMENT VISIBLE - await page.evaluate((lbl) => { - [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === lbl)?.click(); - }, 'Prolonger'); + await clickChip('Prolonger'); await page.waitForTimeout(400); const extendText = await page.textContent('main.content'); ok(extendText.includes('Tracé labs prolongé'), 'légende de la partie prolongée affichée'); @@ -209,15 +210,50 @@ async function main() { ok(extendText.includes('qui peuvent eux-mêmes être erronés'), 'avertissement : les résultats de lab peuvent être erronés'); // 4) Désactive « Prolonger » → avertissement ET légende prolongée disparaissent - await page.evaluate((lbl) => { - [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === lbl)?.click(); - }, 'Prolonger'); + await clickChip('Prolonger'); await page.waitForTimeout(400); const offText = await page.textContent('main.content'); ok(!offText.includes('Tracé labs prolongé') && !offText.includes('Simple simulation, sans garantie'), 'désactivation → légende prolongée + avertissement disparaissent'); await page.screenshot({ path: join(SHOTS, 'e2e-chart-extend.png') }); + // ── 2.quater NUAGE D'INCERTITUDE (v1.9.0, exclusif ESE) ──────────────── + // La démo a maintenant 2 traitements E2 (EEn TFS + EV ESE) → toggles + // alignés : ESE et TFS ON par défaut (v1.4.7) → le chip Nuage est + // ACTIVABLE dès le départ. Séquence : activer Nuage → légende visible ; + // désactiver ESE → le nuage se coupe AUTOMATIQUEMENT (exclusivité) ; + // réactiver ESE → nuage de retour. + console.log('── Nuage d incertitude (#chart, v1.9.0) ──'); + const cloudIsSelected = () => page.evaluate(() => + [...document.querySelectorAll('.chip')] + .some((x) => x.textContent.trim() === 'Nuage' && x.classList.contains('selected'))); + const cloudIsDisabled = () => page.evaluate(() => { + const b = [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === 'Nuage'); + return b ? /opacity:\s*0\.4/.test(b.getAttribute('style') || '') : null; + }); + // ESE est ON à ce stade (scénario 2.bis) → Nuage activable + await clickChip('Nuage'); + await page.waitForTimeout(500); + ok(await cloudIsSelected() === true, 'chip « Nuage » activé (ESE affiché)'); + const cloudText1 = await page.textContent('main.content'); + ok(cloudText1.includes('Nuage pointillé = incertitude des paramètres MCMC'), + 'légende du nuage MCMC affichée (ESE + Nuage ON)'); + // Désactiver ESE → le nuage se coupe AUTOMATIQUEMENT (exclusivité) + await clickChip('Estrannaise'); // ESE OFF + await page.waitForTimeout(500); + ok(await cloudIsSelected() === false, + 'désactiver ESE → le nuage se coupe automatiquement (exclusivité ESE)'); + const offAfter = await page.evaluate(() => { + const b = [...document.querySelectorAll('.chip')].find((x) => x.textContent.trim() === 'Nuage'); + return b ? /opacity:\s*0\.4/.test(b.getAttribute('style') || '') : null; + }); + ok(offAfter === true, 'chip « Nuage » redevient désactivé sans ESE'); + // Réactiver ESE → Nuage ré-activable + await clickChip('Estrannaise'); + await page.waitForTimeout(400); + ok(await cloudIsDisabled() === false, 'réactiver ESE → Nuage redevient activable'); + await page.screenshot({ path: join(SHOTS, 'e2e-chart-cloud.png') }); + // ── 2.ter PERSISTANCE de l'état du graphique (v1.6.1) ─────────────────── // Bug remonté : les options se réinitialisaient « toutes seules » car le // tick minute / une mutation du store / un resize re-créaient l'écran @@ -298,7 +334,7 @@ async function main() { await page.waitForTimeout(300); text = await page.textContent('main.content'); ok(text.includes('Langue'), 'Paramètres : carte langue'); - ok(text.includes('Version 1.8.1 (web)'), 'Paramètres : version affichée'); + ok(text.includes('Version 1.9.0 (web)'), 'Paramètres : version affichée'); ok(text.includes('100 % local'), 'Paramètres : note vie privée'); await page.screenshot({ path: join(SHOTS, 'e2e-settings.png') }); diff --git a/tests/estrannaise-cloud.test.js b/tests/estrannaise-cloud.test.js new file mode 100644 index 0000000..773bb7d --- /dev/null +++ b/tests/estrannaise-cloud.test.js @@ -0,0 +1,69 @@ +/** + * Tests du NUAGE D'INCERTITUDE (v1.9.0 — miroir de `EstrannaiseCloudTest.kt`, + * `js/pk/estrannaise-cloud.js`) : 32 courbes par défaut, dispersion réelle + * entre courbes, fenêtre respectée, exclusivité ESE (TFS/oral → vide). + */ + +import { test, describe, before } from 'node:test'; +import { join } from 'node:path'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { initProfiles, makeTreatment, makeDose, DAY_MS, WEB_ROOT } from './helpers.js'; +import { compute } from '../js/pk/estrannaise-cloud.js'; +import { initWithJson as initMcmc } from '../js/pk/estrannaise-models.js'; + +const NOW = 1_790_000_000_000; + +function ese() { + return makeTreatment({ + name: 'EEn ESE', type: 'ESTRADIOL', route: 'INJECTION_IM', + doseAmount: 5.0, doseUnit: 'mg', esterType: 'EEN', pkModel: 'ESE', + forecastIntervalDays: 7.0, isActive: true, + }); +} + +function doses() { + return [4, 3, 2, 1].map((k) => makeDose(NOW - k * DAY_MS, 5.0)); +} + +describe('EstrannaiseCloud web (miroir Android v1.9.0)', () => { + before(() => { + initProfiles(); + // Le nuage exige le posterior MCMC chargé (313 échantillons/ester) + initMcmc(readFileSync(join(WEB_ROOT, 'assets/mcmc_samples.json'), 'utf8')); + }); + + test('32 courbes avec dispersion réelle entre elles', () => { + const cloud = compute([ese()], doses(), NOW - 30 * DAY_MS, NOW, 3_600_000, NOW); + assert.equal(cloud.length, 32); + assert.ok(cloud.every((c) => c.length >= 2)); + const peaks = [...new Set(cloud.map((c) => Math.max(...c.map((p) => p.e2))))]; + assert.ok(peaks.length >= 8, `les courbes divergent (${peaks.length} maxima distincts)`); + }); + + test('le nuage reste dans la fenêtre demandée', () => { + const start = NOW - 10 * DAY_MS; + const end = NOW; + const cloud = compute([ese()], doses(), start, end, 3_600_000, NOW); + assert.ok(cloud.every((c) => c.every((p) => p.timestamp >= start && p.timestamp <= end))); + }); + + test('exclusivité ESE : TFS et oral produisent un nuage vide', () => { + const tfs = { ...ese(), pkModel: 'TFS' }; + assert.equal(compute([tfs], doses(), NOW - 30 * DAY_MS, NOW, 3_600_000, NOW).length, 0); + const oral = makeTreatment({ + name: 'CPA', type: 'ANTI_ANDROGEN', route: 'ORAL', + doseAmount: 12.5, doseUnit: 'mg', esterType: 'NONE', + forecastIntervalDays: 2.0, isActive: true, + }); + assert.equal(compute([oral], doses(), NOW - 30 * DAY_MS, NOW, 3_600_000, NOW).length, 0); + }); + + test('aucune dose sur le porteur → nuage vide', () => { + assert.equal(compute([ese()], [], NOW - 30 * DAY_MS, NOW, 3_600_000, NOW).length, 0); + }); + + test('nbCurves < 2 → nuage vide', () => { + assert.equal(compute([ese()], doses(), NOW - 30 * DAY_MS, NOW, 3_600_000, NOW, 1).length, 0); + }); +}); diff --git a/tests/estrannaise-models.test.js b/tests/estrannaise-models.test.js new file mode 100644 index 0000000..23f1575 --- /dev/null +++ b/tests/estrannaise-models.test.js @@ -0,0 +1,96 @@ +/** + * Tests du modèle **Estrannaise analytique** (v1.9.0 — miroir de + * `EstrannaiseModelsTest.kt`) : forme close 3C publiée par estrannaise.js, + * fidélité aux tables ODS (RMS ≈ 0), cas dégénérés, MCMC 313, t½ analytique. + */ + +import { test, describe, before } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { initProfiles, WEB_ROOT } from './helpers.js'; +import { + sample, hasModel, model, mcmcSamples, initWithJson, sampleWithParams, +} from '../js/pk/estrannaise-models.js'; + +describe('EstrannaiseModels web (miroir Android v1.9.0)', () => { + before(() => { + initProfiles(); // tables ODS (référence de fidélité, src/test side) + const mcmc = readFileSync(join(WEB_ROOT, 'assets/mcmc_samples.json'), 'utf8'); + initWithJson(mcmc); + }); + + test('FIDÉLITÉ : la forme close reproduit les tables ODS (RMS ≈ 0)', () => { + const profiles = JSON.parse( + readFileSync(join(WEB_ROOT, 'assets/pk_profiles.json'), 'utf8'), + ).profiles; + for (const ester of ['EV', 'EU', 'EEN']) { + const key = Object.keys(profiles) + .find((k) => k.toLowerCase().startsWith(ester.toLowerCase() + '_') && k.toLowerCase().endsWith('ese')); + const arr = profiles[key]; + let maxAbs = 0; + let sumSq = 0; + for (let h = 0; h <= 4800; h++) { + const diff = sample(ester, h) - arr[h]; + maxAbs = Math.max(maxAbs, Math.abs(diff)); + sumSq += diff * diff; + } + const rms = Math.sqrt(sumSq / 4801); + assert.ok(maxAbs <= 0.01 && rms <= 0.01, `${ester} : maxAbs=${maxAbs} rms=${rms}`); + } + }); + + test('les pics publiés sont reproduits (61,12 / 3,44 / 31,35 pg/mL/mg)', () => { + const expects = [ + ['EV', 61.12], ['EU', 3.44], ['EEN', 31.35], + ]; + for (const [ester, peakExpect] of expects) { + let peak = 0; + for (let t = 0; t <= 200; t += 0.25 / 24) { + peak = Math.max(peak, sample(ester, t * 24)); + } + assert.ok( + Math.abs(peak - peakExpect) <= peakExpect * 0.002, + `pic ${ester} = ${peak} (attendu ${peakExpect} ±0,2 %)`, + ); + } + }); + + test('taux dégénérés : solutions limites sans NaN ni négatif', () => { + for (const p of [ + { d: 478, k1: 0.236, k2: 0.236, k3: 1.24 }, + { d: 478, k1: 0.236, k2: 1.24, k3: 0.236 }, + { d: 478, k1: 0.236, k2: 1.24, k3: 1.24 }, + { d: 478, k1: 0.5, k2: 0.5, k3: 0.5 }, + ]) { + for (const t of [0.5, 1.0, 24.0, 240.0, 2400.0]) { + const v = sampleWithParams('EV', t, p); + assert.ok(v >= 0 && !Number.isNaN(v), `finie et ≥ 0 (t=${t})`); + } + } + }); + + test('MCMC : 313 échantillons par ester injectable (6 esters)', () => { + for (const ester of ['EV', 'EU', 'EEN', 'EC', 'EB', 'EUCS']) { + assert.equal(mcmcSamples(ester).length, 313, `posterior ${ester}`); + assert.notEqual( + mcmcSamples(ester)[0].d, mcmcSamples(ester)[312].d, + 'le posterior couvre une plage', + ); + } + }); + + test('t½ terminale ANALYTIQUE : EV = ln2/0,236 ≈ 2,94 j', () => { + const tHalf = model('EV').terminalHalfLifeDays; + assert.ok(Math.abs(tHalf - Math.log(2) / 0.236) < 1e-12); + }); + + test('normalisation par mg + gardes (dt ≤ 0, ester inconnu, EUCS couvert)', () => { + assert.equal(sample('EEN', 0), 0); + assert.equal(sample('EEN', -1), 0); + assert.equal(sample('XXX', 24), 0); + assert.ok(sample('EUCS', 24) > 0); + assert.equal(hasModel('XXX'), false); + assert.equal(hasModel('EUCS'), true); + }); +});