From f0027e7bb12bce9d591d691371d9c56b0cf89679 Mon Sep 17 00:00:00 2001 From: Jason Davies Date: Sat, 2 Mar 2013 01:00:14 +0000 Subject: [PATCH] Support filtering by arbitrary functions. --- crossfilter.js | 66 ++++++++++++++++++++++++++++++++++------ crossfilter.min.js | 2 +- src/crossfilter.js | 66 ++++++++++++++++++++++++++++++++++------ test/crossfilter-test.js | 27 ++++++++++++++-- 4 files changed, 138 insertions(+), 23 deletions(-) diff --git a/crossfilter.js b/crossfilter.js index d79caee8..a0655be4 100644 --- a/crossfilter.js +++ b/crossfilter.js @@ -569,6 +569,7 @@ function crossfilter() { filter: filter, filterExact: filterExact, filterRange: filterRange, + filterFunction: filterFunction, filterAll: filterAll, top: top, bottom: bottom, @@ -585,6 +586,7 @@ function crossfilter() { newIndex, // temporary array storing newly-added index sort = quicksort_by(function(i) { return newValues[i]; }), refilter = crossfilter_filterAll, // for recomputing filter + refilterFunction, // the custom filter function in use indexListeners = [], // when data is added dimensionGroups = [], lo0 = 0, @@ -615,9 +617,15 @@ function crossfilter() { newValues = permute(newValues, newIndex); // Bisect newValues to determine which new records are selected. - var bounds = refilter(newValues), lo1 = bounds[0], hi1 = bounds[1], i; - for (i = 0; i < lo1; ++i) filters[newIndex[i] + n0] |= one; - for (i = hi1; i < n1; ++i) filters[newIndex[i] + n0] |= one; + var bounds = refilter(newValues), lo1 = bounds[0], hi1 = bounds[1], i, k; + if (refilterFunction) { + for (i = 0; i < n1; ++i) { + if (!refilterFunction(newValues[i], k = newIndex[i] + n0)) filters[k] |= one; + } + } else { + for (i = 0; i < lo1; ++i) filters[newIndex[i] + n0] |= one; + for (i = hi1; i < n1; ++i) filters[newIndex[i] + n0] |= one; + } // If this dimension previously had no data, then we don't need to do the // more expensive merge operation; use the new values and index as-is. @@ -673,12 +681,21 @@ function crossfilter() { // Updates the selected values based on the specified bounds [lo, hi]. // This implementation is used by all the public filter methods. - function filterIndex(bounds) { + function filterIndexBounds(bounds) { + var lo1 = bounds[0], + hi1 = bounds[1]; + + if (refilterFunction) { + refilterFunction = null; + filterIndexFunction(function(d, i) { return lo1 <= i && i < hi1; }); + lo0 = lo1; + hi0 = hi1; + return dimension; + } + var i, j, k, - lo1 = bounds[0], - hi1 = bounds[1], added = [], removed = []; @@ -721,24 +738,53 @@ function crossfilter() { function filter(range) { return range == null ? filterAll() : Array.isArray(range) - ? filterRange(range) + ? filterRange(range) : typeof range === "function" + ? filterFunction(range) : filterExact(range); } // Filters this dimension to select the exact value. function filterExact(value) { - return filterIndex((refilter = crossfilter_filterExact(bisect, value))(values)); + return filterIndexBounds((refilter = crossfilter_filterExact(bisect, value))(values)); } // Filters this dimension to select the specified range [lo, hi]. // The lower bound is inclusive, and the upper bound is exclusive. function filterRange(range) { - return filterIndex((refilter = crossfilter_filterRange(bisect, range))(values)); + return filterIndexBounds((refilter = crossfilter_filterRange(bisect, range))(values)); } // Clears any filters on this dimension. function filterAll() { - return filterIndex((refilter = crossfilter_filterAll)(values)); + return filterIndexBounds((refilter = crossfilter_filterAll)(values)); + } + + // Filters this dimension using an arbitrary function. + function filterFunction(f) { + refilter = crossfilter_filterAll; + + filterIndexFunction(refilterFunction = f); + + lo0 = 0; + hi0 = n; + + return dimension; + } + + function filterIndexFunction(f) { + var i, + k, + x, + added = [], + removed = []; + + for (i = 0; i < n; ++i) { + if (!(filters[k = index[i]] & one) ^ (x = f(values[i], k))) { + if (x) filters[k] &= zero, added.push(k); + else filters[k] |= one, removed.push(k); + } + } + filterListeners.forEach(function(l) { l(one, added, removed); }); } // Returns the top K selected records based on this dimension's order. diff --git a/crossfilter.min.js b/crossfilter.min.js index b36e5b52..75e94190 100644 --- a/crossfilter.min.js +++ b/crossfilter.min.js @@ -1 +1 @@ -(function(r){function n(r){return r}function t(r,n){for(var t=0,e=n.length,u=Array(e);e>t;++t)u[t]=r[n[t]];return u}function e(r){function n(n,t,e,u){for(;u>e;){var f=e+u>>>1,o=r(n[f]);o>=t||!(o>=o)?u=f:e=f+1}return e}function t(n,t,e,u){for(;u>e;){var f=e+u>>>1,o=r(n[f]);o>t||!(o>=o)?u=f:e=f+1}return e}return t.right=t,t.left=n,t}function u(r){function n(r,n,t){for(var u=t-n,f=(u>>>1)+1;--f>0;)e(r,f,u,n);return r}function t(r,n,t){for(var u,f=t-n;--f>0;)u=r[n],r[n]=r[n+f],r[n+f]=u,e(r,1,f,n);return r}function e(n,t,e,u){for(var f,o=n[--u+t],i=r(o);(f=t<<1)<=e&&(e>f&&r(n[u+f])>r(n[u+f+1])&&f++,!(i<=r(n[u+f])));)n[u+t]=n[u+f],t=f;n[u+t]=o}return n.sort=t,n}function f(r){function n(n,e,u,f){var o,i,a,c,l=Array(f=Math.min(u-e,f));for(i=0;f>i;++i)l[i]=n[e++];if(t(l,0,f),u>e){o=r(l[0]);do(a=r(c=n[e])>o)&&(l[0]=c,o=r(t(l,0,f)[0]));while(++eu;++u){for(var f,o=u,i=n[u],a=r(i);o>t&&((f=r(n[o-1]))>a||!(f>=f));--o)n[o]=n[o-1];n[o]=i}return n}return n}function i(r){function n(r,n,u){return(U>u-n?e:t)(r,n,u)}function t(t,e,u){for(var f,o;u>e&&!((f=r(t[u-1]))<=f);)u--;for(var i=u;--i>=e;)f=r(o=t[i]),f>=f||(t[i]=t[--u],t[u]=o);var a,c=0|(u-e)/6,l=e+c,v=u-1-c,s=e+u-1>>1,h=s-c,d=s+c,p=t[l],g=r(p),y=t[h],m=r(y),b=t[s],A=r(b),k=t[d],x=r(k),w=t[v],O=r(w);g>m&&(a=p,p=y,y=a,a=g,g=m,m=a),x>O&&(a=k,k=w,w=a,a=x,x=O,O=a),g>A&&(a=p,p=b,b=a,a=g,g=A,A=a),m>A&&(a=y,y=b,b=a,a=m,m=A,A=a),g>x&&(a=p,p=k,k=a,a=g,g=x,x=a),A>x&&(a=b,b=k,k=a,a=A,A=x,x=a),m>O&&(a=y,y=w,w=a,a=m,m=O,O=a),m>A&&(a=y,y=b,b=a,a=m,m=A,A=a),x>O&&(a=k,k=w,w=a,a=x,x=O,O=a);var E=y,M=m,U=k,z=x;t[l]=p,t[h]=t[e],t[s]=b,t[d]=t[u-1],t[v]=w;var N=e+1,C=u-2,S=z>=M&&M>=z;if(S)for(var q=N;C>=q;++q){var R=t[q],j=r(R);if(M>j)q!==N&&(t[q]=t[N],t[N]=R),++N;else if(j>M)for(;;){var B=r(t[C]);{if(!(B>M)){if(M>B){t[q]=t[N],t[N++]=t[C],t[C--]=R;break}t[q]=t[C],t[C--]=R;break}C--}}}else for(var q=N;C>=q;q++){var R=t[q],j=r(R);if(M>j)q!==N&&(t[q]=t[N],t[N]=R),++N;else if(j>z)for(;;){var B=r(t[C]);{if(!(B>z)){M>B?(t[q]=t[N],t[N++]=t[C],t[C--]=R):(t[q]=t[C],t[C--]=R);break}if(C--,q>C)break}}}if(t[e]=t[N-1],t[N-1]=E,t[u-1]=t[C+1],t[C+1]=U,n(t,e,N-1),n(t,C+2,u),S)return t;if(l>N&&C>v){for(var D,B;(D=r(t[N]))<=M&&D>=M;)++N;for(;(B=r(t[C]))<=z&&B>=z;)--C;for(var q=N;C>=q;q++){var R=t[q],j=r(R);if(M>=j&&j>=M)q!==N&&(t[q]=t[N],t[N]=R),N++;else if(z>=j&&j>=z)for(;;){var B=r(t[C]);{if(!(z>=B&&B>=z)){M>B?(t[q]=t[N],t[N++]=t[C],t[C--]=R):(t[q]=t[C],t[C--]=R);break}if(C--,q>C)break}}}}return n(t,N,C+1)}var e=o(r);return n}function a(r){return Array(r)}function c(r,n){return function(t){var e=t.length;return[r.left(t,n,0,e),r.right(t,n,0,e)]}}function l(r,n){var t=n[0],e=n[1];return function(n){var u=n.length;return[r.left(n,t,0,u),r.left(n,e,0,u)]}}function v(r){return[0,r.length]}function s(){return null}function h(){return 0}function d(r){return r+1}function p(r){return r-1}function g(r){return function(n,t){return n+ +r(t)}}function y(r){return function(n,t){return n-r(t)}}function m(){function r(r){var n=O,t=r.length;return t&&(w=w.concat(r),U=S(U,O+=t),C.forEach(function(e){e(r,n,t)})),m}function e(r){function e(n,e,u){K=n.map(r),L=V(A(u),0,u),K=t(K,L);var f,o=W(K),i=o[0],a=o[1];for(f=0;i>f;++f)U[L[f]+e]|=Q;for(f=a;u>f;++f)U[L[f]+e]|=Q;if(!e)return I=K,J=L,Z=i,$=a,void 0;var c=I,l=J,v=0,s=0;for(I=Array(O),J=b(O,O),f=0;e>v&&u>s;++f)c[v]v;++v,++f)I[f]=c[v],J[f]=l[v];for(;u>s;++s,++f)I[f]=K[s],J[f]=L[s]+e;o=W(I),Z=o[0],$=o[1]}function o(r,n,t){X.forEach(function(r){r(K,L,n,t)}),K=L=null}function a(r){var n,t,e,u=r[0],f=r[1],o=[],i=[];if(Z>u)for(n=u,t=Math.min(Z,f);t>n;++n)U[e=J[n]]^=Q,o.push(e);else if(u>Z)for(n=Z,t=Math.min(u,$);t>n;++n)U[e=J[n]]^=Q,i.push(e);if(f>$)for(n=Math.max(u,$),t=f;t>n;++n)U[e=J[n]]^=Q,o.push(e);else if($>f)for(n=Math.max(Z,f),t=$;t>n;++n)U[e=J[n]]^=Q,i.push(e);return Z=u,$=f,N.forEach(function(r){r(Q,o,i)}),P}function m(r){return null==r?j():Array.isArray(r)?R(r):z(r)}function z(r){return a((W=c(x,r))(I))}function R(r){return a((W=l(x,r))(I))}function j(){return a((W=v)(I))}function B(r){for(var n,t=[],e=$;--e>=Z&&r>0;)U[n=J[e]]||(t.push(w[n]),--r);return t}function D(r){for(var n,t=[],e=Z;$>e&&r>0;)U[n=J[e]]||(t.push(w[n]),--r),e++;return t}function F(r){function t(n,t,u,f){function c(){++P===L&&(m=q(m,K<<=1),j=q(j,K),L=k(K))}var l,v,h,d,p,g,y=R,m=b(P,L),A=F,x=H,E=P,M=0,z=0;for(Z&&(A=x=s),R=Array(P),P=0,j=E>1?S(j,O):b(O,L),E&&(h=(v=y[0]).key),d=r(n[z]);f>z;){for(v&&d>=h?(p=v,g=h,m[M]=P,(v=y[++M])&&(h=v.key)):(p={key:d,value:x()},g=d),R[P]=p;!(!(g>=d)&&(d>=d||g>=g)||(j[l=t[z]+u]=P,U[l]&T||(p.value=A(p.value,w[l])),++z>=f));)d=r(n[z]);c()}for(;E>M;)R[m[M]=P]=y[M++],c();if(P>M)for(M=0;u>M;++M)j[M]=m[j[M]];l=N.indexOf(V),P>1?(V=e,W=i):(1===P?(V=o,W=a):(V=s,W=s),j=null),N[l]=V}function e(r,n,t){if(r!==Q&&!Z){var e,u,f,o;for(e=0,f=n.length;f>e;++e)U[u=n[e]]&T||(o=R[j[u]],o.value=F(o.value,w[u]));for(e=0,f=t.length;f>e;++e)(U[u=t[e]]&T)===r&&(o=R[j[u]],o.value=G(o.value,w[u]))}}function o(r,n,t){if(r!==Q&&!Z){var e,u,f,o=R[0];for(e=0,f=n.length;f>e;++e)U[u=n[e]]&T||(o.value=F(o.value,w[u]));for(e=0,f=t.length;f>e;++e)(U[u=t[e]]&T)===r&&(o.value=G(o.value,w[u]))}}function i(){var r,n;for(r=0;P>r;++r)R[r].value=H();for(r=0;O>r;++r)U[r]&T||(n=R[j[r]],n.value=F(n.value,w[r]))}function a(){var r,n=R[0];for(n.value=H(),r=0;O>r;++r)U[r]&T||(n.value=F(n.value,w[r]))}function c(){return Z&&(W(),Z=!1),R}function l(r){var n=B(c(),0,R.length,r);return D.sort(n,0,n.length)}function v(r,n,t){return F=r,G=n,H=t,Z=!0,C}function m(){return v(d,p,h)}function A(r){return v(g(r),y(r),h)}function x(r){function n(n){return r(n.value)}return B=f(n),D=u(n),C}function E(){return x(n)}function M(){return P}function z(){var r=N.indexOf(V);return r>=0&&N.splice(r,1),r=X.indexOf(t),r>=0&&X.splice(r,1),C}var C={top:l,all:c,reduce:v,reduceCount:m,reduceSum:A,order:x,orderNatural:E,size:M,remove:z};Y.push(C);var R,j,B,D,F,G,H,K=8,L=k(K),P=0,V=s,W=s,Z=!0;return arguments.length<1&&(r=n),N.push(V),X.push(t),t(I,J,0,O),m().orderNatural()}function G(){var r=F(s),n=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return n()[0].value},r}function H(){Y.forEach(function(r){r.remove()});var r=C.indexOf(e);for(r>=0&&C.splice(r,1),r=C.indexOf(o),r>=0&&C.splice(r,1),r=0;O>r;++r)U[r]&=T;return E&=T,P}var I,J,K,L,P={filter:m,filterExact:z,filterRange:R,filterAll:j,top:B,bottom:D,group:F,groupAll:G,remove:H},Q=~E&-~E,T=~Q,V=i(function(r){return K[r]}),W=v,X=[],Y=[],Z=0,$=0;return C.unshift(e),C.push(o),E|=Q,(M>=32?!Q:E&(1<t;++t)U[t]||(a=c(a,w[t]))}function n(r,n,t){var e,u,f;if(!m){for(e=0,f=n.length;f>e;++e)U[u=n[e]]||(a=c(a,w[u]));for(e=0,f=t.length;f>e;++e)U[u=t[e]]===r&&(a=l(a,w[u]))}}function t(){var r;for(a=v(),r=0;O>r;++r)U[r]||(a=c(a,w[r]))}function e(r,n,t){return c=r,l=n,v=t,m=!0,s}function u(){return e(d,p,h)}function f(r){return e(g(r),y(r),h)}function o(){return m&&(t(),m=!1),a}function i(){var t=N.indexOf(n);return t>=0&&N.splice(t),t=C.indexOf(r),t>=0&&C.splice(t),s}var a,c,l,v,s={reduce:e,reduceCount:u,reduceSum:f,value:o,remove:i},m=!0;return N.push(n),C.push(r),r(w,0,O),u()}function a(){return O}var m={add:r,dimension:e,groupAll:o,size:a},w=[],O=0,E=0,M=8,U=z(0),N=[],C=[];return arguments.length?r(arguments[0]):m}function b(r,n){return(257>n?z:65537>n?N:C)(r)}function A(r){for(var n=b(r,r),t=-1;++tt;++t)u[t]=r[n[t]];return u}function e(r){function n(n,t,e,u){for(;u>e;){var f=e+u>>>1,o=r(n[f]);o>=t||!(o>=o)?u=f:e=f+1}return e}function t(n,t,e,u){for(;u>e;){var f=e+u>>>1,o=r(n[f]);o>t||!(o>=o)?u=f:e=f+1}return e}return t.right=t,t.left=n,t}function u(r){function n(r,n,t){for(var u=t-n,f=(u>>>1)+1;--f>0;)e(r,f,u,n);return r}function t(r,n,t){for(var u,f=t-n;--f>0;)u=r[n],r[n]=r[n+f],r[n+f]=u,e(r,1,f,n);return r}function e(n,t,e,u){for(var f,o=n[--u+t],i=r(o);(f=t<<1)<=e&&(e>f&&r(n[u+f])>r(n[u+f+1])&&f++,!(i<=r(n[u+f])));)n[u+t]=n[u+f],t=f;n[u+t]=o}return n.sort=t,n}function f(r){function n(n,e,u,f){var o,i,a,c,l=Array(f=Math.min(u-e,f));for(i=0;f>i;++i)l[i]=n[e++];if(t(l,0,f),u>e){o=r(l[0]);do(a=r(c=n[e])>o)&&(l[0]=c,o=r(t(l,0,f)[0]));while(++eu;++u){for(var f,o=u,i=n[u],a=r(i);o>t&&((f=r(n[o-1]))>a||!(f>=f));--o)n[o]=n[o-1];n[o]=i}return n}return n}function i(r){function n(r,n,u){return(U>u-n?e:t)(r,n,u)}function t(t,e,u){for(var f,o;u>e&&!((f=r(t[u-1]))<=f);)u--;for(var i=u;--i>=e;)f=r(o=t[i]),f>=f||(t[i]=t[--u],t[u]=o);var a,c=0|(u-e)/6,l=e+c,v=u-1-c,s=e+u-1>>1,h=s-c,d=s+c,p=t[l],g=r(p),y=t[h],m=r(y),b=t[s],A=r(b),k=t[d],x=r(k),w=t[v],E=r(w);g>m&&(a=p,p=y,y=a,a=g,g=m,m=a),x>E&&(a=k,k=w,w=a,a=x,x=E,E=a),g>A&&(a=p,p=b,b=a,a=g,g=A,A=a),m>A&&(a=y,y=b,b=a,a=m,m=A,A=a),g>x&&(a=p,p=k,k=a,a=g,g=x,x=a),A>x&&(a=b,b=k,k=a,a=A,A=x,x=a),m>E&&(a=y,y=w,w=a,a=m,m=E,E=a),m>A&&(a=y,y=b,b=a,a=m,m=A,A=a),x>E&&(a=k,k=w,w=a,a=x,x=E,E=a);var O=y,M=m,U=k,z=x;t[l]=p,t[h]=t[e],t[s]=b,t[d]=t[u-1],t[v]=w;var N=e+1,C=u-2,S=z>=M&&M>=z;if(S)for(var q=N;C>=q;++q){var F=t[q],R=r(F);if(M>R)q!==N&&(t[q]=t[N],t[N]=F),++N;else if(R>M)for(;;){var j=r(t[C]);{if(!(j>M)){if(M>j){t[q]=t[N],t[N++]=t[C],t[C--]=F;break}t[q]=t[C],t[C--]=F;break}C--}}}else for(var q=N;C>=q;q++){var F=t[q],R=r(F);if(M>R)q!==N&&(t[q]=t[N],t[N]=F),++N;else if(R>z)for(;;){var j=r(t[C]);{if(!(j>z)){M>j?(t[q]=t[N],t[N++]=t[C],t[C--]=F):(t[q]=t[C],t[C--]=F);break}if(C--,q>C)break}}}if(t[e]=t[N-1],t[N-1]=O,t[u-1]=t[C+1],t[C+1]=U,n(t,e,N-1),n(t,C+2,u),S)return t;if(l>N&&C>v){for(var B,j;(B=r(t[N]))<=M&&B>=M;)++N;for(;(j=r(t[C]))<=z&&j>=z;)--C;for(var q=N;C>=q;q++){var F=t[q],R=r(F);if(M>=R&&R>=M)q!==N&&(t[q]=t[N],t[N]=F),N++;else if(z>=R&&R>=z)for(;;){var j=r(t[C]);{if(!(z>=j&&j>=z)){M>j?(t[q]=t[N],t[N++]=t[C],t[C--]=F):(t[q]=t[C],t[C--]=F);break}if(C--,q>C)break}}}}return n(t,N,C+1)}var e=o(r);return n}function a(r){return Array(r)}function c(r,n){return function(t){var e=t.length;return[r.left(t,n,0,e),r.right(t,n,0,e)]}}function l(r,n){var t=n[0],e=n[1];return function(n){var u=n.length;return[r.left(n,t,0,u),r.left(n,e,0,u)]}}function v(r){return[0,r.length]}function s(){return null}function h(){return 0}function d(r){return r+1}function p(r){return r-1}function g(r){return function(n,t){return n+ +r(t)}}function y(r){return function(n,t){return n-r(t)}}function m(){function r(r){var n=E,t=r.length;return t&&(w=w.concat(r),U=S(U,E+=t),C.forEach(function(e){e(r,n,t)})),m}function e(r){function e(n,e,u){P=n.map(r),Q=Y(A(u),0,u),P=t(P,Q);var f,o,i=Z(P),a=i[0],c=i[1];if(T)for(f=0;u>f;++f)T(P[f],o=Q[f]+e)||(U[o]|=W);else{for(f=0;a>f;++f)U[Q[f]+e]|=W;for(f=c;u>f;++f)U[Q[f]+e]|=W}if(!e)return K=P,L=Q,rn=a,nn=c,void 0;var l=K,v=L,s=0,h=0;for(K=Array(E),L=b(E,E),f=0;e>s&&u>h;++f)l[s]s;++s,++f)K[f]=l[s],L[f]=v[s];for(;u>h;++h,++f)K[f]=P[h],L[f]=Q[h]+e;i=Z(K),rn=i[0],nn=i[1]}function o(r,n,t){$.forEach(function(r){r(P,Q,n,t)}),P=Q=null}function a(r){var n=r[0],t=r[1];if(T)return T=null,B(function(r,e){return e>=n&&t>e}),rn=n,nn=t,V;var e,u,f,o=[],i=[];if(rn>n)for(e=n,u=Math.min(rn,t);u>e;++e)U[f=L[e]]^=W,o.push(f);else if(n>rn)for(e=rn,u=Math.min(n,nn);u>e;++e)U[f=L[e]]^=W,i.push(f);if(t>nn)for(e=Math.max(n,nn),u=t;u>e;++e)U[f=L[e]]^=W,o.push(f);else if(nn>t)for(e=Math.max(rn,t),u=nn;u>e;++e)U[f=L[e]]^=W,i.push(f);return rn=n,nn=t,N.forEach(function(r){r(W,o,i)}),V}function m(r){return null==r?R():Array.isArray(r)?F(r):"function"==typeof r?j(r):z(r)}function z(r){return a((Z=c(x,r))(K))}function F(r){return a((Z=l(x,r))(K))}function R(){return a((Z=v)(K))}function j(r){return Z=v,B(T=r),rn=0,nn=E,V}function B(r){var n,t,e,u=[],f=[];for(n=0;E>n;++n)!(U[t=L[n]]&W)^(e=r(K[n],t))&&(e?(U[t]&=X,u.push(t)):(U[t]|=W,f.push(t)));N.forEach(function(r){r(W,u,f)})}function D(r){for(var n,t=[],e=nn;--e>=rn&&r>0;)U[n=L[e]]||(t.push(w[n]),--r);return t}function G(r){for(var n,t=[],e=rn;nn>e&&r>0;)U[n=L[e]]||(t.push(w[n]),--r),e++;return t}function H(r){function t(n,t,u,f){function c(){++P===J&&(m=q(m,I<<=1),R=q(R,I),J=k(I))}var l,v,h,d,p,g,y=F,m=b(P,J),A=D,x=H,O=P,M=0,z=0;for(V&&(A=x=s),F=Array(P),P=0,R=O>1?S(R,E):b(E,J),O&&(h=(v=y[0]).key),d=r(n[z]);f>z;){for(v&&d>=h?(p=v,g=h,m[M]=P,(v=y[++M])&&(h=v.key)):(p={key:d,value:x()},g=d),F[P]=p;!(!(g>=d)&&(d>=d||g>=g)||(R[l=t[z]+u]=P,U[l]&X||(p.value=A(p.value,w[l])),++z>=f));)d=r(n[z]);c()}for(;O>M;)F[m[M]=P]=y[M++],c();if(P>M)for(M=0;u>M;++M)R[M]=m[R[M]];l=N.indexOf(Q),P>1?(Q=e,T=i):(1===P?(Q=o,T=a):(Q=s,T=s),R=null),N[l]=Q}function e(r,n,t){if(r!==W&&!V){var e,u,f,o;for(e=0,f=n.length;f>e;++e)U[u=n[e]]&X||(o=F[R[u]],o.value=D(o.value,w[u]));for(e=0,f=t.length;f>e;++e)(U[u=t[e]]&X)===r&&(o=F[R[u]],o.value=G(o.value,w[u]))}}function o(r,n,t){if(r!==W&&!V){var e,u,f,o=F[0];for(e=0,f=n.length;f>e;++e)U[u=n[e]]&X||(o.value=D(o.value,w[u]));for(e=0,f=t.length;f>e;++e)(U[u=t[e]]&X)===r&&(o.value=G(o.value,w[u]))}}function i(){var r,n;for(r=0;P>r;++r)F[r].value=H();for(r=0;E>r;++r)U[r]&X||(n=F[R[r]],n.value=D(n.value,w[r]))}function a(){var r,n=F[0];for(n.value=H(),r=0;E>r;++r)U[r]&X||(n.value=D(n.value,w[r]))}function c(){return V&&(T(),V=!1),F}function l(r){var n=j(c(),0,F.length,r);return B.sort(n,0,n.length)}function v(r,n,t){return D=r,G=n,H=t,V=!0,C}function m(){return v(d,p,h)}function A(r){return v(g(r),y(r),h)}function x(r){function n(n){return r(n.value)}return j=f(n),B=u(n),C}function O(){return x(n)}function M(){return P}function z(){var r=N.indexOf(Q);return r>=0&&N.splice(r,1),r=$.indexOf(t),r>=0&&$.splice(r,1),C}var C={top:l,all:c,reduce:v,reduceCount:m,reduceSum:A,order:x,orderNatural:O,size:M,remove:z};_.push(C);var F,R,j,B,D,G,H,I=8,J=k(I),P=0,Q=s,T=s,V=!0;return arguments.length<1&&(r=n),N.push(Q),$.push(t),t(K,L,0,E),m().orderNatural()}function I(){var r=H(s),n=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return n()[0].value},r}function J(){_.forEach(function(r){r.remove()});var r=C.indexOf(e);for(r>=0&&C.splice(r,1),r=C.indexOf(o),r>=0&&C.splice(r,1),r=0;E>r;++r)U[r]&=X;return O&=X,V}var K,L,P,Q,T,V={filter:m,filterExact:z,filterRange:F,filterFunction:j,filterAll:R,top:D,bottom:G,group:H,groupAll:I,remove:J},W=~O&-~O,X=~W,Y=i(function(r){return P[r]}),Z=v,$=[],_=[],rn=0,nn=0;return C.unshift(e),C.push(o),O|=W,(M>=32?!W:O&(1<t;++t)U[t]||(a=c(a,w[t]))}function n(r,n,t){var e,u,f;if(!m){for(e=0,f=n.length;f>e;++e)U[u=n[e]]||(a=c(a,w[u]));for(e=0,f=t.length;f>e;++e)U[u=t[e]]===r&&(a=l(a,w[u]))}}function t(){var r;for(a=v(),r=0;E>r;++r)U[r]||(a=c(a,w[r]))}function e(r,n,t){return c=r,l=n,v=t,m=!0,s}function u(){return e(d,p,h)}function f(r){return e(g(r),y(r),h)}function o(){return m&&(t(),m=!1),a}function i(){var t=N.indexOf(n);return t>=0&&N.splice(t),t=C.indexOf(r),t>=0&&C.splice(t),s}var a,c,l,v,s={reduce:e,reduceCount:u,reduceSum:f,value:o,remove:i},m=!0;return N.push(n),C.push(r),r(w,0,E),u()}function a(){return E}var m={add:r,dimension:e,groupAll:o,size:a},w=[],E=0,O=0,M=8,U=z(0),N=[],C=[];return arguments.length?r(arguments[0]):m}function b(r,n){return(257>n?z:65537>n?N:C)(r)}function A(r){for(var n=b(r,r),t=-1;++t