<commit_before>if (! FormField); var FormField = {};

FormField.makeModule = function(module, module_settings) {
    module.enableDrawing = function(map, drawncallback, startovercallback) {
        var drawControl = new L.Control.Draw({
            position: 'topright',
            polygon: module_settings.enableDrawing.is_polygon,
            rectangle: false,
            circle: false,
            marker: module_settings.enableDrawing.is_marker,
            polyline: module_settings.enableDrawing.is_polyline && {
                shapeOptions: {
                    color: '#35FF00',
                    opacity: 0.8,
                    weight: 3
                }
            }
        });
        map.addControl(drawControl);
        map.drawControl = drawControl;

        // Delete current on first clic (start drawing)
        map.on('click', function (e) {
            // Delete current on clic if drawing
            for (var handlertype in map.drawControl.handlers) {
                if (map.drawControl.handlers[handlertype].enabled()) {
                    startovercallback();
                    return;
                }
            }
        });

        // Show control as enabled on activation
        for (var h in map.drawControl.handlers) {
            map.drawControl.handlers[h].on('activated', function () {
                $('.leaflet-control-draw-' + h).parent().addClass('enabled');
            });
        }

        // Listen to all events of creation, Leaflet.Draw naming inconsistency
        var draw_types = {
            'polyline': 'poly',
            'point': 'marker',
            'polygon': 'polygon',
        };
        for (var geomtype in draw_types) {
            var draw_type = draw_types[geomtype];
            map.on('draw:' + draw_type + '-created', L.Util.bind(function (e) {
                console.log('Drawn ' + this.type);
                var drawn = e[this.type];  // Leaflet.Draw naming inconsistency

                // Show control as disabled after creation
                for (var h in map.drawControl.handlers) {
                    $('.leaflet-control-draw-' + h).parent().removeClass('enabled');
                }
                drawncallback(drawn);
            }, {type: draw_type}));
        }
    };

    module.enablePathSnapping = function(map, modelname, objectsLayer) {
        var snapObserver = null;
        // Snapping is always on paths layer. But only if model is not path,
        // since snapping will then be on objects layer.
        // Allows to save loading twice the same layer.
        if (modelname != 'path') {
            var pathsLayer = new MapEntity.ObjectsLayer(null, {
                style: {weight: 2, clickable: true, color: module_settings.colors.paths},
            });
            map.addLayer(pathsLayer);
            snapObserver = new MapEntity.SnapObserver(map, pathsLayer);
            // Start ajax loading at last
            pathsLayer.load(module_settings.enablePathSnapping.pathsLayer_url);
        }
        else {
            snapObserver = new MapEntity.SnapObserver(map, objectsLayer);
        }
        return snapObserver;
    };

    // Returns the pk of the mapentity object if it exists
    // FIXME: $('form') => fails if there are more than one form
    module.getObjectPk = function() {
        // On creation, this should be null
        return $('form input[name="pk"]').val() || null;
    };

    module.addObjectsLayer = function(map, modelname) {
        if (!modelname) {
            throw 'Model name is empty';
        }
        var object_pk = module.getObjectPk();

        var exclude_current_object = null;
        if (object_pk) {
            exclude_current_object = function (geojson) {
                if (geojson.properties && geojson.properties.pk)
                    return geojson.properties.pk != object_pk;
            }
        }

        // Start loading all objects, readonly
        var color = modelname == 'path' ? module_settings.colors.paths : module_settings.colors.others;
        var objectsLayer = new MapEntity.ObjectsLayer(null, {
            style: {weight: 2, clickable: true, 'color': color},
                filter: exclude_current_object
            }),
            url = module_settings.addObjectsLayer.getUrl(modelname);
        map.addLayer(objectsLayer);
        objectsLayer.load(url);
        return objectsLayer;
    };

    module.enableMultipath = function(map, objectsLayer, layerStore, onStartOver, snapObserver) {
        objectsLayer.on('load', function() {

            var parseGraph = function (graph) {

                var multipath_control = new L.Control.Multipath(map, objectsLayer, graph, snapObserver, {
                        handler: {
                            'iconUrl': module_settings.init.iconUrl,
                            'shadowUrl': module_settings.init.shadowUrl,
                            'iconDragUrl': module_settings.init.iconDragUrl,
                        }
                    })
                  , multipath_handler = multipath_control.multipath_handler
                ;

                onStartOver.on('startover', function(obj) {
                    // If startover is not trigger by multipath, delete the geom
                    // Thus, when multipath is called several times, the geom is not deleted
                    // and may be updated
                    if (obj.handler !== 'multipath') {
                        multipath_handler.showPathGeom(null);
                    }
                    if (obj.handler == 'topologypoint') {
                        // Disable multipath
                        multipath_handler.reset();
                        if (multipath_handler.enabled()) multipath_control.toggle();
                    }
                });
                // Delete previous geom
                multipath_handler.on('enabled', function() {
                    onStartOver.fire('startover', {'handler': 'multipath'});
                });

                multipath_handler.on('computed_topology', function (e) {
                    layerStore.storeLayerGeomInField(e.topology);
                });

                map.addControl(multipath_control);

                var initialTopology = layerStore.getSerialized();

                // We should check if the form has an error or not...
                // core.models#TopologyMixin.serialize
                if (initialTopology) {
                    var topo =  JSON.parse(initialTopology);
                    // If it is multipath, restore
                    if (topo.paths && !topo.lat && !topo.lng) {
                        multipath_handler.restoreTopology(topo);
                    }
                }
            };

            $.getJSON(module_settings.enableMultipath.path_json_graph_url, parseGraph).error(function (jqXHR, textStatus, errorThrown) {
                $(map._container).addClass('map-error');
                console.error("Could not load url '" + module_settings.enableMultipath.path_json_graph_url + "': " + textStatus);
                console.error(errorThrown);
            });
        });
    };

    module.enableTopologyPoint = function (map, drawncallback, onStartOver) {
        var control = new L.Control.TopologyPoint(map)
          , handler = control.topologyhandler;
        map.addControl(control);

        // Delete current on first clic (start drawing)
        handler.on('enabled', function (e) {
            onStartOver.fire('startover', {'handler': 'topologypoint'});
        });

        handler.on('added', function (e) {
            drawncallback(e.marker);
        });
    };

    module.init = function(map, bounds, fitToBounds) {
        fitToBounds = fitToBounds === undefined ? true : fitToBounds;

        map.removeControl(map.attributionControl);

        map.addControl(new L.Control.Measurement());

        /*** <Map bounds and reset> ***/

        var initialBounds = bounds,
            objectBounds = module_settings.init.objectBounds,
            currentBounds = objectBounds || initialBounds;

        var getBounds = function () {
            return currentBounds;
        };

        if (fitToBounds) {
            map.fitBounds(currentBounds);
        }

        map.addControl(new L.Control.ResetView(getBounds));
        map.addControl(new L.Control.Scale());

        // Show other objects of same type
        var modelname = $('form input[name="model"]').val(),
            objectsLayer = module.addObjectsLayer(map, modelname);

        // Enable snapping ? Multipath need path snapping too !
        var path_snapping = module_settings.init.pathsnapping || module_settings.init.multipath,
            snapObserver = null;
        MapEntity.MarkerSnapping.prototype.SNAP_DISTANCE = module_settings.enablePathSnapping.SNAP_DISTANCE;

        if (path_snapping) {
            snapObserver = module.enablePathSnapping(map, modelname, objectsLayer);
        }

        var layerStore = MapEntity.makeGeoFieldProxy($(module_settings.init.layerStoreElemSelector));
        layerStore.setTopologyMode(module_settings.init.multipath || module_settings.init.topologypoint);

        /*** <objectLayer> ***/

        function _edit_handler(map, layer) {
            var edit_handler = L.Handler.PolyEdit;
            if (path_snapping) {
                edit_handler = L.Handler.SnappedEdit;
                if (layer instanceof L.Marker) {
                    edit_handler =  MapEntity.MarkerSnapping;
                }
            }
            return new edit_handler(map, layer);
        };

        function onNewLayer(new_layer) {
            if (new_layer instanceof L.Marker) {
                currentBounds = map.getBounds(); // A point has no bounds, take map bounds
                // Set custom icon, using CSS instead of JS
                new_layer.setIcon(new L.Icon({
                        iconUrl: module_settings.init.iconUrl,
                        shadowUrl: module_settings.init.shadowUrl,
                        iconSize: new L.Point(25, 41),
                        iconAnchor: new L.Point(13, 41),
                        popupAnchor: new L.Point(1, -34),
                        shadowSize: new L.Point(41, 41)
                    }));
                $(new_layer._icon).addClass('marker-add');

            }
            else {
                currentBounds = new_layer.getBounds();
            }
            new_layer.editing = _edit_handler(map, new_layer);
            new_layer.editing.enable();
            new_layer.on('move edit', function (e) {
                layerStore.storeLayerGeomInField(e.target);
            });
            layerStore.storeLayerGeomInField(new_layer);
            if (snapObserver) snapObserver.add(new_layer);
        }

        var geojson = module_settings.init.geojson;  // If no field, will be null.
        if (geojson) {
            var objectLayer = new L.GeoJSON(geojson, {
                style: {weight: 5, opacity: 1, clickable: true},
                onEachFeature: function (feature, layer) {
                    onNewLayer(layer);
                }
            });
            map.addLayer(objectLayer);
        }

        /*** </objectLayer> ***/

        /*** <drawing> ***/

        var onDrawn = function (drawn_layer) {
            map.addLayer(drawn_layer);
            onNewLayer(drawn_layer);
        };

        var removeLayerFromLayerStore = function () {
            var old_layer = layerStore.getLayer();
            if (old_layer) {
                map.removeLayer(old_layer);
                if (snapObserver) snapObserver.remove(old_layer);
                currentBounds = initialBounds;
                layerStore.storeLayerGeomInField(null);
            }
        };

        var onStartOver = L.Util.extend({}, L.Mixin.Events);
        onStartOver.on('startover', removeLayerFromLayerStore);

        if (module_settings.init.enableDrawing) {
            module.enableDrawing(map, onDrawn, removeLayerFromLayerStore);
        }

        if (module_settings.init.multipath) {
            module.enableMultipath(map, snapObserver.guidesLayer(), layerStore, onStartOver, snapObserver);
        }

        if (module_settings.init.topologypoint) {
            module.enableTopologyPoint(map, onDrawn, onStartOver);
        }
    };

    return module;
};
<commit_msg>Rework formfield.js topology multipath (ref #329)<commit_after>if (! FormField); var FormField = {};

FormField.makeModule = function(module, module_settings) {
    module.enableDrawing = function(map, drawncallback, startovercallback) {
        var drawControl = new L.Control.Draw({
            position: 'topright',
            polygon: module_settings.enableDrawing.is_polygon,
            rectangle: false,
            circle: false,
            marker: module_settings.enableDrawing.is_marker,
            polyline: module_settings.enableDrawing.is_polyline && {
                shapeOptions: {
                    color: '#35FF00',
                    opacity: 0.8,
                    weight: 3
                }
            }
        });
        map.addControl(drawControl);
        map.drawControl = drawControl;

        // Delete current on first clic (start drawing)
        map.on('click', function (e) {
            // Delete current on clic if drawing
            for (var handlertype in map.drawControl.handlers) {
                if (map.drawControl.handlers[handlertype].enabled()) {
                    startovercallback();
                    return;
                }
            }
        });

        // Show control as enabled on activation
        for (var h in map.drawControl.handlers) {
            map.drawControl.handlers[h].on('activated', function () {
                $('.leaflet-control-draw-' + h).parent().addClass('enabled');
            });
        }

        // Listen to all events of creation, Leaflet.Draw naming inconsistency
        var draw_types = {
            'polyline': 'poly',
            'point': 'marker',
            'polygon': 'polygon',
        };
        for (var geomtype in draw_types) {
            var draw_type = draw_types[geomtype];
            map.on('draw:' + draw_type + '-created', L.Util.bind(function (e) {
                console.log('Drawn ' + this.type);
                var drawn = e[this.type];  // Leaflet.Draw naming inconsistency

                // Show control as disabled after creation
                for (var h in map.drawControl.handlers) {
                    $('.leaflet-control-draw-' + h).parent().removeClass('enabled');
                }
                drawncallback(drawn);
            }, {type: draw_type}));
        }
    };

    module.enablePathSnapping = function(map, modelname, objectsLayer) {
        var snapObserver = null;
        // Snapping is always on paths layer. But only if model is not path,
        // since snapping will then be on objects layer.
        // Allows to save loading twice the same layer.
        if (modelname != 'path') {
            var pathsLayer = new MapEntity.ObjectsLayer(null, {
                style: {weight: 2, clickable: true, color: module_settings.colors.paths},
            });
            map.addLayer(pathsLayer);
            snapObserver = new MapEntity.SnapObserver(map, pathsLayer);
            // Start ajax loading at last
            pathsLayer.load(module_settings.enablePathSnapping.pathsLayer_url);
        }
        else {
            snapObserver = new MapEntity.SnapObserver(map, objectsLayer);
        }
        return snapObserver;
    };

    // Returns the pk of the mapentity object if it exists
    // FIXME: $('form') => fails if there are more than one form
    module.getObjectPk = function() {
        // On creation, this should be null
        return $('form input[name="pk"]').val() || null;
    };

    module.getModelName = function() {
        // Expect failure if null
        var m = $('form input[name="model"]').val() || null;
        if (!m)
            throw "No model name in form";
        return m;
    };

    module.addObjectsLayer = function(map, modelname) {
        if (!modelname) {
            throw 'Model name is empty';
        }
        var object_pk = module.getObjectPk();

        var exclude_current_object = null;
        if (object_pk) {
            exclude_current_object = function (geojson) {
                if (geojson.properties && geojson.properties.pk)
                    return geojson.properties.pk != object_pk;
            }
        }

        // Start loading all objects, readonly
        var color = modelname == 'path' ? module_settings.colors.paths : module_settings.colors.others;
        var objectsLayer = new MapEntity.ObjectsLayer(null, {
            style: {weight: 2, clickable: true, 'color': color},
                filter: exclude_current_object
            }),
            url = module_settings.addObjectsLayer.getUrl(modelname);
        map.addLayer(objectsLayer);
        objectsLayer.load(url);
        return objectsLayer;
    };

    module.enableMultipath = function(map, snapObserver, layerStore, onStartOver) {
        var objectsLayer = snapObserver.guidesLayer();

        var multipath_control = new L.Control.Multipath(map, objectsLayer, graph, snapObserver, {
            handler: {
                'iconUrl': module_settings.init.iconUrl,
                'shadowUrl': module_settings.init.shadowUrl,
                'iconDragUrl': module_settings.init.iconDragUrl,
            }
        }),
        multipath_handler = multipath_control.multipath_handler;

        onStartOver.on('startover', function(obj) {
            // If startover is not trigger by multipath, delete the geom
            // Thus, when multipath is called several times, the geom is not deleted
            // and may be updated
            if (obj.handler !== 'multipath') {
                multipath_handler.showPathGeom(null);
            }
            if (obj.handler == 'topologypoint') {
                // Disable multipath
                multipath_handler.reset();
                if (multipath_handler.enabled()) multipath_control.toggle();
            }
        });

        // Delete previous geom
        multipath_handler.on('enabled', function() {
            onStartOver.fire('startover', {'handler': 'multipath'});
        });

        multipath_handler.on('computed_topology', function (e) {
            layerStore.storeLayerGeomInField(e.topology);
        });

        objectsLayer.on('load', function() {
            // Load graph
            $.getJSON(module_settings.enableMultipath.path_json_graph_url, function (graph) {

                // Add control to the map
                map.addControl(multipath_control);

                // We should check if the form has an error or not...
                // core.models#TopologyMixin.serialize
                var initialTopology = layerStore.getSerialized();
                if (initialTopology) {
                    var topo =  JSON.parse(initialTopology);
                    // If it is multipath, restore
                    if (topo.paths && !topo.lat && !topo.lng) {
                        multipath_handler.restoreTopology(topo);
                    }
                }
            })
            .error(function (jqXHR, textStatus, errorThrown) {
                $(map._container).addClass('map-error');
                console.error("Could not load url '" + module_settings.enableMultipath.path_json_graph_url + "': " + textStatus);
                console.error(errorThrown);
            });
        });
    };

    module.enableTopologyPoint = function (map, layerStore, drawncallback, onStartOver) {
        var control = new L.Control.TopologyPoint(map)
          , handler = control.topologyhandler;
        map.addControl(control);

        // Delete current on first clic (start drawing)
        handler.on('enabled', function (e) {
            onStartOver.fire('startover', {'handler': 'topologypoint'});
        });

        handler.on('added', function (e) {
            drawncallback(e.marker);
        });

        var initialTopology = layerStore.getSerialized();
        if (initialTopology) {
            var point =  JSON.parse(initialTopology);
            // If it is multipath, restore
            if (point.lat && point.lng) {
                drawncallback(L.marker(new L.LatLng(point.lat, point.lng)));
            }
        }
    };

    module.init = function(map, bounds, fitToBounds) {
        fitToBounds = fitToBounds === undefined ? true : fitToBounds;

        map.removeControl(map.attributionControl);

        map.addControl(new L.Control.Measurement());

        /*** <Map bounds and reset> ***/

        var initialBounds = bounds,
            objectBounds = module_settings.init.objectBounds,
            currentBounds = objectBounds || initialBounds;

        var getBounds = function () {
            return currentBounds;
        };

        if (fitToBounds) {
            map.fitBounds(currentBounds);
        }

        map.addControl(new L.Control.ResetView(getBounds));
        map.addControl(new L.Control.Scale());

        // Show other objects of same type
        var modelname = module.getModelName(),
            objectsLayer = module.addObjectsLayer(map, modelname);

        // Enable snapping ? Multipath need path snapping too !
        var path_snapping = module_settings.init.pathsnapping || module_settings.init.multipath,
            snapObserver = null;
        MapEntity.MarkerSnapping.prototype.SNAP_DISTANCE = module_settings.enablePathSnapping.SNAP_DISTANCE;

        if (path_snapping) {
            snapObserver = module.enablePathSnapping(map, modelname, objectsLayer);
        }

        var layerStore = MapEntity.makeGeoFieldProxy($(module_settings.init.layerStoreElemSelector));
        layerStore.setTopologyMode(module_settings.init.multipath || module_settings.init.topologypoint);

        /*** <objectLayer> ***/

        function _edit_handler(map, layer) {
            var edit_handler = L.Handler.PolyEdit;
            if (path_snapping) {
                edit_handler = L.Handler.SnappedEdit;
                if (layer instanceof L.Marker) {
                    edit_handler =  MapEntity.MarkerSnapping;
                }
            }
            return new edit_handler(map, layer);
        };

        function onNewLayer(new_layer) {
            if (new_layer instanceof L.Marker) {
                currentBounds = map.getBounds(); // A point has no bounds, take map bounds
                // Set custom icon, using CSS instead of JS
                new_layer.setIcon(new L.Icon({
                        iconUrl: module_settings.init.iconUrl,
                        shadowUrl: module_settings.init.shadowUrl,
                        iconSize: new L.Point(25, 41),
                        iconAnchor: new L.Point(13, 41),
                        popupAnchor: new L.Point(1, -34),
                        shadowSize: new L.Point(41, 41)
                    }));
                $(new_layer._icon).addClass('marker-add');

            }
            else {
                currentBounds = new_layer.getBounds();
            }
            new_layer.editing = _edit_handler(map, new_layer);
            new_layer.editing.enable();
            new_layer.on('move edit', function (e) {
                layerStore.storeLayerGeomInField(e.target);
            });
            layerStore.storeLayerGeomInField(new_layer);
            if (snapObserver) snapObserver.add(new_layer);
        }

        var geojson = module_settings.init.geojson;  // If no field, will be null.
        if (geojson) {
            var objectLayer = new L.GeoJSON(geojson, {
                style: {weight: 5, opacity: 1, clickable: true},
                onEachFeature: function (feature, layer) {
                    onNewLayer(layer);
                }
            });
            map.addLayer(objectLayer);
        }

        /*** </objectLayer> ***/

        /*** <drawing> ***/

        var onDrawn = function (drawn_layer) {
            map.addLayer(drawn_layer);
            onNewLayer(drawn_layer);
        };

        var removeLayerFromLayerStore = function () {
            var old_layer = layerStore.getLayer();
            if (old_layer) {
                map.removeLayer(old_layer);
                if (snapObserver) snapObserver.remove(old_layer);
                currentBounds = initialBounds;
                layerStore.storeLayerGeomInField(null);
            }
        };

        var onStartOver = L.Util.extend({}, L.Mixin.Events);
        onStartOver.on('startover', removeLayerFromLayerStore);

        if (module_settings.init.enableDrawing) {
            module.enableDrawing(map, onDrawn, removeLayerFromLayerStore);
        }

        if (module_settings.init.multipath) {
            module.enableMultipath(map, snapObserver, layerStore, onStartOver);
        }

        if (module_settings.init.topologypoint) {
            module.enableTopologyPoint(map, layerStore, onDrawn, onStartOver);
        }
    };

    return module;
};
<|endoftext|>


<commit_before>import {test} from "ramda"
import {complement} from "ramda"
import escapeStringRegexp from "escape-string-regexp"

export default function lacksText (subset: string | RegExp): Function {
  const escaped = escapeStringRegexp(subset)
  const pattern = test(new RegExp(escaped))

  return function lacksTextSubset (set: string): boolean {
    return complement(pattern)(set)
  }
}
<commit_msg>Might as well preload<commit_after>import {test} from "ramda"
import {complement} from "ramda"
import escapeStringRegexp from "escape-string-regexp"

export default function lacksText (subset: string | RegExp): Function {
  const escaped = escapeStringRegexp(subset)
  const pattern = test(new RegExp(escaped))
  const patternMatched = complement(pattern)

  return function lacksTextSubset (set: string): boolean {
    return patternMatched(set)
  }
}
<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/Cartesian3',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/destroyObject',
        '../Core/Ellipsoid',
        '../Core/EllipsoidGeometry',
        '../Core/GeometryPipeline',
        '../Core/VertexFormat',
        '../Renderer/BufferUsage',
        '../Renderer/createShaderSource',
        '../Renderer/DrawCommand',
        '../Shaders/SkyAtmosphereFS',
        '../Shaders/SkyAtmosphereVS',
        './BlendingState',
        './CullFace',
        './SceneMode'
    ], function(
        Cartesian3,
        defaultValue,
        defined,
        defineProperties,
        destroyObject,
        Ellipsoid,
        EllipsoidGeometry,
        GeometryPipeline,
        VertexFormat,
        BufferUsage,
        createShaderSource,
        DrawCommand,
        SkyAtmosphereFS,
        SkyAtmosphereVS,
        BlendingState,
        CullFace,
        SceneMode) {
    "use strict";

    /**
     * An atmosphere drawn around the limb of the provided ellipsoid.  Based on
     * {@link http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering}
     * in GPU Gems 2.
     *

     * This is only supported in 3D.  atmosphere is faded out when morphing to 2D or Columbus view.
     *

     *
     * @alias SkyAtmosphere
     * @constructor
     *
     * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around.
     *
     * @example
     * scene.skyAtmosphere = new Cesium.SkyAtmosphere();
     *
     * @see Scene.skyAtmosphere
     */
    var scalarScratch = new Cartesian3();
    var SkyAtmosphere = function(ellipsoid) {
        ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);

        /**
         * Determines if the atmosphere is shown.
         *
         * @type {Boolean}
         * @default true
         */
        this.show = true;

        this._ellipsoid = ellipsoid;
        this._command = new DrawCommand({
            owner : this
        });
        this._spSkyFromSpace = undefined;
        this._spSkyFromAtmosphere = undefined;

        this._fCameraHeight = undefined;
        this._fCameraHeight2 = undefined;
        this._outerRadius = Cartesian3.getMaximumComponent(Cartesian3.multiplyByScalar(ellipsoid.radii, 1.025, scalarScratch));
        var innerRadius = ellipsoid.maximumRadius;
        var rayleighScaleDepth = 0.25;

        var that = this;

        this._command.uniformMap = {
            fCameraHeight : function() {
                return that._fCameraHeight;
            },
            fCameraHeight2 : function() {
                return that._fCameraHeight2;
            },
            fOuterRadius : function() {
                return that._outerRadius;
            },
            fOuterRadius2 : function() {
                return that._outerRadius * that._outerRadius;
            },
            fInnerRadius : function() {
                return innerRadius;
            },
            fScale : function() {
                return 1.0 / (that._outerRadius - innerRadius);
            },
            fScaleDepth : function() {
                return rayleighScaleDepth;
            },
            fScaleOverScaleDepth : function() {
                return (1.0 / (that._outerRadius - innerRadius)) / rayleighScaleDepth;
            }
        };
    };

    defineProperties(SkyAtmosphere.prototype, {
        /**
         * Gets the ellipsoid the atmosphere is drawn around.
         * @memberof SkyAtmosphere.prototype
         * @type {Ellipsoid}
         */
        ellipsoid : {
            get : function() {
                return this._ellipsoid;
            }
        }
    });

    /**
     * @private
     */
    SkyAtmosphere.prototype.update = function(context, frameState) {
        if (!this.show) {
            return undefined;
        }

        if ((frameState.mode !== SceneMode.SCENE3D) &&
            (frameState.mode !== SceneMode.MORPHING)) {
            return undefined;
        }

        // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc.
        if (!frameState.passes.render) {
            return undefined;
        }

        var command = this._command;

        if (!defined(command.vertexArray)) {
            var geometry = EllipsoidGeometry.createGeometry(new EllipsoidGeometry({
                radii : Cartesian3.multiplyByScalar(this._ellipsoid.radii, 1.025, scalarScratch),
                slicePartitions : 256,
                stackPartitions : 256,
                vertexFormat : VertexFormat.POSITION_ONLY
            }));
            command.vertexArray = context.createVertexArrayFromGeometry({
                geometry : geometry,
                attributeLocations : GeometryPipeline.createAttributeLocations(geometry),
                bufferUsage : BufferUsage.STATIC_DRAW
            });
            command.renderState = context.createRenderState({
                cull : {
                    enabled : true,
                    face : CullFace.FRONT
                },
                blending : BlendingState.ALPHA_BLEND
            });

            var vs = createShaderSource({
                defines : ['SKY_FROM_SPACE'],
                sources : [SkyAtmosphereVS]
            });
            this._spSkyFromSpace = context.createShaderProgram(vs, SkyAtmosphereFS);

            vs = createShaderSource({
                defines : ['SKY_FROM_ATMOSPHERE'],
                sources : [SkyAtmosphereVS]
            });
            this._spSkyFromAtmosphere = context.createShaderProgram(vs, SkyAtmosphereFS);
        }

        var cameraPosition = frameState.camera.positionWC;

        this._fCameraHeight2 = Cartesian3.magnitudeSquared(cameraPosition);
        this._fCameraHeight = Math.sqrt(this._fCameraHeight2);

        if (this._fCameraHeight > this._outerRadius) {
            // Camera in space
            command.shaderProgram = this._spSkyFromSpace;
        } else {
            // Camera in atmosphere
            command.shaderProgram = this._spSkyFromAtmosphere;
        }

        return command;
    };

    /**
     * Returns true if this object was destroyed; otherwise, false.
     *

     * If this object was destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.
     *
     * @returns {Boolean} true if this object was destroyed; otherwise, false.
     *
     * @see SkyAtmosphere#destroy
     */
    SkyAtmosphere.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
     * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @returns {undefined}
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @see SkyAtmosphere#isDestroyed
     *
     * @example
     * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy();
     */
    SkyAtmosphere.prototype.destroy = function() {
        var command = this._command;
        command.vertexArray = command.vertexArray && command.vertexArray.destroy();
        this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy();
        this._spSkyFromAtmosphere = this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy();
        return destroyObject(this);
    };

    return SkyAtmosphere;
});<commit_msg>Remove scratch.<commit_after>/*global define*/
define([
        '../Core/Cartesian3',
        '../Core/defaultValue',
        '../Core/defined',
        '../Core/defineProperties',
        '../Core/destroyObject',
        '../Core/Ellipsoid',
        '../Core/EllipsoidGeometry',
        '../Core/GeometryPipeline',
        '../Core/VertexFormat',
        '../Renderer/BufferUsage',
        '../Renderer/createShaderSource',
        '../Renderer/DrawCommand',
        '../Shaders/SkyAtmosphereFS',
        '../Shaders/SkyAtmosphereVS',
        './BlendingState',
        './CullFace',
        './SceneMode'
    ], function(
        Cartesian3,
        defaultValue,
        defined,
        defineProperties,
        destroyObject,
        Ellipsoid,
        EllipsoidGeometry,
        GeometryPipeline,
        VertexFormat,
        BufferUsage,
        createShaderSource,
        DrawCommand,
        SkyAtmosphereFS,
        SkyAtmosphereVS,
        BlendingState,
        CullFace,
        SceneMode) {
    "use strict";

    /**
     * An atmosphere drawn around the limb of the provided ellipsoid.  Based on
     * {@link http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering}
     * in GPU Gems 2.
     *

     * This is only supported in 3D.  atmosphere is faded out when morphing to 2D or Columbus view.
     *

     *
     * @alias SkyAtmosphere
     * @constructor
     *
     * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around.
     *
     * @example
     * scene.skyAtmosphere = new Cesium.SkyAtmosphere();
     *
     * @see Scene.skyAtmosphere
     */
    var SkyAtmosphere = function(ellipsoid) {
        ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);

        /**
         * Determines if the atmosphere is shown.
         *
         * @type {Boolean}
         * @default true
         */
        this.show = true;

        this._ellipsoid = ellipsoid;
        this._command = new DrawCommand({
            owner : this
        });
        this._spSkyFromSpace = undefined;
        this._spSkyFromAtmosphere = undefined;

        this._fCameraHeight = undefined;
        this._fCameraHeight2 = undefined;
        this._outerRadius = Cartesian3.getMaximumComponent(Cartesian3.multiplyByScalar(ellipsoid.radii, 1.025, new Cartesian3()));
        var innerRadius = ellipsoid.maximumRadius;
        var rayleighScaleDepth = 0.25;

        var that = this;

        this._command.uniformMap = {
            fCameraHeight : function() {
                return that._fCameraHeight;
            },
            fCameraHeight2 : function() {
                return that._fCameraHeight2;
            },
            fOuterRadius : function() {
                return that._outerRadius;
            },
            fOuterRadius2 : function() {
                return that._outerRadius * that._outerRadius;
            },
            fInnerRadius : function() {
                return innerRadius;
            },
            fScale : function() {
                return 1.0 / (that._outerRadius - innerRadius);
            },
            fScaleDepth : function() {
                return rayleighScaleDepth;
            },
            fScaleOverScaleDepth : function() {
                return (1.0 / (that._outerRadius - innerRadius)) / rayleighScaleDepth;
            }
        };
    };

    defineProperties(SkyAtmosphere.prototype, {
        /**
         * Gets the ellipsoid the atmosphere is drawn around.
         * @memberof SkyAtmosphere.prototype
         * @type {Ellipsoid}
         */
        ellipsoid : {
            get : function() {
                return this._ellipsoid;
            }
        }
    });

    /**
     * @private
     */
    SkyAtmosphere.prototype.update = function(context, frameState) {
        if (!this.show) {
            return undefined;
        }

        if ((frameState.mode !== SceneMode.SCENE3D) &&
            (frameState.mode !== SceneMode.MORPHING)) {
            return undefined;
        }

        // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc.
        if (!frameState.passes.render) {
            return undefined;
        }

        var command = this._command;

        if (!defined(command.vertexArray)) {
            var geometry = EllipsoidGeometry.createGeometry(new EllipsoidGeometry({
                radii : Cartesian3.multiplyByScalar(this._ellipsoid.radii, 1.025, new Cartesian3()),
                slicePartitions : 256,
                stackPartitions : 256,
                vertexFormat : VertexFormat.POSITION_ONLY
            }));
            command.vertexArray = context.createVertexArrayFromGeometry({
                geometry : geometry,
                attributeLocations : GeometryPipeline.createAttributeLocations(geometry),
                bufferUsage : BufferUsage.STATIC_DRAW
            });
            command.renderState = context.createRenderState({
                cull : {
                    enabled : true,
                    face : CullFace.FRONT
                },
                blending : BlendingState.ALPHA_BLEND
            });

            var vs = createShaderSource({
                defines : ['SKY_FROM_SPACE'],
                sources : [SkyAtmosphereVS]
            });
            this._spSkyFromSpace = context.createShaderProgram(vs, SkyAtmosphereFS);

            vs = createShaderSource({
                defines : ['SKY_FROM_ATMOSPHERE'],
                sources : [SkyAtmosphereVS]
            });
            this._spSkyFromAtmosphere = context.createShaderProgram(vs, SkyAtmosphereFS);
        }

        var cameraPosition = frameState.camera.positionWC;

        this._fCameraHeight2 = Cartesian3.magnitudeSquared(cameraPosition);
        this._fCameraHeight = Math.sqrt(this._fCameraHeight2);

        if (this._fCameraHeight > this._outerRadius) {
            // Camera in space
            command.shaderProgram = this._spSkyFromSpace;
        } else {
            // Camera in atmosphere
            command.shaderProgram = this._spSkyFromAtmosphere;
        }

        return command;
    };

    /**
     * Returns true if this object was destroyed; otherwise, false.
     *

     * If this object was destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.
     *
     * @returns {Boolean} true if this object was destroyed; otherwise, false.
     *
     * @see SkyAtmosphere#destroy
     */
    SkyAtmosphere.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
     * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @returns {undefined}
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @see SkyAtmosphere#isDestroyed
     *
     * @example
     * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy();
     */
    SkyAtmosphere.prototype.destroy = function() {
        var command = this._command;
        command.vertexArray = command.vertexArray && command.vertexArray.destroy();
        this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy();
        this._spSkyFromAtmosphere = this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy();
        return destroyObject(this);
    };

    return SkyAtmosphere;
});
<|endoftext|>


<commit_before>function getNumbers(year, month, day, hour, minute, clickNumber) {

    function seperateNumbers(num) {
        var out = [];
        var str = '';
        if(typeof num === 'string') {
            str = num;
        }
        else if(typeof num === 'number') {
            str = num.toString();
        }

        if(str.length > 0) {
            var strArray = str.split('');
            strArray.forEach(function(char){
                if('0' <= char && char <= '9') {
                    out.push(parseInt(char));
                }
                else {
                    console.warn('invalid number char : ', num);
                }
            });
        }
        return out;
    }

    function getCircle(year, month, day) {
        var circle = [];
        for(var i = 0; i < 10; i++) {
            // 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9
            circle[i] = 0;
        }

        seperateNumbers(year).forEach(function(num) {
            circle[num]++;
        });
        seperateNumbers(month).forEach(function(num) {
            circle[num]++;
        });
        seperateNumbers(day).forEach(function(num) {
            circle[num]++;
        });

        if(Number(month) < 10 ) {
            circle[0]++;
        }
        if(Number(day) < 10) {
            circle[0]++;
        }

        return circle;
    }

    function getTriangle(masterNumberObj) {
        return masterNumberObj.acquiredNumber;
    }

    function getRectangle(masterNumberObj) {
        return masterNumberObj.masterFateNumber;
    }

    function sumUpPoints(circles, triangle, rectangle) {
        var p = [];
        for(var i = 0; i < 10; i++) {
            p[i] = 0;
        }

        for(var j = 0; j < 10; j++) {
            p[j] = circles[j];
        }

        if(triangle !== undefined) {
            for(var k = 0; k < triangle.length; k++) {
                p[ triangle[k] ]++;
            }
        }

        if(triangle !== undefined) {
            p[ rectangle ]++;
        }

        return p;
    }

    clickNumber =3

    function getLines(points, clickNumber) {
        var p = points;
        var lines = [];

        if(typeof clickNumber === 'number' || typeof clickNumber === 'string') {
            clickNumber = Number(clickNumber);

            for(var i = 0; i < 10; i++) {
                if(i === clickNumber)
                    continue;

                if(p[i] > 1) {
                    if( (clickNumber === 1 && (i!==6 && i!==8)) ||
                        (clickNumber === 2 && (i!==7 && i!==9)) ||
                        (clickNumber === 3 && (i!==4 && i!==8)) ||
                        (clickNumber === 4 && (i!==3 && i!==9)) ||
                        (clickNumber === 6 && (i!==1 && i!==7)) ||
                        (clickNumber === 7 && (i!==2 && i!==6)) ||
                        (clickNumber === 8 && (i!==1 && i!==3)) ||
                        (clickNumber === 9 && (i!==2 && i!==4))
                    ) {
                        lines.push({start: i, end: clickNumber, arrow: true})
                    }
                }
            }
        }
        else {
            if(p[1]>0 && p[2]>0 && p[3]>0)
                lines.push( {start:1, end:3, arrow:false} );
            if(p[4]>0 && p[5]>0 && p[6]>0)
                lines.push( {start:4, end:6, arrow:false} );
            if(p[7]>0 && p[8]>0 && p[9]>0)
                lines.push( {start:7, end:9, arrow:false} );
            if(p[1]>0 && p[4]>0 && p[7]>0)
                lines.push( {start:1, end:7, arrow:false} );
            if(p[2]>0 && p[5]>0 && p[8]>0)
                lines.push( {start:2, end:8, arrow:false} );
            if(p[3]>0 && p[6]>0 && p[9]>0)
                lines.push( {start:3, end:9, arrow:false} );
            if(p[1]>0 && p[5]>0 && p[9]>0)
                lines.push( {start:1, end:9, arrow:false} );
            if(p[3]>0 && p[5]>0 && p[7]>0)
                lines.push( {start:3, end:7, arrow:false} );
            if(p[2]>0 && p[4]>0)
                lines.push( {start:2, end:4, arrow:false} );
            if(p[2]>0 && p[6]>0)
                lines.push( {start:2, end:6, arrow:false} );
            if(p[6]>0 && p[8]>0)
                lines.push( {start:6, end:8, arrow:false} );
            if(p[4]>0 && p[8]>0)
                lines.push( {start:4, end:8, arrow:false} );
        }

        return lines;
    }

    function getOldLines(circles, triangle, rectangle, clickNumber) {
        var p = sumUpPoints(circles, triangle, rectangle);
        return getLines(p, clickNumber);
    }

    function getYoungLines(circles, clickNumber) {
        var p = sumUpPoints(circles);
        return getLines(p, clickNumber);
    }

    function getMasterNumber(year, month, day, exp) {
        var sum1 = 0, sum2 = 0;
        var masterFateNumber = 0;
        var acquiredNumber = [];
        var acquiredNumberString = '';

        if(typeof exp === 'number') {
            // for level number calculating
            if(typeof year === 'string') {
                sum1 = parseInt(year);
            }
            else if(typeof year === 'number'){
                sum1 = year
            }
            sum1 += exp;
        }
        else {
            // normal case
            seperateNumbers(year).forEach(function(num) {
                sum1 += num;
            });
            seperateNumbers(month).forEach(function(num) {
                sum1 += num;
            });
            seperateNumbers(day).forEach(function(num) {
                sum1 += num;
            });
        }

        seperateNumbers(sum1).forEach(function(num) {
            sum2 += num;
            acquiredNumber.push(num);
        });

        masterFateNumber = sum2;
        acquiredNumberString = sum1 + '/' + sum2;

        // might not happen
        if(sum2 >= 10) {
            var sum3 = 0;
            seperateNumbers(sum2).forEach(function(num) {
                sum3 += num;
                acquiredNumber.push(num);
            });

            masterFateNumber = sum3;
            acquiredNumberString += '/' + sum3;
        }

        return {
            masterFateNumber : masterFateNumber,
            acquiredNumber : acquiredNumber,
            acquiredNumberString : acquiredNumberString,
            exp : sum1
        }
    }

    function getLevelNumber(year, month, day, hour, minute) {
        var levelSum = [];
        var secretNumber = [];
        var outputSecretNumber = [];
        for (var i = 0; i < 5; i++) {
            levelSum[i] = 0;
            secretNumber[i] = '';
            outputSecretNumber[i] = '';
        }

        seperateNumbers(year).forEach(function(num) {
            levelSum[0] += num;
        });
        seperateNumbers(month).forEach(function(num) {
            levelSum[1] += num;
        });
        seperateNumbers(day).forEach(function(num) {
            levelSum[2] += num;
        });
        seperateNumbers(hour).forEach(function(num) {
            levelSum[3] += num;
        });
        seperateNumbers(minute).forEach(function(num) {
            levelSum[4] += num;
        });

        secretNumber[0] = getMasterNumber(year);
        secretNumber[1] = getMasterNumber(levelSum[1], null, null, secretNumber[0].exp);
        secretNumber[2] = getMasterNumber(levelSum[2], null, null, secretNumber[1].exp);
        if(hour.length > 0) {
            secretNumber[3] = getMasterNumber(levelSum[3], null, null, secretNumber[2].exp);

            if(minute.length > 0) {
                secretNumber[4] = getMasterNumber(levelSum[4], null, null, secretNumber[3].exp);
            }
        }

        for (var j = 0; j < 5; j++) {
            if(secretNumber[j].acquiredNumberString !== undefined)
                outputSecretNumber[j] = secretNumber[j].acquiredNumberString;
        }

        return outputSecretNumber;
    }

    // Start here
    var masterNumber = getMasterNumber(year, month, day);
    var circle = getCircle(year, month, day);
    var triangle = getTriangle(masterNumber);
    var rectangle = getRectangle(masterNumber);

    return {
        masterNumber : masterNumber.masterFateNumber,
        acquiredNumberString : masterNumber.acquiredNumberString,
        levelNumber : getLevelNumber(year, month, day, hour, minute),
        circle : circle,
        triangle : triangle,
        rectangle: rectangle,
        oldLines : getOldLines(circle, triangle, rectangle, clickNumber),
        youngLines : getYoungLines(circle, clickNumber)
    }
}
<commit_msg>remove test code<commit_after>function getNumbers(year, month, day, hour, minute, clickNumber) {

    function seperateNumbers(num) {
        var out = [];
        var str = '';
        if(typeof num === 'string') {
            str = num;
        }
        else if(typeof num === 'number') {
            str = num.toString();
        }

        if(str.length > 0) {
            var strArray = str.split('');
            strArray.forEach(function(char){
                if('0' <= char && char <= '9') {
                    out.push(parseInt(char));
                }
                else {
                    console.warn('invalid number char : ', num);
                }
            });
        }
        return out;
    }

    function getCircle(year, month, day) {
        var circle = [];
        for(var i = 0; i < 10; i++) {
            // 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9
            circle[i] = 0;
        }

        seperateNumbers(year).forEach(function(num) {
            circle[num]++;
        });
        seperateNumbers(month).forEach(function(num) {
            circle[num]++;
        });
        seperateNumbers(day).forEach(function(num) {
            circle[num]++;
        });

        if(Number(month) < 10 ) {
            circle[0]++;
        }
        if(Number(day) < 10) {
            circle[0]++;
        }

        return circle;
    }

    function getTriangle(masterNumberObj) {
        return masterNumberObj.acquiredNumber;
    }

    function getRectangle(masterNumberObj) {
        return masterNumberObj.masterFateNumber;
    }

    function sumUpPoints(circles, triangle, rectangle) {
        var p = [];
        for(var i = 0; i < 10; i++) {
            p[i] = 0;
        }

        for(var j = 0; j < 10; j++) {
            p[j] = circles[j];
        }

        if(triangle !== undefined) {
            for(var k = 0; k < triangle.length; k++) {
                p[ triangle[k] ]++;
            }
        }

        if(triangle !== undefined) {
            p[ rectangle ]++;
        }

        return p;
    }

    function getLines(points, clickNumber) {
        var p = points;
        var lines = [];

        if(typeof clickNumber === 'number' || typeof clickNumber === 'string') {
            clickNumber = Number(clickNumber);

            for(var i = 0; i < 10; i++) {
                if(i === clickNumber)
                    continue;

                if(p[i] > 1) {
                    if( (clickNumber === 1 && (i!==6 && i!==8)) ||
                        (clickNumber === 2 && (i!==7 && i!==9)) ||
                        (clickNumber === 3 && (i!==4 && i!==8)) ||
                        (clickNumber === 4 && (i!==3 && i!==9)) ||
                        (clickNumber === 6 && (i!==1 && i!==7)) ||
                        (clickNumber === 7 && (i!==2 && i!==6)) ||
                        (clickNumber === 8 && (i!==1 && i!==3)) ||
                        (clickNumber === 9 && (i!==2 && i!==4))
                    ) {
                        lines.push({start: i, end: clickNumber, arrow: true})
                    }
                }
            }
        }
        else {
            if(p[1]>0 && p[2]>0 && p[3]>0)
                lines.push( {start:1, end:3, arrow:false} );
            if(p[4]>0 && p[5]>0 && p[6]>0)
                lines.push( {start:4, end:6, arrow:false} );
            if(p[7]>0 && p[8]>0 && p[9]>0)
                lines.push( {start:7, end:9, arrow:false} );
            if(p[1]>0 && p[4]>0 && p[7]>0)
                lines.push( {start:1, end:7, arrow:false} );
            if(p[2]>0 && p[5]>0 && p[8]>0)
                lines.push( {start:2, end:8, arrow:false} );
            if(p[3]>0 && p[6]>0 && p[9]>0)
                lines.push( {start:3, end:9, arrow:false} );
            if(p[1]>0 && p[5]>0 && p[9]>0)
                lines.push( {start:1, end:9, arrow:false} );
            if(p[3]>0 && p[5]>0 && p[7]>0)
                lines.push( {start:3, end:7, arrow:false} );
            if(p[2]>0 && p[4]>0)
                lines.push( {start:2, end:4, arrow:false} );
            if(p[2]>0 && p[6]>0)
                lines.push( {start:2, end:6, arrow:false} );
            if(p[6]>0 && p[8]>0)
                lines.push( {start:6, end:8, arrow:false} );
            if(p[4]>0 && p[8]>0)
                lines.push( {start:4, end:8, arrow:false} );
        }

        return lines;
    }

    function getOldLines(circles, triangle, rectangle, clickNumber) {
        var p = sumUpPoints(circles, triangle, rectangle);
        return getLines(p, clickNumber);
    }

    function getYoungLines(circles, clickNumber) {
        var p = sumUpPoints(circles);
        return getLines(p, clickNumber);
    }

    function getMasterNumber(year, month, day, exp) {
        var sum1 = 0, sum2 = 0;
        var masterFateNumber = 0;
        var acquiredNumber = [];
        var acquiredNumberString = '';

        if(typeof exp === 'number') {
            // for level number calculating
            if(typeof year === 'string') {
                sum1 = parseInt(year);
            }
            else if(typeof year === 'number'){
                sum1 = year
            }
            sum1 += exp;
        }
        else {
            // normal case
            seperateNumbers(year).forEach(function(num) {
                sum1 += num;
            });
            seperateNumbers(month).forEach(function(num) {
                sum1 += num;
            });
            seperateNumbers(day).forEach(function(num) {
                sum1 += num;
            });
        }

        seperateNumbers(sum1).forEach(function(num) {
            sum2 += num;
            acquiredNumber.push(num);
        });

        masterFateNumber = sum2;
        acquiredNumberString = sum1 + '/' + sum2;

        // might not happen
        if(sum2 >= 10) {
            var sum3 = 0;
            seperateNumbers(sum2).forEach(function(num) {
                sum3 += num;
                acquiredNumber.push(num);
            });

            masterFateNumber = sum3;
            acquiredNumberString += '/' + sum3;
        }

        return {
            masterFateNumber : masterFateNumber,
            acquiredNumber : acquiredNumber,
            acquiredNumberString : acquiredNumberString,
            exp : sum1
        }
    }

    function getLevelNumber(year, month, day, hour, minute) {
        var levelSum = [];
        var secretNumber = [];
        var outputSecretNumber = [];
        for (var i = 0; i < 5; i++) {
            levelSum[i] = 0;
            secretNumber[i] = '';
            outputSecretNumber[i] = '';
        }

        seperateNumbers(year).forEach(function(num) {
            levelSum[0] += num;
        });
        seperateNumbers(month).forEach(function(num) {
            levelSum[1] += num;
        });
        seperateNumbers(day).forEach(function(num) {
            levelSum[2] += num;
        });
        seperateNumbers(hour).forEach(function(num) {
            levelSum[3] += num;
        });
        seperateNumbers(minute).forEach(function(num) {
            levelSum[4] += num;
        });

        secretNumber[0] = getMasterNumber(year);
        secretNumber[1] = getMasterNumber(levelSum[1], null, null, secretNumber[0].exp);
        secretNumber[2] = getMasterNumber(levelSum[2], null, null, secretNumber[1].exp);
        if(hour.length > 0) {
            secretNumber[3] = getMasterNumber(levelSum[3], null, null, secretNumber[2].exp);

            if(minute.length > 0) {
                secretNumber[4] = getMasterNumber(levelSum[4], null, null, secretNumber[3].exp);
            }
        }

        for (var j = 0; j < 5; j++) {
            if(secretNumber[j].acquiredNumberString !== undefined)
                outputSecretNumber[j] = secretNumber[j].acquiredNumberString;
        }

        return outputSecretNumber;
    }

    // Start here
    var masterNumber = getMasterNumber(year, month, day);
    var circle = getCircle(year, month, day);
    var triangle = getTriangle(masterNumber);
    var rectangle = getRectangle(masterNumber);

    return {
        masterNumber : masterNumber.masterFateNumber,
        acquiredNumberString : masterNumber.acquiredNumberString,
        levelNumber : getLevelNumber(year, month, day, hour, minute),
        circle : circle,
        triangle : triangle,
        rectangle: rectangle,
        oldLines : getOldLines(circle, triangle, rectangle, clickNumber),
        youngLines : getYoungLines(circle, clickNumber)
    }
}
<|endoftext|>


<commit_before>'use strict';

const Worker = require('worker-loader?inline&fallback=false!./worker.js');
const worker = new Worker();

const LS = require('./localStorage');
const seeds = require('./seeds');
const emitter = require('lib/emitter');
const crypto = require('crypto');
const encryption = require('lib/encryption');
const CsWallet = require('cs-wallet');
const validateSend = require('./validator');
const request = require('lib/request');
const EthereumWallet = require('cs-ethereum-wallet');
const RippleWallet = require('cs-ripple-wallet');
const StellarWallet = require('cs-stellar-wallet');
const EOSWallet = require('cs-eos-wallet');
const { eddsa } = require('elliptic');
const ec = new eddsa('ed25519');
const touchId = require('lib/touch-id');
const ticker = require('lib/ticker-api');

const convert = require('lib/convert');
const {
  getToken,
  getTokenNetwork,
  setToken,
} = require('lib/token');
const details = require('lib/wallet/details');
const settings = require('lib/wallet/settings');
const _ = require('lodash');
const bchaddr = require('bchaddrjs');

const state = {
  wallet: null,
};

const Wallet = {
  bitcoin: CsWallet,
  bitcoincash: CsWallet,
  bitcoinsv: CsWallet,
  litecoin: CsWallet,
  ethereum: EthereumWallet,
  ripple: RippleWallet,
  stellar: StellarWallet,
  eos: EOSWallet,
  dogecoin: CsWallet,
  dash: CsWallet,
};

const { urlRoot } = window;

function createWallet(passphrase) {
  const data = { passphrase };
  return new Promise((resolve, reject) => {
    worker.onmessage = function(event) {
      seeds.set('private', event.data.seed);
      resolve({ mnemonic: event.data.mnemonic });
    };
    worker.onerror = function(event) {
      event.preventDefault();
      reject(new Error('Invalid passphrase'));
    };
    worker.postMessage(data);
  });
}

async function registerWallet(pin) {
  const pinKey = crypto.randomBytes(32).toString('hex');
  const walletSeed = seeds.get('private');
  const wallet = ec.keyFromSecret(walletSeed);
  const deviceSeed = crypto.randomBytes(32).toString('hex');
  const device = ec.keyFromSecret(deviceSeed);
  const deviceId = device.getPublic('hex');
  const pinHash = crypto.createHmac('sha256', Buffer.from(pinKey, 'hex')).update(pin).digest('hex');
  const detailsKey = crypto.createHmac('sha256', 'hello bro!').update(walletSeed).digest('hex');
  const { publicToken, privateToken } = await request({
    url: `${urlRoot}v2/register`,
    method: 'post',
    data: {
      walletId: wallet.getPublic('hex'),
      deviceId,
      pinHash,
    },
    seed: 'private',
  });
  seeds.set('public', deviceSeed, publicToken);
  seeds.set('private', walletSeed, privateToken);
  LS.setEncryptedSeed('public', encryption.encrypt(deviceSeed, publicToken));
  LS.setEncryptedSeed('private', encryption.encrypt(walletSeed, privateToken));
  LS.setPinKey(pinKey);
  LS.setId(deviceId);
  LS.setDetailsKey(detailsKey);
  await Promise.all([details.init(), settings.init()]);
  await initWallet(pin);
}

async function loginWithPin(pin) {
  if (LS.isRegisteredLegacy()) {
    return migrateLegacyWallet(pin);
  }
  const pinHash = crypto.createHmac('sha256', Buffer.from(LS.getPinKey(), 'hex')).update(pin).digest('hex');
  const { publicToken } = await request({
    url: `${urlRoot}v2/token/public/pin?id=${LS.getId()}`,
    method: 'post',
    data: {
      pinHash,
    },
  });
  seeds.unlock('public', publicToken);
  await Promise.all([details.init(), settings.init()]);
  await initWallet();
}

async function loginWithTouchId(showSpinner) {
  if (process.env.BUILD_TYPE === 'phonegap') {
    await touchId.phonegap();
    const pin = LS.getPin();
    showSpinner();
    if (LS.isRegisteredLegacy()) {
      return migrateLegacyWallet(pin);
    }
    return loginWithPin(pin);
  } else {
    const publicToken = await touchId.publicToken();
    showSpinner();
    seeds.unlock('public', publicToken);
    await Promise.all([details.init(), settings.init()]);
    await initWallet();
  }
}

async function initWallet(pin) {
  const networkName = getTokenNetwork();
  let token = getToken();
  if (!isValidWalletToken(token)) {
    setToken(networkName);
    token = false;
  }

  let publicKey;
  const seed = seeds.get('private');
  if (seed) {
    Object.keys(Wallet).forEach((key) => {
      let wallet;
      if (key === networkName) {
        wallet = new Wallet[key](Object.assign({ seed, networkName }, getExtraOptions(networkName)));
        state.wallet = wallet;
        state.wallet.lock();
      } else {
        wallet = new Wallet[key]({ seed, networkName: key });
      }
      LS.setPublicKey(wallet, seeds.get('public'));
    });
  } else {
    publicKey = LS.getPublicKey(networkName, seeds.get('public'));
    const options = Object.assign({ publicKey, networkName }, getExtraOptions(networkName));
    state.wallet = new Wallet[networkName](options);
  }

  if (networkName === 'ethereum') {
    convert.setDecimals(token ? token.decimals : 18);
  } else if (['bitcoin', 'bitcoincash', 'bitcoinsv', 'litecoin', 'dogecoin', 'dash'].indexOf(networkName) !== -1) {
    convert.setDecimals(8);
  } else if (networkName === 'ripple') {
    convert.setDecimals(0);
  } else if (networkName === 'stellar') {
    convert.setDecimals(0);
  } else if (networkName === 'eos') {
    convert.setDecimals(0);
  }

  await ticker.load(state.wallet.denomination);

  state.wallet.load({
    getDynamicFees() {
      return request({
        url: urlRoot + 'v1/fees',
        params: { network: networkName },
      }).catch(console.error);
    },
    getCsFee() {
      return request({
        url: urlRoot + 'v1/csFee',
        params: { network: networkName },
      }).catch(console.error);
    },
    done(err) {
      emitter.emit('wallet-ready', { pin, err });
    },
  });

  function getExtraOptions(networkName) {
    const options = {};
    if (networkName === 'ethereum') {
      options.minConf = 12;
      options.token = token;
    } else if (['bitcoin', 'bitcoincash', 'bitcoinsv', 'litecoin', 'dogecoin', 'dash'].indexOf(networkName) !== -1) {
      options.minConf = 3;
      options.addressType = details.get(networkName + '.addressType') || 'p2pkh';
      if (networkName === 'bitcoincash') {
        options.minConf = 0;
      }
    } else if (networkName === 'eos') {
      options.accountName = details.get('eosAccountName') || '';
    }
    return options;
  }
}

async function removeAccount() {
  await request({
    url: `${urlRoot}v2/wallet?id=${LS.getId()}`,
    method: 'delete',
    seed: 'private',
  });
  LS.reset();
}

function setUsername(username) {
  const userInfo = details.get('userInfo');
  const oldUsername = (userInfo.username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  const newUsername = (username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  if (newUsername === oldUsername) {
    return Promise.resolve(userInfo.username);
  }
  return request({
    url: `${urlRoot}v2/username?id=${LS.getId()}`,
    method: 'put',
    data: {
      username: newUsername,
    },
    seed: 'public',
  }).then((data) => {
    return data.username;
  });
}

function isValidWalletToken(token) {
  if (token && token.isDefault) return true;
  const walletTokens = details.get('walletTokens') || [];
  const isFound = _.find(walletTokens, (item) => {
    return _.isEqual(token, item);
  });
  return !!isFound;
}

function getWallet() {
  return state.wallet;
}

function getDestinationInfo(to) {
  if (state.wallet.networkName === 'ripple' || state.wallet.networkName === 'stellar') {
    return state.wallet.getDestinationInfo(to);
  } else {
    return Promise.resolve();
  }
}

function setToAlias(data) {
  if (state.wallet.networkName !== 'bitcoincash') return;
  try {
    const legacy = bchaddr.toLegacyAddress(data.to);
    if (legacy !== data.to) {
      data.alias = data.to;
      data.to = legacy;
    }
  // eslint-disable-next-line
  } catch (e) {}
}

async function migrateLegacyWallet(pin) {
  await loginWithPinLegacy(pin);
  await registerWallet(pin);
  LS.deleteCredentialsLegacy();
}

// DEPRECATED
async function loginWithPinLegacy(pin) {
  const credentials = LS.getCredentials();
  const { id } = credentials;
  const encryptedSeed = credentials.seed;
  const token = await request({
    url: `${urlRoot}v1/login`,
    method: 'post',
    data: { wallet_id: id, pin },
  });
  seeds.set('private', encryption.decrypt(encryptedSeed, token));
}

module.exports = {
  createWallet,
  registerWallet,
  loginWithPin,
  loginWithTouchId,
  removeAccount,
  setUsername,
  getWallet,
  initWallet,
  validateSend,
  getDestinationInfo,
  setToAlias,
};
<commit_msg>fix(app): hello bro!<commit_after>'use strict';

const Worker = require('worker-loader?inline&fallback=false!./worker.js');
const worker = new Worker();

const LS = require('./localStorage');
const seeds = require('./seeds');
const emitter = require('lib/emitter');
const crypto = require('crypto');
const encryption = require('lib/encryption');
const CsWallet = require('cs-wallet');
const validateSend = require('./validator');
const request = require('lib/request');
const EthereumWallet = require('cs-ethereum-wallet');
const RippleWallet = require('cs-ripple-wallet');
const StellarWallet = require('cs-stellar-wallet');
const EOSWallet = require('cs-eos-wallet');
const { eddsa } = require('elliptic');
const ec = new eddsa('ed25519');
const touchId = require('lib/touch-id');
const ticker = require('lib/ticker-api');

const convert = require('lib/convert');
const {
  getToken,
  getTokenNetwork,
  setToken,
} = require('lib/token');
const details = require('lib/wallet/details');
const settings = require('lib/wallet/settings');
const _ = require('lodash');
const bchaddr = require('bchaddrjs');

const state = {
  wallet: null,
};

const Wallet = {
  bitcoin: CsWallet,
  bitcoincash: CsWallet,
  bitcoinsv: CsWallet,
  litecoin: CsWallet,
  ethereum: EthereumWallet,
  ripple: RippleWallet,
  stellar: StellarWallet,
  eos: EOSWallet,
  dogecoin: CsWallet,
  dash: CsWallet,
};

const { urlRoot } = window;

function createWallet(passphrase) {
  const data = { passphrase };
  return new Promise((resolve, reject) => {
    worker.onmessage = function(event) {
      seeds.set('private', event.data.seed);
      resolve({ mnemonic: event.data.mnemonic });
    };
    worker.onerror = function(event) {
      event.preventDefault();
      reject(new Error('Invalid passphrase'));
    };
    worker.postMessage(data);
  });
}

async function registerWallet(pin) {
  const pinKey = crypto.randomBytes(32).toString('hex');
  const walletSeed = seeds.get('private');
  const wallet = ec.keyFromSecret(walletSeed);
  const deviceSeed = crypto.randomBytes(32).toString('hex');
  const device = ec.keyFromSecret(deviceSeed);
  const deviceId = device.getPublic('hex');
  const pinHash = crypto.createHmac('sha256', Buffer.from(pinKey, 'hex')).update(pin).digest('hex');
  const detailsKey = crypto.createHmac('sha256', 'Coin Wallet').update(walletSeed).digest('hex');
  const { publicToken, privateToken } = await request({
    url: `${urlRoot}v2/register`,
    method: 'post',
    data: {
      walletId: wallet.getPublic('hex'),
      deviceId,
      pinHash,
    },
    seed: 'private',
  });
  seeds.set('public', deviceSeed, publicToken);
  seeds.set('private', walletSeed, privateToken);
  LS.setEncryptedSeed('public', encryption.encrypt(deviceSeed, publicToken));
  LS.setEncryptedSeed('private', encryption.encrypt(walletSeed, privateToken));
  LS.setPinKey(pinKey);
  LS.setId(deviceId);
  LS.setDetailsKey(detailsKey);
  await Promise.all([details.init(), settings.init()]);
  await initWallet(pin);
}

async function loginWithPin(pin) {
  if (LS.isRegisteredLegacy()) {
    return migrateLegacyWallet(pin);
  }
  const pinHash = crypto.createHmac('sha256', Buffer.from(LS.getPinKey(), 'hex')).update(pin).digest('hex');
  const { publicToken } = await request({
    url: `${urlRoot}v2/token/public/pin?id=${LS.getId()}`,
    method: 'post',
    data: {
      pinHash,
    },
  });
  seeds.unlock('public', publicToken);
  await Promise.all([details.init(), settings.init()]);
  await initWallet();
}

async function loginWithTouchId(showSpinner) {
  if (process.env.BUILD_TYPE === 'phonegap') {
    await touchId.phonegap();
    const pin = LS.getPin();
    showSpinner();
    if (LS.isRegisteredLegacy()) {
      return migrateLegacyWallet(pin);
    }
    return loginWithPin(pin);
  } else {
    const publicToken = await touchId.publicToken();
    showSpinner();
    seeds.unlock('public', publicToken);
    await Promise.all([details.init(), settings.init()]);
    await initWallet();
  }
}

async function initWallet(pin) {
  const networkName = getTokenNetwork();
  let token = getToken();
  if (!isValidWalletToken(token)) {
    setToken(networkName);
    token = false;
  }

  let publicKey;
  const seed = seeds.get('private');
  if (seed) {
    Object.keys(Wallet).forEach((key) => {
      let wallet;
      if (key === networkName) {
        wallet = new Wallet[key](Object.assign({ seed, networkName }, getExtraOptions(networkName)));
        state.wallet = wallet;
        state.wallet.lock();
      } else {
        wallet = new Wallet[key]({ seed, networkName: key });
      }
      LS.setPublicKey(wallet, seeds.get('public'));
    });
  } else {
    publicKey = LS.getPublicKey(networkName, seeds.get('public'));
    const options = Object.assign({ publicKey, networkName }, getExtraOptions(networkName));
    state.wallet = new Wallet[networkName](options);
  }

  if (networkName === 'ethereum') {
    convert.setDecimals(token ? token.decimals : 18);
  } else if (['bitcoin', 'bitcoincash', 'bitcoinsv', 'litecoin', 'dogecoin', 'dash'].indexOf(networkName) !== -1) {
    convert.setDecimals(8);
  } else if (networkName === 'ripple') {
    convert.setDecimals(0);
  } else if (networkName === 'stellar') {
    convert.setDecimals(0);
  } else if (networkName === 'eos') {
    convert.setDecimals(0);
  }

  await ticker.load(state.wallet.denomination);

  state.wallet.load({
    getDynamicFees() {
      return request({
        url: urlRoot + 'v1/fees',
        params: { network: networkName },
      }).catch(console.error);
    },
    getCsFee() {
      return request({
        url: urlRoot + 'v1/csFee',
        params: { network: networkName },
      }).catch(console.error);
    },
    done(err) {
      emitter.emit('wallet-ready', { pin, err });
    },
  });

  function getExtraOptions(networkName) {
    const options = {};
    if (networkName === 'ethereum') {
      options.minConf = 12;
      options.token = token;
    } else if (['bitcoin', 'bitcoincash', 'bitcoinsv', 'litecoin', 'dogecoin', 'dash'].indexOf(networkName) !== -1) {
      options.minConf = 3;
      options.addressType = details.get(networkName + '.addressType') || 'p2pkh';
      if (networkName === 'bitcoincash') {
        options.minConf = 0;
      }
    } else if (networkName === 'eos') {
      options.accountName = details.get('eosAccountName') || '';
    }
    return options;
  }
}

async function removeAccount() {
  await request({
    url: `${urlRoot}v2/wallet?id=${LS.getId()}`,
    method: 'delete',
    seed: 'private',
  });
  LS.reset();
}

function setUsername(username) {
  const userInfo = details.get('userInfo');
  const oldUsername = (userInfo.username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  const newUsername = (username || '').toLowerCase().replace(/[^a-z0-9-]/g, '');
  if (newUsername === oldUsername) {
    return Promise.resolve(userInfo.username);
  }
  return request({
    url: `${urlRoot}v2/username?id=${LS.getId()}`,
    method: 'put',
    data: {
      username: newUsername,
    },
    seed: 'public',
  }).then((data) => {
    return data.username;
  });
}

function isValidWalletToken(token) {
  if (token && token.isDefault) return true;
  const walletTokens = details.get('walletTokens') || [];
  const isFound = _.find(walletTokens, (item) => {
    return _.isEqual(token, item);
  });
  return !!isFound;
}

function getWallet() {
  return state.wallet;
}

function getDestinationInfo(to) {
  if (state.wallet.networkName === 'ripple' || state.wallet.networkName === 'stellar') {
    return state.wallet.getDestinationInfo(to);
  } else {
    return Promise.resolve();
  }
}

function setToAlias(data) {
  if (state.wallet.networkName !== 'bitcoincash') return;
  try {
    const legacy = bchaddr.toLegacyAddress(data.to);
    if (legacy !== data.to) {
      data.alias = data.to;
      data.to = legacy;
    }
  // eslint-disable-next-line
  } catch (e) {}
}

async function migrateLegacyWallet(pin) {
  await loginWithPinLegacy(pin);
  await registerWallet(pin);
  LS.deleteCredentialsLegacy();
}

// DEPRECATED
async function loginWithPinLegacy(pin) {
  const credentials = LS.getCredentials();
  const { id } = credentials;
  const encryptedSeed = credentials.seed;
  const token = await request({
    url: `${urlRoot}v1/login`,
    method: 'post',
    data: { wallet_id: id, pin },
  });
  seeds.set('private', encryption.decrypt(encryptedSeed, token));
}

module.exports = {
  createWallet,
  registerWallet,
  loginWithPin,
  loginWithTouchId,
  removeAccount,
  setUsername,
  getWallet,
  initWallet,
  validateSend,
  getDestinationInfo,
  setToAlias,
};
<|endoftext|>