PageSourceSearch

https://sciencevsmagic.net/castles/js/regular/chain.js

js sciencevsmagic.net collected 2026-09-24 10:28:48 UTC 3,409 bytes, 123 lines download raw bytes

1modules.chain=(function(){
2  'use strict';
3  //the undo redo chain. funny name, but i've grown attached to it.
4	//this chain isn't project specific, so methods should be provided to encode and decode the hash.
5
6  var chain={};
7  var lists=modules.lists;
8  var actions=modules.actions;
9  var base64=modules.base64;
10
11  chain.actiontypes={};
12  var totype=function(type,command){
13    	return chain.actiontypes[command.type][type](command);
14  };
15
16  chain.actions=[];
17  chain.unactions=[];
18  chain.do=function(command,spec){
19    spec=spec||{};
20    command.hash=totype('hash',command);
21    chain.actions.push(command);
22    totype('do',command);
23    chain.unactions=[];
24    if (!spec.fromhash){
25      chain.updatehash();
26    }
27  };
28	chain.unhash=function(command,spec){
29		//trigger an action from a hash rather than a command.
30		chain.do(totype('unhash',command),{fromhash:true});
31	};
32  chain.undo=function(){
33		if (chain.actions.length===0){
34			return;
35		}
36		var command=chain.actions.pop();
37		totype('undo',command);
38		chain.unactions.push(command);
39    chain.updatehash();
40  };
41  chain.redo=function(){
42		if (chain.unactions.length===0){
43			return;
44		}
45    var command=chain.unactions.pop();
46    chain.actions.push(command);
47    totype('do',command);
48		chain.updatehash();
49  };
50  chain.reset=function(){
51    if (chain.resetmethod){
52      //if possible, use a quick reset method the app provides
53      chain.resetmethod();
54      if (chain.actions.length>0){
55        chain.unactions=chain.unactions.concat(chain.actions.reverse());
56        chain.actions=[];
57      }
58      chain.updatehash();
59    }
60    else{
61      //as a fallback, just undo a million times.
62      while(chain.actions.length){
63    		chain.undo();
64    	}
65    }
66  };
67  chain.squash=function(commands){
68    //need a better name for these things.
69    //hopefully this is the right order to squash in.
70    //first numbers become the biggest ones.
71    return lists.reduce(commands,function(memo,command){
72      return {squashed:memo*command.max+command.value,max:memo.max*command.max};
73    },{squashed:0,max:0});
74  };
75  chain.expand=function(squashed,max){
76    //should be able to be an array or a single value.
77    //pulls out biggest numbers first.
78    var expanded=[];
79    if (Array.isArray(max)){
80      lists.each(max,function(thismax){
81        expanded.push(squashed%thismax);
82        squashed=Math.floor(squashed/thismax);
83      });
84      return {expanded:expanded};
85    }
86    else{
87      while(squashed>0){
88        expanded.push(squashed%max);
89        squashed=Math.floor(squashed/max);
90      }
91      return {expanded:expanded,remainder:squashed};
92    }
93  };
94	chain.updatehash=function(){
95		if (!chain.encodemethod){
96			console.log('ERROR: no encode method for chain');
97      return;
98		}
99    var hash='#';
100  	hash=hash+chain.encodemethod();
101    chain.hash=hash;
102    if (window.location&&window.location.replace){
103      window.location.replace(hash);
104    }
105	};
106  chain.decode=function(string){
107		if (!chain.decodemethod){
108			console.log('ERROR: no decode method for chain');
109			return;
110		}
111		chain.reset();
112		//ditch the # and pass to the project decode method.
113		chain.decodemethod(string.substr(1));
114    chain.updatehash();
115  };
116	window.addEventListener("hashchange", function(){
117    var newhash=window.location.hash;
118    if (newhash!==chain.hash&&((newhash+'#')!==chain.hash)){
119      chain.decode(newhash);
120    }
121	}, false);
122  return chain;
123}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.