Northern Pileated Marmoset

    backbone.facetr

    0.4.3 • Public • Published

    Backbone.Facetr

    npm npm Bower Build Status Coverage Status

    CONTENTS

    INTRODUCTION

    Backbone.Facetr is an utility which enables filtering of Backbone collections through facets. It can be used to implement faceted search, which follows the faceted classification system.

    It works flawlessly up to 2500 items; computation starts getting slower with 5000 - 10000 items. This is however an early version; optimizations may improve performance in future realeases.

    INSTALLATION

    Production bundles can be found in the dist folder. Facetr is distributed via bower and npm. Both AMD and CommonJS are supported.

    npm

    npm install backbone.facetr --save

    bower

    bower install Backbone.Facetr --save

    build from source

    git clone git@github.com:arillo/Backbone.Facetr.git # clone repo 
    cd Backbone.Facetr # navigate to local repo 
    npm install -g grunt-cli # install grunt globally 
    npm install # install dependencies 
    grunt # build to dist folder 

    Include in your code using any of the following methods

    AMD

    define('yourmodule', ['backbone.facetr'], function(Facetr){
        // ... 
    });

    CommonJS

    var Facetr = require('backbone.facetr');

    script tag

    <!-- deps -->
    <script src="path/to/libs/backbone.js"></script>
    <script src="path/to/libs/underscore.js"></script>
    <!-- facetr -->
    <script src="path/to/libs/backbone.facetr.js"></script>

    BASIC USAGE

    // create a collection with few test items
    var collection = new Backbone.Collection([
        {
            'Name'      : {
                'FirstName' : 'Bob',
                'LastName' : 'Smith'
            },
            'Age'       : 20,
            'Country'   : 'Australia',
            'Hobbies'   : ['fishing','painting','playing the ukulele'],
            'Profession': 'manager'
        },
        {
            'Name'      : {
                'FirstName' : 'Otto',
                'LastName'  : 'Von Braun'
            },
            'Age'       : 35,
            'Country'   : 'New Zealand',
            'Hobbies'   : ['drawing', 'painting', 'shopping'],
            'Profession': 'team manager'
        },
        {
            'Name'      : {
                'FirstName' : 'Sarah',
                'LastName'  : 'Smith'
            },
            'Age'       : 28,
            'Country'   : 'Ireland',
            'Hobbies'   : ['shopping','painting'],
            'Profession': 'project manager'
        }
    ]);
     
    Facetr(collection).facet('Name.LastName').value('Smith'); // collection contains 'Sarah Smith' and 'Bob Smith'
    Facetr(collection).facet('Hobbies').value('shopping'); // contains only 'Sarah Smith' 
    Facetr(collection).facet('Name.LastName').removeValue('Smith'); // contains 'Sarah Smith' and 'Otto Von Braun'
     
    // removes all facet values and restores original collection content
    Facetr(collection).clearValues();
     
    // if chaining is not your cup of tea, the following is equivalent to the above code
    var facetCollection = Facetr(collection); // returns a FacetCollection object
    var lastNameFacet = facetCollection.facet('Name.LastName'); // returns a Facet object
    var hobbiesFacet = facetCollection.facet('Hobbies');
     
    lastNameFacet.value('Smith'); // returns a FacetExp object
    hobbiesFacet.value('shopping');
    lastNameFacet.removeValue('Smith');
     
    // read the API Reference section for more
    // most examples will use the above collection reference to illustrate functionalities

    DOT NOTATION

    Syntax: PropertyName{1}(.PropertyName)*
    

    In the context of Facetr, Dot Notation refers to the syntax used to define facets on a collection. Using the Facetr Dot Notation it is possible to define facets on properties of a Model, as well as on properties of its properties.

    For example, consider the following model:

    var model = new Backbone.Model({
        'Name' : {
            'FirstName' : 'John',
            'LastName' : ['Smith','White']
        },
        'City' : 'London',
        'Age' : 45,
        'FamilyMembers' : [
            { 'Name' : 'Robert' },
            { 'Name' : 'Margaret' }
        ]
    });

    To add a facet on property 'FirstName' the following expression in Dot Notation syntax can be used: 'Name.FirstName'.

    Facetr(collection).facet('Name.FirstName');

    Theoretically there is no depth limit for a Dot Notation expression (e.g. PropertyName1.PropertyName2...PropertyNameN), the only limitation being the common sense.

    A facet can only be added on a Backbone Model or object property having any of the following value types:

    • string | number | boolean
    • Array of strings
    • Array of numbers
    • Array of booleans
    • Array of objects
    • Array of Backbone models

    It cannot be added on properties having the following value / composite types:

    • object
    • Backbone Collection
    • Array of arrays
    • Array of Backbone collections

    .. and in any other case not mentioned in the list of allowed value types

    EXAMPLE

    Facetr(collection).facet('City');               // valid, City is a string
    Facetr(collection).facet('Age');                // valid, Age is a Number
    Facetr(collection).facet('Name.LastName');      // valid, LastName is an Array of strings
    Facetr(collection).facet('FamilyMembers.Name'); // valid, takes value of Name of each object in array FamilyMembers
    Facetr(collection).facet('Name');               // error, Name is an object
     
    // etc..

    OPERATORS

    Facets filtering can be combined using logical operators 'or' and 'and', both between different facets (external operator, see FacetCollection.facet method) and between values of one facet (internal operator, see Facet.value method and FacetExp).

    External Operator

    // create a facet with default external operator 'and'
    var facetCountry = Facetr(collection).facet('Country');
     
    // or set the external operator explicitly
    var facetLastName = Facetr(collection).facet('Name.LastName', 'and');
     
    // when filtering, such operator will be used to combine filters of the two facets
    facetCountry.value('Australia');
    facetLastName.value('Smith');
     
    // collection contains all models with Country equal 'Australia' and LastName equal 'Smith'

    Internal Operator

    // add a value with default internal operator 'or'
    facetCountry.value('Australia');
     
    // or set the internal operator explicitly
    facetCountry.value('Ireland', 'or');
     
    // it is possible to use chaining syntax to combine values
    facetCountry.value('Australia').or('Ireland');
     
    // collection contains all models with Country equal either 'Australia' or 'Ireland'

    API Reference

    Facetr

    Facetr(collection:Backbone.Collection, [id:string]) : FacetCollection

    Initialize a Collection to be used with Facetr. The first building block of any Facetr expression. Returns the created FacetCollection instance for method chaining. An id can be associated with the collection.

    Example

    Facetr(collection);
     
    // or also
    Facetr(collection, 'myCollection');
     
    // which enables the following syntax
    Facetr('myCollection') === Facetr(collection); // true

    FacetCollection

    facet(dotNotationExpr:string, [externalOperator:string], [silent:boolean]) : Facet

    Adds a Facet on the given collection using the property refered to by the Dot Notation expression (see Dot Notation section for more details). Valid external operator values are: 'or' and 'and' (default is 'and'). Returns the created Facet instance to allow method chaining. Triggers a facet event with the facetName passed to the callback, unless true is passed as last parameter.

    Example

    Facetr(collection).on('facet', function(facetName) {
        console.log('added facet', facetName);
    });
     
    // add facet on property 'Age' using default operator ('and')
    Facetr(collection).facet('Age');
     
    // add facet on property 'LastName' of object 'Name' using 'or' operator
    Facetr(collection).facet('Name.LastName', 'or');
     
    // console output would be
    // added facet Age
    // added facet Name.LastName
    toJSON() : Array

    Returns an array containing objects representing the status of the facets added to the collection. Useful for rendering out facets lists. Each object in the array is the result of invoking toJSON on each Facet (see Facet documentation below for the Facet.toJSON method).

    Example

    // create a collection with two models
    var collection = new Backbone.Collection([
        {
            'Name'      : {
                'FirstName' : 'Bob',
                'LastName' : 'Smith'
            },
            'Age'       : 20
        },
        {
            'Name'      : {
                'FirstName' : 'Otto',
                'LastName'  : 'Von Braun'
            },
            'Age'       : 35
        }
    ]);
     
    Facetr(collection).facet('Name.FirstName').label('First Name');
    Facetr(collection).facet('Name.FirstName').value('Bob');
     
    var json = Facetr(collection).toJSON();
     
    // value of json will be an array of Facet data object with the following format:
    //
    // [
    //      {
    //          data : {
    //              extOperator : 'and',
    //              intOperator : 'or',
    //              label       : 'First Name',
    //              name        : 'Name.FirstName',
    //              selected    : true,
    //              sort        : {
    //                  by        : 'value',
    //                  direction : 'asc'
    //              }
    //              customData : {}
    //          },
    //          values : [
    //              {
    //                  active      : true,
    //                  activeCount : 1,
    //                  count       : 1,
    //                  value       : 'Bob'
    //              },
    //              {
    //                  active      : false,
    //                  activeCount : 0,
    //                  count       : 1,
    //                  value       : 'Otto'
    //              }
    //          ]
    //      }
    // ]
    clear([silent:boolean]) : FacetCollection

    Removes all the facets added to the collection and unfilters it accordingly. Use this method to reset the original models in the collection. Triggers a clear event, unless true is passed as parameter.

    Example

    Facet(collection).on('clear', function() {
        console.log('All facets were removed');
    });
     
    Facet(collection).clear();
     
    // console output:
    // All facets were removed
    remove() : undefined

    Removes all the facets and the facetrid added on the collection id upon Facetr(collection) initialization. Resets the original items in the collection.

    Example

    Facetr(collection).remove()
    sortBy(attribute:string, [silent]) : FacetCollection

    Sorts the collection according to the given attribute name. By default ascendent sort is used. See asc() and desc() methods below to define sort direction. Triggers sort event unless true is passed as last parameter. This method automatically recognizes string, numeric or date values.

    Example

    Facetr(collection).on('sort', function(attr, dir) {
        console.log('Sorting by ' + attr + ' ' + dir);
    });
     
    Facetr(collection).sortBy('Age');
     
    // console output:
    // Sorting by Age asc
    asc([silent:boolean]) : FacetCollection

    Sorts the collection in ascendent order by the attribute selected using sortBy method. If sortBy was not invoked before, this method has no effect. Triggers sort event unless true is passed as parameter.

    Example

    Facetr(collection).sortBy('Age').asc();
    desc([silent:boolean]) : FacetCollection

    Sorts the collection in descendent order by the attribute selected using sortBy method. If sortBy was not invoked before, this method has no effect. Triggers sort event unless true is passed as parameter.

    Example

    Facetr(collection).sortBy('Age').desc();
    addFilter(filterName:string, filter:function, [silent:boolean]) : FacetCollection

    Adds a filter which is used to filter the collection by testing each model against it. Triggers Backbone.Collection reset unless true is passed as last parameter. Multiple filters can be added as long as they have different names. Adding two filters with the same name will result in the first being overwritten by the second.

    Example

    Facetr(collection).addFilter('AgeFilter', function(model) {
        return model.get('Age') >= 20 && model.get('Age') < 60; 
    });
    removeFilter(filterName:string, [silent:boolean]) : FacetCollection

    Removes the filter with the given name from the collection and unfilters it accordingly. Triggers reset unless true is passed as last parameter.

    Example

    Facetr(collection).removeFilter('AgeFilter');
    clearFilters([silent:boolean]) : FacetCollection

    Removes all the filters previously added to the collection and unfilters it accordingly. Triggers reset unless true is passed as parameter.

    Example

    Facetr(collection).clearFilters();
    clearValues([silent:boolean]) : FacetCollection

    Removes all the currently selected values from all the facets, bringing the collection to its initial state. Triggers a clearValues event unless true is passed as parameter.

    Example

    Facetr(collection).clearValues();
    facetsOrder(facetNames:Array, [silent:boolean]) : FacetCollection

    Sometimes it is convinient to give the facets list a predefined order. This method can be used to achieve this by passing an array of facet names which corresponds to the order to be given to the facets in the list. Triggers a 'facetsOrder' event with the facetNames array passed to the event handler, unless true is given as last parameter.

    Example

    Facetr(collection).facet('Age');
    Facetr(collection).facet('Name.FirstName');
     
    // Facetr(collection).toJSON() has facet 'Age' at index 0 and 'Name.FirstName' at index 1
     
    Facetr(collection).facetsOrder(['Name.FirstName', 'Age']);
     
    // Facetr(collection).toJSON() has facet 'Name.FirstName' at index 0 and 'Age' at index 1
    collection() : Backbone.Collection

    Returns the reference to the Backbone.Collection. Useful for cases where the reference is needed but it was declared in another scope and is no more accessible.

    Example

    Facetr(collection).collection() === collection; // true
    origLength() : Number

    Returns the length of the collection before any faceted filtering was applied.

    Example

    var collection = new Backbone.Collection([
        {
            Name : 'John'
            Age  : 19
        },
        {
            Name : 'Sarah',
            Age  : 35
        }
    ]);
     
    collection.length() // 2
     
    Facetr(collection).facet('Age').value(35);
     
    collection.length(); // 1
    Facetr(collection).origLength(); // 2
    facets() : Array

    Returns an array containing all the Facet instances created on this FacetCollection.

    settingsJSON() : object

    Returns an object representation of the current state of the Facetr collection which can be used to reload the same state in future using the initFromSettingsJSON method.

    Example

    Facetr(collection).facet('Name.FirstName').label('First Name');
    Facetr(collection).sortBy('Name.FirstName').asc();
    Facetr(collection).facet('Name.FirstName').value('Bob');
     
    var json = Facetr(collection).settingsJSON();
     
    // value of json will be the following:
    //  
    // {
    //      sort : {
    //          by  :   "Name.FirstName",
    //          dir :   "asc"
    //      },
    //      facets : [
    //          {
    //              attr    :   "Name.FirstName",
    //              eop     :   "and",
    //              iop     :   "or",
    //              vals    :   [ "Bob" ]
    //          }
    //      ]
    //  }
    initFromSettingsJSON(json:object) : FacetCollection

    Initializes the Facetr collection using a settings object generated using the settingsJSON method. Triggers an "initFromSettingsJSON" event.

    Facet

    value(value:string, [internalOperator:string], [silent:boolean]) : FacetExp

    Adds a value to the facet. This will result in the collection being filtered by { FacetName : 'Value' }. Valid internal operator values are: 'or' and 'and' (default is 'or'). Triggers a 'filter' event on the FacetCollection passing facetName and facetValue to the handler and a 'value' event on the Facet passing the facetValue to the handler, unless true is passed as last parameter.

    Example

    Facetr(collection).on('filter', function(facetName, facetValue) {
        console.log('filtered by '+ facetName + ' with value equal ' + facetValue);
    });
     
    var facet = Facetr(collection).facet('Name.FirstName');
     
    facet.on('value', function(facetValue){
        console.log('the following value was added to the facet: ' + facetValue);
    });
     
    facet.value('Bob');
     
    // console output: "filtered by Name.FirstName with value Bob"
    // collection contains only models with FirstName = 'Bob'
    removeValue(value:string, [silent:boolean]) : FacetExp

    Removes the given value from the facet and resets the collection to the state previous of the filtering caused by the removed value. Triggers a 'unfilter' event on the FacetCollection passing facetName and facetValue to the handler and a 'removeValue' event on the Facet passing the facetValue to the handler, unless true is passed as last parameter.

    Example

    Facetr(collection).on('unfilter', function(facetName, facetValue) {
        console.log('unfiltered by '+ facetName + ' with value equal ' + facetValue);
    });
     
    var facet = Facetr(collection).facet('Name.FirstName');
     
    facet.on('removeValue', function(value){
        console.log('the following value was removed from the facet: ' + value);
    });
     
    facet.removeValue('Bob');
     
    // console output: "unfiltered by Name.FirstName with value Bob"
    // collection contains again also models with FirstName = 'Bob'
    toJSON() : object

    Returns an object representation of the current facet data and values. Useful for rendering the facet to the page.

    Example

    // create a collection with two models
    var collection = new Backbone.Collection([
        {
            'Name'      : {
                'FirstName' : 'Bob',
                'LastName' : 'Smith'
            },
            'Age'       : 20
        },
        {
            'Name'      : {
                'FirstName' : 'Otto',
                'LastName'  : 'Von Braun'
            },
            'Age'       : 35
        }
    ]);
     
    Facetr(collection).facet('Name.FirstName').label('First Name');
    Facetr(collection).facet('Name.FirstName').value('Bob');
     
    var json = Facetr(collection).facet('Name.FirstName').toJSON();
     
    // json is equal to:
    //
    //  {
    //      data : {
    //          extOperator : 'and',
    //          intOperator : 'or',
    //          label       : 'First Name',
    //          name        : 'Name.FirstName',
    //          selected    : true,
    //          sort        : {
    //              by        : 'value',
    //              direction : 'asc'
    //          }
    //          customData : {}
    //      },
    //      values : [
    //          {
    //              active      : true,
    //              activeCount : 1,
    //              count       : 1,
    //              value       : 'Bob'
    //          },
    //          {
    //              active      : false,
    //              activeCount : 0,
    //              count       : 1,
    //              value       : 'Otto'
    //          }
    //      ]
    //  }
    label(label:string) : Facet

    Use this method to set a human readable label for the facet. This can be used when rendering the facet on the page.

    Example

    Facetr(collection).facet('Name.FirstName').label('First Name');
     
    Facetr(collection).facet('Name.FirstName').toJSON();
     
    // the property data.label has value 'First Name'
    // while the property data.name stays 'Name.FirstName'
    sortByCount() : Facet

    Sorts the facet values by their count. The count is the number of models in the original collection with an attribute having as name the facet name and value the given value.

    Example

    // we use the colleciton defined in Basic Usage section
    var facet = Facetr(collection).facet('Hobbies');
     
    facet.value('painting'); // painting count = 3  
    facet.value('drawing');  // drawing count = 1
     
    // facet.toJSON().data.values[0] = 'drawing'
    // facet.toJSON().data.values[1] = 'painting'
     
    facet.sortByCount();
     
    // facet.toJSON().data.values[0] = 'painting'
    // facet.toJSON().data.values[1] = 'drawing'
    sortByActiveCount() : Facet

    Sorts the facet values by their active count. The active count is the number of models in the current filtered collection with an attribute having as name the facet name and value the given value.

    Example

    var facet = Facetr(collection).facet('Hobbies');
     
    facet.value('fishing');
    facet.value('shopping');
     
    // fishing active count = 1
    // shopping active count = 2
     
    // facet.toJSON().data.values[0] = 'fishing'
    // facet.toJSON().data.values[1] = 'shopping'
     
    facet.sortByActiveCount();
     
    // facet.toJSON().data.values[0] = 'shopping'
    // facet.toJSON().data.values[1] = 'fishing'
    sortByValue() : Facet

    Sorts the facet values by their value. This is the default sort.

    asc() : Facet

    Sets the direction of the values sort to ascendent.

    Example

    Facetr(collection).facet('Name.FirstName').asc();
    desc() : Facet

    Sets the direction of the values sort to descendant.

    Example

    Facetr(collection).facet('Name.FirstName').sortByCount().desc();
    remove([silent:boolean]) : undefined

    Removes the facet and all its values and unfilters the collection accordingly. It triggers a "removeFacet" event on the facet collection, unless true is passed as parameter.

    var facetCollection = Facetr(collection);
    var facet = facetCollection.facet('Age');
     
    facetCollection.on('removeFacet', function(facetName){
        console.log('removed facet', facetName);
    });
     
    facet.remove();
     
    // console output would be
    // removed facet Age
    clear([silent:boolean]) : Facet

    Unselects all the values from the facet. It triggers a 'clear' event unless true is passed as parameter.

    customData(key:string, [value:object]) : Facet

    This method can be used to add arbitrary data to pass to the templates. Data added using this method is included in the object returned by the toJSON() method in the data.customData property. To retrieve previously set data, just pass the key parameter without any value.

    Example

    var facet = Facetr('myCollection').facet('Hobbies').customData('sublabel', 'Available hobbies');
     
    // facet.customData('sublabel') returns 'Available hobbies'
    // facet.toJSON().data.customData = { sublabel : 'Available hobbies' }
    isSelected : Boolean

    Returns true if any value is selected from this facet, false otherwise.

    Example

    var facet = Facetr('myCollection').facet('Hobbies');
     
    facet.value('fishing');
     
    // facet.isSelected() returns true
     
    facet.clear(); // remove all selected values
     
    // facet.isSelected() returns false
    hierarchy(hierarchySettings:Array) : Facet

    This method creates a hierarchical representation of facet values, based on the settings object given as parameter. Once this method is used, the facet becomes a "hierarchical" facet. You can then use the facet as you usually would, with the following differences:

    • the data section of the object resulting from invoking the toJSON method will also contain a "hierarchical" property with value true and a "groupedValues" array, with the following format:

    groupedValues

    [
        {
            value: "manager",
            label: "Manager",
            active: false,
            activeCount: 7,
            count: 7,
            groups: [
                {
                    value: "team manager",
                    label: "Team Manager",
                    active: false,
                    activeCount: 5,
                    count: 5,
                    groups: [
                        { ... other groups values ... }
                    ]
                },
                 {
                    value: "manager",
                    label: "Manager",
                    active: false,
                    activeCount: 5,
                    count: 5 // no groups property means that this value has no children groups
                },
            ]
        }
    ]
    • when a value from the facet is selected, also the models resulting from selecting its descendents values are included in the result set

    • the count includes both the count of the value itself and that of its descendants values

    The hierarchySettings argument is an array with different "hierarchical value" objects, where it is possible to specify the hierarchy of values along with a label. See the Example below to understand the hierarchySettings format.

    Example

        var hierarchySettings = [
            {               
                value: "manager",
                label: "Manager",
                groups: [
                    {
                        value: "project manager",
                        label: "Project Manager",
                        groups: [
                            {
                                value: "team manager",
                                label: "Team Manager"
                            }
                        ]
                    }
                ]
            }
        ];
     
        var profession = Facetr(collection).facet('Profession').hierarchy(hierarchySettings);
     
        var json = profession.toJSON();
     
        // value of json variable would be:
        //
        // {
        //  "data": {
        //      "name":"Profession",
        //      "hierarchical":true,
        //      "label":"Profession",
        //      "extOperator":"and",
        //      "intOperator":"or",
        //      "sort":{
        //          "by":"activeCount",
        //          "direction":"desc"
        //      },
        //      "selected":false,
        //      "customData":{}
        //  },
        //  "values": [ ... stays as the normal facets ... ],
        //  "groupedValues":[
        //      {
        //          "value":"manager",
        //          "label":"Manager",
        //          "active":false,
        //          "activeCount":3,
        //          "count":3,
        //          "groups":[
        //              {
        //                  "value":"project manager",
        //                  "label":"Project Manager",
        //                  "active":false,
        //                  "activeCount":2,
        //                  "count":2,
        //                  "groups":[
        //                      {
        //                          "value":"team manager",
        //                          "label":"Team Manager",
        //                          "active":false,
        //                          "activeCount":1,
        //                          "count":1
        //                      }
        //                  ]
        //              }
        //          ]
        //      }
        //  ]
        // }

    FacetExp

    FacetExp objects are returned from Facet value and removeValue methods. They can be used to coincisely define multiple values on a facet, using different operators.

    Example

    Facetr(collection).facet('Age').value(12, 'and');
    Facetr(collection).facet('Age').value(15, 'or');
    Facetr(collection).facet('Age').value(39, 'and');
     
    // can also be expressed with the following syntax
     
    Facetr(collection).facet('Age').value(12, 'and').or(15).and(39);
    and(value:string, [silent:boolean]) : Facet

    Equivalent to facet.value('Value', 'and'), but can be used for FacetExp chains.

    or(value:string, [silent:boolean]) : Facet

    Equivalent to facet.value('Value', 'or'), but can be used for FacetExp chains.

    EXAMPLES

    This section contains a list of websites / projects using Facetr.

    LICENSE

    Backbone.Facetr may be freely distributed under the MIT license.

    Copyright (C) 2012 Arillo GmbH http://arillo.net

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Install

    npm i backbone.facetr

    DownloadsWeekly Downloads

    4

    Version

    0.4.3

    License

    MIT

    Last publish

    Collaborators

    • francesko
    • banglashi