text: JS.LinkedList=new JS.Class('LinkedList',{include:JS.Enumerable||{},initialize:function(a,b){this.length=0;this.first=this.last=null;if(!a)return;for(var c=0,d=a.length;c<d;c++)this.push(b?new this.klass.Node(a[c]):a[c])},forEach:function(a,b){if(!a)return this.enumFor('forEach');a=JS.Enumerable.toFn(a);var c=this.first,d,e,f;for(e=0,f=this.length;e<f;e++){d=c.next;a.call(b||null,c,e);if(c===this.last)break;c=d}return this},at:function(a){if(a<0||a>=this.length)return undefined;var b=this.first;while(a--)b=b.next;return b},pop:function(){return this.length?this.remove(this.last):undefined},shift:function(){return this.length?this.remove(this.first):undefined},insertAfter:function(){},push:function(){},remove:function(){},extend:{Node:new JS.Class({initialize:function(a){this.data=a;this.prev=this.next=this.list=null}})}});JS.LinkedList.Doubly=new JS.Class('LinkedList.Doubly',JS.LinkedList,{insertAt:function(a,b){if(a<0||a>=this.length)return;this.insertBefore(this.at(a),b)},unshift:function(a){this.length>0?this.insertBefore(this.first,a):this.push(a)},insertBefore:function(){}});JS.LinkedList.insertTemplate=function(c,d,e){return function(a,b){if(a.list!==this)return;b[c]=a;b[d]=a[d];a[d]=(a[d][c]=b);if(b[c]===this[e])this[e]=b;b.list=this;this.length++}};JS.LinkedList.Doubly.Circular=new JS.Class('LinkedList.Doubly.Circular',JS.LinkedList.Doubly,{insertAfter:JS.LinkedList.insertTemplate('prev','next','last'),insertBefore:JS.LinkedList.insertTemplate('next','prev','first'),push:function(a){if(this.length)return this.insertAfter(this.last,a);this.first=this.last=a.prev=a.next=a;a.list=this;this.length=1},remove:function(a){if(a.list!==this||this.length===0)return null;if(this.length>1){a.prev.next=a.next;a.next.prev=a.prev;if(a===this.first)this.first=a.next;if(a===this.last)this.last=a.prev}else{this.first=this.last=null}a.prev=a.next=a.list=null;this.length--;return a}});