<commit_before>// Copyright (c) 2011, Centrum Cyfrowe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Centrum Cyfrowe nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

var _table = (function () {

//  P U B L I C   I N T E R F A C E
    var that = {};

    that.clean_table = function () {
        $('#app-tb-datatable > thead').empty();
        $('#app-tb-datatable > tbody').empty();
        $('#app-tb-filteredtable > thead').empty();
        $('#app-tb-filteredtable > tbody').empty();
    };

    that.init_table = function () {
        _utils.create_preloader('Wczytuj tabel');
        if ( !_store.active_filtered() ) {
            create_thead();
            create_tbody();
            _gui.make_zebra();
            $('#app-tb-tl-columns-button').show();
            $('#app-tb-tl-clear-button').show();
            $('#app-tb-tl-filter-button').show();
            $('#app-tb-tl-sort-button').show();
//            $('#app-tb-tl-sort-button').css({
//                'border-radius': '5px 0px 0px 5px',
//                '-moz-border-radius': '5px 0px 0px 5px',
//                '-webkit-border-radius': '5px 0px 0px 5px'
//            });
        } else {
            create_filtered_thead();
            create_filtered_tbody();
            $('#app-tb-tl-columns-button').hide();
            $('#app-tb-tl-clear-button').hide();
            $('#app-tb-tl-filter-button').hide();
            $('#app-tb-tl-sort-button').hide();
//            $('#app-tb-tl-sort-button').css({
//                'border-radius': '5px',
//                '-moz-border-radius': '5px',
//                '-webkit-border-radius': '5px'
//            });
        }

        _utils.clean_preloader();
    };

    that.add_node = function ( parent_id ) {
        var children = _store.active_rows().filter( function ( e ) {
            return e['data']['parent'] === parent_id;
        });

        add_rows( children );
        _gui.make_zebra();
    };

    return that;

//  P R I V A T E   I N T E R F A C E

    function create_thead() {
        var schema = _store.active_columns();
        var total = _store.active_rows()['total'];
        var html = [ '
' ];

        // create header
        schema.forEach( function ( column ) {
            html.push( '' );
            html.push( column['label'] );
            html.push( '	' );
        });

        html.push( '
' );

        // create total row
        if( !!total ) {
            html.push( '
' );

            schema.forEach( function ( column ) {
                html.push( '' );
                html.push( total['data'][ column['key'] ] );
                html.push( '	' );
            });

            html.push( '
' );
        }
        $('#app-tb-datatable > thead').append( html.join('') );
    }

    function create_tbody() {
        var level = 'a';
        var hashed_list = _utils.hash_list( _store.active_rows() );
        var selected_node;

        while( !!hashed_list[ level ] ) {
            if( level === 'a' ) {
                add_top_level( hashed_list[ level ] );
            }
            else {
                add_rows( hashed_list[ level ] );
            }

            level = _utils.next_letter( level );
        }

        // apply node selection(if there is selected node) to css classes
        selected_node = _store.active_rows().filter( function ( e ) {
            return e['state']['selected'];
        });
        if ( selected_node.length > 0 ) {
            apply_selection( selected_node[0]['data']['idef'] );
        }
    }

    function add_top_level( data ) {
        var i, len = data.length;
        var schema = _store.active_columns();

        for( i = 0; i < len; ++i ) {
            $('#app-tb-datatable > tbody').append( generate_row({
                node: data[i],
                index: i,
                schema: schema
            }));
        }
    }

    function add_rows( data ) {
        var i = data.length - 1;
        var schema = _store.active_columns();
        var parent;

        for( ; i >= 0; i -= 1 ) {
            parent = $( '#' + data[i]['data']['parent'] );
//            if( parent.attr( 'data-open' ) === 'false' ) {
//                continue;
//            }
            parent.after( generate_row({
                node: data[i],
                schema: schema
            }));
        }
//        _gui.make_zebra();
    }

    // generate a single table row
    function generate_row( args ) {
        var node = args['node'];
        var data = node['data'];
        var schema = args['schema'];
        var is_open = node['state']['open'];
        var is_selected = node['state']['selected'];
        var html = [];
        var row;

        // row definition
        html.push( '
' );

        // cells definition
        // TODO >> it can be sligthly slower than for loop - test it
        schema.forEach( function ( column ) {
            html.push( '' : '">' );
            html.push( data[column['key']] );
            html.push( '	' );
        });

        html.push( '
' );

        // create & arm row
        row = $( html.join('') );
        row.click( function ( event ) {
                // update css classes connected with node selection
                apply_selection( $(this).attr('id') );

                // open/close a subtree if it's a-level or already selected/open
                open_close_subtree( $(this), a_parent( $(this) ) );

            })
            .hover(
                function () {
                    row.find('.click').css('color', '#11a8f7' );
                },
                function () {
                    raw.find('.click').css('color', '#1a7aad' );
                }
            );

        return row;
    }

    function create_filtered_thead() {
        var schema = _store.active_columns();
        var html = [];

        html.push( '
' );
        schema.forEach( function ( column ) {
            html.push( '' );
            html.push( column['label'], '	' );
        });
        html.push( '
' );

        $('#app-tb-filteredtable > thead').append( html.join('') );
    }

    function create_filtered_tbody() {
        var schema = _store.active_columns();
        // deep copy is made to ensure that _store is not changed by sort
        var rows_copy = [];
        $.extend( true, rows_copy, _store.active_rows() );

        rows_copy.sort( function ( a, b ) {
                     var return_value;
                     if ( a['data']['idef_sort']  b['data']['idef_sort'] ) {
                         return_value = 1;
                     } else {
                         return_value = 0;
                     }
                return return_value;
            })
            .forEach( function ( row ) {
                var new_node = generate_filtered_row({
                                    node: row,
                                    schema: schema
                                });
                $('#app-tb-filteredtable > tbody').append( new_node );
            });
    }

    function generate_filtered_row( args ) {
        var node = args['node'];
        var breadcrumb = node['breadcrumb'] || '';
        var html = [];

        // breadcrumb
        html.push( '
' );
        html.push( '');
        html.push( breadcrumb );
        html.push( '	' );
        html.push( '
');

        // filtered row
        html.push( '
' );
        args['schema'].forEach( function ( column ) {
            html.push( '' );
            html.push( node['data'][ column['key'] ] );
            html.push('	');
        });
        html.push( '
' );

        return $( html.join('') );
    }

    function find_parent( id ) {
        var parent_id = _utils.get_parent_id( id );
        var parent;

        while ( !!parent_id ) {
            parent = $( '#' + parent_id );
            if ( !!parent.length ) {
                return parent;
            }
            parent_id = _utils.get_parent_id( parent_id );
        }
        // if parent not found, return ''
        return null;
    }

    function apply_selection( id ) {
        var node = $('#' + id);

        // a-level parent
        var a_root = a_parent( node );
        var a_root_id = a_root.attr('id');
        // next a-level node
        var a_root_index = parseInt( a_root.attr( 'data-index' ), 10 );
        var next = $('tr[data-index='+ (a_root_index + 1) +']');

        // dim everything outside this a-rooted subtree
        a_root
            .siblings()
            .addClass('dim')
            .end()
            .removeClass('dim');

        // make a-root background black
        $('tr.root').removeClass('root');
        a_root.addClass('root');

        // highlight the subtree
        _utils.with_subtree( a_root.attr('id'), function () {
            // uses 'this' instead of '$(this)' for fun.call reason
            this.removeClass( 'dim' );
        });

        // add the bottom border
        $('.next').removeClass('next');
        next.addClass('next');
    }

    function show_selected_subtree( id ) {
     $('tr.'+id).each( function () {
                    var node = $(this);
             if ( node.attr( 'data-open' ) === 'true' ) {
                 show_selected_subtree( node.attr('id') );
             }
             _store.set_visible( id, true );
             node.show();
        });
    }

    function open_close_subtree( node, root ) {
        var a_root = root || a_parent( node );
        var a_root_id = a_root.attr('id');
        var is_a_open     = a_root.attr( 'data-open' );
        var is_a_selected = a_root.attr( 'data-selected' );
        var id = node.attr('id');
        var children;
        var previously_selected_id;

        if ( is_a_selected === is_a_open ) {
            // if the node is closed
            if( node.attr( 'data-open' ) === 'false' ) {

                // if children are hidden
                var test = $('.'+id);
                if( $('.'+id).length !== 0 ) {
                   // _utils.with_subtree( id, $.fn.show );
                   show_selected_subtree( id );
                }
                // if children not loaded yet
                else {
                    _db.download_node( id );

                // if there is previously selected node, unselect it in _store
                previously_selected_id = $('tr[data-selected=true]').attr('id');
                if ( !!previously_selected_id ) {
                    _store.set_selected( previously_selected_id, false );
                }

                // mark subtree as open
                _store.set_open( id, true );
                node.attr( 'data-open', 'true' );

                // clear selected attributes and set selection to clicked tree
                _store.set_selected( a_root_id, true );
                $('tr[data-selected=true]').attr('data-selected', 'false');
                a_root.attr('data-selected', 'true');
            }
            // the node is closed
            else {
                // hide subtree
                _utils.with_subtree( id, $.fn.hide );

                // mark subtree as closed
                _store.set_open( id, false );
                node.attr( 'data-open', 'false' );

                // if it's a-level node - clear the css highlight/dim
                if( node.hasClass( 'a' ) ) {
                    node.removeClass( 'root' );
                    $('.dim').removeClass('dim');
                    $('.next').removeClass('next');

                    // clear selected attributes and set selection to clicked tree
                    _store.set_selected( a_root_id, false );
                    $('tr[data-selected=true]').attr('data-selected', 'false');
                }
            }
        }
        else if( a_root.attr( 'data-selected' ) === 'false' ) {
            // unselect previously selected node in _store
            previously_selected_id = $('tr[data-selected=true]').attr('id');
            _store.set_selected( previously_selected_id, false );

            _store.set_selected( a_root_id, true );
            $('tr[data-selected=true]').attr('data-selected', 'false');
            a_root.attr('data-selected', 'true');
        }
    }

    // return a-level parent of a given node
    function a_parent( node ) {
        if( node.hasClass( 'a' ) ) {
            return node;
        }
        var prev = node.prev();

        return prev.hasClass('a') ? prev : a_parent( prev );
    }

})();
<commit_msg>add visible to raws 2<commit_after>// Copyright (c) 2011, Centrum Cyfrowe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Centrum Cyfrowe nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

var _table = (function () {

//  P U B L I C   I N T E R F A C E
    var that = {};

    that.clean_table = function () {
        $('#app-tb-datatable > thead').empty();
        $('#app-tb-datatable > tbody').empty();
        $('#app-tb-filteredtable > thead').empty();
        $('#app-tb-filteredtable > tbody').empty();
    };

    that.init_table = function () {
        _utils.create_preloader('Wczytuj tabel');
        if ( !_store.active_filtered() ) {
            create_thead();
            create_tbody();
            _gui.make_zebra();
            $('#app-tb-tl-columns-button').show();
            $('#app-tb-tl-clear-button').show();
            $('#app-tb-tl-filter-button').show();
            $('#app-tb-tl-sort-button').show();
//            $('#app-tb-tl-sort-button').css({
//                'border-radius': '5px 0px 0px 5px',
//                '-moz-border-radius': '5px 0px 0px 5px',
//                '-webkit-border-radius': '5px 0px 0px 5px'
//            });
        } else {
            create_filtered_thead();
            create_filtered_tbody();
            $('#app-tb-tl-columns-button').hide();
            $('#app-tb-tl-clear-button').hide();
            $('#app-tb-tl-filter-button').hide();
            $('#app-tb-tl-sort-button').hide();
//            $('#app-tb-tl-sort-button').css({
//                'border-radius': '5px',
//                '-moz-border-radius': '5px',
//                '-webkit-border-radius': '5px'
//            });
        }

        _utils.clean_preloader();
    };

    that.add_node = function ( parent_id ) {
        var children = _store.active_rows().filter( function ( e ) {
            return e['data']['parent'] === parent_id;
        });

        add_rows( children );
        _gui.make_zebra();
    };

    return that;

//  P R I V A T E   I N T E R F A C E

    function create_thead() {
        var schema = _store.active_columns();
        var total = _store.active_rows()['total'];
        var html = [ '
' ];

        // create header
        schema.forEach( function ( column ) {
            html.push( '' );
            html.push( column['label'] );
            html.push( '	' );
        });

        html.push( '
' );

        // create total row
        if( !!total ) {
            html.push( '
' );

            schema.forEach( function ( column ) {
                html.push( '' );
                html.push( total['data'][ column['key'] ] );
                html.push( '	' );
            });

            html.push( '
' );
        }
        $('#app-tb-datatable > thead').append( html.join('') );
    }

    function create_tbody() {
        var level = 'a';
        var hashed_list = _utils.hash_list( _store.active_rows() );
        var selected_node;

        while( !!hashed_list[ level ] ) {
            if( level === 'a' ) {
                add_top_level( hashed_list[ level ] );
            }
            else {
                add_rows( hashed_list[ level ] );
            }

            level = _utils.next_letter( level );
        }

        // apply node selection(if there is selected node) to css classes
        selected_node = _store.active_rows().filter( function ( e ) {
            return e['state']['selected'];
        });
        if ( selected_node.length > 0 ) {
            apply_selection( selected_node[0]['data']['idef'] );
        }
    }

    function add_top_level( data ) {
        var i, len = data.length;
        var schema = _store.active_columns();

        for( i = 0; i < len; ++i ) {
            $('#app-tb-datatable > tbody').append( generate_row({
                node: data[i],
                index: i,
                schema: schema
            }));
        }
    }

    function add_rows( data ) {
        var i = data.length - 1;
        var schema = _store.active_columns();
        var parent;

        for( ; i >= 0; i -= 1 ) {
            parent = $( '#' + data[i]['data']['parent'] );
//            if( parent.attr( 'data-open' ) === 'false' ) {
//                continue;
//            }
            parent.after( generate_row({
                node: data[i],
                schema: schema
            }));
        }
//        _gui.make_zebra();
    }

    // generate a single table row
    function generate_row( args ) {
        var node = args['node'];
        var data = node['data'];
        var schema = args['schema'];
        var is_open = node['state']['open'];
        var is_selected = node['state']['selected'];
        var html = [];
        var row;

        // row definition
        html.push( '
' );

        // cells definition
        // TODO >> it can be sligthly slower than for loop - test it
        schema.forEach( function ( column ) {
            html.push( '' : '">' );
            html.push( data[column['key']] );
            html.push( '	' );
        });

        html.push( '
' );

        // create & arm row
        row = $( html.join('') );
        row.click( function ( event ) {
                // update css classes connected with node selection
                apply_selection( $(this).attr('id') );

                // open/close a subtree if it's a-level or already selected/open
                open_close_subtree( $(this), a_parent( $(this) ) );

            })
            .hover(
                function () {
                    row.find('.click').css('color', '#11a8f7' );
                },
                function () {
                    raw.find('.click').css('color', '#1a7aad' );
                }
            );

        return row;
    }

    function create_filtered_thead() {
        var schema = _store.active_columns();
        var html = [];

        html.push( '
' );
        schema.forEach( function ( column ) {
            html.push( '' );
            html.push( column['label'], '	' );
        });
        html.push( '
' );

        $('#app-tb-filteredtable > thead').append( html.join('') );
    }

    function create_filtered_tbody() {
        var schema = _store.active_columns();
        // deep copy is made to ensure that _store is not changed by sort
        var rows_copy = [];
        $.extend( true, rows_copy, _store.active_rows() );

        rows_copy.sort( function ( a, b ) {
                     var return_value;
                     if ( a['data']['idef_sort']  b['data']['idef_sort'] ) {
                         return_value = 1;
                     } else {
                         return_value = 0;
                     }
                return return_value;
            })
            .forEach( function ( row ) {
                var new_node = generate_filtered_row({
                                    node: row,
                                    schema: schema
                                });
                $('#app-tb-filteredtable > tbody').append( new_node );
            });
    }

    function generate_filtered_row( args ) {
        var node = args['node'];
        var breadcrumb = node['breadcrumb'] || '';
        var html = [];

        // breadcrumb
        html.push( '
' );
        html.push( '');
        html.push( breadcrumb );
        html.push( '	' );
        html.push( '
');

        // filtered row
        html.push( '
' );
        args['schema'].forEach( function ( column ) {
            html.push( '' );
            html.push( node['data'][ column['key'] ] );
            html.push('	');
        });
        html.push( '
' );

        return $( html.join('') );
    }

    function find_parent( id ) {
        var parent_id = _utils.get_parent_id( id );
        var parent;

        while ( !!parent_id ) {
            parent = $( '#' + parent_id );
            if ( !!parent.length ) {
                return parent;
            }
            parent_id = _utils.get_parent_id( parent_id );
        }
        // if parent not found, return ''
        return null;
    }

    function apply_selection( id ) {
        var node = $('#' + id);

        // a-level parent
        var a_root = a_parent( node );
        var a_root_id = a_root.attr('id');
        // next a-level node
        var a_root_index = parseInt( a_root.attr( 'data-index' ), 10 );
        var next = $('tr[data-index='+ (a_root_index + 1) +']');

        // dim everything outside this a-rooted subtree
        a_root
            .siblings()
            .addClass('dim')
            .end()
            .removeClass('dim');

        // make a-root background black
        $('tr.root').removeClass('root');
        a_root.addClass('root');

        // highlight the subtree
        _utils.with_subtree( a_root.attr('id'), function () {
            // uses 'this' instead of '$(this)' for fun.call reason
            this.removeClass( 'dim' );
        });

        // add the bottom border
        $('.next').removeClass('next');
        next.addClass('next');
    }

    function show_selected_subtree( id ) {
     $('tr.'+id).each( function () {
                    var node = $(this);
             if ( node.attr( 'data-open' ) === 'true' ) {
                 show_selected_subtree( node.attr('id') );
             }
             _store.set_visible( id, true );
             node.show();
        });
    }

    function open_close_subtree( node, root ) {
        var a_root = root || a_parent( node );
        var a_root_id = a_root.attr('id');
        var is_a_open     = a_root.attr( 'data-open' );
        var is_a_selected = a_root.attr( 'data-selected' );
        var id = node.attr('id');
        var children;
        var previously_selected_id;

        if ( is_a_selected === is_a_open ) {
            // if the node is closed
            if( node.attr( 'data-open' ) === 'false' ) {

                // if children are hidden
                var test = $('.'+id);
                if( $('.'+id).length !== 0 ) {
                   // _utils.with_subtree( id, $.fn.show );
                   show_selected_subtree( id );
                }
                // if children not loaded yet
                else {
                    _db.download_node( id );
                }

                // if there is previously selected node, unselect it in _store
                previously_selected_id = $('tr[data-selected=true]').attr('id');
                if ( !!previously_selected_id ) {
                    _store.set_selected( previously_selected_id, false );
                }

                // mark subtree as open
                _store.set_open( id, true );
                node.attr( 'data-open', 'true' );

                // clear selected attributes and set selection to clicked tree
                _store.set_selected( a_root_id, true );
                $('tr[data-selected=true]').attr('data-selected', 'false');
                a_root.attr('data-selected', 'true');
            }
            // the node is closed
            else {
                // hide subtree
                _utils.with_subtree( id, $.fn.hide );

                // mark subtree as closed
                _store.set_open( id, false );
                node.attr( 'data-open', 'false' );

                // if it's a-level node - clear the css highlight/dim
                if( node.hasClass( 'a' ) ) {
                    node.removeClass( 'root' );
                    $('.dim').removeClass('dim');
                    $('.next').removeClass('next');

                    // clear selected attributes and set selection to clicked tree
                    _store.set_selected( a_root_id, false );
                    $('tr[data-selected=true]').attr('data-selected', 'false');
                }
            }
        }
        else if( a_root.attr( 'data-selected' ) === 'false' ) {
            // unselect previously selected node in _store
            previously_selected_id = $('tr[data-selected=true]').attr('id');
            _store.set_selected( previously_selected_id, false );

            _store.set_selected( a_root_id, true );
            $('tr[data-selected=true]').attr('data-selected', 'false');
            a_root.attr('data-selected', 'true');
        }
    }

    // return a-level parent of a given node
    function a_parent( node ) {
        if( node.hasClass( 'a' ) ) {
            return node;
        }
        var prev = node.prev();

        return prev.hasClass('a') ? prev : a_parent( prev );
    }

})();
<|endoftext|>


<commit_before>/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.ShadowMapPlugin = function () {

	var _gl,
	_renderer,
	_lights, _webglObjects, _webglObjectsImmediate,
	_depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,

	_frustum = new THREE.Frustum(),
	_projScreenMatrix = new THREE.Matrix4(),

	_min = new THREE.Vector3(),
	_max = new THREE.Vector3(),

	_matrixPosition = new THREE.Vector3(),

	_renderList = [];

	this.init = function ( renderer, lights, webglObjects, webglObjectsImmediate ) {

		_gl = renderer.context;
		_renderer = renderer;
		_lights = lights;

		_webglObjects = webglObjects;
		_webglObjectsImmediate = webglObjectsImmediate;

		var depthShader = THREE.ShaderLib[ "depthRGBA" ];
		var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );

		_depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
		_depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
		_depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
		_depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } );

		_depthMaterial._shadowPass = true;
		_depthMaterialMorph._shadowPass = true;
		_depthMaterialSkin._shadowPass = true;
		_depthMaterialMorphSkin._shadowPass = true;

	};

	this.render = function ( scene, camera ) {

		if ( _renderer.shadowMapEnabled === false || _renderer.shadowMapAutoUpdate === false ) return;

		this.update( scene, camera );

	};

	this.update = function ( scene, camera ) {

		var i, il, j, jl, n,

		shadowMap, shadowMatrix, shadowCamera,
		program, buffer, material,
		webglObject, object, light,

		lights = [],
		k = 0,

		fog = null;

		// set GL state for depth map

		_gl.clearColor( 1, 1, 1, 1 );
		_gl.disable( _gl.BLEND );

		_gl.enable( _gl.CULL_FACE );
		_gl.frontFace( _gl.CCW );

		if ( _renderer.shadowMapCullFace === THREE.CullFaceFront ) {

			_gl.cullFace( _gl.FRONT );

		} else {

			_gl.cullFace( _gl.BACK );

		}

		_renderer.setDepthTest( true );

		// preprocess lights
		// 	- skip lights that are not casting shadows
		//	- create virtual lights for cascaded shadow maps

		for ( i = 0, il = _lights.length; i < il; i ++ ) {

			light = _lights[ i ];

			if ( ! light.castShadow ) continue;

			if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {

				for ( n = 0; n < light.shadowCascadeCount; n ++ ) {

					var virtualLight;

					if ( ! light.shadowCascadeArray[ n ] ) {

						virtualLight = createVirtualLight( light, n );
						virtualLight.originalCamera = camera;

						var gyro = new THREE.Gyroscope();
						gyro.position.copy( light.shadowCascadeOffset );

						gyro.add( virtualLight );
						gyro.add( virtualLight.target );

						camera.add( gyro );

						light.shadowCascadeArray[ n ] = virtualLight;

						console.log( "Created virtualLight", virtualLight );

					} else {

						virtualLight = light.shadowCascadeArray[ n ];

					}

					updateVirtualLight( light, n );

					lights[ k ] = virtualLight;
					k ++;

				}

			} else {

				lights[ k ] = light;
				k ++;

			}

		}

		// render depth map

		for ( i = 0, il = lights.length; i < il; i ++ ) {

			light = lights[ i ];

			if ( ! light.shadowMap ) {

				var shadowFilter = THREE.LinearFilter;

				if ( _renderer.shadowMapType === THREE.PCFSoftShadowMap ) {

					shadowFilter = THREE.NearestFilter;

				}

				var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };

				light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
				light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );

				light.shadowMatrix = new THREE.Matrix4();

			}

			if ( ! light.shadowCamera ) {

				if ( light instanceof THREE.SpotLight ) {

					light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );

				} else if ( light instanceof THREE.DirectionalLight ) {

					light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );

				} else {

					console.error( "Unsupported light type for shadow" );
					continue;

				}

				scene.add( light.shadowCamera );

				if ( scene.autoUpdate === true ) scene.updateMatrixWorld();

			}

			if ( light.shadowCameraVisible && ! light.cameraHelper ) {

				light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
				light.shadowCamera.add( light.cameraHelper );

			}

			if ( light.isVirtual && virtualLight.originalCamera == camera ) {

				updateShadowCamera( camera, light );

			}

			shadowMap = light.shadowMap;
			shadowMatrix = light.shadowMatrix;
			shadowCamera = light.shadowCamera;

			shadowCamera.position.setFromMatrixPosition( light.matrixWorld );
			_matrixPosition.setFromMatrixPosition( light.target.matrixWorld );
			shadowCamera.lookAt( _matrixPosition );
			shadowCamera.updateMatrixWorld();

			shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );

			if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
			if ( light.shadowCameraVisible ) light.cameraHelper.update();

			// compute shadow matrix

			shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
							  0.0, 0.5, 0.0, 0.5,
							  0.0, 0.0, 0.5, 0.5,
							  0.0, 0.0, 0.0, 1.0 );

			shadowMatrix.multiply( shadowCamera.projectionMatrix );
			shadowMatrix.multiply( shadowCamera.matrixWorldInverse );

			// update camera matrices and frustum

			_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
			_frustum.setFromMatrix( _projScreenMatrix );

			// render shadow map

			_renderer.setRenderTarget( shadowMap );
			_renderer.clear();

			// set object matrices & frustum culling

			_renderList.length = 0;
			projectObject(scene,scene,shadowCamera);

			// render regular objects

			var objectMaterial, useMorphing, useSkinning;

			for ( j = 0, jl = _renderList.length; j < jl; j ++ ) {

				webglObject = _renderList[ j ];

				object = webglObject.object;
				buffer = webglObject.buffer;

				// culling is overriden globally for all objects
				// while rendering depth map

				// need to deal with MeshFaceMaterial somehow
				// in that case just use the first of material.materials for now
				// (proper solution would require to break objects by materials
				//  similarly to regular rendering and then set corresponding
				//  depth materials per each chunk instead of just once per object)

				objectMaterial = getObjectMaterial( object );

				useMorphing = object.geometry.morphTargets !== undefined && object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets;
				useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning;

				if ( object.customDepthMaterial ) {

					material = object.customDepthMaterial;

				} else if ( useSkinning ) {

					material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin;

				} else if ( useMorphing ) {

					material = _depthMaterialMorph;

				} else {

					material = _depthMaterial;

				}

				_renderer.setMaterialFaces( objectMaterial );

				if ( buffer instanceof THREE.BufferGeometry ) {

					_renderer.renderBufferDirect( shadowCamera, _lights, fog, material, buffer, object );

				} else {

					_renderer.renderBuffer( shadowCamera, _lights, fog, material, buffer, object );

				}

			}

			// set matrices and render immediate objects

			for ( j = 0, jl = _webglObjectsImmediate.length; j < jl; j ++ ) {

				webglObject = _webglObjectsImmediate[ j ];
				object = webglObject.object;

				if ( object.visible && object.castShadow ) {

					object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );

					_renderer.renderImmediateObject( shadowCamera, _lights, fog, _depthMaterial, object );

				}

			}

		}

		// restore GL state

		var clearColor = _renderer.getClearColor(),
		clearAlpha = _renderer.getClearAlpha();

		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
		_gl.enable( _gl.BLEND );

		if ( _renderer.shadowMapCullFace === THREE.CullFaceFront ) {

			_gl.cullFace( _gl.BACK );

		}

		_renderer.resetGLState();

	};

	function projectObject(scene, object,shadowCamera){

		if ( object.visible ) {

			var webglObjects = _webglObjects[object.id];

			if (webglObjects && object.castShadow && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) {

				for (var i = 0, l = webglObjects.length; i < l; i++){

					var webglObject = webglObjects[i];

					object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
					_renderList.push(webglObject);

				}
			}

			for(var i = 0, l = object.children.length; i < l; i++) {

				projectObject(scene, object.children[i],shadowCamera);
			}

		}
	}

	function createVirtualLight( light, cascade ) {

		var virtualLight = new THREE.DirectionalLight();

		virtualLight.isVirtual = true;

		virtualLight.onlyShadow = true;
		virtualLight.castShadow = true;

		virtualLight.shadowCameraNear = light.shadowCameraNear;
		virtualLight.shadowCameraFar = light.shadowCameraFar;

		virtualLight.shadowCameraLeft = light.shadowCameraLeft;
		virtualLight.shadowCameraRight = light.shadowCameraRight;
		virtualLight.shadowCameraBottom = light.shadowCameraBottom;
		virtualLight.shadowCameraTop = light.shadowCameraTop;

		virtualLight.shadowCameraVisible = light.shadowCameraVisible;

		virtualLight.shadowDarkness = light.shadowDarkness;

		virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
		virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
		virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];

		virtualLight.pointsWorld = [];
		virtualLight.pointsFrustum = [];

		var pointsWorld = virtualLight.pointsWorld,
			pointsFrustum = virtualLight.pointsFrustum;

		for ( var i = 0; i < 8; i ++ ) {

			pointsWorld[ i ] = new THREE.Vector3();
			pointsFrustum[ i ] = new THREE.Vector3();

		}

		var nearZ = light.shadowCascadeNearZ[ cascade ];
		var farZ = light.shadowCascadeFarZ[ cascade ];

		pointsFrustum[ 0 ].set( - 1, - 1, nearZ );
		pointsFrustum[ 1 ].set(  1, - 1, nearZ );
		pointsFrustum[ 2 ].set( - 1,  1, nearZ );
		pointsFrustum[ 3 ].set(  1,  1, nearZ );

		pointsFrustum[ 4 ].set( - 1, - 1, farZ );
		pointsFrustum[ 5 ].set(  1, - 1, farZ );
		pointsFrustum[ 6 ].set( - 1,  1, farZ );
		pointsFrustum[ 7 ].set(  1,  1, farZ );

		return virtualLight;

	}

	// Synchronize virtual light with the original light

	function updateVirtualLight( light, cascade ) {

		var virtualLight = light.shadowCascadeArray[ cascade ];

		virtualLight.position.copy( light.position );
		virtualLight.target.position.copy( light.target.position );
		virtualLight.lookAt( virtualLight.target );

		virtualLight.shadowCameraVisible = light.shadowCameraVisible;
		virtualLight.shadowDarkness = light.shadowDarkness;

		virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];

		var nearZ = light.shadowCascadeNearZ[ cascade ];
		var farZ = light.shadowCascadeFarZ[ cascade ];

		var pointsFrustum = virtualLight.pointsFrustum;

		pointsFrustum[ 0 ].z = nearZ;
		pointsFrustum[ 1 ].z = nearZ;
		pointsFrustum[ 2 ].z = nearZ;
		pointsFrustum[ 3 ].z = nearZ;

		pointsFrustum[ 4 ].z = farZ;
		pointsFrustum[ 5 ].z = farZ;
		pointsFrustum[ 6 ].z = farZ;
		pointsFrustum[ 7 ].z = farZ;

	}

	// Fit shadow camera's ortho frustum to camera frustum

	function updateShadowCamera( camera, light ) {

		var shadowCamera = light.shadowCamera,
			pointsFrustum = light.pointsFrustum,
			pointsWorld = light.pointsWorld;

		_min.set( Infinity, Infinity, Infinity );
		_max.set( - Infinity, - Infinity, - Infinity );

		for ( var i = 0; i < 8; i ++ ) {

			var p = pointsWorld[ i ];

			p.copy( pointsFrustum[ i ] );
			p.unproject( camera );

			p.applyMatrix4( shadowCamera.matrixWorldInverse );

			if ( p.x < _min.x ) _min.x = p.x;
			if ( p.x > _max.x ) _max.x = p.x;

			if ( p.y < _min.y ) _min.y = p.y;
			if ( p.y > _max.y ) _max.y = p.y;

			if ( p.z < _min.z ) _min.z = p.z;
			if ( p.z > _max.z ) _max.z = p.z;

		}

		shadowCamera.left = _min.x;
		shadowCamera.right = _max.x;
		shadowCamera.top = _max.y;
		shadowCamera.bottom = _min.y;

		// can't really fit near/far
		//shadowCamera.near = _min.z;
		//shadowCamera.far = _max.z;

		shadowCamera.updateProjectionMatrix();

	}

	// For the moment just ignore objects that have multiple materials with different animation methods
	// Only the first material will be taken into account for deciding which depth material to use for shadow maps

	function getObjectMaterial( object ) {

		return object.material instanceof THREE.MeshFaceMaterial
			? object.material.materials[ 0 ]
			: object.material;

	};

};
<commit_msg>ShadowMapPlugin: Clean up.<commit_after>/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.ShadowMapPlugin = function () {

	var _gl,
	_renderer,
	_lights, _webglObjects, _webglObjectsImmediate,
	_depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,

	_frustum = new THREE.Frustum(),
	_projScreenMatrix = new THREE.Matrix4(),

	_min = new THREE.Vector3(),
	_max = new THREE.Vector3(),

	_matrixPosition = new THREE.Vector3(),

	_renderList = [];

	this.init = function ( renderer, lights, webglObjects, webglObjectsImmediate ) {

		_gl = renderer.context;
		_renderer = renderer;
		_lights = lights;

		_webglObjects = webglObjects;
		_webglObjectsImmediate = webglObjectsImmediate;

		var depthShader = THREE.ShaderLib[ "depthRGBA" ];
		var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );

		_depthMaterial = new THREE.ShaderMaterial( {
			uniforms: depthUniforms,
			vertexShader: depthShader.vertexShader,
			fragmentShader: depthShader.fragmentShader
		 } );

		_depthMaterialMorph = new THREE.ShaderMaterial( {
			uniforms: depthUniforms,
			vertexShader: depthShader.vertexShader,
			fragmentShader: depthShader.fragmentShader,
			morphTargets: true
		} );

		_depthMaterialSkin = new THREE.ShaderMaterial( {
			uniforms: depthUniforms,
			vertexShader: depthShader.vertexShader,
			fragmentShader: depthShader.fragmentShader,
			skinning: true
		} );

		_depthMaterialMorphSkin = new THREE.ShaderMaterial( {
			uniforms: depthUniforms,
			vertexShader: depthShader.vertexShader,
			fragmentShader: depthShader.fragmentShader,
			morphTargets: true,
			skinning: true
		} );

		_depthMaterial._shadowPass = true;
		_depthMaterialMorph._shadowPass = true;
		_depthMaterialSkin._shadowPass = true;
		_depthMaterialMorphSkin._shadowPass = true;

	};

	this.render = function ( scene, camera ) {

		if ( _renderer.shadowMapEnabled === false || _renderer.shadowMapAutoUpdate === false ) return;

		this.update( scene, camera );

	};

	this.update = function ( scene, camera ) {

		var i, il, j, jl, n,

		shadowMap, shadowMatrix, shadowCamera,
		program, buffer, material,
		webglObject, object, light,

		lights = [],
		k = 0,

		fog = null;

		// set GL state for depth map

		_gl.clearColor( 1, 1, 1, 1 );
		_gl.disable( _gl.BLEND );

		_gl.enable( _gl.CULL_FACE );
		_gl.frontFace( _gl.CCW );

		if ( _renderer.shadowMapCullFace === THREE.CullFaceFront ) {

			_gl.cullFace( _gl.FRONT );

		} else {

			_gl.cullFace( _gl.BACK );

		}

		_renderer.setDepthTest( true );

		// preprocess lights
		// 	- skip lights that are not casting shadows
		//	- create virtual lights for cascaded shadow maps

		for ( i = 0, il = _lights.length; i < il; i ++ ) {

			light = _lights[ i ];

			if ( ! light.castShadow ) continue;

			if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {

				for ( n = 0; n < light.shadowCascadeCount; n ++ ) {

					var virtualLight;

					if ( ! light.shadowCascadeArray[ n ] ) {

						virtualLight = createVirtualLight( light, n );
						virtualLight.originalCamera = camera;

						var gyro = new THREE.Gyroscope();
						gyro.position.copy( light.shadowCascadeOffset );

						gyro.add( virtualLight );
						gyro.add( virtualLight.target );

						camera.add( gyro );

						light.shadowCascadeArray[ n ] = virtualLight;

						console.log( "Created virtualLight", virtualLight );

					} else {

						virtualLight = light.shadowCascadeArray[ n ];

					}

					updateVirtualLight( light, n );

					lights[ k ] = virtualLight;
					k ++;

				}

			} else {

				lights[ k ] = light;
				k ++;

			}

		}

		// render depth map

		for ( i = 0, il = lights.length; i < il; i ++ ) {

			light = lights[ i ];

			if ( ! light.shadowMap ) {

				var shadowFilter = THREE.LinearFilter;

				if ( _renderer.shadowMapType === THREE.PCFSoftShadowMap ) {

					shadowFilter = THREE.NearestFilter;

				}

				var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };

				light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
				light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );

				light.shadowMatrix = new THREE.Matrix4();

			}

			if ( ! light.shadowCamera ) {

				if ( light instanceof THREE.SpotLight ) {

					light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );

				} else if ( light instanceof THREE.DirectionalLight ) {

					light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );

				} else {

					console.error( "Unsupported light type for shadow" );
					continue;

				}

				scene.add( light.shadowCamera );

				if ( scene.autoUpdate === true ) scene.updateMatrixWorld();

			}

			if ( light.shadowCameraVisible && ! light.cameraHelper ) {

				light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
				light.shadowCamera.add( light.cameraHelper );

			}

			if ( light.isVirtual && virtualLight.originalCamera == camera ) {

				updateShadowCamera( camera, light );

			}

			shadowMap = light.shadowMap;
			shadowMatrix = light.shadowMatrix;
			shadowCamera = light.shadowCamera;

			shadowCamera.position.setFromMatrixPosition( light.matrixWorld );
			_matrixPosition.setFromMatrixPosition( light.target.matrixWorld );
			shadowCamera.lookAt( _matrixPosition );
			shadowCamera.updateMatrixWorld();

			shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );

			if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
			if ( light.shadowCameraVisible ) light.cameraHelper.update();

			// compute shadow matrix

			shadowMatrix.set(
				0.5, 0.0, 0.0, 0.5,
				0.0, 0.5, 0.0, 0.5,
				0.0, 0.0, 0.5, 0.5,
				0.0, 0.0, 0.0, 1.0
			);

			shadowMatrix.multiply( shadowCamera.projectionMatrix );
			shadowMatrix.multiply( shadowCamera.matrixWorldInverse );

			// update camera matrices and frustum

			_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
			_frustum.setFromMatrix( _projScreenMatrix );

			// render shadow map

			_renderer.setRenderTarget( shadowMap );
			_renderer.clear();

			// set object matrices & frustum culling

			_renderList.length = 0;
			projectObject(scene,scene,shadowCamera);

			// render regular objects

			var objectMaterial, useMorphing, useSkinning;

			for ( j = 0, jl = _renderList.length; j < jl; j ++ ) {

				webglObject = _renderList[ j ];

				object = webglObject.object;
				buffer = webglObject.buffer;

				// culling is overriden globally for all objects
				// while rendering depth map

				// need to deal with MeshFaceMaterial somehow
				// in that case just use the first of material.materials for now
				// (proper solution would require to break objects by materials
				//  similarly to regular rendering and then set corresponding
				//  depth materials per each chunk instead of just once per object)

				objectMaterial = getObjectMaterial( object );

				useMorphing = object.geometry.morphTargets !== undefined && object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets;
				useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning;

				if ( object.customDepthMaterial ) {

					material = object.customDepthMaterial;

				} else if ( useSkinning ) {

					material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin;

				} else if ( useMorphing ) {

					material = _depthMaterialMorph;

				} else {

					material = _depthMaterial;

				}

				_renderer.setMaterialFaces( objectMaterial );

				if ( buffer instanceof THREE.BufferGeometry ) {

					_renderer.renderBufferDirect( shadowCamera, _lights, fog, material, buffer, object );

				} else {

					_renderer.renderBuffer( shadowCamera, _lights, fog, material, buffer, object );

				}

			}

			// set matrices and render immediate objects

			for ( j = 0, jl = _webglObjectsImmediate.length; j < jl; j ++ ) {

				webglObject = _webglObjectsImmediate[ j ];
				object = webglObject.object;

				if ( object.visible && object.castShadow ) {

					object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );

					_renderer.renderImmediateObject( shadowCamera, _lights, fog, _depthMaterial, object );

				}

			}

		}

		// restore GL state

		var clearColor = _renderer.getClearColor(),
		clearAlpha = _renderer.getClearAlpha();

		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
		_gl.enable( _gl.BLEND );

		if ( _renderer.shadowMapCullFace === THREE.CullFaceFront ) {

			_gl.cullFace( _gl.BACK );

		}

		_renderer.resetGLState();

	};

	function projectObject(scene, object,shadowCamera){

		if ( object.visible ) {

			var webglObjects = _webglObjects[object.id];

			if (webglObjects && object.castShadow && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) {

				for (var i = 0, l = webglObjects.length; i < l; i++){

					var webglObject = webglObjects[i];

					object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
					_renderList.push(webglObject);

				}
			}

			for(var i = 0, l = object.children.length; i < l; i++) {

				projectObject(scene, object.children[i],shadowCamera);
			}

		}
	}

	function createVirtualLight( light, cascade ) {

		var virtualLight = new THREE.DirectionalLight();

		virtualLight.isVirtual = true;

		virtualLight.onlyShadow = true;
		virtualLight.castShadow = true;

		virtualLight.shadowCameraNear = light.shadowCameraNear;
		virtualLight.shadowCameraFar = light.shadowCameraFar;

		virtualLight.shadowCameraLeft = light.shadowCameraLeft;
		virtualLight.shadowCameraRight = light.shadowCameraRight;
		virtualLight.shadowCameraBottom = light.shadowCameraBottom;
		virtualLight.shadowCameraTop = light.shadowCameraTop;

		virtualLight.shadowCameraVisible = light.shadowCameraVisible;

		virtualLight.shadowDarkness = light.shadowDarkness;

		virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
		virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
		virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];

		virtualLight.pointsWorld = [];
		virtualLight.pointsFrustum = [];

		var pointsWorld = virtualLight.pointsWorld,
			pointsFrustum = virtualLight.pointsFrustum;

		for ( var i = 0; i < 8; i ++ ) {

			pointsWorld[ i ] = new THREE.Vector3();
			pointsFrustum[ i ] = new THREE.Vector3();

		}

		var nearZ = light.shadowCascadeNearZ[ cascade ];
		var farZ = light.shadowCascadeFarZ[ cascade ];

		pointsFrustum[ 0 ].set( - 1, - 1, nearZ );
		pointsFrustum[ 1 ].set(  1, - 1, nearZ );
		pointsFrustum[ 2 ].set( - 1,  1, nearZ );
		pointsFrustum[ 3 ].set(  1,  1, nearZ );

		pointsFrustum[ 4 ].set( - 1, - 1, farZ );
		pointsFrustum[ 5 ].set(  1, - 1, farZ );
		pointsFrustum[ 6 ].set( - 1,  1, farZ );
		pointsFrustum[ 7 ].set(  1,  1, farZ );

		return virtualLight;

	}

	// Synchronize virtual light with the original light

	function updateVirtualLight( light, cascade ) {

		var virtualLight = light.shadowCascadeArray[ cascade ];

		virtualLight.position.copy( light.position );
		virtualLight.target.position.copy( light.target.position );
		virtualLight.lookAt( virtualLight.target );

		virtualLight.shadowCameraVisible = light.shadowCameraVisible;
		virtualLight.shadowDarkness = light.shadowDarkness;

		virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];

		var nearZ = light.shadowCascadeNearZ[ cascade ];
		var farZ = light.shadowCascadeFarZ[ cascade ];

		var pointsFrustum = virtualLight.pointsFrustum;

		pointsFrustum[ 0 ].z = nearZ;
		pointsFrustum[ 1 ].z = nearZ;
		pointsFrustum[ 2 ].z = nearZ;
		pointsFrustum[ 3 ].z = nearZ;

		pointsFrustum[ 4 ].z = farZ;
		pointsFrustum[ 5 ].z = farZ;
		pointsFrustum[ 6 ].z = farZ;
		pointsFrustum[ 7 ].z = farZ;

	}

	// Fit shadow camera's ortho frustum to camera frustum

	function updateShadowCamera( camera, light ) {

		var shadowCamera = light.shadowCamera,
			pointsFrustum = light.pointsFrustum,
			pointsWorld = light.pointsWorld;

		_min.set( Infinity, Infinity, Infinity );
		_max.set( - Infinity, - Infinity, - Infinity );

		for ( var i = 0; i < 8; i ++ ) {

			var p = pointsWorld[ i ];

			p.copy( pointsFrustum[ i ] );
			p.unproject( camera );

			p.applyMatrix4( shadowCamera.matrixWorldInverse );

			if ( p.x < _min.x ) _min.x = p.x;
			if ( p.x > _max.x ) _max.x = p.x;

			if ( p.y < _min.y ) _min.y = p.y;
			if ( p.y > _max.y ) _max.y = p.y;

			if ( p.z < _min.z ) _min.z = p.z;
			if ( p.z > _max.z ) _max.z = p.z;

		}

		shadowCamera.left = _min.x;
		shadowCamera.right = _max.x;
		shadowCamera.top = _max.y;
		shadowCamera.bottom = _min.y;

		// can't really fit near/far
		//shadowCamera.near = _min.z;
		//shadowCamera.far = _max.z;

		shadowCamera.updateProjectionMatrix();

	}

	// For the moment just ignore objects that have multiple materials with different animation methods
	// Only the first material will be taken into account for deciding which depth material to use for shadow maps

	function getObjectMaterial( object ) {

		return object.material instanceof THREE.MeshFaceMaterial
			? object.material.materials[ 0 ]
			: object.material;

	};

};
<|endoftext|>


<commit_before>var initTabContainer = function ($context) {

    $(".tabContainer, .tabContainerAlt").on('click', '.tab', function () {
        var me = $(this);
        me.parent().parent().find(".active").removeClass("active");
        me.addClass("active");
        $("#" + me.attr("id").replace("tab", "container")).addClass("active");
    });

    var accordion = $.extend($(".accordionContainer", $context), {
        hasOutsideScroll: function() {
            return this.parent().height() < this.height();
        },
        updateHeight:       function() {
            var contentCells = $("> .container-accordion > .accordion-cell", this);
            var tabCells = $("> .accordion", this);
            var tabCellsHeight = this.parent().height();

            $.each(tabCells, function(idx, el) {
                var tabCell = $(el);
                tabCellsHeight -= tabCell.height();
            });
            contentCells.height(tabCellsHeight);
        }
    });

    // IE Scroll BugFix
    if(accordion.hasOutsideScroll()){
        accordion.updateHeight();
        $(window).on('resize', $.proxy(accordion.updateHeight, accordion));
    }

    accordion.on('click', '.accordion', function(event) {
        var me = $(this);
        var tab = $(event.delegateTarget);
        var isActive = me.hasClass('active');

        if(isActive) {
            return;
        }

        var previous = tab.find(".active");
        previous.removeClass("active");

        if(me.hasClass('accordion')) {
            if(isActive) {
                me.removeClass('active');
            } else {
                me.addClass('active');
                $("#" + me.attr("id").replace("accordion", "container"), tab).addClass("active");
            }
        } else {
            me.addClass("active");
            $("#" + me.attr("id").replace("tab", "container"), tab).addClass("active");
        }

        me.trigger('selected', {
            current:    me,
            currentTab: tab,
            previous:   previous
        });
    });

    accordion.bind('select', function(e, title) {
        return $(e.currentTarget).find('.accordion > .tablecell:contains("' + title + '")').trigger('click');
    });

    accordion.data('ready',true);
    accordion.trigger('ready');
};

$(function () {
    // init tabcontainers --------------------------------------------------------------------
    initTabContainer($('body'));
});
<commit_msg>fix 'active' by accordion in accordion<commit_after>var initTabContainer = function ($context) {

    $(".tabContainer, .tabContainerAlt").on('click', '.tab', function () {
        var me = $(this);
        me.parent().parent().find(".active").removeClass("active");
        me.addClass("active");
        $("#" + me.attr("id").replace("tab", "container")).addClass("active");
    });

    var accordion = $.extend($(".accordionContainer", $context), {
        hasOutsideScroll: function() {
            return this.parent().height() < this.height();
        },
        updateHeight:       function() {
            var contentCells = $("> .container-accordion > .accordion-cell", this);
            var tabCells = $("> .accordion", this);
            var tabCellsHeight = this.parent().height();

            $.each(tabCells, function(idx, el) {
                var tabCell = $(el);
                tabCellsHeight -= tabCell.height();
            });
            contentCells.height(tabCellsHeight);
        }
    });

    // IE Scroll BugFix
    if(accordion.hasOutsideScroll()){
        accordion.updateHeight();
        $(window).on('resize', $.proxy(accordion.updateHeight, accordion));
    }

    accordion.on('click', '.accordion', function(event) {
        var me = $(this);
        var tab = $(event.delegateTarget);
        var isActive = me.hasClass('active');

        if(isActive) {
            return;
        }

        var previous = tab.find("> .active");
        previous.removeClass("active");

        if(me.hasClass('accordion')) {
            if(isActive) {
                me.removeClass('active');
            } else {
                me.addClass('active');
                $("#" + me.attr("id").replace("accordion", "container"), tab).addClass("active");
            }
        } else {
            me.addClass("active");
            $("#" + me.attr("id").replace("tab", "container"), tab).addClass("active");
        }

        me.trigger('selected', {
            current:    me,
            currentTab: tab,
            previous:   previous
        });
    });

    accordion.bind('select', function(e, title) {
        return $(e.currentTarget).find('.accordion > .tablecell:contains("' + title + '")').trigger('click');
    });

    accordion.data('ready',true);
    accordion.trigger('ready');
};

$(function () {
    // init tabcontainers --------------------------------------------------------------------
    initTabContainer($('body'));
});
<|endoftext|>


<commit_before>var path = require('path'),
    fs = require('fs'),
    External = require('./external'),
    Step = require('./step'),
    _ = require('underscore')._,
    sys = require('sys');

require.paths.unshift(path.join(__dirname, '..', 'lib'));

var mess = {},
    less = require('less');

/**
 * Convert a two-element-per-item Array
 * into an object, for the purpose of checking membership
 * and replacing stuff.
 * @param {Array} list a list.
 */
var to = function(list) {
    return _.reduce(list, function(m, r) {
        m[r[0]] = r[1];
        return m;
    }, {});
};

mess.Renderer = function Renderer(env) {
    return {
        grab: function(uri, callback) {
            console.log('Download external\n\t' + uri);
            new(External)({
                data_dir: 'test'
            }).process(uri, callback);
        },
        /**
         * Download any file-based remote datsources
         */
        localizeExternals: function(m, callback) {
            var that = this;
            Step(
                function() {
                    var group = this.group();
                    m.Map.Layer.forEach(function(l) {
                        if (l.Datasource.file) {
                            that.grab(l.Datasource.file, group());
                        }
                    });
                },
                function(err, results) {
                    var result_map = to(results);
                    m.Map.Layer.forEach(function(l) {
                        if (l.Datasource.file) {
                            l.Datasource.file = result_map[l.Datasource.file];
                        }
                    });
                    callback(err, m);
                }
            );
        },
        /**
         * Download any remote stylesheets
         */
        localizeStyle: function(m, callback) {
            var that = this;
            Step(
                function() {
                    var group = this.group();
                    m.Map.Stylesheet.forEach(function(s) {
                        that.grab(s, group());
                    });
                },
                function(err, results) {
                    var result_map = to(results);
                    for (s in m.Map.Stylesheet) {
                        m.Map.Stylesheet[s] = result_map[m.Map.Stylesheet[s]];
                    }
                    callback(err, m);
                }
            );
        },
        style: function(m, callback) {
            Step(
                function() {
                    var group = this.group();
                    m.Map.Stylesheet.forEach(function(s) {
                        fs.readFile(s, 'utf-8', function(err, data) {
                            group()(err, [s, data]);
                        });
                    });
                },
                function(e, results) {
                    var options = {},
                        group = this.group();
                    if (e) {
                        sys.puts('lessc: ' + e.message);
                        process.exit(1);
                    }
                    for (var i = 0, l = results.length; i < l; i++) {
                        new(less.Parser)({
                            filename: s
                        }).parse(results[i][1], function(err, tree) {
                            // require('eyes').inspect(err);
                            if (err) {
                                less.writeError(err, options);
                                process.exit(1);
                            } else {
                                try {
                                    group()(err, [
                                        results[i][0],
                                        tree.toCSS({ compress: false })]);
                                } catch (e) {
                                    less.writeError(e, options);
                                    process.exit(2);
                                }
                            }
                        });
                    }
                },
                function(err, results) {
                    require('eyes').inspect(results);
                    var group = this.group();
                    results.forEach(function(r) {
                        fs.writeFile(r[0].replace('.mss', '.xml'), r[1], function(err) {
                            group()(null, [r[0], r[0].replace('.mss', '.xml')]);
                        });
                    });
                },
                function(err, results) {
                    var result_map = to(results);
                    for (s in m.Map.Stylesheet) {
                        m.Map.Stylesheet[s] = result_map[m.Map.Stylesheet[s]];
                    }
                    callback(err, m);
                }
            );
        },
        template: function(m, callback) {
            var entities = _.template('<?xml version="1.0" ' +
                'encoding="utf-8"?>\n' +
                '<!DOCTYPE Map[\n<% for (ref in stylesheets) { %>' +
                '  <!ENTITY <%= ref %> SYSTEM "<%= stylesheets[ref] %>">\n' +
                '<% } %>]>\n');
            var layer = _.template('<Layer\n  id="<%= id %>"\n ' +
                ' srs="<%= srs %>">\n' +
                '  <Datasource>\n<% for (n in Datasource) { %>' +
                '    <Parameter name="<%= n %>"><%= Datasource[n] %>' +
                '</Parameter>\n' +
                '<% } %>  </Datasource>\n' +
                '</Layer>\n');
            var references = _.template('<% for (ref in stylesheets) { %>' +
                '&<%= ref %>;\n' +
                '<% } %>');

            var stylesheets = { stylesheets: [] };
            m.Map.Stylesheet.forEach(function(s) {
                // XML entities must begin with a letter, hence a
                stylesheets.stylesheets[
                    'a' + require('crypto')
                        .createHash('md5')
                        .update(m.Map.Stylesheet[s])
                        .digest('hex')] =
                        s;
            });
            var output = [entities(stylesheets)];
            output.push('<Map>');
            // using array joins here: faster in IE7, unclear in general.
            m.Map.Layer.forEach(function(l) {
                // require('eyes').inspect(l);
                output.push(layer(l));
            });
            output.push(references(stylesheets));
            output.push('</Map>');
            callback(null, output.join(''));
        },
        render: function(str, callback) {
            var m = JSON.parse(str),
                that = this;
            this.localizeExternals(m, function(err, res) {
                that.localizeStyle(res, function(err, res) {
                    that.style(res, function(err, res) {
                        that.template(res, function(err, res) {
                            console.log(res);
                        });
                    });
                });
            });
        }
    };
};

module.exports = mess;
<commit_msg>First full-process successful map render. Fixes #5<commit_after>var path = require('path'),
    fs = require('fs'),
    External = require('./external'),
    Step = require('./step'),
    _ = require('underscore')._,
    sys = require('sys');

require.paths.unshift(path.join(__dirname, '..', 'lib'));

var mess = {},
    less = require('less');

/**
 * Convert a two-element-per-item Array
 * into an object, for the purpose of checking membership
 * and replacing stuff.
 * @param {Array} list a list.
 */
var to = function(list) {
    return _.reduce(list, function(m, r) {
        m[r[0]] = r[1];
        return m;
    }, {});
};

mess.Renderer = function Renderer(env) {
    return {
        grab: function(uri, callback) {
            console.log('Download external\n\t' + uri);
            new(External)({
                data_dir: 'test'
            }).process(uri, callback);
        },
        /**
         * Download any file-based remote datsources
         */
        localizeExternals: function(m, callback) {
            var that = this;
            Step(
                function() {
                    var group = this.group();
                    m.Map.Layer.forEach(function(l) {
                        if (l.Datasource.file) {
                            that.grab(l.Datasource.file, group());
                        }
                    });
                },
                function(err, results) {
                    var result_map = to(results);
                    m.Map.Layer.forEach(function(l) {
                        if (l.Datasource.file) {
                            l.Datasource.file = result_map[l.Datasource.file];
                        }
                    });
                    callback(err, m);
                }
            );
        },
        /**
         * Download any remote stylesheets
         */
        localizeStyle: function(m, callback) {
            var that = this;
            Step(
                function() {
                    var group = this.group();
                    m.Map.Stylesheet.forEach(function(s) {
                        that.grab(s, group());
                    });
                },
                function(err, results) {
                    var result_map = to(results);
                    for (s in m.Map.Stylesheet) {
                        m.Map.Stylesheet[s] = result_map[m.Map.Stylesheet[s]];
                    }
                    callback(err, m);
                }
            );
        },
        style: function(m, callback) {
            Step(
                function() {
                    var group = this.group();
                    m.Map.Stylesheet.forEach(function(s) {
                        fs.readFile(s, 'utf-8', function(err, data) {
                            group()(err, [s, data]);
                        });
                    });
                },
                function(e, results) {
                    var options = {},
                        group = this.group();
                    if (e) {
                        sys.puts('lessc: ' + e.message);
                        process.exit(1);
                    }
                    for (var i = 0, l = results.length; i < l; i++) {
                        new(less.Parser)({
                            filename: s
                        }).parse(results[i][1], function(err, tree) {
                            if (err) {
                                less.writeError(err, options);
                                process.exit(1);
                            } else {
                                try {
                                    group()(err, [
                                        results[i][0],
                                        tree.toCSS({ compress: false }),
                                        tree]);
                                } catch (e) {
                                    less.writeError(e, options);
                                    process.exit(2);
                                }
                            }
                        });
                    }
                },
                function(err, results) {
                    var group = this.group();
                    results.forEach(function(r) {
                        fs.writeFile(r[0].replace('.mss', '.xml'),
                            r[1], function(err) {
                            group()(
                                null, [
                                    r[0],
                                    r[0].replace('.mss', '.xml'),
                                    r[2]]);
                        });
                    });
                },
                function(err, results) {
                    var result_map = to(results);
                    for (s in m.Map.Stylesheet) {
                        m.Map.Stylesheet[s] = result_map[m.Map.Stylesheet[s]];
                    }
                    callback(err, [m, results]);
                }
            );
        },
        template: function(res, callback) {
            var m = res[0],
                stylesheets = res[1],

                entities = _.template('<?xml version="1.0" ' +
                'encoding="utf-8"?>\n' +
                '<!DOCTYPE Map[\n' +
                '<% for (ref in stylesheets) { %>' +
                '  <!ENTITY <%= ref %> SYSTEM "<%= stylesheets[ref] %>">\n' +
                '<% } %>]>\n'),

                styles = _.template('<StyleName><%= name %></StyleName>'),

                layer = _.template('<Layer\n  id="<%= id %>"\n ' +
                ' srs="<%= srs %>">\n' +
                ' <% for (s in styles) { %>\n' +
                '  <StyleName><%= styles[s] %></StyleName>\n' +
                ' <% } %>\n' +
                '  <Datasource>\n<% for (n in Datasource) { %>' +
                '    <Parameter name="<%= n %>"><%= Datasource[n] %>' +
                '</Parameter>\n' +
                '<% } %>  </Datasource>\n' +
                '</Layer>\n'),

                references = _.template('<% for (ref in stylesheets) { %>' +
                '&<%= ref %>;\n' +
                '<% } %>'),

                stylesheet_list = { stylesheets: [] };

            m.Map.Stylesheet.forEach(function(s) {
                // XML entities must begin with a letter, hence a
                stylesheet_list.stylesheets[
                    'a' + require('crypto')
                        .createHash('md5')
                        .update(m.Map.Stylesheet[s])
                        .digest('hex')] =
                        s;
            });

            var ruleHash = function(stylesheets) {
                return _.flatten(_.map(stylesheets, function(s) {
                    return _.map(s[2].rules, function(r) {
                        if (r && r.selectors[0]._css) {
                            return r.selectors[0]._css;
                        }
                    });
                }));
            };

            var styleIntersect = function(layer, stylesheets) {
                var hash = ruleHash(stylesheets);
                layer.styles = [];
                if (_.include(hash, 'id-' + layer.id)) {
                    layer.styles.push('id-' + layer.id);
                }
                return layer;
            };

            var output = [entities(stylesheet_list)];

            output.push('<Map>');
            // using array joins here: faster in IE7, unclear in general.
            m.Map.Layer.forEach(function(l) {
                l = styleIntersect(l, stylesheets);
                output.push(layer(l));
            });
            output.push(references(stylesheet_list));
            output.push('</Map>');
            callback(null, output.join(''));
        },
        render: function(str, callback) {
            var m = JSON.parse(str),
                that = this;
            this.localizeExternals(m, function(err, res) {
                that.localizeStyle(res, function(err, res) {
                    that.style(res, function(err, res) {
                        that.template(res, function(err, res) {
                            console.log(res);
                        });
                    });
                });
            });
        }
    };
};

module.exports = mess;
<|endoftext|>


<commit_before>import React     from 'react'
import _         from 'lodash'

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

function match(value, item) {
  const regexp = new RegExp(escapeRegExp(value), 'i')
  return regexp.test(item.name) || regexp.test(item.phone.replace(/ /g, ''))
}

function isNumber(number) {
  return /^(\+?255\-?|0)[0123456789]{9}$/.test(number.replace(/ /g, ''))
}

class PhoneLookup extends React.Component {
  constructor(props) {
    let entries = {}
    props.entries.forEach(item => { entries[item.phone] = item })
    super({
      entries, ...props
    })
    this.state = {
      value    : '',
      results  : [],
      entry    : null,
      isNumber : false
    }
  }
  handleChange(event) {
    const { entries } = this.props
    const value = event.target.value
    const results = value ? _.pick(entries, item => match(value, item)) : {}
    this.setState({
      value,
      results,
      isNumber : isNumber(value),
      entry    : null
    })
  }
  selectEntry(entry) {
    this.setState({
      value    : entry ? entry.name : '',
      results  : [],
      isNumber : false,
      entry
    })
  }
  reset() {
    this.selectEntry(null)
  }
  render() {
    const { value, results, entry, isNumber } = this.state
    const { maxResults } = this.props
    const inputStyle = !!entry ? {backgroundColor: '#fff4a8'} : !!isNumber ? {backgroundColor: '#a8f4a8'} : {}
    const keys = _.keysIn(results)
    return (

        <input
          style    = {inputStyle}
          type     = 'text'
          value    = {value}
          onChange = {this.handleChange.bind(this)}
        />
        {(!!entry || isNumber) && (

            <button onClick={this.reset.bind(this)}>
              Reset
            </button>
            <button>
              Call
            </button>

        )}
        {!!keys.length && (

            {keys.slice(0, maxResults ? maxResults : -1).map(key => {
              const result = results[key]
              return (

                   this.selectEntry(result)}>
                    {result.name} ({result.phone})

              )
            })}

        )}

    )
  }
}

PhoneLookup.defaultProps = {
  maxResults : 10,
  entries    : []
}

export default PhoneLookup
<commit_msg>remove explicit null argument<commit_after>import React     from 'react'
import _         from 'lodash'

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

function match(value, item) {
  const regexp = new RegExp(escapeRegExp(value), 'i')
  return regexp.test(item.name) || regexp.test(item.phone.replace(/ /g, ''))
}

function isNumber(number) {
  return /^(\+?255\-?|0)[0123456789]{9}$/.test(number.replace(/ /g, ''))
}

class PhoneLookup extends React.Component {
  constructor(props) {
    let entries = {}
    props.entries.forEach(item => { entries[item.phone] = item })
    super({
      entries, ...props
    })
    this.state = {
      value    : '',
      results  : [],
      entry    : null,
      isNumber : false
    }
  }
  handleChange(event) {
    const { entries } = this.props
    const value = event.target.value
    const results = value ? _.pick(entries, item => match(value, item)) : {}
    this.setState({
      value,
      results,
      isNumber : isNumber(value),
      entry    : null
    })
  }
  selectEntry(entry) {
    this.setState({
      value    : entry ? entry.name : '',
      results  : [],
      isNumber : false,
      entry
    })
  }
  reset() {
    this.selectEntry()
  }
  render() {
    const { value, results, entry, isNumber } = this.state
    const { maxResults } = this.props
    const inputStyle = !!entry ? {backgroundColor: '#fff4a8'} : !!isNumber ? {backgroundColor: '#a8f4a8'} : {}
    const keys = _.keysIn(results)
    return (

        <input
          style    = {inputStyle}
          type     = 'text'
          value    = {value}
          onChange = {this.handleChange.bind(this)}
        />
        {(!!entry || isNumber) && (

            <button onClick={this.reset.bind(this)}>
              Reset
            </button>
            <button>
              Call
            </button>

        )}
        {!!keys.length && (

            {keys.slice(0, maxResults ? maxResults : -1).map(key => {
              const result = results[key]
              return (

                   this.selectEntry(result)}>
                    {result.name} ({result.phone})

              )
            })}

        )}

    )
  }
}

PhoneLookup.defaultProps = {
  maxResults : 10,
  entries    : []
}

export default PhoneLookup
<|endoftext|>