Checkpoint in module refactor for the new server git repo.
authordsc <david.schoonover@gmail.com>
Wed, 1 Dec 2010 09:45:21 +0000 (01:45 -0800)
committerdsc <david.schoonover@gmail.com>
Wed, 1 Dec 2010 09:45:21 +0000 (01:45 -0800)
46 files changed:
bin/cjs.py
doc/gameplay.md
index.php
lib/cjs/require.js
lib/jquery.hotkeys.js
lib/jquery.hotkeys.min.js
lib/jquery.sparkline.js
lib/jquery.sparkline.min.js
src/Y/class.cjs
src/Y/core.cjs
src/Y/index.cjs
src/Y/modules/y.event.cjs
src/Y/type.cjs
src/Y/types/function.cjs
src/evt/class.cjs [moved from src/evt/evt.class.js with 100% similarity]
src/ezl/loop/eventloop.cjs
src/ezl/math/rect.cjs
src/ezl/math/vec.cjs
src/ezl/shape/circle.cjs
src/ezl/shape/line.cjs
src/ezl/shape/rect.cjs
src/ezl/shape/shape.cjs
src/ezl/util/tree/quadtree.cjs
src/tanks/config.cjs
src/tanks/game.cjs
src/tanks/globals.js [moved from src/tanks/globals.cjs with 68% similarity]
src/tanks/index.cjs
src/tanks/map/index.cjs
src/tanks/map/level.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/trajectory.cjs
src/tanks/map/wall.cjs [new file with mode: 0644]
src/tanks/thing/bullet.cjs
src/tanks/thing/customtank.cjs [moved from src/tanks/thing/custom-tank.cjs with 58% similarity]
src/tanks/thing/index.cjs
src/tanks/thing/player.cjs
src/tanks/thing/tank.cjs
src/tanks/thing/thing.cjs
src/tanks/ui/config.cjs [moved from src/tanks/ui/ui-config.cjs with 90% similarity]
src/tanks/ui/grid.cjs
src/tanks/ui/index.cjs
src/tanks/ui/main.cjs
src/tanks/ui/ui.cjs [deleted file]
src/tanks/util/config.cjs
tags.php [new file with mode: 0644]
tanks.php

index dbdbc72..1bd5429 100755 (executable)
@@ -7,11 +7,12 @@ __version__   = (0, 0, 1)
 __all__ = ('ResolutionError', 'Module', 'JSResolver',)
 
 
-import sys, re, json
+import sys, re, jsond as json
 from itertools import chain, repeat
 from collections import defaultdict
 from subprocess import Popen, check_output, STDOUT, PIPE
 from glob import glob
+from pprint import pprint, pformat
 
 from bunch import *
 from path import path
@@ -72,6 +73,8 @@ def partition(it, sep):
         return (before, None, [])
     return (before, sep, list(it))
 
+
+
 def canonicalise(query, base=None):
     """ query: A module ID (relative or absolute) or filepath
         base: Optional. The referring module ID.
@@ -185,6 +188,9 @@ class Module(Bunch):
     def requires(self):
         return self.calcRequires('_at_requires') + self._requires
     
+    def __json_default__(self):
+        return dict( (k,self[k]) for k in 'id file name _requires _at_requires'.split(' ') )
+    
     def __hash__(self):
         return hash(self.id)
     
@@ -206,32 +212,12 @@ class Module(Bunch):
 class CommonJS(object):
     """ Compiles JS modules into browser-safe JS files. """
     
-    @staticmethod
-    def discover(files, repos, **options):
-        "Discover listed modules and their dependencies."
-        cjs   = CommonJS(repos, **options)
-        queue = [ cjs.lookup(f) for f in files ]
-        seen  = set()
-        while queue:
-            mod = queue.pop(0)
-            seen.add(mod)
-            # print mod, "requirements:", mod.requires
-            for query in mod.requires:
-                # print mod, "requires", query
-                req = cjs.lookup(query, mod)
-                if req not in seen:
-                    queue.append(req)
-        if cjs.deps_name:
-            cjs.genDepLoader()
-        return cjs
-    
-    
     repos   = []
     modules = {} # id -> Module
     _graph    = None # id -> set(dependants)
     _at_graph = None # id -> set(dependants)
     
-    def __init__(self, repos, out='build', deps_name=None, clean=True, **options):
+    def __init__(self, repos, out='build', save='build', deps_name=None, clean=True, **options):
         self.modules  = {}
         self.options  = options
         self.deps_name = deps_name
@@ -274,6 +260,11 @@ class CommonJS(object):
         for k, mod in self.modules.iteritems():
             yield k, mod
     
+    def reset(self):
+        self._graph = None
+        self._at_graph = None
+        return self
+    
     def calcGraph(self, attr):
         if self._graph is None:
             graph   = self._graph    = defaultdict(set)
@@ -294,31 +285,38 @@ class CommonJS(object):
         return self.calcGraph('_at_graph')
     
     def tsort(self, graph):
-        p = Popen(['tsort'], stderr=STDOUT, stdin=PIPE, stdout=PIPE)
+        p = Popen(['tsort'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
         deps = '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in graph.iteritems() for dep in deps )
         p.stdin.write(deps)
         p.stdin.close()
         if p.wait() != 0:
             raise ResolutionError('Cannot resolve dependencies! Requirements must be acyclic!')
-        return p.stdout.read()
+        return p.stdout.read().strip().split('\n')
     
     @property
     def dependencies(self):
-        deps = (self.tsort(self.atGraph)+self.tsort(self.graph)).strip().split('\n')
-        for i, dep in reversed(list(enumerate(deps[:]))):
-            try:
-                idx = deps.index(dep, 0, i-1)
-                if i != idx:
-                    del deps[idx]
-            except ValueError: pass
-        return deps
+        atg = self.tsort(self.atGraph)
+        nog = self.tsort(self.graph)
+        atdeps = self.atGraph.keys()
+        
+        for dep in atg[:]:
+            if dep not in atdeps:
+                try: atg.remove(dep)
+                except ValueError: pass
+            else:
+                try: nog.remove(dep)
+                except ValueError: pass
+        
+        # print '\nAtKeys:\n', pformat(atdeps), '\n'
+        # print '\nAtDeps:\n', pformat(atg), '\n'
+        # print '\nNoKeys:\n', pformat(nog), '\n'
+        return atg+nog
     
     def dumpDependencies(self):
         column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
-        mods = self.modules.values()
-        for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
+        # for mod in sorted(self.modules.values(), key=lambda m: len(m.requires), reverse=True):
+        for mod in sorted(self.modules.values()):
             column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
-            # print '%s\t->\t%r' % (mod, sorted(mod.requires))
         column.stdin.close()
         if column.wait() != 0:
             print >> sys.stderr, 'Some sort of error has occurred!'
@@ -335,6 +333,54 @@ class CommonJS(object):
     @property
     def scriptTags(self):
         return '\n'.join( '<script src="{}" type="text/javascript"></script>'.format(uri) for uri in self.uris )
+    
+    def save(self, dir):
+        with (path(dir)/'.modules.json').open('w') as f:
+            json.dump({
+                'modules' : self.modules,
+                'ensure' : dict( (id, list(mod.id for mod in mods)) for id,mods in self.atGraph.iteritems() ),
+                'graph'  : dict( (id, list(mod.id for mod in mods)) for id,mods in self.graph.iteritems() ),
+            }, f, indent=4)
+        return self
+    
+    @staticmethod
+    def discover(files, repos, **options):
+        "Discover listed modules and their dependencies."
+        cjs = CommonJS(repos, **options)
+        
+        # print >> sys.stderr, '\n[ %s ]' % f
+        
+        queue = [ cjs.reset().lookup(f) for f in files ]
+        seen  = set()
+        while queue:
+            mod = queue.pop(0)
+            seen.add(mod)
+            # print mod, "requirements:", mod.requires
+            for query in mod.requires:
+                # print mod, "requires", query
+                req = cjs.lookup(query, mod)
+                if req not in seen:
+                    queue.append(req)
+        
+        if options.get('deps_name', None):
+            cjs.genDepLoader()
+        
+        if options.get('print_deps', None):
+            print >> sys.stderr, '\n[ %s ]' % f
+            print >> sys.stderr, 'All Dependencies:'
+            print >> sys.stderr, cjs.dumpDependencies()
+            print >> sys.stderr, ''
+            print >> sys.stderr, 'Resolution:'
+            print >> sys.stderr, '\n'.join(cjs.dependencies)
+        
+        if options.get('script_tags', None):
+            print cjs.scriptTags
+        
+        if options.get('state', None):
+            cjs.save(options['state'])
+        
+        return cjs
+
 
 
 
@@ -360,6 +406,9 @@ def main():
         help="Generates a JS script with the given name which doc-writes tags for this set of modules.")
     parser.add_option("-s", "--script-tags", default=False, action="store_true",
         help="Emits script-tags for this set of modules in dependency order. [default: %default]")
+    parser.add_option("-S", "--state", default='build',
+        help="Directory to save build state. [default: %default]")
+    
     
     (options, args) = parser.parse_args()
     
@@ -373,21 +422,11 @@ def main():
     
     # print 'files:', files, 'repos:', (repos or ['.'])
     try:
-        js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+        cjs = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
     except ResolutionError as ex:
         print >> sys.stderr, str(ex)
         return 1
     
-    if options.script_tags:
-        print js.scriptTags
-    
-    if options.print_deps:
-        print >> sys.stderr, 'All Dependencies:'
-        print >> sys.stderr, js.dumpDependencies()
-        print >> sys.stderr, ''
-        print >> sys.stderr, 'Resolution:'
-        print >> sys.stderr, '\n'.join(js.dependencies)
-    
     return 0
 
 if __name__ == '__main__':
index 02a1ac4..fd3a511 100644 (file)
@@ -1,63 +1,93 @@
 # The Littlest Battletank
 
-Inspired by Tanks minigame off Wii Play.
+Inspired by the Tanks minigame in Wii Play.
+
 
 ## The Basics
 - Your tank has 1hp.
 - Your basic cannon shoots bullets. A bullet lives for one bounce or until it kills something. You can have up to 5 bullets at a time in the air.
 - When you die, you respawn after a few seconds. (In single player, it restarts the level.)
 
+
 ## Controls
-- wasd, arrows: move your tank.
-- mouse: aim your reticule.
-- click, space, enter: fire a shot.
-- 0-9: use items.
-- All controls can be configured.
-
-## Ideas
-- Simplicity is king.
-- Only bosses have more than 1hp
-- Always on one screen
-- No stats: all items are qualitative
-- AI makes commentary on situations. "That was close. Sucker." "loool, you always die here."
-- Use TruRank-style player rating system, but the point of multiplayer will not be the ladder
-- Optional registration (Flash cookie every user)
-- Badges, awards, stats
-- Virtual currency from various in-game activities
-
-## Power-Ups
-- Missiles (fast, no bounce)
-- Refractor Rounds (slow, infi bounces)
-- Flamethrower (Cone AOE)
-- Shrapnel Rounds (splits once on impact)
-- Mortar Rounds (Projectile AOE)
-- Mines (Stationary Prox AOE)
-- Heatseekers (Projectile Prox)
-- Nukes (Absurd AOE which often kills you)
-- Portal Cannon (Exchanges your position with your cursor)
-- K-Boss Shield (Absorbs 1 damage)
-- Gin & Tonic / iPhone 3G / Hannah Montana Lamp (Extra Life)
-- Deuschund Trebuchet (Parabolic Arc lulz)
-- Light Cannon (Faster Move, -1 Shots in Air)
-- EMP Device (aka, the "Stunna") (Freezes everyone in place. Including you.)
-
-## Mechanics
-- AOE
-- Shot Travel Speed
-- Shot Bounces
-- Shot Cooldown
-- Shots in Air
-- Move Speed
-- HP (Bosses only)
-- Allies -- companion AI tanks which play for your side, but they can still damage you
-- Can use Items
-- AI type, quality
-- Mutable Environment?
+
+### Desktop Controls
+
+- Move: wasd, arrows for cardinal directions; combine for 45-degree moves
+- Shoot:
+    - Aim your reticule with the mouse
+    - Click, or press space to fire a shot
+- Items: Press `12345zxc
+- Zoom: Mouse wheel
+- Customization:
+    - Keyboard controls can be rebound
+    - Multiple UI trays
+
+### iOS Controls
+- Move: Trace a path from your tank with your finger
+- Shoot:
+     - Tap once somewhere sufficiently far from your tank to shoot one bullet on a trajectory aimed at that point
+     - Tap once and hold to see the trajectory line
+          - Move your finger to drag the line at a new point
+          - Release the tap to shoot along that trajectory
+          - Tap with your other hand sufficiently far from your tank and the current trajectory point to cancel
+- Items: On-screen buttons, possibly modal
+- Zoom: Pinch
+- Customization:
+     - Modal buttons used to switch between multiple UI "trays" with buttons
+     - Free gestures can be rebound (two/three finger swipe, double-tap, triple-tap)
+
+
+## Gameplay Ideas
+- No camera control: camera centers on tank and moves with it, though player can zoom the map
+- No number games: all items are qualitative (so, ex: only bosses have more than 1hp, but items (like shields) might absorb damage)
+- Allies: companion AI tanks which play for your side (beware friendly fire)- Mutable Environment: obstacles can be destroyed with the right weapons, enemies can be pushed
 
 
+## Items
 
+### Cannons
+- Missiles: Faster projectile, but no bounce
+- Refractor Rounds: Slower projectile, but infi bounces
+- Shrapnel Rounds: Projectile that splits instead of bounce
 
+### Heavy Munitions
+- Flamethrower: Cone AOE
+- Mortar Rounds: Projectile with AOE on detonation
+- Proximity Missiles: Projectile that explodes on prox
+- Mines: Stationary prox AOE
 
+### Special Weapons
+- Heatseekers: Projectile that will guide around walls to get to your target point, and then explodes even if no one is there
+- Nuke: Slow projectile with enormous AOE (reminder: friendly fire)
+- Trebuchet Rounds: Projectile which only collides when it reaches its destination (as if it was fired in a parabolic arc)
+- Portal Cannon: Makes source/dest wormholes
 
+### Passives
+- Light Ordinance: Faster move, fewer shots in air
+- Tactical Driver: Attempts to automatically move your tank out of harm's way when a bullet is imminent
+- Chameleon Engine: Makes enemies unable to see you for a limited time, confusing pathing
+
+### Shields
+- Turret Shield: extends 45-degrees around tour tank, centered on the barrel; impact pushes your tank back
+- Orbital Shield: small pellet-shield that orbits your tank
+- Stationary Shield: stationary shield sphere, passable to tanks but not bullets
+- Imprinted Stationary Shield: as the stationary shield, but passable only to your team and not others
+
+### Consumables
+- Cloudpot: Your tank deploys an emergency zeppelin to float quickly from your current position to your cursor. Tank can only be hit by Trebuchet Rounds during that time.
+- The Stunna Shocka (EMP Device): Freezes all tanks in place (including you)
+
+
+## Tank Attributes
+- Movement: speed, turning speed
+- Cannon: cooldown, max in air, recoil?
+- Bullets: speed, num bounces, proximity, AOE explosion
+- Toughness: hp (Bosses only), shields, resistance to certain classes of weapons
+
+
+## Flavor
+- AI makes commentary on situations. "That was close. Sucker." "loool, you always die here."
+- Papercraft art style, vector graphics
 
 
index 3ac3f78..8d435d9 100644 (file)
--- a/index.php
+++ b/index.php
@@ -29,7 +29,7 @@
 <div id="ai" style="display:none" class="bigblue">
     <div class="box">
         <h2>Add Tank AI</h2>
-        <textarea id="custom-tank"></textarea>
+        <textarea id="customtank"></textarea>
         <div class="ready pinkbutton rounded">Ready</div>
     </div>
 </div>
index 98d77d7..586ad3e 100644 (file)
@@ -10,7 +10,7 @@ function require(id){
     if ( !modules.hasOwnProperty(id) )
         throw new Error('No such module "'+id+'"!');
     
-    var module  = modules[ids]
+    var module  = modules[id]
     ,   exports = module.exports = {};
     
     // TODO: load the module
index fbd71c7..315014f 100644 (file)
@@ -1,3 +1,4 @@
+//@require('jquery')
 /*
  * jQuery Hotkeys Plugin
  * Copyright 2010, John Resig
index 6689e7a..90a601f 100644 (file)
@@ -1 +1,2 @@
+//@require('jquery')
 (function(b){b.fn.__bind__=b.fn.bind;b.fn.__unbind__=b.fn.unbind;b.fn.__find__=b.fn.find;var a={version:"0.7.9",override:/keypress|keydown|keyup/g,triggersMap:{},specialKeys:{27:"esc",9:"tab",32:"space",13:"return",8:"backspace",145:"scroll",20:"capslock",144:"numlock",19:"pause",45:"insert",36:"home",46:"del",35:"end",33:"pageup",34:"pagedown",37:"left",38:"up",39:"right",40:"down",109:"-",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",191:"/"},shiftNums:{"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":'"',",":"<",".":">","/":"?","\\":"|"},newTrigger:function(e,d,f){var c={};c[e]={};c[e][d]={cb:f,disableInInput:false};return c}};a.specialKeys=b.extend(a.specialKeys,{96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/"});b.fn.find=function(c){this.query=c;return b.fn.__find__.apply(this,arguments)};b.fn.unbind=function(h,e,g){if(b.isFunction(e)){g=e;e=null}if(e&&typeof e==="string"){var f=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();var d=h.split(" ");for(var c=0;c<d.length;c++){delete a.triggersMap[f][d[c]][e]}}return this.__unbind__(h,g)};b.fn.bind=function(j,f,k){var h=j.match(a.override);if(b.isFunction(f)||!h){return this.__bind__(j,f,k)}else{var n=null,i=b.trim(j.replace(a.override,""));if(i){n=this.__bind__(i,f,k)}if(typeof f==="string"){f={combi:f}}if(f.combi){for(var m=0;m<h.length;m++){var d=h[m];var g=f.combi.toLowerCase(),e=a.newTrigger(d,g,k),l=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();e[d][g].disableInInput=f.disableInInput;if(!a.triggersMap[l]){a.triggersMap[l]=e}else{if(!a.triggersMap[l][d]){a.triggersMap[l][d]=e[d]}}var c=a.triggersMap[l][d][g];if(!c){a.triggersMap[l][d][g]=[e[d][g]]}else{if(c.constructor!==Array){a.triggersMap[l][d][g]=[c]}else{a.triggersMap[l][d][g][c.length]=e[d][g]}}this.each(function(){var o=b(this);if(o.attr("hkId")&&o.attr("hkId")!==l){l=o.attr("hkId")+";"+l}o.attr("hkId",l)});n=this.__bind__(h.join(" "),f,a.handler)}}return n}};a.findElement=function(c){if(!b(c).attr("hkId")){if(b.browser.opera||b.browser.safari){while(!b(c).attr("hkId")&&c.parentNode){c=c.parentNode}}}return c};a.handler=function(e){var o=a.findElement(e.currentTarget),i=b(o),d=i.attr("hkId");if(d){d=d.split(";");var g=e.which,q=e.type,p=a.specialKeys[g],n=!p&&String.fromCharCode(g).toLowerCase(),h=e.shiftKey,c=e.ctrlKey,m=e.altKey||e.originalEvent.altKey,f=null;for(var r=0;r<d.length;r++){if(a.triggersMap[d[r]][q]){f=a.triggersMap[d[r]][q];break}}if(f){var j;if(!h&&!c&&!m){j=f[p]||(n&&f[n])}else{var l="";if(m){l+="alt+"}if(c){l+="ctrl+"}if(h){l+="shift+"}j=f[l+p];if(!j){if(n){j=f[l+n]||f[l+a.shiftNums[n]]||(l==="shift+"&&f[a.shiftNums[n]])}}}if(j){var s=false;for(var r=0;r<j.length;r++){if(j[r].disableInInput){var k=b(e.target);if(i.is("input")||i.is("textarea")||i.is("select")||k.is("input")||k.is("textarea")||k.is("select")){return true}}s=s||j[r].cb.apply(this,[e])}return s}}}};window.hotkeys=a;return b})(jQuery);
\ No newline at end of file
index 1c35b5f..06a630e 100644 (file)
@@ -1,3 +1,4 @@
+//@require('jquery')
 /**
 *
 * jquery.sparkline.js
index 08a30bf..2868b2b 100644 (file)
@@ -1,5 +1,5 @@
+//@require('jquery')
 /* jquery.sparkline 1.5.1 - http://omnipotent.net/jquery.sparkline/ */
-
 (function($){$.fn.simpledraw=function(width,height,use_existing){if(use_existing&&this[0].vcanvas)return this[0].vcanvas;if(width==undefined)width=$(this).innerWidth();if(height==undefined)height=$(this).innerHeight();if($.browser.hasCanvas){return new vcanvas_canvas(width,height,this);}else if($.browser.msie){return new vcanvas_vml(width,height,this);}else{return false;}};var pending=[];$.fn.sparkline=function(uservalues,options){var options=$.extend({type:'line',lineColor:'#00f',fillColor:'#cdf',defaultPixelsPerValue:3,width:'auto',height:'auto',composite:false},options?options:{});return this.each(function(){var render=function(){var values=(uservalues=='html'||uservalues==undefined)?$(this).text().split(','):uservalues;var width=options.width=='auto'?values.length*options.defaultPixelsPerValue:options.width;if(options.height=='auto'){if(!options.composite||!this.vcanvas){var tmp=document.createElement('span');tmp.innerHTML='a';$(this).html(tmp);height=$(tmp).innerHeight();$(tmp).remove();}}else{height=options.height;}
 $.fn.sparkline[options.type].call(this,values,options,width,height);}
 if(($(this).html()&&$(this).is(':hidden'))||($.fn.jquery<"1.3.0"&&$(this).parents().is(':hidden'))){pending.push([this,render]);}else{render.call(this);}});};$.sparkline_display_visible=function(){for(var i=pending.length-1;i>=0;i--){var el=pending[i][0];if($(el).is(':visible')&&!$(el).parents().is(':hidden')){pending[i][1].call(el);pending.splice(i,1);}}};$.fn.sparkline.line=function(values,options,width,height){var options=$.extend({spotColor:'#f80',spotRadius:1.5,minSpotColor:'#f80',maxSpotColor:'#f80',lineWidth:1,normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:'#ccc',chartRangeMin:undefined,chartRangeMax:undefined,chartRangeMinX:undefined,chartRangeMaxX:undefined},options?options:{});var xvalues=[],yvalues=[],yminmax=[];for(i=0;i<values.length;i++){var v=values[i];var isstr=typeof(values[i])=='string';var isarray=typeof(values[i])=='object'&&values[i]instanceof Array;var sp=isstr&&values[i].split(':');if(isstr&&sp.length==2){xvalues.push(Number(sp[0]));yvalues.push(Number(sp[1]));yminmax.push(Number(sp[1]));}else if(isarray){xvalues.push(values[i][0]);yvalues.push(values[i][1]);yminmax.push(values[i][1]);}else{xvalues.push(i);if(values[i]===null||values[i]=='null'){yvalues.push(null);}else{yvalues.push(Number(values[i]));yminmax.push(Number(values[i]));}}}
index dc1a4b5..5e90e10 100644 (file)
@@ -1,9 +1,21 @@
 // Inspired by John Resig's "Simple Class Inheritence" -- http://ejohn.org/blog/simple-javascript-inheritance/
 
-var type      = require('Y/type')
-,   YFunction = require('Y/types/function').YFunction
-,   core      = require('Y/core')
-,   slice     = core.slice
+var type       = require('Y/type')
+,   core       = require('Y/core')
+,   YFunction  = require('Y/types/function').YFunction
+,   isFunction = type.isFunction
+,   slice      = core.slice
+
+,   globals   = (function(){ return this; })()
+,   _Object   = globals.Object
+,   _Function = globals.Function
+,   _Array    = globals.Array
+,   _String   = globals.String
+,   _Number   = globals.Number
+
+,   slice    = _Array.prototype.slice
+,   hasOwn   = _Object.prototype.hasOwnProperty
+,   getProto = _Object.getPrototypeOf
 
 ,   KNOWN_CLASSES = type.type.KNOWN_CLASSES
 ,   classToString = function toString(){ return this.className+"()"; }
index 0725a30..ee42dc3 100644 (file)
@@ -5,6 +5,7 @@ var undefined
 ,   _Array    = globals.Array
 ,   PT = "prototype"
 ,   slice = _Array[PT].slice
+,   type = require('Y/type')
 ;
 
 // function slice(a){
@@ -47,7 +48,7 @@ function map(o, fn){
 }
 
 function forEach(o, fn){
-    map(o, fn, cxt);
+    map(o, fn, arguments[2] || o);
     return o;
 }
 
@@ -86,7 +87,7 @@ function dset(o, key, value, def){
 function attr(o, key, value, def){
     if ( !o || key === undefined ) return o;
     
-    if ( Y.isPlainObject(key) )
+    if ( type.isPlainObject(key) )
         return extend(o, key);
     
     if ( value !== undefined || def !== undefined ){
index cdfd44e..f15d71a 100644 (file)
@@ -43,11 +43,13 @@ addNames('curry methodize genericize compose chain memoize', yfn);
 // Curry all operators
 var op = require('Y/op');
 core.forEach(op, YFunction);
-Y['op'] = op['curried'] = op.extend({}, core.map(yfn.curry, op));
-// Y['op'] = core.reduce(op, function(Yop, fn, k){
-//     Yop[k] = yfn.curry(fn);
-//     return Yop;
-// }, {});
+// Y['op'] = op['curried'] = op.extend({}, core.map(op, yfn.curry));
+Y['op'] =
+op['curried'] = 
+    core.reduce(op, function(Yop, fn, k){
+        Yop[k] = fn.curry();
+        return Yop;
+    }, {});
 
 // var yclass = require('Y/types/class');
 addNames('Class subclass instantiate fabricate YBase',