You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2016/11/27 10:28:11 UTC

[14/50] [abbrv] kylin git commit: KYLIN-2202 fix the conflict between KYLIN-1851 and KYLIN-2202. Remove some useless MR files.

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctColumnsReducer2.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctColumnsReducer2.java b/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctColumnsReducer2.java
deleted file mode 100644
index b5aeef6..0000000
--- a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctColumnsReducer2.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-package org.apache.kylin.engine.mr.steps.fdc2;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.io.IOUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FSDataOutputStream;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.io.NullWritable;
-import org.apache.hadoop.io.Text;
-import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.common.util.ByteArray;
-import org.apache.kylin.common.util.Bytes;
-import org.apache.kylin.cube.CubeInstance;
-import org.apache.kylin.cube.CubeManager;
-import org.apache.kylin.cube.model.CubeDesc;
-import org.apache.kylin.engine.mr.KylinReducer;
-import org.apache.kylin.engine.mr.common.AbstractHadoopJob;
-import org.apache.kylin.engine.mr.common.BatchConstants;
-import org.apache.kylin.engine.mr.common.CubeStatsWriter;
-import org.apache.kylin.measure.hllc.HyperLogLogPlusCounter;
-import org.apache.kylin.metadata.model.TblColRef;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- */
-public class FactDistinctColumnsReducer2 extends KylinReducer<SelfDefineSortableKey, Text, NullWritable, Text> {
-
-    private List<TblColRef> columnList;
-    private String statisticsOutput = null;
-    private List<Long> baseCuboidRowCountInMappers;
-    protected Map<Long, HyperLogLogPlusCounter> cuboidHLLMap = null;
-    protected long baseCuboidId;
-    protected CubeDesc cubeDesc;
-    private long totalRowsBeforeMerge = 0;
-    private int samplingPercentage;
-    private List<ByteArray> colValues;
-    private TblColRef col = null;
-    private boolean isStatistics = false;
-    private boolean isPartitionCol = false;
-    private KylinConfig cubeConfig;
-    protected static final Logger logger = LoggerFactory.getLogger(FactDistinctColumnsReducer2.class);
-
-    @Override
-    protected void setup(Context context) throws IOException {
-        super.bindCurrentConfiguration(context.getConfiguration());
-
-        Configuration conf = context.getConfiguration();
-        KylinConfig config = AbstractHadoopJob.loadKylinPropsAndMetadata();
-        String cubeName = conf.get(BatchConstants.CFG_CUBE_NAME);
-        CubeInstance cube = CubeManager.getInstance(config).getCube(cubeName);
-        cubeConfig = cube.getConfig();
-        cubeDesc = cube.getDescriptor();
-        columnList = CubeManager.getInstance(config).getAllDictColumnsOnFact(cubeDesc);
-
-        boolean collectStatistics = Boolean.parseBoolean(conf.get(BatchConstants.CFG_STATISTICS_ENABLED));
-        int numberOfTasks = context.getNumReduceTasks();
-        int taskId = context.getTaskAttemptID().getTaskID().getId();
-
-        if (collectStatistics && (taskId == numberOfTasks - 1)) {
-            // hll
-            isStatistics = true;
-            statisticsOutput = conf.get(BatchConstants.CFG_STATISTICS_OUTPUT);
-            baseCuboidRowCountInMappers = Lists.newArrayList();
-            cuboidHLLMap = Maps.newHashMap();
-            samplingPercentage = Integer.parseInt(context.getConfiguration().get(BatchConstants.CFG_STATISTICS_SAMPLING_PERCENT));
-        } else if (collectStatistics && (taskId == numberOfTasks - 2)) {
-            // partition col
-            isStatistics = false;
-            isPartitionCol = true;
-            col = cubeDesc.getModel().getPartitionDesc().getPartitionDateColumnRef();
-            colValues = Lists.newLinkedList();
-        } else {
-            // col
-            isStatistics = false;
-            isPartitionCol = false;
-            col = columnList.get(taskId);
-            colValues = Lists.newLinkedList();
-        }
-    }
-
-    @Override
-    protected void doReduce(SelfDefineSortableKey skey, Iterable<Text> values, Context context) throws IOException, InterruptedException {
-        Text key = skey.getText();
-        if (isStatistics == true) {
-            // for hll
-            long cuboidId = Bytes.toLong(key.getBytes(), 1, Bytes.SIZEOF_LONG);
-            for (Text value : values) {
-                HyperLogLogPlusCounter hll = new HyperLogLogPlusCounter(cubeConfig.getCubeStatsHLLPrecision());
-                ByteBuffer bf = ByteBuffer.wrap(value.getBytes(), 0, value.getLength());
-                hll.readRegisters(bf);
-
-                totalRowsBeforeMerge += hll.getCountEstimate();
-
-                if (cuboidId == baseCuboidId) {
-                    baseCuboidRowCountInMappers.add(hll.getCountEstimate());
-                }
-
-                if (cuboidHLLMap.get(cuboidId) != null) {
-                    cuboidHLLMap.get(cuboidId).merge(hll);
-                } else {
-                    cuboidHLLMap.put(cuboidId, hll);
-                }
-            }
-        } else if (isPartitionCol == true) {
-            // for partition col min/max value
-            ByteArray value = new ByteArray(Bytes.copy(key.getBytes(), 1, key.getLength() - 1));
-            if (colValues.size() > 1) {
-                colValues.set(1, value);
-            } else {
-                colValues.add(value);
-            }
-        } else {
-            colValues.add(new ByteArray(Bytes.copy(key.getBytes(), 1, key.getLength() - 1)));
-            if (colValues.size() == 1000000) { //spill every 1 million
-                logger.info("spill values to disk...");
-                outputDistinctValues(col, colValues, context);
-                colValues.clear();
-            }
-        }
-    }
-
-    private void outputDistinctValues(TblColRef col, Collection<ByteArray> values, Context context) throws IOException {
-        final Configuration conf = context.getConfiguration();
-        final FileSystem fs = FileSystem.get(conf);
-        final String outputPath = conf.get(BatchConstants.CFG_OUTPUT_PATH);
-        final Path outputFile = new Path(outputPath, col.getName());
-
-        FSDataOutputStream out = null;
-        try {
-            if (fs.exists(outputFile)) {
-                out = fs.append(outputFile);
-                logger.info("append file " + outputFile);
-            } else {
-                out = fs.create(outputFile);
-                logger.info("create file " + outputFile);
-            }
-
-            for (ByteArray value : values) {
-                out.write(value.array(), value.offset(), value.length());
-                out.write('\n');
-            }
-        } finally {
-            IOUtils.closeQuietly(out);
-        }
-    }
-
-    @Override
-    protected void doCleanup(Context context) throws IOException, InterruptedException {
-
-        if (isStatistics == false) {
-            if (colValues.size() > 0) {
-                outputDistinctValues(col, colValues, context);
-                colValues.clear();
-            }
-        } else {
-            //output the hll info;
-            long grandTotal = 0;
-            for (HyperLogLogPlusCounter hll : cuboidHLLMap.values()) {
-                grandTotal += hll.getCountEstimate();
-            }
-            double mapperOverlapRatio = grandTotal == 0 ? 0 : (double) totalRowsBeforeMerge / grandTotal;
-            
-            int mapperNumber = baseCuboidRowCountInMappers.size();
-
-            writeMapperAndCuboidStatistics(context); // for human check
-            CubeStatsWriter.writeCuboidStatistics(context.getConfiguration(), new Path(statisticsOutput), //
-                    cuboidHLLMap, samplingPercentage, mapperNumber, mapperOverlapRatio);
-        }
-    }
-
-    private void writeMapperAndCuboidStatistics(Context context) throws IOException {
-        Configuration conf = context.getConfiguration();
-        FileSystem fs = FileSystem.get(conf);
-        FSDataOutputStream out = fs.create(new Path(statisticsOutput, BatchConstants.CFG_STATISTICS_CUBE_ESTIMATION_FILENAME));
-
-        try {
-            String msg;
-
-            List<Long> allCuboids = Lists.newArrayList();
-            allCuboids.addAll(cuboidHLLMap.keySet());
-            Collections.sort(allCuboids);
-
-            msg = "Total cuboid number: \t" + allCuboids.size();
-            writeLine(out, msg);
-            msg = "Samping percentage: \t" + samplingPercentage;
-            writeLine(out, msg);
-
-            writeLine(out, "The following statistics are collected based on sampling data.");
-            writeLine(out, "Number of Mappers: " + baseCuboidRowCountInMappers.size());
-            for (int i = 0; i < baseCuboidRowCountInMappers.size(); i++) {
-                if (baseCuboidRowCountInMappers.get(i) > 0) {
-                    msg = "Base Cuboid in Mapper " + i + " row count: \t " + baseCuboidRowCountInMappers.get(i);
-                    writeLine(out, msg);
-                }
-            }
-
-            long grantTotal = 0;
-            for (long i : allCuboids) {
-                grantTotal += cuboidHLLMap.get(i).getCountEstimate();
-                msg = "Cuboid " + i + " row count is: \t " + cuboidHLLMap.get(i).getCountEstimate();
-                writeLine(out, msg);
-            }
-
-            msg = "Sum of all the cube segments (before merge) is: \t " + totalRowsBeforeMerge;
-            writeLine(out, msg);
-
-            msg = "After merge, the cube has row count: \t " + grantTotal;
-            writeLine(out, msg);
-
-            if (grantTotal > 0) {
-                msg = "The mapper overlap ratio is: \t" + totalRowsBeforeMerge / grantTotal;
-                writeLine(out, msg);
-            }
-
-        } finally {
-            IOUtils.closeQuietly(out);
-        }
-    }
-
-    private void writeLine(FSDataOutputStream out, String msg) throws IOException {
-        out.write(msg.getBytes());
-        out.write('\n');
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctHiveColumnsMapper2.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctHiveColumnsMapper2.java b/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctHiveColumnsMapper2.java
deleted file mode 100644
index bdf631d..0000000
--- a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/FactDistinctHiveColumnsMapper2.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-package org.apache.kylin.engine.mr.steps.fdc2;
-
-import com.google.common.collect.Lists;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hasher;
-import com.google.common.hash.Hashing;
-import org.apache.hadoop.io.Text;
-import org.apache.kylin.common.util.ByteArray;
-import org.apache.kylin.common.util.Bytes;
-import org.apache.kylin.cube.cuboid.CuboidScheduler;
-import org.apache.kylin.engine.mr.common.BatchConstants;
-import org.apache.kylin.measure.BufferedMeasureCodec;
-import org.apache.kylin.measure.hllc.HyperLogLogPlusCounter;
-import org.apache.kylin.metadata.datatype.DataType;
-import org.apache.kylin.metadata.model.TblColRef;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.List;
-
-/**
- */
-public class FactDistinctHiveColumnsMapper2<KEYIN> extends FactDistinctColumnsMapperBase2<KEYIN, Object> {
-
-    protected boolean collectStatistics = false;
-    protected CuboidScheduler cuboidScheduler = null;
-    protected int nRowKey;
-    private Integer[][] allCuboidsBitSet = null;
-    private HyperLogLogPlusCounter[] allCuboidsHLL = null;
-    private Long[] cuboidIds;
-    private HashFunction hf = null;
-    private int rowCount = 0;
-    private int samplingPercentage;
-    private ByteArray[] row_hashcodes = null;
-    private ByteBuffer keyBuffer;
-    private static final Text EMPTY_TEXT = new Text();
-    public static final byte MARK_FOR_PARTITION_COL = (byte) 0xFE;
-    public static final byte MARK_FOR_HLL = (byte) 0xFF;
-
-    private int partitionColumnIndex = -1;
-    private boolean needFetchPartitionCol = true;
-
-    @Override
-    protected void setup(Context context) throws IOException {
-        super.setup(context);
-        keyBuffer = ByteBuffer.allocate(4096);
-        collectStatistics = Boolean.parseBoolean(context.getConfiguration().get(BatchConstants.CFG_STATISTICS_ENABLED));
-        if (collectStatistics) {
-            samplingPercentage = Integer.parseInt(context.getConfiguration().get(BatchConstants.CFG_STATISTICS_SAMPLING_PERCENT));
-            cuboidScheduler = new CuboidScheduler(cubeDesc);
-            nRowKey = cubeDesc.getRowkey().getRowKeyColumns().length;
-
-            List<Long> cuboidIdList = Lists.newArrayList();
-            List<Integer[]> allCuboidsBitSetList = Lists.newArrayList();
-            addCuboidBitSet(baseCuboidId, allCuboidsBitSetList, cuboidIdList);
-
-            allCuboidsBitSet = allCuboidsBitSetList.toArray(new Integer[cuboidIdList.size()][]);
-            cuboidIds = cuboidIdList.toArray(new Long[cuboidIdList.size()]);
-
-            allCuboidsHLL = new HyperLogLogPlusCounter[cuboidIds.length];
-            for (int i = 0; i < cuboidIds.length; i++) {
-                allCuboidsHLL[i] = new HyperLogLogPlusCounter(cubeDesc.getConfig().getCubeStatsHLLPrecision());
-            }
-
-            hf = Hashing.murmur3_32();
-            row_hashcodes = new ByteArray[nRowKey];
-            for (int i = 0; i < nRowKey; i++) {
-                row_hashcodes[i] = new ByteArray();
-            }
-
-            TblColRef partitionColRef = cubeDesc.getModel().getPartitionDesc().getPartitionDateColumnRef();
-            if (partitionColRef != null) {
-                partitionColumnIndex = intermediateTableDesc.getColumnIndex(partitionColRef);
-            }
-
-            // check whether need fetch the partition col values
-            if (partitionColumnIndex < 0) {
-                // if partition col not on cube, no need
-                needFetchPartitionCol = false;
-            } else {
-                for (int x : dictionaryColumnIndex) {
-                    if (x == partitionColumnIndex) {
-                        // if partition col already build dict, no need
-                        needFetchPartitionCol = false;
-                        break;
-                    }
-                }
-            }
-
-        }
-    }
-
-    private void addCuboidBitSet(long cuboidId, List<Integer[]> allCuboidsBitSet, List<Long> allCuboids) {
-        allCuboids.add(cuboidId);
-        Integer[] indice = new Integer[Long.bitCount(cuboidId)];
-
-        long mask = Long.highestOneBit(baseCuboidId);
-        int position = 0;
-        for (int i = 0; i < nRowKey; i++) {
-            if ((mask & cuboidId) > 0) {
-                indice[position] = i;
-                position++;
-            }
-            mask = mask >> 1;
-        }
-
-        allCuboidsBitSet.add(indice);
-        Collection<Long> children = cuboidScheduler.getSpanningCuboid(cuboidId);
-        for (Long childId : children) {
-            addCuboidBitSet(childId, allCuboidsBitSet, allCuboids);
-        }
-    }
-
-    @Override
-    public void doMap(KEYIN key, Object record, Context context) throws IOException, InterruptedException {
-        String[] row = flatTableInputFormat.parseMapperInput(record);
-
-        keyBuffer.clear();
-        try {
-            for (int i = 0; i < factDictCols.size(); i++) {
-                String fieldValue = row[dictionaryColumnIndex[i]];
-                if (fieldValue == null)
-                    continue;
-                int offset = keyBuffer.position();
-                keyBuffer.put(Bytes.toBytes(i)[3]); // one byte is enough
-                keyBuffer.put(Bytes.toBytes(fieldValue));
-                outputKey.set(keyBuffer.array(), offset, keyBuffer.position() - offset);
-                sortableKey.setText(outputKey);
-                //judge type
-                DataType type = factDictCols.get(i).getType();
-                if (!type.isNumberFamily()) {
-                    sortableKey.setTypeId((byte) TypeFlag.NONE_NUMERIC_TYPE.ordinal());
-                } else if (type.isIntegerFamily()) {
-                    sortableKey.setTypeId((byte) TypeFlag.INTEGER_FAMILY_TYPE.ordinal());
-                } else {
-                    sortableKey.setTypeId((byte) TypeFlag.DOUBLE_FAMILY_TYPE.ordinal());
-                }
-                context.write(sortableKey, EMPTY_TEXT);
-            }
-        } catch (Exception ex) {
-            handleErrorRecord(row, ex);
-        }
-
-        if (collectStatistics) {
-            if (rowCount < samplingPercentage) {
-                putRowKeyToHLL(row);
-            }
-
-            if (needFetchPartitionCol == true) {
-                String fieldValue = row[partitionColumnIndex];
-                if (fieldValue != null) {
-                    int offset = keyBuffer.position();
-                    keyBuffer.put(MARK_FOR_PARTITION_COL);
-                    keyBuffer.put(Bytes.toBytes(fieldValue));
-                    outputKey.set(keyBuffer.array(), offset, keyBuffer.position() - offset);
-                    sortableKey.setText(outputKey);
-                    sortableKey.setTypeId((byte) 0);
-                    context.write(sortableKey, EMPTY_TEXT);
-                }
-            }
-        }
-
-        if (rowCount++ == 100)
-            rowCount = 0;
-    }
-
-    private void putRowKeyToHLL(String[] row) {
-
-        //generate hash for each row key column
-        for (int i = 0; i < nRowKey; i++) {
-            Hasher hc = hf.newHasher();
-            String colValue = row[intermediateTableDesc.getRowKeyColumnIndexes()[i]];
-            if (colValue != null) {
-                row_hashcodes[i].set(hc.putString(colValue).hash().asBytes());
-            } else {
-                row_hashcodes[i].set(hc.putInt(0).hash().asBytes());
-            }
-        }
-
-        // user the row key column hash to get a consolidated hash for each cuboid
-        for (int i = 0, n = allCuboidsBitSet.length; i < n; i++) {
-            Hasher hc = hf.newHasher();
-            for (int position = 0; position < allCuboidsBitSet[i].length; position++) {
-                hc.putBytes(row_hashcodes[allCuboidsBitSet[i][position]].array());
-            }
-
-            allCuboidsHLL[i].add(hc.hash().asBytes());
-        }
-    }
-
-    @Override
-    protected void doCleanup(Context context) throws IOException, InterruptedException {
-        if (collectStatistics) {
-            ByteBuffer hllBuf = ByteBuffer.allocate(BufferedMeasureCodec.DEFAULT_BUFFER_SIZE);
-            // output each cuboid's hll to reducer, key is 0 - cuboidId
-            HyperLogLogPlusCounter hll;
-            for (int i = 0; i < cuboidIds.length; i++) {
-                hll = allCuboidsHLL[i];
-
-                keyBuffer.clear();
-                keyBuffer.put(MARK_FOR_HLL); // one byte
-                keyBuffer.putLong(cuboidIds[i]);
-                outputKey.set(keyBuffer.array(), 0, keyBuffer.position());
-                sortableKey.setText(outputKey);
-                sortableKey.setTypeId((byte) 0);
-                hllBuf.clear();
-                hll.writeRegisters(hllBuf);
-                outputValue.set(hllBuf.array(), 0, hllBuf.position());
-                context.write(sortableKey, outputValue);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/SelfDefineSortableKey.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/SelfDefineSortableKey.java b/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/SelfDefineSortableKey.java
deleted file mode 100644
index a3351fa..0000000
--- a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/SelfDefineSortableKey.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-package org.apache.kylin.engine.mr.steps.fdc2;
-
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.io.WritableComparable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-
-/**
- * Created by xiefan on 16-11-1.
- */
-public class SelfDefineSortableKey implements WritableComparable<SelfDefineSortableKey> {
-
-    private byte typeId; //non-numeric(0000 0000) int(0000 0001) other numberic(0000 0010)
-
-    private Text text;
-
-    private static final Logger logger = LoggerFactory.getLogger(SelfDefineSortableKey.class);
-
-    public SelfDefineSortableKey() {
-    }
-
-    public SelfDefineSortableKey(byte typeId, Text text) {
-        this.typeId = typeId;
-        this.text = text;
-    }
-
-    @Override
-    public int compareTo(SelfDefineSortableKey o) {
-        if (!o.isNumberFamily()) {
-            return this.text.compareTo(o.text);
-        } else {
-            byte[] data1 = this.text.getBytes();
-            byte[] data2 = o.text.getBytes();
-            String str1 = new String(data1, 1, data1.length - 1);
-            String str2 = new String(data2, 1, data2.length - 1);
-            if (str1 == null || str1.equals("") || str2 == null || str2.equals("")) {
-                //should not achieve here
-                logger.error("none numeric value!");
-                return 0;
-            }
-            if (o.isIntegerFamily()) {  //integer type
-                try {
-                    Long num1 = Long.parseLong(str1);
-                    Long num2 = Long.parseLong(str2);
-                    return num1.compareTo(num2);
-                } catch (NumberFormatException e) {
-                    System.out.println("NumberFormatException when parse integer family number.str1:" + str1 + " str2:" + str2);
-                    logger.error("NumberFormatException when parse integer family number.str1:" + str1 + " str2:" + str2);
-                    e.printStackTrace();
-                    return 0;
-                }
-            } else {  //other numeric type
-                try {
-                    Double num1 = Double.parseDouble(str1);
-                    Double num2 = Double.parseDouble(str2);
-                    return num1.compareTo(num2);
-                } catch (NumberFormatException e) {
-                    System.out.println("NumberFormatException when parse double family number.str1:" + str1 + " str2:" + str2);
-                    logger.error("NumberFormatException when parse doul family number.str1:" + str1 + " str2:" + str2);
-                    //e.printStackTrace();
-                    return 0;
-                }
-            }
-        }
-    }
-
-    @Override
-    public void write(DataOutput dataOutput) throws IOException {
-        dataOutput.writeByte(typeId);
-        text.write(dataOutput);
-    }
-
-    @Override
-    public void readFields(DataInput dataInput) throws IOException {
-        this.typeId = dataInput.readByte();
-        this.text = new Text();
-        text.readFields(dataInput);
-    }
-
-    public short getTypeId() {
-        return typeId;
-    }
-
-    public Text getText() {
-        return text;
-    }
-
-    public boolean isNumberFamily() {
-        if (typeId == TypeFlag.NONE_NUMERIC_TYPE.ordinal()) return false;
-        return true;
-    }
-
-    public boolean isIntegerFamily() {
-        return (typeId == TypeFlag.INTEGER_FAMILY_TYPE.ordinal());
-    }
-
-    public boolean isOtherNumericFamily() {
-        return (typeId == TypeFlag.DOUBLE_FAMILY_TYPE.ordinal());
-    }
-
-    public void setTypeId(byte typeId) {
-        this.typeId = typeId;
-    }
-
-    public void setText(Text text) {
-        this.text = text;
-    }
-}

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/TypeFlag.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/TypeFlag.java b/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/TypeFlag.java
deleted file mode 100644
index c69acfd..0000000
--- a/engine-mr/src/main/java/org/apache/kylin/engine/mr/steps/fdc2/TypeFlag.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-package org.apache.kylin.engine.mr.steps.fdc2;
-
-/**
- * Created by xiefan on 16-11-2.
- */
-public enum TypeFlag {
-    NONE_NUMERIC_TYPE,
-    INTEGER_FAMILY_TYPE,
-    DOUBLE_FAMILY_TYPE
-}

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/test/java/org/apache/kylin/engine/mr/SortedColumnReaderTest.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/test/java/org/apache/kylin/engine/mr/SortedColumnReaderTest.java b/engine-mr/src/test/java/org/apache/kylin/engine/mr/SortedColumnReaderTest.java
new file mode 100644
index 0000000..2f2170c
--- /dev/null
+++ b/engine-mr/src/test/java/org/apache/kylin/engine/mr/SortedColumnReaderTest.java
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package org.apache.kylin.engine.mr;
+
+import org.apache.kylin.dict.ByteComparator;
+import org.apache.kylin.dict.BytesConverter;
+import org.apache.kylin.dict.DictionaryManager;
+import org.apache.kylin.dict.IDictionaryValueEnumerator;
+import org.apache.kylin.dict.StringBytesConverter;
+import org.apache.kylin.dict.TableColumnValueEnumerator;
+import org.apache.kylin.metadata.datatype.DataType;
+import org.apache.kylin.source.ReadableTable;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.omg.Messaging.SYNC_WITH_TRANSPORT;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Random;
+import java.util.UUID;
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by xiefan on 16-11-14.
+ */
+public class SortedColumnReaderTest {
+
+    @Test
+    public void testReadStringMultiFile() throws Exception{
+        String dirPath = "src/test/resources/multi_file_str";
+        StringBytesConverter converter = new StringBytesConverter();
+        ArrayList<String> correctAnswer = readAllFiles(dirPath);
+        Collections.sort(correctAnswer, new ByteComparator<String>(new StringBytesConverter()));
+        SortedColumn column = new SortedColumn(dirPath + "/",DataType.getType("varchar"));
+        IDictionaryValueEnumerator e = new TableColumnValueEnumerator(column.getReader(),-1);
+        ArrayList<String> output = new ArrayList<>();
+        while(e.moveNext()){
+            output.add(new String(e.current()));
+        }
+        System.out.println(correctAnswer.size());
+        assertTrue(correctAnswer.size() == output.size());
+        for(int i=0;i<correctAnswer.size();i++){
+            assertEquals(correctAnswer.get(i),output.get(i));
+        }
+    }
+
+
+    @Ignore
+    @Test
+    public void createStringTestFiles() throws Exception{
+        String dirPath = "src/test/resources/multi_file_str";
+        String prefix = "src/test/resources/multi_file_str/data_";
+        ArrayList<String> data = new ArrayList<>();
+        int num = 10000;
+        for(int i=0;i<num;i++){
+            UUID uuid = UUID.randomUUID();
+            data.add(uuid.toString());
+        }
+        Collections.sort(data,new ByteComparator<String>(new StringBytesConverter()));
+        Random rand = new Random(System.currentTimeMillis());
+        ArrayList<File> allFiles = new ArrayList<>();
+        int fileNum = 5;
+        for(int i=0;i<fileNum;i++){
+            File f = new File(prefix + i);
+            if(!f.exists())
+                f.createNewFile();
+            allFiles.add(f);
+        }
+        ArrayList<BufferedWriter> bws = new ArrayList<>();
+        for(File f : allFiles){
+            bws.add(new BufferedWriter(new FileWriter(f)));
+        }
+        System.out.println(data.size());
+        for(String str : data){
+            int fileId = rand.nextInt(fileNum);
+            BufferedWriter bw = bws.get(fileId);
+            bw.write(str);
+            bw.newLine();
+        }
+        for(BufferedWriter bw : bws)
+        {
+            bw.flush();
+            bw.close();
+        }
+        File dir = new File(dirPath);
+        File[] files = dir.listFiles();
+        for(File file : files){
+            System.out.println("file:"+file.getAbsolutePath()+" size:"+file.length());
+        }
+    }
+
+    @Test
+    public void testReadIntegerMultiFiles() throws Exception{
+        String dirPath = "src/test/resources/multi_file_int";
+        ArrayList<String> correctAnswer = readAllFiles(dirPath);
+        Collections.sort(correctAnswer, new Comparator<String>() {
+            @Override
+            public int compare(String o1, String o2) {
+                try{
+                    Long l1 = Long.parseLong(o1);
+                    Long l2 = Long.parseLong(o2);
+                    return l1.compareTo(l2);
+                }catch (NumberFormatException e){
+                    e.printStackTrace();
+                    return 0;
+                }
+            }
+        });
+        SortedColumn column = new SortedColumn(dirPath + "/",DataType.getType("long"));
+        IDictionaryValueEnumerator e = new TableColumnValueEnumerator(column.getReader(),-1);
+        ArrayList<String> output = new ArrayList<>();
+        while(e.moveNext()){
+            System.out.println(new String(e.current()));
+            output.add(new String(e.current()));
+        }
+        System.out.println(correctAnswer.size());
+        assertTrue(correctAnswer.size() == output.size());
+        for(int i=0;i<correctAnswer.size();i++){
+            assertEquals(correctAnswer.get(i),output.get(i));
+        }
+    }
+
+    @Test
+    public void testEmptyDir() throws Exception{
+        String dirPath = "src/test/resources/empty_dir";
+        SortedColumn column = new SortedColumn(dirPath + "/",DataType.getType("varchar"));
+        IDictionaryValueEnumerator e = new TableColumnValueEnumerator(column.getReader(),-1);
+        ArrayList<String> output = new ArrayList<>();
+        while(e.moveNext()){
+            System.out.println(new String(e.current()));
+            output.add(new String(e.current()));
+        }
+        System.out.println(output.size());
+    }
+
+    @Test
+    public void testEmptyFile() throws Exception{
+        String dirPath = "src/test/resources/multi_file_empty_file";
+        ArrayList<String> correctAnswer = readAllFiles(dirPath);
+        final BytesConverter<String> converter = new StringBytesConverter();
+        Collections.sort(correctAnswer, new ByteComparator<String>(new StringBytesConverter()));
+        System.out.println("correct answer:"+correctAnswer);
+        SortedColumn column = new SortedColumn(dirPath + "/",DataType.getType("varchar"));
+        IDictionaryValueEnumerator e = new TableColumnValueEnumerator(column.getReader(),-1);
+        ArrayList<String> output = new ArrayList<>();
+        while(e.moveNext()){
+            output.add(new String(e.current()));
+        }
+        System.out.println(correctAnswer.size());
+        assertTrue(correctAnswer.size() == output.size());
+        for(int i=0;i<correctAnswer.size();i++){
+            assertEquals(correctAnswer.get(i),output.get(i));
+        }
+    }
+
+
+    @Ignore
+    @Test
+    public void createIntegerTestFiles() throws Exception{
+        String dirPath = "src/test/resources/multi_file_int";
+        String prefix = "src/test/resources/multi_file_int/data_";
+        Random rand = new Random(System.currentTimeMillis());
+        ArrayList<String> data = new ArrayList<>();
+        int num = 10000;
+        for(int i=0;i<num;i++){
+            data.add(i+"");
+        }
+        ArrayList<File> allFiles = new ArrayList<>();
+        int fileNum = 5;
+        for(int i=0;i<fileNum;i++){
+            File f = new File(prefix + i);
+            if(!f.exists())
+                f.createNewFile();
+            allFiles.add(f);
+        }
+        ArrayList<BufferedWriter> bws = new ArrayList<>();
+        for(File f : allFiles){
+            bws.add(new BufferedWriter(new FileWriter(f)));
+        }
+        System.out.println(data.size());
+        for(String str : data){
+            int fileId = rand.nextInt(fileNum);
+            BufferedWriter bw = bws.get(fileId);
+            bw.write(str);
+            bw.newLine();
+        }
+        for(BufferedWriter bw : bws)
+        {
+            bw.flush();
+            bw.close();
+        }
+        File dir = new File(dirPath);
+        File[] files = dir.listFiles();
+        for(File file : files){
+            System.out.println("file:"+file.getAbsolutePath()+" size:"+file.length());
+        }
+    }
+
+    @Test
+    public void testReadDoubleMultiFiles() throws Exception{
+        String dirPath = "src/test/resources/multi_file_double";
+        ArrayList<String> correctAnswer = readAllFiles(dirPath);
+        Collections.sort(correctAnswer, new Comparator<String>() {
+            @Override
+            public int compare(String o1, String o2) {
+                try{
+                    Double d1 = Double.parseDouble(o1);
+                    Double d2 = Double.parseDouble(o2);
+                    return d1.compareTo(d2);
+                }catch (NumberFormatException e){
+                    e.printStackTrace();
+                    return 0;
+                }
+            }
+        });
+        SortedColumn column = new SortedColumn(dirPath + "/",DataType.getType("double"));
+        IDictionaryValueEnumerator e = new TableColumnValueEnumerator(column.getReader(),-1);
+        ArrayList<String> output = new ArrayList<>();
+        while(e.moveNext()){
+            System.out.println(new String(e.current()));
+            output.add(new String(e.current()));
+        }
+        System.out.println(correctAnswer.size());
+        assertTrue(correctAnswer.size() == output.size());
+        for(int i=0;i<correctAnswer.size();i++){
+            assertEquals(correctAnswer.get(i),output.get(i));
+        }
+    }
+
+
+    @Ignore
+    @Test
+    public void createDoubleTestFiles() throws Exception{
+        String dirPath = "src/test/resources/multi_file_double";
+        String prefix = "src/test/resources/multi_file_double/data_";
+        Random rand = new Random(System.currentTimeMillis());
+        ArrayList<String> data = new ArrayList<>();
+        int num = 10000;
+        double k = 0.0;
+        for(int i=0;i<num;i++){
+            data.add(k+"");
+            k+=0.52;
+        }
+        ArrayList<File> allFiles = new ArrayList<>();
+        int fileNum = 5;
+        for(int i=0;i<fileNum;i++){
+            File f = new File(prefix + i);
+            if(!f.exists())
+                f.createNewFile();
+            allFiles.add(f);
+        }
+        ArrayList<BufferedWriter> bws = new ArrayList<>();
+        for(File f : allFiles){
+            bws.add(new BufferedWriter(new FileWriter(f)));
+        }
+        System.out.println(data.size());
+        for(String str : data){
+            int fileId = rand.nextInt(fileNum);
+            BufferedWriter bw = bws.get(fileId);
+            bw.write(str);
+            bw.newLine();
+        }
+        for(BufferedWriter bw : bws)
+        {
+            bw.flush();
+            bw.close();
+        }
+        File dir = new File(dirPath);
+        File[] files = dir.listFiles();
+        for(File file : files){
+            System.out.println("file:"+file.getAbsolutePath()+" size:"+file.length());
+        }
+    }
+
+    private ArrayList<String> readAllFiles(String dirPath) throws Exception{
+        ArrayList<String> result = new ArrayList<>();
+        File dir = new File(dirPath);
+        for(File f : dir.listFiles()){
+            BufferedReader br = new BufferedReader(new FileReader(f));
+            String str = br.readLine();
+            while(str != null){
+                result.add(str);
+                str = br.readLine();
+            }
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/NumberDictionaryForestTest.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/NumberDictionaryForestTest.java b/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/NumberDictionaryForestTest.java
index 47b10e8..677e386 100644
--- a/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/NumberDictionaryForestTest.java
+++ b/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/NumberDictionaryForestTest.java
@@ -23,8 +23,7 @@ import org.apache.kylin.dict.NumberDictionaryBuilder;
 import org.apache.kylin.dict.NumberDictionaryForestBuilder;
 import org.apache.kylin.dict.StringBytesConverter;
 import org.apache.kylin.dict.TrieDictionaryForest;
-import org.apache.kylin.engine.mr.steps.fdc2.SelfDefineSortableKey;
-import org.apache.kylin.engine.mr.steps.fdc2.TypeFlag;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -91,6 +90,7 @@ public class NumberDictionaryForestTest {
         }
     }
 
+
     @Test
     public void testVerySmallDouble() {
         List<String> testData = new ArrayList<>();
@@ -151,6 +151,19 @@ public class NumberDictionaryForestTest {
         }
     }
 
+    @Ignore
+    @Test
+    public void testDecimalsWithBeginZero(){
+        List<String> testData = new ArrayList<>();
+        testData.add("000000000000000000000000000.4868");
+        testData.add("00000000000000000000000000000000000000");
+        NumberDictionaryForestBuilder b = new NumberDictionaryForestBuilder();
+        for (String str : testData)
+            b.addValue(str);
+        TrieDictionaryForest<String> dict = b.build();
+        dict.dump(System.out);
+    }
+
     private static TrieDictionaryForest<String> testSerialize(TrieDictionaryForest<String> dict) {
         try {
             ByteArrayOutputStream bout = new ByteArrayOutputStream();

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/SelfDefineSortableKeyTest.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/SelfDefineSortableKeyTest.java b/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/SelfDefineSortableKeyTest.java
index 81aa836..b03514c 100644
--- a/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/SelfDefineSortableKeyTest.java
+++ b/engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/SelfDefineSortableKeyTest.java
@@ -12,8 +12,6 @@ import java.util.UUID;
 
 import org.apache.hadoop.io.Text;
 import org.apache.kylin.common.util.Bytes;
-import org.apache.kylin.engine.mr.steps.fdc2.SelfDefineSortableKey;
-import org.apache.kylin.engine.mr.steps.fdc2.TypeFlag;
 import org.junit.Test;
 
 /**

http://git-wip-us.apache.org/repos/asf/kylin/blob/2b7fe610/engine-mr/src/test/resources/multi_file_double/data_0
----------------------------------------------------------------------
diff --git a/engine-mr/src/test/resources/multi_file_double/data_0 b/engine-mr/src/test/resources/multi_file_double/data_0
new file mode 100644
index 0000000..e3da559
--- /dev/null
+++ b/engine-mr/src/test/resources/multi_file_double/data_0
@@ -0,0 +1,2006 @@
+0.0
+2.6
+3.12
+5.199999999999999
+7.279999999999998
+7.799999999999997
+10.399999999999995
+11.439999999999994
+11.959999999999994
+16.63999999999999
+17.15999999999999
+20.279999999999987
+22.879999999999985
+24.439999999999984
+25.479999999999983
+25.999999999999982
+31.719999999999978
+32.23999999999998
+38.48000000000002
+39.00000000000002
+40.56000000000003
+41.080000000000034
+41.60000000000004
+42.64000000000004
+46.80000000000007
+48.88000000000008
+50.44000000000009
+50.96000000000009
+51.480000000000096
+53.040000000000106
+54.600000000000115
+56.160000000000124
+59.800000000000146
+61.88000000000016
+65.00000000000017
+68.12000000000015
+68.64000000000014
+73.8400000000001
+75.40000000000009
+76.44000000000008
+80.60000000000005
+81.12000000000005
+82.16000000000004
+86.32000000000001
+90.99999999999997
+94.63999999999994
+96.71999999999993
+97.23999999999992
+99.8399999999999
+102.95999999999988
+106.07999999999986
+115.43999999999978
+117.51999999999977
+119.59999999999975
+120.11999999999975
+123.23999999999972
+126.8799999999997
+128.9599999999997
+129.4799999999997
+129.99999999999972
+131.03999999999974
+134.1599999999998
+135.71999999999983
+144.56
+145.60000000000002
+150.28000000000011
+151.84000000000015
+152.88000000000017
+153.9200000000002
+157.56000000000026
+159.6400000000003
+161.20000000000033
+165.3600000000004
+166.92000000000044
+172.64000000000055
+173.68000000000058
+175.2400000000006
+178.36000000000067
+179.9200000000007
+180.4400000000007
+181.48000000000073
+183.56000000000077
+184.08000000000078
+185.1200000000008
+186.16000000000082
+190.8400000000009
+196.04000000000102
+197.60000000000105
+198.64000000000107
+201.24000000000112
+203.84000000000117
+213.20000000000135
+214.24000000000137
+215.2800000000014
+219.9600000000015
+222.04000000000153
+223.08000000000155
+224.64000000000158
+225.1600000000016
+228.80000000000166
+229.84000000000168
+230.8800000000017
+239.20000000000186
+241.2800000000019
+243.88000000000196
+244.40000000000197
+247.00000000000202
+250.12000000000208
+251.1600000000021
+254.80000000000217
+255.32000000000218
+256.3600000000022
+260.00000000000205
+266.2400000000018
+269.3600000000017
+269.8800000000017
+271.44000000000165
+275.6000000000015
+277.16000000000145
+277.6800000000014
+280.28000000000134
+281.3200000000013
+286.00000000000114
+286.5200000000011
+293.80000000000086
+294.8400000000008
+296.4000000000008
+300.04000000000065
+301.6000000000006
+303.6800000000005
+304.2000000000005
+304.7200000000005
+309.9200000000003
+310.96000000000026
+312.5200000000002
+315.6400000000001
+317.20000000000005
+323.9599999999998
+326.03999999999974
+326.5599999999997
+338.5199999999993
+339.0399999999993
+341.1199999999992
+341.6399999999992
+346.839999999999
+348.39999999999895
+349.9599999999989
+350.4799999999989
+355.1599999999987
+357.23999999999864
+358.2799999999986
+361.9199999999985
+366.5999999999983
+369.7199999999982
+376.99999999999795
+378.5599999999979
+385.31999999999766
+386.3599999999976
+393.1199999999974
+393.63999999999737
+394.15999999999735
+396.75999999999726
+397.7999999999972
+401.9599999999971
+402.99999999999704
+403.519999999997
+406.6399999999969
+409.2399999999968
+410.2799999999968
+412.3599999999967
+413.91999999999666
+415.9999999999966
+417.55999999999653
+420.6799999999964
+422.23999999999637
+422.75999999999635
+426.3999999999962
+427.4399999999962
+428.99999999999613
+429.5199999999961
+434.19999999999595
+434.71999999999593
+435.2399999999959
+437.31999999999584
+443.03999999999564
+443.5599999999956
+444.0799999999956
+446.15999999999553
+447.7199999999955
+451.35999999999535
+453.95999999999526
+454.47999999999524
+454.9999999999952
+461.239999999995
+462.79999999999495
+463.31999999999493
+463.8399999999949
+464.3599999999949
+471.11999999999466
+471.63999999999464
+476.3199999999945
+478.9199999999944
+480.47999999999433
+480.9999999999943
+483.07999999999424
+484.6399999999942
+485.15999999999417
+487.2399999999941
+488.27999999999406
+495.0399999999938
+497.11999999999375
+500.23999999999364
+500.7599999999936
+501.2799999999936
+506.4799999999934
+506.9999999999934
+508.03999999999337
+508.55999999999335
+509.07999999999333
+510.1199999999933
+511.15999999999326
+516.3599999999931
+516.8799999999931
+517.919999999993
+519.479999999993
+522.0799999999929
+522.5999999999929
+530.9199999999926
+532.4799999999925
+537.6799999999923
+541.3199999999922
+543.9199999999921
+545.4799999999921
+545.999999999992
+549.1199999999919
+553.2799999999918
+553.7999999999918
+554.8399999999917
+561.0799999999915
+561.5999999999915
+565.2399999999914
+568.8799999999912
+571.4799999999912
+579.2799999999909
+579.7999999999909
+580.3199999999908
+587.0799999999906
+592.2799999999904
+593.3199999999904
+594.3599999999904
+595.3999999999903
+603.71999999999
+606.3199999999899
+607.3599999999899
+608.3999999999899
+608.9199999999898
+609.9599999999898
+615.6799999999896
+617.7599999999895
+618.2799999999895
+621.9199999999894
+625.5599999999893
+626.0799999999892
+630.2399999999891
+635.4399999999889
+635.9599999999889
+636.4799999999889
+638.5599999999888
+640.1199999999887
+641.6799999999887
+643.2399999999886
+648.9599999999884
+651.0399999999884
+657.2799999999881
+659.3599999999881
+666.1199999999878
+674.4399999999875
+683.2799999999872
+684.3199999999872
+684.8399999999872
+686.3999999999871
+687.4399999999871
+688.999999999987
+691.079999999987
+696.7999999999868
+697.8399999999867
+699.3999999999867
+700.4399999999866
+703.5599999999865
+705.6399999999865
+707.1999999999864
+711.8799999999862
+715.5199999999861
+717.0799999999861
+719.159999999986
+721.2399999999859
+723.8399999999858
+728.5199999999857
+730.0799999999856
+732.6799999999855
+733.7199999999855
+734.7599999999854
+738.9199999999853
+741.5199999999852
+748.279999999985
+750.8799999999849
+751.3999999999849
+755.5599999999847
+759.7199999999846
+762.3199999999845
+762.8399999999845
+764.9199999999844
+769.5999999999842
+776.879999999984
+777.9199999999839
+779.9999999999839
+781.0399999999838
+783.6399999999837
+787.7999999999836
+790.3999999999835
+792.4799999999834
+793.5199999999834
+794.5599999999833
+795.0799999999833
+797.1599999999833
+803.399999999983
+809.6399999999828
+810.6799999999828
+816.3999999999826
+818.9999999999825
+819.5199999999825
+822.6399999999824
+823.6799999999823
+825.7599999999823
+827.8399999999822
+831.479999999982
+834.079999999982
+834.599999999982
+835.6399999999819
+838.2399999999818
+845.5199999999816
+846.0399999999815
+847.5999999999815
+848.1199999999815
+852.2799999999813
+853.8399999999813
+856.4399999999812
+857.9999999999811
+858.5199999999811
+862.159999999981
+864.7599999999809
+867.8799999999808
+868.3999999999808
+871.5199999999807
+872.0399999999806
+873.0799999999806
+876.7199999999805
+879.3199999999804
+887.6399999999801
+894.3999999999799
+895.4399999999798
+896.4799999999798
+896.9999999999798
+897.5199999999797
+903.7599999999795
+915.1999999999791
+916.7599999999791
+918.319999999979
+922.9999999999789
+925.5999999999788
+927.6799999999787
+940.1599999999783
+947.959999999978
+949.5199999999779
+951.5999999999779
+952.1199999999778
+952.6399999999778
+955.7599999999777
+960.9599999999775
+961.4799999999775
+970.8399999999772
+973.4399999999771
+979.1599999999769
+979.6799999999769
+980.1999999999769
+982.7999999999768
+983.8399999999767
+985.3999999999767
+986.9599999999766
+989.0399999999765
+990.0799999999765
+991.1199999999765
+991.6399999999765
+992.1599999999764
+992.6799999999764
+994.2399999999764
+997.8799999999762
+998.3999999999762
+1010.3599999999758
+1010.8799999999758
+1014.5199999999757
+1016.0799999999756
+1020.7599999999754
+1024.3999999999753
+1025.9599999999753
+1029.0799999999751
+1031.679999999975
+1033.759999999975
+1035.319999999975
+1037.9199999999748
+1039.4799999999748
+1039.9999999999748
+1044.6799999999746
+1048.3199999999745
+1050.9199999999744
+1055.5999999999742
+1058.719999999974
+1060.279999999974
+1065.9999999999739
+1068.0799999999738
+1069.6399999999737
+1072.7599999999736
+1073.2799999999736
+1078.9999999999734
+1083.1599999999733
+1084.1999999999732
+1085.7599999999732
+1093.039999999973
+1095.1199999999728
+1095.6399999999728
+1097.1999999999728
+1100.3199999999727
+1100.8399999999726
+1101.3599999999726
+1106.5599999999724
+1108.1199999999724
+1110.1999999999723
+1113.3199999999722
+1114.8799999999721
+1116.439999999972
+1120.599999999972
+1125.2799999999718
+1127.8799999999717
+1131.5199999999716
+1134.1199999999715
+1136.1999999999714
+1136.7199999999714
+1142.4399999999712
+1142.9599999999712
+1151.7999999999709
+1152.3199999999708
+1155.4399999999707
+1158.0399999999706
+1160.6399999999705
+1161.6799999999705
+1162.1999999999705
+1163.7599999999704
+1166.3599999999703
+1169.9999999999702
+1172.5999999999701
+1173.11999999997
+1177.27999999997
+1178.31999999997
+1183.5199999999697
+1185.0799999999697
+1195.4799999999693
+1196.5199999999693
+1199.6399999999692
+1201.1999999999691
+1203.279999999969
+1205.879999999969
+1206.399999999969
+1208.4799999999689
+1208.9999999999688
+1212.1199999999687
+1214.1999999999687
+1217.3199999999686
+1217.8399999999685
+1221.9999999999684
+1228.2399999999682
+1229.7999999999681
+1230.839999999968
+1231.879999999968
+1234.999999999968
+1238.1199999999678
+1240.1999999999678
+1246.4399999999675
+1247.9999999999675
+1249.0399999999674
+1251.6399999999674
+1253.7199999999673
+1257.8799999999671
+1259.439999999967
+1260.999999999967
+1264.119999999967
+1265.6799999999669
+1266.1999999999668
+1267.7599999999668
+1272.4399999999666
+1277.1199999999665
+1278.1599999999664
+1280.2399999999664
+1283.3599999999662
+1284.3999999999662
+1289.079999999966
+1290.119999999966
+1292.199999999966
+1293.7599999999659
+1294.2799999999659
+1296.3599999999658
+1298.9599999999657
+1300.5199999999656
+1308.3199999999654
+1315.0799999999651
+1315.5999999999651
+1319.759999999965
+1321.839999999965
+1325.9999999999648
+1329.1199999999646
+1330.1599999999646
+1330.6799999999646
+1332.7599999999645
+1333.2799999999645
+1333.7999999999645
+1334.3199999999645
+1334.8399999999644
+1337.9599999999643
+1339.5199999999643
+1341.0799999999642
+1341.5999999999642
+1344.719999999964
+1346.799999999964
+1356.1599999999637
+1358.2399999999636
+1358.7599999999636
+1372.7999999999631
+1374.879999999963
+1377.479999999963
+1378.519999999963
+1379.039999999963
+1380.5999999999628
+1381.1199999999628
+1384.2399999999627
+1385.2799999999627
+1388.3999999999626
+1389.9599999999625
+1394.6399999999624
+1402.959999999962
+1405.039999999962
+1406.599999999962
+1410.2399999999618
+1411.7999999999618
+1412.3199999999617
+1413.3599999999617
+1414.3999999999617
+1415.9599999999616
+1419.0799999999615
+1420.6399999999614
+1421.1599999999614
+1429.4799999999611
+1437.2799999999609
+1441.9599999999607
+1445.5999999999606
+1446.6399999999605
+1451.8399999999604
+1453.9199999999603
+1458.0799999999601
+1458.5999999999601
+1459.63999999996
+1461.71999999996
+1463.79999999996
+1468.9999999999598
+1469.5199999999597
+1471.5999999999597
+1472.1199999999596
+1474.7199999999596
+1478.8799999999594
+1479.9199999999594
+1480.4399999999594
+1483.5599999999592
+1484.0799999999592
+1489.279999999959
+1489.799999999959
+1492.919999999959
+1493.439999999959
+1494.9999999999588
+1496.0399999999588
+1496.5599999999588
+1497.5999999999588
+1500.7199999999586
+1504.8799999999585
+1505.3999999999585
+1506.4399999999584
+1512.6799999999582
+1513.7199999999582
+1514.2399999999582
+1516.319999999958
+1516.839999999958
+1517.359999999958
+1518.919999999958
+1520.479999999958
+1522.039999999958
+1524.6399999999578
+1525.6799999999578
+1526.1999999999578
+1529.3199999999576
+1536.0799999999574
+1537.1199999999574
+1541.2799999999572
+1544.3999999999571
+1549.079999999957
+1551.6799999999569
+1554.7999999999568
+1558.9599999999566
+1559.9999999999566
+1563.1199999999565
+1568.3199999999563
+1570.9199999999562
+1574.559999999956
+1577.159999999956
+1578.719999999956
+1586.5199999999556
+1590.1599999999555
+1592.7599999999554
+1594.8399999999554
+1596.3999999999553
+1597.4399999999553
+1597.9599999999552
+1598.4799999999552
+1598.9999999999552
+1602.119999999955
+1602.639999999955
+1603.159999999955
+1606.279999999955
+1610.4399999999548
+1613.0399999999547
+1614.0799999999547
+1615.1199999999546
+1615.6399999999546
+1618.2399999999545
+1619.2799999999545
+1621.8799999999544
+1624.9999999999543
+1625.5199999999543
+1626.0399999999543
+1629.6799999999541
+1633.319999999954
+1635.399999999954
+1637.4799999999539
+1639.5599999999538
+1645.7999999999536
+1646.3199999999536
+1647.8799999999535
+1650.4799999999534
+1651.5199999999534
+1652.5599999999533
+1656.1999999999532
+1657.7599999999532
+1660.359999999953
+1669.1999999999528
+1669.7199999999527
+1672.3199999999526
+1673.3599999999526
+1674.9199999999526
+1679.5999999999524
+1685.3199999999522
+1687.3999999999521
+1687.919999999952
+1689.999999999952
+1694.1599999999519
+1697.7999999999518
+1699.8799999999517
+1701.4399999999516
+1707.1599999999514
+1710.2799999999513
+1718.079999999951
+1719.119999999951
+1720.159999999951
+1721.719999999951
+1722.7599999999509
+1726.9199999999507
+1727.9599999999507
+1731.0799999999506
+1732.1199999999506
+1732.6399999999505
+1734.1999999999505
+1736.2799999999504
+1736.7999999999504
+1741.4799999999502
+1744.0799999999501
+1745.11999999995
+1745.63999999995
+1750.83999999995
+1753.4399999999498
+1754.4799999999498
+1758.1199999999496
+1764.3599999999494
+1770.5999999999492
+1773.1999999999491
+1775.279999999949
+1776.319999999949
+1781.5199999999488
+1782.0399999999488
+1788.7999999999486
+1790.3599999999485
+1793.4799999999484
+1794.5199999999484
+1795.0399999999483
+1796.5999999999483
+1798.1599999999482
+1798.6799999999482
+1800.2399999999482
+1800.7599999999481
+1801.799999999948
+1802.319999999948
+1808.039999999948
+1813.7599999999477
+1814.2799999999477
+1815.8399999999476
+1816.3599999999476
+1825.1999999999473
+1828.3199999999472
+1831.439999999947
+1835.079999999947
+1836.119999999947
+1836.639999999947
+1838.7199999999468
+1839.2399999999468
+1840.2799999999468
+1844.4399999999466
+1847.0399999999465
+1849.6399999999464
+1850.1599999999464
+1850.6799999999464
+1852.2399999999463
+1853.2799999999463
+1855.3599999999462
+1862.119999999946
+1866.7999999999458
+1878.7599999999454
+1880.8399999999453
+1883.4399999999453
+1884.4799999999452
+1884.9999999999452
+1887.599999999945
+1894.3599999999449
+1899.0399999999447
+1901.1199999999446
+1903.7199999999445
+1904.2399999999445
+1904.7599999999445
+1906.3199999999445
+1906.8399999999444
+1907.3599999999444
+1910.4799999999443
+1912.5599999999442
+1919.319999999944
+1920.879999999944
+1921.399999999944
+1923.4799999999439
+1925.0399999999438
+1927.1199999999437
+1934.3999999999435
+1935.4399999999434
+1936.4799999999434
+1936.9999999999434
+1940.1199999999433
+1942.7199999999432
+1944.2799999999431
+1948.959999999943
+1949.999999999943
+1950.519999999943
+1954.1599999999428
+1957.2799999999427
+1958.3199999999426
+1963.5199999999425
+1971.3199999999422
+1975.999999999942
+1976.519999999942
+1979.639999999942
+1985.8799999999417
+1986.3999999999417
+1988.4799999999416
+1989.5199999999415
+1993.6799999999414
+1995.7599999999413
+1997.8399999999413
+1998.8799999999412
+2005.119999999941
+2006.159999999941
+2014.4799999999407
+2014.9999999999407
+2017.0799999999406
+2017.5999999999406
+2018.6399999999405
+2023.8399999999403
+2027.4799999999402
+2030.0799999999401
+2032.67999999994
+2035.27999999994
+2036.31999999994
+2038.3999999999398
+2040.9999999999397
+2043.5999999999397
+2044.1199999999396
+2044.6399999999396
+2050.8799999999396
+2051.3999999999396
+2053.9999999999395
+2054.5199999999395
+2055.0399999999395
+2059.7199999999393
+2065.439999999939
+2067.519999999939
+2069.599999999939
+2070.119999999939
+2070.639999999939
+2072.199999999939
+2074.799999999939
+2078.4399999999387
+2082.0799999999385
+2085.7199999999384
+2087.2799999999384
+2090.3999999999382
+2091.959999999938
+2093.519999999938
+2096.119999999938
+2097.159999999938
+2097.679999999938
+2105.9999999999377
+2111.7199999999375
+2113.2799999999374
+2114.3199999999374
+2118.4799999999373
+2122.639999999937
+2123.679999999937
+2125.239999999937
+2131.479999999937
+2135.1199999999367
+2138.2399999999366
+2146.0399999999363
+2149.159999999936
+2150.199999999936
+2152.799999999936
+2154.359999999936
+2155.919999999936
+2159.039999999936
+2162.1599999999357
+2172.0399999999354
+2172.5599999999354
+2175.1599999999353
+2178.799999999935
+2179.319999999935
+2180.359999999935
+2189.199999999935
+2192.3199999999347
+2205.839999999934
+2209.479999999934
+2209.999999999934
+2212.079999999934
+2214.679999999934
+2217.799999999934
+2218.8399999999338
+2221.9599999999336
+2222.9999999999336
+2225.0799999999335
+2230.2799999999334
+2230.7999999999333
+2234.959999999933
+2237.559999999933
+2238.599999999933
+2243.799999999933
+2244.319999999933
+2247.4399999999328
+2248.9999999999327
+2250.0399999999327
+2251.0799999999326
+2256.7999999999324
+2258.3599999999324
+2259.3999999999323
+2259.9199999999323
+2263.559999999932
+2264.599999999932
+2267.199999999932
+2269.279999999932
+2271.879999999932
+2273.959999999932
+2276.5599999999317
+2277.0799999999317
+2278.1199999999317
+2283.8399999999315
+2284.3599999999315
+2288.5199999999313
+2289.0399999999313
+2290.5999999999312
+2295.279999999931
+2298.919999999931
+2299.439999999931
+2299.959999999931
+2304.6399999999308
+2310.3599999999306
+2313.9999999999304
+2317.1199999999303
+2319.71999999993
+2322.83999999993
+2323.87999999993
+2324.91999999993
+2328.03999999993
+2329.59999999993
+2330.63999999993
+2331.67999999993
+2332.19999999993
+2333.2399999999298
+2334.2799999999297
+2334.7999999999297
+2337.3999999999296
+2338.4399999999296
+2340.5199999999295
+2345.7199999999293
+2346.7599999999293
+2348.319999999929
+2349.879999999929
+2350.919999999929
+2355.079999999929
+2355.599999999929
+2357.159999999929
+2357.679999999929
+2360.799999999929
+2364.9599999999286
+2370.1599999999285
+2371.7199999999284
+2374.3199999999283
+2377.439999999928
+2377.959999999928
+2378.479999999928
+2379.519999999928
+2380.039999999928
+2381.079999999928
+2381.599999999928
+2383.159999999928
+2384.719999999928
+2385.759999999928
+2387.839999999928
+2394.5999999999276
+2395.6399999999276
+2396.6799999999275
+2397.1999999999275
+2405.519999999927
+2407.599999999927
+2409.159999999927
+2411.239999999927
+2416.439999999927
+2417.999999999927
+2422.6799999999266
+2427.3599999999265
+2428.9199999999264
+2432.0399999999263
+2434.119999999926
+2439.319999999926
+2445.559999999926
+2447.6399999999257
+2449.1999999999257
+2450.2399999999257
+2451.2799999999256
+2454.3999999999255
+2455.9599999999255
+2457.5199999999254
+2461.1599999999253
+2462.719999999925
+2464.799999999925
+2467.399999999925
+2473.639999999925
+2474.679999999925
+2477.2799999999247
+2477.7999999999247
+2485.0799999999244
+2489.7599999999243
+2491.319999999924
+2493.919999999924
+2495.479999999924
+2496.519999999924
+2498.079999999924
+2498.599999999924
+2502.239999999924
+2503.799999999924
+2507.4399999999237
+2510.0399999999236
+2513.6799999999234
+2515.7599999999234
+2516.7999999999233
+2520.439999999923
+2521.479999999923
+2529.279999999923
+2538.1199999999226
+2539.1599999999225
+2539.6799999999225
+2541.7599999999225
+2542.7999999999224
+2545.3999999999223
+2551.639999999922
+2552.679999999922
+2560.479999999922
+2562.0399999999217
+2562.5599999999217
+2565.1599999999216
+2569.8399999999215
+2570.3599999999215
+2571.9199999999214
+2573.9999999999213
+2574.5199999999213
+2577.639999999921
+2585.439999999921
+2590.6399999999207
+2594.2799999999206
+2595.3199999999206
+2597.9199999999205
+2598.4399999999205
+2605.71999999992
+2606.75999999992
+2609.35999999992
+2609.87999999992
+2610.39999999992
+2610.91999999992
+2611.95999999992
+2612.99999999992
+2617.67999999992
+2619.2399999999197
+2624.4399999999196
+2624.9599999999195
+2631.1999999999193
+2632.7599999999193
+2634.319999999919
+2638.479999999919
+2638.999999999919
+2643.679999999919
+2646.279999999919
+2648.8799999999187
+2650.9599999999186
+2655.6399999999185
+2687.8799999999173
+2689.9599999999173
+2698.799999999917
+2700.879999999917
+2705.0399999999167
+2707.1199999999167
+2709.7199999999166
+2710.7599999999165
+2712.8399999999165
+2719.5999999999162
+2720.119999999916
+2725.319999999916
+2726.359999999916
+2728.959999999916
+2731.039999999916
+2731.559999999916
+2738.3199999999156
+2741.9599999999155
+2742.4799999999154
+2745.0799999999153
+2759.119999999915
+2770.0399999999145
+2772.6399999999144
+2783.039999999914
+2783.559999999914
+2787.199999999914
+2790.8399999999137
+2791.8799999999137
+2796.5599999999135
+2800.1999999999134
+2801.2399999999134
+2802.2799999999133
+2805.3999999999132
+2806.959999999913
+2808.519999999913
+2810.599999999913
+2811.119999999913
+2813.199999999913
+2813.719999999913
+2815.799999999913
+2816.839999999913
+2819.4399999999127
+2820.4799999999127
+2821.5199999999127
+2824.1199999999126
+2826.7199999999125
+2827.7599999999125
+2829.3199999999124
+2831.9199999999123
+2834.519999999912
+2839.719999999912
+2841.279999999912
+2841.799999999912
+2844.399999999912
+2848.0399999999117
+2849.5999999999117
+2851.1599999999116
+2853.7599999999115
+2856.8799999999114
+2861.0399999999113
+2861.5599999999113
+2862.0799999999113
+2866.239999999911
+2866.759999999911
+2867.799999999911
+2874.039999999911
+2874.559999999911
+2875.599999999911
+2882.3599999999105
+2885.4799999999104
+2888.5999999999103
+2896.91999999991
+2900.03999999991
+2908.3599999999096
+2910.4399999999096
+2916.6799999999093
+2917.1999999999093
+2918.7599999999093
+2920.839999999909
+2927.079999999909
+2929.159999999909
+2931.239999999909
+2933.3199999999088
+2933.8399999999087
+2935.9199999999087
+2940.5999999999085
+2942.1599999999085
+2946.3199999999083
+2949.439999999908
+2949.959999999908
+2953.599999999908
+2954.639999999908
+2960.879999999908
+2961.9199999999078
+2966.0799999999076
+2966.5999999999076
+2967.1199999999076
+2967.6399999999076
+2969.1999999999075
+2981.159999999907
+2983.759999999907
+2984.799999999907
+2987.399999999907
+2988.959999999907
+2989.999999999907
+2992.0799999999067
+2994.1599999999066
+2997.2799999999065
+3000.3999999999064
+3000.9199999999064
+3001.9599999999064
+3002.9999999999063
+3005.5999999999062
+3009.759999999906
+3014.959999999906
+3016.519999999906
+3020.1599999999057
+3020.6799999999057
+3021.1999999999057
+3022.2399999999056
+3024.8399999999056
+3025.8799999999055
+3027.9599999999054
+3028.4799999999054
+3030.0399999999054
+3032.1199999999053
+3034.719999999905
+3035.759999999905
+3038.359999999905
+3041.999999999905
+3043.039999999905
+3048.2399999999047
+3050.3199999999047
+3050.8399999999046
+3052.9199999999046
+3053.9599999999045
+3054.9999999999045
+3056.0399999999045
+3057.5999999999044
+3059.1599999999044
+3063.839999999904
+3065.919999999904
+3070.599999999904
+3071.119999999904
+3082.5599999999035
+3083.5999999999035
+3085.6799999999034
+3088.2799999999033
+3090.8799999999032
+3091.919999999903
+3092.439999999903
+3092.959999999903
+3093.479999999903
+3097.639999999903
+3103.359999999903
+3103.879999999903
+3104.399999999903
+3111.6799999999025
+3115.3199999999024
+3115.8399999999024
+3116.3599999999024
+3116.8799999999023
+3121.039999999902
+3124.159999999902
+3125.199999999902
+3127.279999999902
+3129.359999999902
+3129.879999999902
+3130.919999999902
+3131.959999999902
+3135.5999999999017
+3138.7199999999016
+3139.2399999999016
+3139.7599999999015
+3140.2799999999015
+3140.7999999999015
+3141.3199999999015
+3142.3599999999014
+3146.5199999999013
+3148.0799999999012
+3149.119999999901
+3151.199999999901
+3151.719999999901
+3153.279999999901
+3154.319999999901
+3161.079999999901
+3162.1199999999008
+3163.1599999999007
+3174.5999999999003
+3175.1199999999003
+3175.6399999999003
+3180.8399999999
+3183.4399999999
+3184.4799999999
+3188.1199999999
+3190.7199999998998
+3192.7999999998997
+3197.4799999998995
+3199.0399999998995
+3204.7599999998993
+3205.7999999998992
+3206.839999999899
+3208.399999999899
+3211.519999999899
+3212.039999999899
+3217.759999999899
+3219.8399999998987
+3222.4399999998986
+3223.4799999998986
+3227.1199999998985
+3228.1599999998984
+3229.7199999998984
+3231.2799999998983
+3232.8399999998983
+3235.439999999898
+3235.959999999898
+3241.679999999898
+3242.199999999898
+3242.719999999898
+3245.839999999898
+3246.359999999898
+3247.399999999898
+3248.9599999998977
+3249.4799999998977
+3251.0399999998976
+3254.6799999998975
+3256.2399999998975
+3258.3199999998974
+3262.4799999998972
+3265.079999999897
+3265.599999999897
+3268.199999999897
+3269.759999999897
+3273.399999999897
+3283.2799999998965
+3287.9599999998964
+3291.599999999896
+3296.799999999896
+3298.879999999896
+3300.959999999896
+3302.519999999896
+3304.079999999896
+3304.5999999998958
+3305.1199999998958
+3305.6399999998957
+3306.1599999998957
+3306.6799999998957
+3309.2799999998956
+3311.3599999998955
+3313.4399999998955
+3320.199999999895
+3321.759999999895
+3326.439999999895
+3327.479999999895
+3328.519999999895
+3333.7199999998948
+3334.2399999998947
+3336.3199999998947
+3344.1199999998944
+3349.839999999894
+3350.359999999894
+3353.479999999894
+3356.079999999894
+3356.599999999894
+3361.7999999998938
+3364.9199999998937
+3371.1599999998934
+3371.6799999998934
+3373.2399999998934
+3377.399999999893
+3377.919999999893
+3379.479999999893
+3380.519999999893
+3381.039999999893
+3385.719999999893
+3391.9599999998927
+3398.1999999998925
+3399.7599999998924
+3401.8399999998924
+3402.3599999998924
+3405.999999999892
+3408.079999999892
+3409.119999999892
+3411.199999999892
+3412.759999999892
+3413.279999999892
+3414.319999999892
+3414.839999999892
+3416.399999999892
+3418.479999999892
+3418.9999999998918
+3423.1599999998916
+3433.0399999998913
+3433.5599999998913
+3437.719999999891
+3443.439999999891
+3443.959999999891
+3444.479999999891
+3446.559999999891
+3447.5999999998908
+3449.1599999998907
+3450.7199999998907
+3452.2799999998906
+3452.7999999998906
+3458.5199999998904
+3460.5999999998903
+3461.1199999998903
+3462.6799999998902
+3466.31999999989
+3467.87999999989
+3472.55999999989
+3476.7199999998898
+3477.7599999998897
+3485.5599999998894
+3486.0799999998894
+3486.5999999998894
+3487.6399999998894
+3488.1599999998894
+3494.919999999889
+3499.599999999889
+3500.119999999889
+3501.159999999889
+3502.719999999889
+3503.239999999889
+3503.759999999889
+3504.279999999889
+3505.8399999998887
+3508.4399999998886
+3508.9599999998886
+3511.0399999998886
+3516.2399999998884
+3518.8399999998883
+3520.919999999888
+3524.039999999888
+3527.159999999888
+3529.759999999888
+3534.9599999998877
+3535.4799999998877
+3535.9999999998877
+3540.1599999998875
+3542.2399999998875
+3548.999999999887
+3551.079999999887
+3556.799999999887
+3560.959999999887
+3563.5599999998867
+3564.0799999998867
+3566.1599999998866
+3568.2399999998865
+3568.7599999998865
+3571.8799999998864
+3576.0399999998863
+3579.159999999886
+3580.719999999886
+3581.239999999886
+3582.279999999886
+3593.7199999998857
+3597.8799999998855
+3599.9599999998854
+3603.5999999998853
+3604.6399999998853
+3609.319999999885
+3609.839999999885
+3610.879999999885
+3615.559999999885
+3616.079999999885
+3623.8799999998846
+3624.3999999998846
+3625.4399999998845
+3626.9999999998845
+3629.0799999998844
+3631.6799999998843
+3632.1999999998843
+3635.319999999884
+3635.839999999884
+3638.959999999884
+3643.119999999884
+3645.199999999884
+3649.8799999998837
+3650.3999999998837
+3651.4399999998836
+3651.9599999998836
+3656.6399999998835
+3657.1599999998834
+3664.959999999883
+3665.999999999883
+3667.559999999883
+3674.839999999883
+3675.359999999883
+3678.9999999998827
+3684.1999999998825
+3685.2399999998825
+3685.7599999998824
+3687.3199999998824
+3694.079999999882
+3702.919999999882
+3704.479999999882
+3707.5999999998817
+3714.3599999998814
+3720.0799999998812
+3720.599999999881
+3724.759999999881
+3725.799999999881
+3726.839999999881
+3729.959999999881
+3730.999999999881
+3731.519999999881
+3733.5999999998808
+3736.1999999998807
+3739.3199999998806
+3739.8399999998805
+3740.3599999998805
+3747.6399999998803
+3748.1599999998803
+3749.71999999988
+3750.23999999988
+3751.27999999988
+3752.83999999988
+3754.39999999988
+3757.51999999988
+3758.55999999988
+3759.07999999988
+3762.1999999998798
+3763.7599999998797
+3764.2799999998797
+3774.6799999998793
+3776.7599999998793
+3777.2799999998792
+3789.239999999879
+3791.8399999998787
+3795.9999999998786
+3796.5199999998786
+3797.5599999998785
+3801.1999999998784
+3802.2399999998784
+3805.8799999998782
+3809.519999999878
+3817.319999999878
+3817.839999999878
+3820.9599999998777
+3828.7599999998774
+3831.3599999998773
+3832.3999999998773
+3837.599999999877
+3842.799999999877
+3843.319999999877
+3848.5199999998767
+3849.0399999998767
+3850.5999999998767
+3851.1199999998767
+3852.1599999998766
+3854.2399999998765
+3854.7599999998765
+3856.8399999998765
+3860.9999999998763
+3862.5599999998763
+3865.679999999876
+3867.759999999876
+3868.799999999876
+3873.479999999876
+3875.039999999876
+3878.1599999998757
+3879.7199999998757
+3882.3199999998756
+3883.3599999998755
+3886.4799999998754
+3888.5599999998753
+3897.399999999875
+3899.999999999875
+3902.599999999875
+3907.2799999998747
+3910.3999999998746
+3912.4799999998745
+3914.5599999998744
+3916.6399999998744
+3920.2799999998742
+3921.839999999874
+3923.399999999874
+3924.439999999874
+3925.999999999874
+3930.679999999874
+3933.7999999998738
+3937.9599999998736
+3940.0399999998735
+3944.1999999998734
+3944.7199999998734
+3945.2399999998734
+3947.8399999998733
+3953.559999999873
+3955.639999999873
+3956.159999999873
+3957.199999999873
+3958.239999999873
+3960.839999999873
+3961.879999999873
+3963.4399999998727
+3975.9199999998723
+3979.039999999872
+3980.599999999872
+3984.759999999872
+3985.279999999872
+3990.479999999872
+3991.5199999998717
+3992.0399999998717
+4000.8799999998714
+4003.4799999998713
+4005.0399999998713
+4005.5599999998713
+4007.639999999871
+4009.199999999871
+4011.279999999871
+4015.439999999871
+4016.479999999871
+4021.6799999998707
+4022.1999999998707
+4023.7599999998706
+4028.4399999998705
+4029.9999999998704
+4030.5199999998704
+4034.1599999998703
+4037.79999999987
+4038.31999999987
+4040.91999999987
+4045.07999999987
+4047.15999999987
+4051.8399999998696
+4055.9999999998695
+4056.5199999998695
+4057.0399999998695
+4059.6399999998694
+4064.319999999869
+4075.239999999869
+4076.279999999869
+4076.7999999998688
+4080.9599999998686
+4083.0399999998685
+4086.1599999998684
+4087.1999999998684
+4087.7199999998684
+4090.3199999998683
+4094.479999999868
+4096.039999999868
+4099.159999999871
+4100.199999999872
+4101.239999999872
+4107.479999999878
+4110.59999999988
+4111.119999999881
+4114.759999999884
+4115.799999999885
+4126.199999999893
+4126.719999999894
+4132.439999999899
+4133.4799999998995
+4136.599999999902
+4139.199999999904
+4140.239999999905
+4141.279999999906
+4145.43999999991
+4145.95999999991
+4146.47999999991
+4151.159999999914
+4152.199999999915
+4153.7599999999165
+4155.319999999918
+4158.959999999921
+4159.999999999922
+4167.279999999928
+4168.319999999929
+4169.35999999993
+4172.999999999933
+4176.639999999936
+4177.159999999936
+4178.199999999937
+4179.239999999938
+4181.31999999994
+4189.119999999946
+4193.79999999995
+4194.839999999951
+4197.959999999954
+4200.039999999955
+4204.199999999959
+4205.23999999996
+4206.279999999961
+4209.399999999963
+4214.079999999967
+4215.6399999999685
+4216.159999999969
+4216.679999999969
+4217.71999999997
+4221.879999999974
+4225.519999999977
+4228.119999999979
+4229.67999999998
+4231.759999999982
+4232.2799999999825
+4236.439999999986
+4237.479999999987
+4237.999999999987
+4245.799999999994
+4250.479999999998
+4254.120000000001
+4255.160000000002
+4259.320000000005
+4263.480000000009
+4266.080000000011
+4267.120000000012
+4268.160000000013
+4269.2000000000135
+4270.760000000015
+4271.800000000016
+4275.960000000019
+4280.640000000023
+4281.1600000000235
+4281.680000000024
+4282.720000000025
+4288.44000000003
+4291.560000000032
+4296.240000000036
+4302.480000000041
+4304.040000000043
+4311.320000000049
+4316.520000000053
+4331.080000000065
+4333.160000000067
+4335.240000000069
+4343.040000000075
+4345.120000000077
+4345.640000000078
+4348.76000000008
+4354.480000000085
+4356.560000000087
+4361.240000000091
+4362.280000000092
+4362.800000000092
+4368.520000000097
+4375.2800000001025
+4376.840000000104
+4377.360000000104
+4378.400000000105
+4383.6000000001095
+4386.720000000112
+4391.9200000001165
+4399.200000000123
+4401.280000000124
+4402.320000000125
+4402.840000000126
+4404.920000000127
+4407.000000000129
+4408.04000000013
+4410.640000000132
+4412.720000000134
+4416.880000000137
+4422.600000000142
+4423.120000000143
+4425.200000000144
+4429.880000000148
+4433.520000000151
+4435.080000000153
+4435.600000000153
+4439.760000000157
+4443.92000000016
+4448.080000000164
+4448.600000000164
+4450.680000000166
+4454.840000000169
+4463.160000000176
+4465.240000000178
+4465.7600000001785
+4467.84000000018
+4470.960000000183
+4472.000000000184
+4472.520000000184
+4474.600000000186
+4475.120000000186
+4475.640000000187
+4476.680000000188
+4478.760000000189
+4480.840000000191
+4483.440000000193
+4487.080000000196
+4492.800000000201
+4493.840000000202
+4497.480000000205
+4500.080000000207
+4501.120000000208
+4502.160000000209
+4504.760000000211
+4507.880000000214
+4508.400000000214
+4513.600000000219
+4519.320000000223
+4526.080000000229
+4527.12000000023
+4528.680000000231
+4530.760000000233
+4531.800000000234
+4532.320000000234
+4544.800000000245
+4545.320000000245
+4546.880000000247
+4549.480000000249
+4552.080000000251
+4554.680000000253
+4555.720000000254
+4558.320000000256
+4559.360000000257
+4560.920000000258
+4564.560000000261
+4566.120000000263
+4566.640000000263
+4568.720000000265
+4571.320000000267
+4576.000000000271
+4577.040000000272
+4577.560000000272
+4579.640000000274
+4580.1600000002745
+4580.680000000275
+4581.720000000276
+4582.240000000276
+4583.280000000277
+4586.92000000028
+4587.960000000281
+4589.000000000282
+4593.680000000286
+4595.240000000287
+4595.760000000288
+4596.280000000288
+4600.440000000292
+4603.040000000294
+4606.160000000296
+4609.280000000299
+4611.360000000301
+4616.560000000305
+4620.720000000309
+4621.240000000309
+4623.840000000311
+4625.920000000313
+4626.960000000314
+4628.000000000315
+4632.680000000319
+4634.24000000032
+4638.400000000323
+4642.0400000003265
+4646.20000000033
+4646.72000000033
+4647.760000000331
+4649.840000000333
+4655.040000000337
+4656.080000000338
+4656.600000000339
+4657.64000000034
+4659.720000000341
+4662.840000000344
+4663.880000000345
+4665.960000000347
+4669.080000000349
+4674.2800000003535
+4675.840000000355
+4676.880000000356
+4677.920000000357
+4684.680000000362
+4690.9200000003675
+4692.480000000369
+4697.680000000373
+4698.720000000374
+4708.080000000382
+4711.720000000385
+4715.8800000003885
+4717.44000000039
+4722.640000000394
+4726.800000000398
+4727.320000000398
+4729.4000000004
+4730.440000000401
+4736.1600000004055
+4746.040000000414
+4746.560000000414
+4747.600000000415
+4749.680000000417
+4751.240000000418
+4752.280000000419
+4756.960000000423
+4759.560000000425
+4763.200000000428
+4773.0800000004365
+4775.160000000438
+4781.4000000004435
+4782.960000000445
+4787.120000000448
+4787.640000000449
+4788.160000000449
+4791.280000000452
+4793.880000000454
+4806.360000000464
+4810.520000000468
+4812.60000000047
+4815.720000000472
+4816.760000000473
+4817.800000000474
+4819.880000000476
+4820.920000000477
+4826.640000000481
+4831.840000000486
+4832.360000000486
+4833.400000000487
+4833.920000000488
+4834.960000000488
+4837.560000000491
+4839.640000000492
+4844.840000000497
+4846.400000000498
+4847.440000000499
+4849.520000000501
+4857.840000000508
+4861.480000000511
+4862.520000000512
+4864.080000000513
+4865.120000000514
+4866.160000000515
+4867.2000000005155
+4867.720000000516
+4868.240000000516
+4868.760000000517
+4870.320000000518
+4873.960000000521
+4874.480000000522
+4876.040000000523
+4880.200000000526
+4881.240000000527
+4881.760000000528
+4890.080000000535
+4894.760000000539
+4895.8000000005395
+4897.360000000541
+4900.480000000543
+4902.040000000545
+4908.80000000055
+4911.920000000553
+4915.560000000556
+4916.0800000005565
+4930.120000000568
+4930.640000000569
+4932.7200000005705
+4934.800000000572
+4941.0400000005775
+4942.080000000578
+4943.64000000058
+4948.840000000584
+4955.60000000059
+4957.6800000005915
+4959.240000000593
+4964.960000000598
+4965.480000000598
+4966.520000000599
+4970.680000000602
+4971.200000000603
+4971.720000000603
+4973.280000000605
+4976.920000000608
+4977.440000000608
+4979.000000000609
+4979.52000000061
+4983.680000000613
+4984.720000000614
+4987.320000000616
+4990.960000000619
+4996.680000000624
+4997.200000000625
+4998.760000000626
+4999.800000000627
+5001.360000000628
+5001.880000000629
+5009.680000000635
+5011.240000000636
+5011.760000000637
+5012.800000000638
+5015.40000000064
+5017.480000000642
+5018.000000000642
+5020.080000000644
+5021.640000000645
+5022.160000000646
+5023.2000000006465
+5026.320000000649
+5028.920000000651
+5034.640000000656
+5042.440000000663
+5043.4800000006635
+5052.840000000671
+5053.360000000672
+5054.920000000673
+5058.040000000676
+5061.680000000679
+5063.7600000006805
+5064.280000000681
+5066.360000000683
+5068.960000000685
+5073.640000000689
+5075.720000000691
+5076.240000000691
+5076.760000000691
+5077.280000000692
+5079.360000000694
+5079.880000000694
+5082.480000000696
+5085.080000000698
+5085.600000000699
+5086.120000000699
+5087.1600000007
+5087.680000000701
+5088.200000000701
+5090.280000000703
+5092.880000000705
+5093.920000000706
+5096.000000000708
+5107.440000000717
+5111.08000000072
+5111.600000000721
+5112.120000000721
+5114.200000000723
+5115.760000000724
+5116.280000000725
+5117.840000000726
+5120.440000000728
+5123.560000000731
+5125.120000000732
+5126.160000000733
+5127.720000000734
+5128.760000000735
+5129.2800000007355
+5132.400000000738
+5134.48000000074
+5136.560000000742
+5138.120000000743
+5143.320000000747
+5143.840000000748
+5145.400000000749
+5146.96000000075
+5147.480000000751
+5148.520000000752
+5149.040000000752
+5151.120000000754
+5151.640000000754
+5154.760000000757
+5156.840000000759
+5158.40000000076
+5163.600000000764
+5164.640000000765
+5165.160000000766
+5168.280000000768
+5169.320000000769
+5170.36000000077
+5171.400000000771
+5171.920000000771
+5175.560000000774
+5176.080000000775
+5177.640000000776
+5179.200000000777
+5180.240000000778
+5184.400000000782
+5187.000000000784
+5188.560000000785
+5192.720000000789
+5194.28000000079
+5197.920000000793