Sorted `europe.cson` by key

Sorted `europe.cson` by key

--- dev/europe.cson
+++ dev/europe.cson
@@ -1,656 +1,654 @@
-{
-  information_pedestrian_crossing:
-    category: 'other'
-    name: 'pedestrian crossing'
-    elements: [
-      { type: 'square-bg', value: 'blue' }
-      { type: 'tri-bg-in', value: 'white', transform: 'scale(.9)' }
-      { type: 'pedestrian-crossing', value: 'black' }
+danger_bend_first_left:
+  category: 'danger'
+  name: 'bend first left'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'd-curve-l', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_bend_first_right:
+  category: 'danger'
+  name: 'bend first right'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'd-curve-l', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
+  ]
+
+danger_bend_left:
+  category: 'danger'
+  name: 'bend left'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'turn-l', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_bend_right:
+  category: 'danger'
+  name: 'bend right'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'turn-l', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
+  ]
+
+danger_construction:
+  category: 'danger'
+  name: 'construction/road works'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'roadworks', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_cycle_crossing:
+  category: 'danger'
+  name: 'cycle crossing'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'bicycle', value: 'black', transform: '{fit_triangle}'}
+  ]
+
+danger_danger:
+  category: 'danger'
+  name: 'danger'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'exclamation', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_intersection:
+  category: 'priority'
+  name: 'intersection'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'right-of-way', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_pedestrian_crossing:
+  category: 'danger'
+  name: 'pedestrian crossing'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'pedestrian', value: 'black' }
+  ]
+
+danger_quayside_or_ferry_berth:
+  category: 'danger'
+  name: 'quayside or ferry berth'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'cliff', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_road_narrows:
+  category: 'danger'
+  name: 'road narrows'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'narrow-road-both', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_road_narrows_left:
+  category: 'danger'
+  name: 'road narrows left'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'narrow-road-l', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_road_narrows_right:
+  category: 'danger'
+  name: 'road narrows right'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'narrow-road-l', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
+  ]
+
+danger_roundabout:
+  category: 'danger'
+  name: 'roundabout'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'roundabout', value: 'black', transform: '{fit_triangle}' }
+  ]
+
+danger_school_crossing:
+  category: 'danger'
+  name: 'school crossing'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'children', value: 'black'}
+  ]
+
+danger_slippery_road:
+  category: 'danger'
+  name: 'slippery road'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'slippery-road', value: 'black'}
+  ]
+
+danger_snow:
+  category: 'danger'
+  name: 'danger snow'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'snowflake', value: 'black', transform: '{fit_triangle}'}
+  ]
+
+danger_traffic_signal:
+  category: 'danger'
+  name: 'traffic signal'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'traffic-l-bg', value: 'black' }
+    { type: 'traffic-l-middle', value: 'red', transform: 'translate(0,-16%)' }
+    { type: 'traffic-l-middle', value: 'yellow' }
+    { type: 'traffic-l-middle', value: 'green', transform: 'translate(0,16%)' }
+  ]
+
+danger_uneven_road:
+  category: 'danger'
+  name: 'uneven road'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'bump', value: 'black'}
+  ]
+
+danger_wild_animals:
+  category: 'danger'
+  name: 'wild animals crossing'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'wild-animal', value: 'black', transform: '{fit_triangle}'}
+  ]
+
+information_disabled_parking:
+  category: 'information'
+  name: 'disabled parking'
+  elements: [
+    { type: 'square-bg', value: 'blue' }
+    { type: 'disabled-p', value: 'white' }
+  ]
+
+information_parking:
+  category: 'information'
+  name: 'parking'
+  elements: [
+    { type: 'square-bg', value: 'blue' }
+    { type: 'parking', value: 'white' }
+  ]
+
+mandatory_bicycle_pedestrian_dual_track:
+  category: 'mandatory'
+  name: 'bicycle/pedestrian dual track'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'bicycle', value: 'white', transform: '{right_half}' }
+    { type: 'footpath', value: 'white', transform: '{left_half}' }
+    { type: 'circle-separator', value: 'white' }
+  ]
+
+mandatory_cycle_track:
+  category: 'mandatory'
+  name: 'cycle track'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'bicycle', value: 'white' }
+  ]
+
+mandatory_footpath:
+  category: 'mandatory'
+  name: 'footpath'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'footpath', value: 'white' }
+  ]
+
+mandatory_go_left:
+  category: 'mandatory'
+  name: 'go left'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-90deg)' }
+  ]
+
+mandatory_go_left_or_right:
+  category: 'mandatory'
+  name: 'go left or right'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'translate(0,-15%) rotate(135deg) scale(.6) translate(0,-32%)' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'translate(0,-15%) rotate(-135deg) scale(.6) translate(0,-32%)' }
+  ]
+
+mandatory_go_right:
+  category: 'mandatory'
+  name: 'go right'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(90deg)' }
+  ]
+
+mandatory_go_straight:
+  category: 'mandatory'
+  name: 'go straight'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'white' }
+  ]
+
+mandatory_keep_left:
+  category: 'mandatory'
+  name: 'keep left'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-135deg)' }
+  ]
+
+mandatory_keep_right:
+  category: 'mandatory'
+  name: 'keep right'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(135deg)' }
+  ]
+
+mandatory_minimum_speed:
+  category: 'mandatory'
+  name: 'minimum speed'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'speed_value', value: 'white'}
+  ]
+
+mandatory_minimum_speed_end:
+  category: 'mandatory'
+  name: 'end of minimum speed limit'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'speed_value', value: 'white'}
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)'}
+  ]
+
+mandatory_pedestrian_bicycle_dual_track:
+  category: 'mandatory'
+  name: 'pedestrian/bicycle dual track'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'bicycle', value: 'white', transform: '{left_half}' }
+    { type: 'footpath', value: 'white', transform: '{right_half}' }
+    { type: 'circle-separator', value: 'white' }
+  ]
+
+mandatory_pedestrian_cycle_track:
+  category: 'mandatory'
+  name: 'pedestrian cycle track'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'footpath', value: 'white', transform: '{top_half}' }
+    { type: 'bicycle', value: 'white', transform: '{bottom_half}' }
+    { type: 'circle-separator', value: 'white', transform: 'rotate(90deg)' }
+  ]
+
+mandatory_roundabout:
+  category: 'mandatory'
+  name: 'roundabout'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'roundabout', value: 'white' }
+  ]
+
+mandatory_turn_left:
+  category: 'mandatory'
+  name: 'turn left'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'arrow-l', value: 'white' }
+  ]
+
+mandatory_turn_left_or_straight:
+  category: 'mandatory'
+  name: 'turn left or straight'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'arrow-s-l', value: 'white' }
+  ]
+
+mandatory_turn_right:
+  category: 'mandatory'
+  name: 'turn right'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'arrow-l', value: 'white', transform: 'scale(-1,1)' }
+  ]
+
+mandatory_turn_right_or_straight:
+  category: 'mandatory'
+  name: 'turn right or straight'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'arrow-s-l', value: 'white', transform: 'scale(-1,1)' }
+  ]
+
+other_no_entry:
+  category: 'other'
+  name: 'no entry'
+  elements: [
+    { type: 'circle-bg', value: 'red' }
+    { type: 'circle-bar', value: 'white' }
+  ]
+
+other_pedestrian_crossing:
+  category: 'other'
+  name: 'pedestrian crossing'
+  elements: [
+    { type: 'square-bg', value: 'blue' }
+    { type: 'tri-bg-in', value: 'white', transform: 'scale(.9)' }
+    { type: 'pedestrian-crossing', value: 'black' }
+  ]
+
+other_stop_position:
+  category: 'other'
+  name: 'stop position (bus/tram)'
+  elements: [
+    { type: 'circle-bg', value: 'yellow' }
+    { type: 'circle-o', value: 'green'}
+    { type: 'h', value: 'green', transform: '{fit_border_circle}'}
+  ]
+
+priority_give_way:
+  category: 'priority'
+  name: 'give way'
+  elements: [
+    { type: 'tri-r-bg', value: 'white' }
+    { type: 'tri-r-o', value: 'red' }
+  ]
+
+priority_narrow:
+  category: 'priority'
+  name: 'priority at narrow location'
+  elements: [
+    { type: 'square-bg', value: 'blue' }
+    { type: 'DE-arrow-up', value: 'red', transform: 'scale(.7) translate(-25%,5%) rotate(180deg)' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'scale(.7) translate(25%,-5%)' }
+  ]
+
+priority_narrow2:
+  category: 'priority'
+  name: 'no priority at narrow location'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'DE-arrow-up', value: 'black', transform: '{fit_border_circle} scale(.7) translate(-25%,5%) rotate(180deg)' }
+    { type: 'DE-arrow-up', value: 'red', transform: '{fit_border_circle} scale(.7) translate(25%,-5%)' }
+  ]
+
+priority_next_intersection_left:
+  category: 'priority'
+  name: 'priority at next intersection on the left'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'right-of-way-l fit', value: 'black', transform: '{fit_triangle}' }
     ]

-  mandatory_keep_right:
-    category: 'mandatory'
-    name: 'keep right'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(135deg)' }
+priority_next_intersection_right:
+  category: 'priority'
+  name: 'priority at next intersection on the right'
+  elements: [
+    { type: 'tri-bg', value: 'white' }
+    { type: 'tri-o', value: 'red' }
+    { type: 'right-of-way-l fit', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
     ]

-  mandatory_keep_left:
-    category: 'mandatory'
-    name: 'keep left'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-135deg)' }
-    ]
-
-  mandatory_go_left:
-    category: 'mandatory'
-    name: 'go left'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-90deg)' }
-    ]
-
-  mandatory_go_right:
-    category: 'mandatory'
-    name: 'go right'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(90deg)' }
-    ]
-
-  mandatory_minimum_speed:
-    category: 'mandatory'
-    name: 'minimum speed'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'speed_value', value: 'white'}
-    ]
-
-  mandatory_minimum_speed_end:
-    category: 'mandatory'
-    name: 'end of minimum speed limit'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'speed_value', value: 'white'}
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)'}
-    ]
-
-  other_give_way:
-    category: 'priority'
-    name: 'give way'
-    elements: [
-      { type: 'tri-r-bg', value: 'white' }
-      { type: 'tri-r-o', value: 'red' }
-    ]
-
-  information_parking:
-    category: 'information'
-    name: 'parking'
-    elements: [
-      { type: 'square-bg', value: 'blue' }
-      { type: 'parking', value: 'white' }
-    ]
-
-  priority_narrow:
-    category: 'priority'
-    name: 'priority at narrow location'
-    elements: [
-      { type: 'square-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'red', transform: 'scale(.7) translate(-25%,5%) rotate(180deg)' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'scale(.7) translate(25%,-5%)' }
-    ]
-
-  priority_narrow2:
-    category: 'priority'
-    name: 'no priority at narrow location'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'DE-arrow-up', value: 'black', transform: '{fit_border_circle} scale(.7) translate(-25%,5%) rotate(180deg)' }
-      { type: 'DE-arrow-up', value: 'red', transform: '{fit_border_circle} scale(.7) translate(25%,-5%)' }
-    ]
-
-  other_no_entry:
-    category: 'other'
-    name: 'no entry'
-    elements: [
-      { type: 'circle-bg', value: 'red' }
-      { type: 'circle-bar', value: 'white' }
-    ]
-
-  prohibitory_no_parking:
-    category: 'prohibitory'
-    name: 'no_parking'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-    ]
-
-  prohibitory_no_parking_left:
-    category: 'prohibitory'
-    name: 'no_parking'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(90deg) scale(.3) translate(95%)' }
-    ]
-
-  prohibitory_no_parking_right:
-    category: 'prohibitory'
-    name: 'no_parking'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-90deg) scale(.3) translate(95%)' }
-    ]
-
-  priority_priority_road:
-    category: 'priority'
-    name: 'priority_road'
-    elements: [
-      { type: 'diamond-bg', value: 'yellow' }
-      { type: 'diamond-o', value: 'white' }
-    ]
-
-  prohibitory_speed_limit:
-    category: 'prohibitory'
-    name: 'speed limit'
-    elements: [
-      { type: 'circle-bg', value: 'red' }
-      { type: 'circle-bg', value: 'white', transform: '{fit_border_circle}' }
-      { type: 'speed_value', value: 'black' }
-    ]
-
-  mandatory_pedestrian_cycle_dual_track:
-    category: 'mandatory'
-    name: 'pedestrian cycle dual track'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'bicycle', value: 'white', transform: '{left_half}' }
-      { type: 'footpath', value: 'white', transform: '{right_half}' }
-      { type: 'circle-separator', value: 'white' }
-    ]
-
-  danger_animals:
-    category: 'danger'
-    name: 'wild animals crossing'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'wild-animal', value: 'black', transform: '{fit_triangle}'}
-    ]
-
-  danger_snow:
-    category: 'danger'
-    name: 'danger snow'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'snowflake', value: 'black', transform: '{fit_triangle}'}
-    ]
-
-  danger_intersection:
-    category: 'priority'
-    name: 'intersection'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'right-of-way', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  danger_road_works:
-    category: 'danger'
-    name: 'road works'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'roadworks', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  danger_construction:
-      category: 'danger'
-      name: 'construction'
-      elements: [
-        { type: 'tri-bg', value: 'white' }
-        { type: 'tri-o', value: 'red' }
-        { type: 'roadworks', value: 'black', transform: '{fit_triangle}' }
-      ]
-
-  mandatory_roundabout:
-    category: 'mandatory'
-    name: 'roundabout'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'roundabout', value: 'white' }
-    ]
-
-  danger_roundabout:
-    category: 'danger'
-    name: 'roundabout'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'roundabout', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  prohibitory_no_traffic_both_ways:
-    category: 'prohibitory'
-    name: 'no traffic both ways'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-    ]
-
-  mandatory_pedestrian_cycle_track:
-    category: 'mandatory'
-    name: 'pedestrian cycle track'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'footpath', value: 'white', transform: '{top_half}' }
-      { type: 'bicycle', value: 'white', transform: '{bottom_half}' }
-      { type: 'circle-separator', value: 'white', transform: 'rotate(90deg)' }
-    ]
-
-  danger_traffic_signal:
-    category: 'danger'
-    name: 'traffic signal'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'traffic-l-bg', value: 'black' }
-      { type: 'traffic-l-middle', value: 'red', transform: 'translate(0,-16%)' }
-      { type: 'traffic-l-middle', value: 'yellow' }
-      { type: 'traffic-l-middle', value: 'green', transform: 'translate(0,16%)' }
-    ]
-
-  mandatory_cycle_track:
-    category: 'mandatory'
-    name: 'cycle track'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'bicycle', value: 'white' }
-    ]
-
-  danger_uneven_road:
-    category: 'danger'
-    name: 'uneven road'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'bump', value: 'black'}
-    ]
-
-  danger_danger:
-    category: 'danger'
-    name: 'danger'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'exclamation', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  prohibitory_no_parking_or_stopping:
-    category: 'prohibitory'
-    name: 'no parking or stopping'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
-    ]
-
-  prohibitory_no_parking_or_stopping_left:
-    category: 'prohibitory'
-    name: 'no parking or stopping'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-90deg) scale(.3) translate(95%)' }
-    ]
-
-  prohibitory_no_parking_or_stopping_right:
-    category: 'prohibitory'
-    name: 'no parking or stopping'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'rotate(90deg) scale(.3) translate(95%)' }
-    ]
-
-  prohibitory_overtaking:
-    category: 'prohibitory'
-    name: 'no overtaking'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'car-left', value: 'red' }
-      { type: 'car-right', value: 'black' }
-    ]
-
-  prohibitory_overtaking_trucks:
-      category: 'prohibitory'
-      name: 'no overtaking trucks'
-      elements: [
-        { type: 'circle-bg', value: 'white' }
-        { type: 'circle-o', value: 'red' }
-        { type: 'lorry-left', value: 'red' }
-        { type: 'car-right', value: 'black' }
-      ]
-
-  priority_priority_intersection_left:
-    category: 'priority'
-    name: 'priority at next intersection on the left'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'right-of-way-l fit', value: 'black', transform: '{fit_triangle}' }
-      ]
-
-  priority_priority_intersection_right:
-    category: 'priority'
-    name: 'priority at next intersection on the right'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'right-of-way-l fit', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
-      ]
-
-  mandatory_turn_left_or_right:
-    category: 'mandatory'
-    name: 'go left or right'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'translate(0,-15%) rotate(135deg) scale(.6) translate(0,-32%)' }
-      { type: 'DE-arrow-up', value: 'white', transform: 'translate(0,-15%) rotate(-135deg) scale(.6) translate(0,-32%)' }
-    ]
-
-  prohibitory_no_u_turn:
-    category: 'prohibitory'
-    name: 'no u-turn'
-    elements: [
-      { type: 'circle-bg', value: 'red' }
-      { type: 'circle-bg', value: 'white', transform: '{fit_border_circle}' }
-      { type: 'turnaround', value: 'black' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-55deg)' }
-      { type: 'turnaround2', value: 'black' }
-    ]
-
-  mandatory_go_straight:
-    category: 'mandatory'
-    name: 'go straight'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'DE-arrow-up', value: 'white' }
-    ]
-
-  mandatory_turn_left:
-    category: 'mandatory'
-    name: 'turn left'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'arrow-l', value: 'white' }
-    ]
-
-  mandatory_turn_right:
-    category: 'mandatory'
-    name: 'turn right'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'arrow-l', value: 'white', transform: 'scale(-1,1)' }
-    ]
-
-  mandatory_turn_right_or_straight:
-      category: 'mandatory'
-      name: 'turn right or straight'
-      elements: [
-        { type: 'circle-bg', value: 'blue' }
-        { type: 'arrow-s-l', value: 'white', transform: 'scale(-1,1)' }
-      ]
-
-  mandatory_turn_left_or_straight:
-        category: 'mandatory'
-        name: 'turn left or straight'
-        elements: [
-          { type: 'circle-bg', value: 'blue' }
-          { type: 'arrow-s-l', value: 'white' }
-        ]
-
-  priority_stop:
-    category: 'priority'
-    name: 'stop'
-    elements: [
-      { type: 'octagon', value: 'red' }
-      { type: 'stop', value: 'white' }
-    ]
-
-  prohibitory_noturn_right:
-    category: 'prohibitory'
-    name: 'no turn right'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'turn-l', value: 'black', transform: 'scale(-1,1)' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
-    ]
-
-  prohibitory_noturn_left:
-    category: 'prohibitory'
-    name: 'no turn left'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'turn-l', value: 'black' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
-    ]
-
-  danger_bend_right:
-      category: 'danger'
-      name: 'bend right'
-      elements: [
-        { type: 'tri-bg', value: 'white' }
-        { type: 'tri-o', value: 'red' }
-        { type: 'turn-l', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
-      ]
-
-  danger_bend_left:
-    category: 'danger'
-    name: 'bend left'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'turn-l', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  information_disabled_persons:
-    category: 'information'
-    name: 'disabled parking'
-    elements: [
-      { type: 'square-bg', value: 'blue' }
-      { type: 'disabled-p', value: 'white' }
-    ]
-
-  mandatory_footpath:
-    category: 'mandatory'
-    name: 'footpath'
-    elements: [
-      { type: 'circle-bg', value: 'blue' }
-      { type: 'footpath', value: 'white' }
-    ]
-
-  prohibitory_vehicle_height_limit:
-    category: 'prohibitory'
-    name: 'vehicle_height_limit'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'height', value: 'black' }
-      { type: 'height_value', value: 'black'}
-    ]
-
-  prohibitory_vehicle_width_limit:
-    category: 'prohibitory'
-    name: 'vehicle_width_limit'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'height', value: 'black', transform: 'rotate(90deg)' }
-      { type: 'width_value', value: 'black'}
-    ]
-
-  prohibitory_vehicle_weight_limit:
-    category: 'prohibitory'
-    name: 'vehicle weight limit'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'weight_value', value: 'black' }
-    ]
-
-  danger_bend_first_right:
-    category: 'danger'
-    name: 'bend first right'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'd-curve-l', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
-    ]
-
-  danger_bend_first_left:
-    category: 'danger'
-    name: 'bend first left'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'd-curve-l', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  prohibitory_no_vehicle_with_dangerous_goods:
-    category: 'prohibitory'
-    name: 'no vehicle with dangerous goods'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'diamond-bg', value: 'orange', transform: 'scale(.4) translate(0,-15%) rotate(45deg)' }
-      { type: 'lorry', value: 'black' }
-    ]
-
-  danger_road_narrows:
-    category: 'danger'
-    name: 'road narrows'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'narrow-road-both', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-  danger_road_narrows_left:
-      category: 'danger'
-      name: 'road narrows left'
-      elements: [
-        { type: 'tri-bg', value: 'white' }
-        { type: 'tri-o', value: 'red' }
-        { type: 'narrow-road-l', value: 'black', transform: '{fit_triangle}' }
-      ]
-
-  danger_road_narrows_right:
-        category: 'danger'
-        name: 'road narrows right'
-        elements: [
-          { type: 'tri-bg', value: 'white' }
-          { type: 'tri-o', value: 'red' }
-          { type: 'narrow-road-l', value: 'black', transform: '{fit_triangle} scale(-1,1)' }
-        ]
-
-  danger_cycle_crossing:
-    category: 'danger'
-    name: 'cycle crossing'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'bicycle', value: 'black', transform: '{fit_triangle}'}
-    ]
-
-  danger_school_crossing:
-    category: 'danger'
-    name: 'school crossing'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'children', value: 'black'}
-    ]
-
-  danger_slippery_road:
-    category: 'danger'
-    name: 'slippery road'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'slippery-road', value: 'black'}
-    ]
-
-  danger_pedestrian_crossing:
-    category: 'danger'
-    name: 'pedestrian crossing'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'pedestrian', value: 'black' }
-    ]
-
-  danger_quayside_or_ferry_berth:
-    category: 'danger'
-    name: 'quayside or ferry berth'
-    elements: [
-      { type: 'tri-bg', value: 'white' }
-      { type: 'tri-o', value: 'red' }
-      { type: 'cliff', value: 'black', transform: '{fit_triangle}' }
-    ]
-
-
-  prohibitory_no_motor_vehicles:
-    category: 'prohibitory'
-    name: 'motor vehicles prohibited'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'motorbike', value: 'black', transform: '{fit_border_circle} {top_half}' }
-      { type: 'car', value: 'black', transform: '{fit_border_circle} {bottom_half}' }
-      { type: 'circle-separator', value: 'black', transform: 'rotate(90deg) {fit_border_circle}' }
-    ]
-
-  prohibitory_no_motorcycles:
-    category: 'prohibitory'
-    name: 'motorcycles prohibited'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'motorbike', value: 'black', transform: '{fit_border_circle}' }
-    ]
-
-  prohibitory_no_pedestrians_and_bicycles:
-    category: 'prohibitory'
-    name: 'pedestrians and bicycles prohibited'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'footpath', value: 'black', transform: '{fit_border_circle} {top_half}' }
-      { type: 'bicycle', value: 'black', transform: '{fit_border_circle} {bottom_half}' }
-    ]
-
-  prohibitory_no_trucks:
-    category: 'prohibitory'
-    name: 'no trucks'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'truck', value: 'black' }
-    ]
-
-  prohibitory_no_trucks_bar:
-    category: 'prohibitory'
-    name: 'no trucks'
-    elements: [
-      { type: 'circle-bg', value: 'white' }
-      { type: 'circle-o', value: 'red' }
-      { type: 'truck', value: 'black' }
-      { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)'}
-    ]
-
-  other_stop_position:
-    category: 'other'
-    name: 'stop position (bus/tram)'
-    elements: [
-      { type: 'circle-bg', value: 'yellow' }
-      { type: 'circle-o', value: 'green'}
-      { type: 'h', value: 'green', transform: '{fit_border_circle}'}
-    ]
-}
+priority_priority_road:
+  category: 'priority'
+  name: 'priority_road'
+  elements: [
+    { type: 'diamond-bg', value: 'yellow' }
+    { type: 'diamond-o', value: 'white' }
+  ]
+
+priority_stop:
+  category: 'priority'
+  name: 'stop'
+  elements: [
+    { type: 'octagon', value: 'red' }
+    { type: 'stop', value: 'white' }
+  ]
+
+prohibitory_motorcycles:
+  category: 'prohibitory'
+  name: 'motorcycles prohibited'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'motorbike', value: 'black', transform: '{fit_border_circle}' }
+  ]
+
+prohibitory_motor_vehicles:
+  category: 'prohibitory'
+  name: 'motor vehicles prohibited'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'motorbike', value: 'black', transform: '{fit_border_circle} {top_half}' }
+    { type: 'car', value: 'black', transform: '{fit_border_circle} {bottom_half}' }
+    { type: 'circle-separator', value: 'black', transform: 'rotate(90deg) {fit_border_circle}' }
+  ]
+
+prohibitory_no_parking:
+  category: 'prohibitory'
+  name: 'no_parking'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+  ]
+
+prohibitory_no_parking_or_stopping:
+  category: 'prohibitory'
+  name: 'no parking or stopping'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
+  ]
+
+prohibitory_no_parking_or_stopping_left:
+  category: 'prohibitory'
+  name: 'no parking or stopping'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-90deg) scale(.3) translate(95%)' }
+  ]
+
+prohibitory_no_parking_or_stopping_right:
+  category: 'prohibitory'
+  name: 'no parking or stopping'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(90deg) scale(.3) translate(95%)' }
+  ]
+
+prohibitory_no_parking_left:
+  category: 'prohibitory'
+  name: 'no_parking'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(90deg) scale(.3) translate(95%)' }
+  ]
+
+prohibitory_no_parking_right:
+  category: 'prohibitory'
+  name: 'no_parking'
+  elements: [
+    { type: 'circle-bg', value: 'blue' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+    { type: 'DE-arrow-up', value: 'white', transform: 'rotate(-90deg) scale(.3) translate(95%)' }
+  ]
+
+prohibitory_no_traffic_both_ways:
+  category: 'prohibitory'
+  name: 'no traffic both ways'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+  ]
+
+prohibitory_no_turn_left:
+  category: 'prohibitory'
+  name: 'no turn left'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'turn-l', value: 'black' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)' }
+  ]
+
+prohibitory_no_turn_right:
+  category: 'prohibitory'
+  name: 'no turn right'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'turn-l', value: 'black', transform: 'scale(-1,1)' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-45deg)' }
+  ]
+
+prohibitory_no_u_turn:
+  category: 'prohibitory'
+  name: 'no u-turn'
+  elements: [
+    { type: 'circle-bg', value: 'red' }
+    { type: 'circle-bg', value: 'white', transform: '{fit_border_circle}' }
+    { type: 'turnaround', value: 'black' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(-55deg)' }
+    { type: 'turnaround2', value: 'black' }
+  ]
+
+prohibitory_overtaking:
+  category: 'prohibitory'
+  name: 'no overtaking'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'car-left', value: 'red' }
+    { type: 'car-right', value: 'black' }
+  ]
+
+prohibitory_overtaking_trucks:
+  category: 'prohibitory'
+  name: 'no overtaking trucks'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'lorry-left', value: 'red' }
+    { type: 'car-right', value: 'black' }
+  ]
+
+prohibitory_pedestrians_and_bicycles:
+  category: 'prohibitory'
+  name: 'pedestrians and bicycles prohibited'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'footpath', value: 'black', transform: '{fit_border_circle} {top_half}' }
+    { type: 'bicycle', value: 'black', transform: '{fit_border_circle} {bottom_half}' }
+  ]
+
+prohibitory_speed_limit:
+  category: 'prohibitory'
+  name: 'speed limit'
+  elements: [
+    { type: 'circle-bg', value: 'red' }
+    { type: 'circle-bg', value: 'white', transform: '{fit_border_circle}' }
+    { type: 'speed_value', value: 'black' }
+  ]
+
+prohibitory_trucks:
+  category: 'prohibitory'
+  name: 'no trucks'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'truck', value: 'black' }
+  ]
+
+prohibitory_trucks_bar:
+  category: 'prohibitory'
+  name: 'no trucks'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'truck', value: 'black' }
+    { type: 'circle-bar-rounded', value: 'red', transform: 'rotate(45deg)'}
+  ]
+
+prohibitory_vehicle_height_limit:
+  category: 'prohibitory'
+  name: 'vehicle_height_limit'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'height', value: 'black' }
+    { type: 'height_value', value: 'black'}
+  ]
+
+prohibitory_vehicle_weight_limit:
+  category: 'prohibitory'
+  name: 'vehicle weight limit'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'weight_value', value: 'black' }
+  ]
+
+prohibitory_vehicle_width_limit:
+  category: 'prohibitory'
+  name: 'vehicle_width_limit'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'height', value: 'black', transform: 'rotate(90deg)' }
+    { type: 'width_value', value: 'black'}
+  ]
+
+prohibitory_vehicles_with_dangerous_goods:
+  category: 'prohibitory'
+  name: 'no vehicles with dangerous goods'
+  elements: [
+    { type: 'circle-bg', value: 'white' }
+    { type: 'circle-o', value: 'red' }
+    { type: 'diamond-bg', value: 'orange', transform: 'scale(.4) translate(0,-15%) rotate(45deg)' }
+    { type: 'lorry', value: 'black' }
+  ]


Fixed selector problem for JNewStatusUpdate

--- workers/sitemapgenerator/lib/sitemapgenerator/sitemapgeneratorworker.coffee
+++ workers/sitemapgenerator/lib/sitemapgenerator/sitemapgeneratorworker.coffee
@@ -20,7 +20,7 @@

     # while generating main sitemap, we don't need hashbang in the url.
     for url in urls
-      if /^guest-/.test url
+      if not /^guest-/.test url
         sitemap += "<url><loc>#{@options.uri.address}/#!/#{url}</loc></url>"
     sitemap += sitemapFooter
     return sitemap
@@ -44,35 +44,27 @@
     {JSitemap} = @bongo.models
     JSitemap.update {name}, $set : {content}, {upsert : yes}, (err)->
       return console.log err if err
-      console.log "sitemap generated successfuly"

   generate:=>
-    console.log "Started to generate sitemap"

-    {JName, JGroup, JSitemap} = @bongo.models
+    {JName, JSitemap} = @bongo.models

-    groupSelector = {
-      privacy:'public'
-    }
     generateSitemapIndex = (sitemapNames)=>
       name = "sitemap.xml"
       content = @generateSitemapIndexString sitemapNames
       @saveSitemap name, content

-    # this query is not working
     selector = {
       $or: [
         {
           'slugs.group': 'koding',
-          'slugs.constructorName': $not : 'JNewStatusUpdate'
+          'slugs.constructorName': $ne : 'JNewStatusUpdate'
         }
         { 'slugs.usedAsPath':'username' }
       ]
     }

     JName.count selector, (err, count)=>
-      console.log "count"
-      console.log count
       numberOfNamePages = Math.ceil(count / NAMEPERPAGE)

       queue = [1..numberOfNamePages].map (pageNumber)=>=>


StackTemplate: Tests: use test plan for tests

--- workers/social/lib/social/models/computeproviders/stacktemplate.test.coffee
+++ workers/social/lib/social/models/computeproviders/stacktemplate.test.coffee
@@ -248,7 +248,7 @@
           async.series [

             (next) ->
-              group.update { $set: { 'config.testplan': 'default' } }, (err) ->
+              group.update { $set: { 'config.testplan': 'test' } }, (err) ->
                 expect(err).to.not.exist
                 next()


Cleanup, delay compilation of methods

Cleanup, delay compilation of methods

--- layout.coffee
+++ layout.coffee
@@ -163,282 +163,6 @@
       return true
   # propertyBindings.find = _.memoize(propertyBindings.find)

-  class Node extends Module
-    @include Events
-
-    matchConstraint = /\${(.+)}/
-    constructor: (el, attributes = {}) ->
-      @subnodes = []
-      # Install types
-      @types = attributes.$types ? {}
-      delete attributes.$types
-
-      # Install methods
-      for methodname, method of attributes.$methods
-        # console.log 'installing method', methodname, method, @
-        installMethod(@, methodname, method)
-      delete attributes.$methods
-
-      for {name, script, args, type} in attributes.$handlers?
-        name = name.substr(2)
-        # console.log 'installing handler', name, args, type, script, @
-        @bind(name, @eventCallback(name, script, @, args, type))
-      delete attributes.$handlers
-
-      # Bind to event expressions and set attributes
-      for name, value of attributes
-        constraint = value.match?(matchConstraint)
-        if constraint
-          @applyConstraint(name, constraint[1])
-        else if name.indexOf('on') == 0
-          name = name.substr(2)
-          # console.log('binding to event expression', name, value, @)
-          @bind(name, @eventCallback(name, value, @))
-        else
-          @setAttribute(name, value)
-
-      @bindConstraints() if @constraints
-      # console.log 'new node', @, attributes
-      @trigger('init', @) if @events?['init']
-
-
-
-    applyConstraint: (name, expression) ->
-      @constraints ?= {}
-      @constraints[name] = compileScript('return ' + expression).bind(@)
-      # console.log 'adding constraint', name, expression, @
-      # console.log 'eval', @constraints[name]()
-
-      constraintBinding = @constraints[name]
-      bindings = constraintBinding.bindings ?= {}
-
-      scopes = propertyBindings.find(expression)
-      # console.log 'found scopes', scopes
-      for scope in scopes
-        bindexpression = scope.binding
-        scope.compiled = compileScript('return ' + bindexpression).bind(@)
-        bindings[bindexpression] = scope
-        # console.log 'applied', scope.property, bindexpression, 'for', @
-
-      # console.log 'matched constraint', name, @, expression
-      return
-
-    setAttribute: (name, value) ->
-      # TODO: add support for dynamic constraints
-      # constraint = value.match?(matchConstraint)
-      # if constraint
-      #   @applyConstraint(name, constraint[1])
-      #   return
-
-      # coerce value to type
-      type = @types[name]
-      if type
-        value = typemappings[type](value) if type of typemappings
-        # console.log 'type', name, type, value, @
-
-      if @[name] != value
-        # console.log 'setAttribute', name, value
-        setter = 'set_' + name
-        if setter of @
-          # console.log 'calling setter', setter, value, @[setter]
-          @[setter](value)
-        else
-          # console.log 'setting style', name, value
-          @[name] = value
-
-      # send event
-      @trigger(name, value, @, name) if @events?[name]
-      @
-
-    # generate a callback for an event expression in a way that preserves scope, e.g. on_x="console.log(value, this, ...)"
-    eventCallback: (name, script, scope, fnargs=['value'], type) ->
-      # console.log 'binding to event expression', name, script, scope
-      js = compileScript(script, fnargs, type)
-      () ->
-        if name of scope
-          args = [scope[name]]
-        else
-          args = arguments
-        # console.log 'event callback', name, args, scope, js
-        js.apply(scope, args)
-
-    bindConstraints: () ->
-      # register constraints last
-      for name, value of @constraints
-        # console.log 'binding constraint', name, value, @
-        constraint = @constraintCallback(name, value)
-        for bindexpression, binding of @constraints[name].bindings
-          property = binding.property
-          boundref = binding.compiled()
-          boundref ?= boundref.$view
-          # console.log 'binding to', property, 'on', boundref
-          boundref.bind(property, constraint)
-
-        @setAttribute(name, value())
-
-      return
-
-    # generate a callback for a constraint expression, e.g. x="${this.parent.baz.x + 10}"
-    constraintCallback: (name, fn) ->
-      # console.log('binding to constraint fn', name, fn, @)
-      () =>
-        # console.log 'setting', name, fn(), @
-        @setAttribute(name, fn())
-
-    set_parent: (parent) ->
-      # console.log 'set_parent', parent, @
-      # normalize to jQuery object
-      if parent instanceof Node
-        # store references to parent and children
-        @parent = parent
-        parent[@name] = @ if @name
-        parent.subnodes.push(@)
-        parent.trigger('subnodes', @) if parent.events?['subnodes']
-
-    set_name: (@name) ->
-      # console.log 'set_name', name, this
-      @parent?[name] = @
-
-
-  class Sprite
-#    guid = 0
-    stylemap= {x: 'left', y: 'top', bgcolor: 'background-color'}
-
-    constructor: (@jqel = $('<div/>'), view) ->
-      # console.log 'new sprite', @jqel, view
-      @jqel = $(@jqel) unless @jqel instanceof jQuery
-      @jqel[0].$view = view
-
-      # normalize to jQuery object
-#      guid++
-#      @jqel.attr('id', 'jqel-' + guid) if not @jqel.attr('id')
-      @jqel.addClass('sprite')
-    setStyle: (name, value) ->
-      value ?= ''
-      name = stylemap[name] if name of stylemap
-      # console.log('setStyle', name, value, @jqel[0])
-      @jqel.css(name, value)
-    set_parent: (parent) ->
-      if parent instanceof Sprite
-        parent = parent.jqel
-
-      parent = $(parent) unless parent instanceof jQuery
-      # console.log 'set_parent', parent
-      parent.append(@jqel)
-    set_id: (@id) ->
-      # console.log('setid', @id)
-      @jqel.attr('id', @id)
-    animate: =>
-      # console.log 'sprite animate', arguments, @jqel
-      @jqel.animate.apply(@jqel, arguments)
-
-
-  ignoredAttributes = {parent: true, id: true, name: true, extends: true, type: true}
-  class View extends Node
-    constructor: (el, attributes = {}) ->
-      @subviews = []
-      attributes.$types = {x: 'number', y: 'number', width: 'number', height: 'number'}
-      if (el instanceof HTMLElement and el.$view)
-        console.warn 'already bound view', el.$view, el
-        return
-
-      if (el instanceof View)
-        el = el.sprite
-
-      @sprite = new Sprite(el, @)
-
-      super(el, attributes)
-      # console.log 'new view', el, attributes, @
-
-    gotStyle: (name, value) ->
-      if not ignoredAttributes[name]
-        # if view.events?[name])
-        _super::setAttribute.apply(@, arguments)
-
-    setAttribute: (name, value) ->
-      if not (ignoredAttributes[name] or @[name] == value)
-        # console.log 'setting style', name, @[name], value, @
-        @sprite.setStyle(name, value)
-      super(name, value)
-
-    set_parent: (parent) ->
-      # console.log 'view set_parent', parent, @
-      super(parent)
-
-      # store references subviews
-      if parent instanceof View
-        parent.subviews.push(@)
-        parent.trigger('subviews', @) if parent.events?['subviews']
-        parent = parent.sprite
-      @sprite.set_parent parent
-
-    set_id: (@id) ->
-      @sprite.set_id(id)
-
-    animate: ->
-      # console.log 'animate', arguments, @sprite.animate
-      @sprite.animate.apply(this, arguments)
-
-  # flatten element.attributes to a hash
-  flattenattributes = (namednodemap)  ->
-    attributes = {}
-    for i in namednodemap
-      attributes[i.name] = i.value
-    attributes
-
-  specialtags = ['handler', 'method', 'attribute', 'setter']
-  # init classes based on an existing element
-  initFromElement = (el, parent) ->
-    tagname = el.localName
-    if not (tagname of lz)
-      console.warn 'could not find class for tag', tagname, el
-      return
-
-    attributes = flattenattributes(el.attributes)
-
-    # swallow builtin mouse attributes to prevent events from the tag
-    for event in mouseEvents
-      el.removeAttribute('on' + event)
-
-    parent ?= el.parentNode
-    attributes.parent = parent if parent?
-    # console.log 'parent', tagname, attributes, parent
-
-    children = (child for child in el.childNodes when child.nodeType == 1)
-
-    if tagname is 'class'
-      for child in children
-        # console.log 'creating child', tagname, child.localName, child, parent
-        # console.dir(child)
-        # console.log 'defer', child
-        child.$defer = true
-
-    processSpecialTags(el, attributes, attributes.type)
-
-    parent = new lz[tagname](el, attributes)
-
-    unless tagname is 'class'
-      for child in children
-        initFromElement(child, parent) unless child.localName in specialtags
-
-    return
-
-
-  # write default CSS to the DOM
-  writeDefaultStyle = () ->
-    style = document.createElement('style')
-    style.type = 'text/css'
-    style.innerHTML = '.sprite{position:absolute;} .hidden{display:none;}'
-    document.getElementsByTagName('head')[0].appendChild(style)
-
-  # init all views in the DOM recursively
-  init = (selector = $('view')) ->
-    for el, i in selector
-      initFromElement(el) unless el.$defer or el.$view
-    # listen for jQuery style changes
-    hackstyle(true)
-    # console.log 'caches', compileCache
-
   compileCache.script ?= {'coffee': {}}
   coffeeCache = compileCache.script.coffee
   compilermappings =
@@ -463,6 +187,281 @@
     catch e
       console.error('failed to compile', args, script, e)

+
+  class Node extends Module
+    @include Events
+
+    matchConstraint = /\${(.+)}/
+    constructor: (el, attributes = {}) ->
+      @subnodes = []
+      # Install types
+      @types = attributes.$types ? {}
+      delete attributes.$types
+
+      # Install methods
+      for methodname, method of attributes.$methods
+        # console.log 'installing method', methodname, method, @
+        installMethod(@, methodname, compileScript.apply(null, method))
+      delete attributes.$methods
+
+      for {name, script, args, type} in attributes.$handlers?
+        name = name.substr(2)
+        # console.log 'installing handler', name, args, type, script, @
+        @bind(name, @eventCallback(name, script, @, args, type))
+      delete attributes.$handlers
+
+      # Bind to event expressions and set attributes
+      for name, value of attributes
+        constraint = value.match?(matchConstraint)
+        if constraint
+          @applyConstraint(name, constraint[1])
+        else if name.indexOf('on') == 0
+          name = name.substr(2)
+          # console.log('binding to event expression', name, value, @)
+          @bind(name, @eventCallback(name, value, @))
+        else
+          @setAttribute(name, value)
+
+      @bindConstraints() if @constraints
+      # console.log 'new node', @, attributes
+      @trigger('init', @) if @events?['init']
+
+    applyConstraint: (name, expression) ->
+      @constraints ?= {}
+      @constraints[name] = compileScript('return ' + expression).bind(@)
+      # console.log 'adding constraint', name, expression, @
+      # console.log 'eval', @constraints[name]()
+
+      constraintBinding = @constraints[name]
+      bindings = constraintBinding.bindings ?= {}
+
+      scopes = propertyBindings.find(expression)
+      # console.log 'found scopes', scopes
+      for scope in scopes
+        bindexpression = scope.binding
+        scope.compiled = compileScript('return ' + bindexpression).bind(@)
+        bindings[bindexpression] = scope
+        # console.log 'applied', scope.property, bindexpression, 'for', @
+
+      # console.log 'matched constraint', name, @, expression
+      return
+
+    setAttribute: (name, value) ->
+      # TODO: add support for dynamic constraints
+      # constraint = value.match?(matchConstraint)
+      # if constraint
+      #   @applyConstraint(name, constraint[1])
+      #   return
+
+      # coerce value to type
+      type = @types[name]
+      if type
+        value = typemappings[type](value) if type of typemappings
+        # console.log 'type', name, type, value, @
+
+      if @[name] != value
+        # console.log 'setAttribute', name, value
+        setter = 'set_' + name
+        if setter of @
+          # console.log 'calling setter', setter, value, @[setter]
+          @[setter](value)
+        else
+          # console.log 'setting style', name, value
+          @[name] = value
+
+      # send event
+      @trigger(name, value, @, name) if @events?[name]
+      @
+
+    # generate a callback for an event expression in a way that preserves scope, e.g. on_x="console.log(value, this, ...)"
+    eventCallback: (name, script, scope, fnargs=['value'], type) ->
+      # console.log 'binding to event expression', name, script, scope
+      js = compileScript(script, fnargs, type)
+      () ->
+        if name of scope
+          args = [scope[name]]
+        else
+          args = arguments
+        # console.log 'event callback', name, args, scope, js
+        js.apply(scope, args)
+
+    bindConstraints: () ->
+      # register constraints last
+      for name, value of @constraints
+        # console.log 'binding constraint', name, value, @
+        constraint = @constraintCallback(name, value)
+        for bindexpression, binding of @constraints[name].bindings
+          property = binding.property
+          boundref = binding.compiled()
+          boundref ?= boundref.$view
+          # console.log 'binding to', property, 'on', boundref
+          boundref.bind(property, constraint)
+
+        @setAttribute(name, value())
+
+      return
+
+    # generate a callback for a constraint expression, e.g. x="${this.parent.baz.x + 10}"
+    constraintCallback: (name, fn) ->
+      # console.log('binding to constraint fn', name, fn, @)
+      () =>
+        # console.log 'setting', name, fn(), @
+        @setAttribute(name, fn())
+
+    set_parent: (parent) ->
+      # console.log 'set_parent', parent, @
+      # normalize to jQuery object
+      if parent instanceof Node
+        # store references to parent and children
+        @parent = parent
+        parent[@name] = @ if @name
+        parent.subnodes.push(@)
+        parent.trigger('subnodes', @) if parent.events?['subnodes']
+
+    set_name: (@name) ->
+      # console.log 'set_name', name, this
+      @parent?[name] = @
+
+
+  class Sprite
+#    guid = 0
+    stylemap= {x: 'left', y: 'top', bgcolor: 'background-color'}
+
+    constructor: (@jqel = $('<div/>'), view) ->
+      # console.log 'new sprite', @jqel, view
+      @jqel = $(@jqel) unless @jqel instanceof jQuery
+      @jqel[0].$view = view
+
+      # normalize to jQuery object
+#      guid++
+#      @jqel.attr('id', 'jqel-' + guid) if not @jqel.attr('id')
+      @jqel.addClass('sprite')
+    setStyle: (name, value) ->
+      value ?= ''
+      name = stylemap[name] if name of stylemap
+      # console.log('setStyle', name, value, @jqel[0])
+      @jqel.css(name, value)
+    set_parent: (parent) ->
+      if parent instanceof Sprite
+        parent = parent.jqel
+
+      parent = $(parent) unless parent instanceof jQuery
+      # console.log 'set_parent', parent
+      parent.append(@jqel)
+    set_id: (@id) ->
+      # console.log('setid', @id)
+      @jqel.attr('id', @id)
+    animate: =>
+      # console.log 'sprite animate', arguments, @jqel
+      @jqel.animate.apply(@jqel, arguments)
+
+
+  ignoredAttributes = {parent: true, id: true, name: true, extends: true, type: true}
+  class View extends Node
+    constructor: (el, attributes = {}) ->
+      @subviews = []
+      attributes.$types = {x: 'number', y: 'number', width: 'number', height: 'number'}
+      if (el instanceof HTMLElement and el.$view)
+        console.warn 'already bound view', el.$view, el
+        return
+
+      if (el instanceof View)
+        el = el.sprite
+
+      @sprite = new Sprite(el, @)
+
+      super(el, attributes)
+      # console.log 'new view', el, attributes, @
+
+    gotStyle: (name, value) ->
+      if not ignoredAttributes[name]
+        # if view.events?[name])
+        _super::setAttribute.apply(@, arguments)
+
+    setAttribute: (name, value) ->
+      if not (ignoredAttributes[name] or @[name] == value)
+        # console.log 'setting style', name, @[name], value, @
+        @sprite.setStyle(name, value)
+      super(name, value)
+
+    set_parent: (parent) ->
+      # console.log 'view set_parent', parent, @
+      super(parent)
+
+      # store references subviews
+      if parent instanceof View
+        parent.subviews.push(@)
+        parent.trigger('subviews', @) if parent.events?['subviews']
+        parent = parent.sprite
+      @sprite.set_parent parent
+
+    set_id: (@id) ->
+      @sprite.set_id(id)
+
+    animate: ->
+      # console.log 'animate', arguments, @sprite.animate
+      @sprite.animate.apply(this, arguments)
+
+  # flatten element.attributes to a hash
+  flattenattributes = (namednodemap)  ->
+    attributes = {}
+    for i in namednodemap
+      attributes[i.name] = i.value
+    attributes
+
+  specialtags = ['handler', 'method', 'attribute', 'setter']
+  # init classes based on an existing element
+  initFromElement = (el, parent) ->
+    tagname = el.localName
+    if not (tagname of lz)
+      console.warn 'could not find class for tag', tagname, el
+      return
+
+    attributes = flattenattributes(el.attributes)
+
+    # swallow builtin mouse attributes to prevent events from the tag
+    for event in mouseEvents
+      el.removeAttribute('on' + event)
+
+    parent ?= el.parentNode
+    attributes.parent = parent if parent?
+    # console.log 'parent', tagname, attributes, parent
+
+    children = (child for child in el.childNodes when child.nodeType == 1)
+
+    if tagname is 'class'
+      for child in children
+        # console.log 'creating child', tagname, child.localName, child, parent
+        # console.dir(child)
+        # console.log 'defer', child
+        child.$defer = true
+
+    processSpecialTags(el, attributes, attributes.type)
+
+    parent = new lz[tagname](el, attributes)
+
+    unless tagname is 'class'
+      for child in children
+        initFromElement(child, parent) unless child.localName in specialtags
+
+    return
+
+
+  # write default CSS to the DOM
+  writeDefaultStyle = () ->
+    style = document.createElement('style')
+    style.type = 'text/css'
+    style.innerHTML = '.sprite{position:absolute;} .hidden{display:none;}'
+    document.getElementsByTagName('head')[0].appendChild(style)
+
+  # init all views in the DOM recursively
+  init = (selector = $('view')) ->
+    for el, i in selector
+      initFromElement(el) unless el.$defer or el.$view
+    # listen for jQuery style changes
+    hackstyle(true)
+    # console.log 'caches', compileCache
+
   # http://stackoverflow.com/questions/1248849/converting-sanitised-html-back-to-displayable-html
   htmlDecode = (input) ->
     # return if not input
@@ -497,13 +496,13 @@
         args = (attributes.args ? '').split()
         script = htmlDecode(child.innerHTML)
         type = attributes.type or defaulttype
-        classattributes.$methods[attributes.name] = compileScript(script, args, type)
+        classattributes.$methods[attributes.name] = [script, args, type]
         # console.log 'added method', attributes.name, script, classattributes
       else if childname == 'setter'
         args = (attributes.args ? '').split()
         script = htmlDecode(child.innerHTML)
         type = attributes.type or defaulttype
-        classattributes.$methods['set_' + attributes.name] = compileScript(script, args, type)
+        classattributes.$methods['set_' + attributes.name] = [script, args, type]
         # console.log 'added setter', 'set_' + attributes.name, args, classattributes.$methods
       else if childname == 'attribute'
         classattributes[attributes.name] = attributes.value
@@ -521,7 +520,7 @@
         delete classattributes[ignored]

       processSpecialTags(el, classattributes, compilertype)
-      # console.log('compiled class', name, extend, (classattributes))
+      # console.log('compiled class', name, extend, classattributes)

       # serialize the tag's contents
       body = el.innerHTML


VueJS Slot snippet for Atom

VueJS Slot snippet for Atom

Signed-off-by: Salim Djerbouh <64b2b6d12bfe4baae7dad3d018f8cbf6b0e7a044@caddydz.me>

--- src/atom/snippets.cson
+++ src/atom/snippets.cson
@@ -1,21 +1,25 @@
 '.source.php':
-  'comment':
-    'prefix' : 'comment'
-    'body': '/**\n * $1\n * @param $2\n * @var $3\n * @return $4\n */$5'
+	'comment':
+		'prefix' : 'comment'
+		'body': '/**\n * $1\n * @param $2\n * @var $3\n * @return $4\n */$5'
 '.blade.php':
-  'bstext':
-    'prefix' : 'bstext'
-    'body': '
\n\t$2:\n\t<input type="text" class="form-control" name="$1" id="$1">\n
\n$3'
-  'Vue JS Router':
-    'prefix' : 'router'
-    'body': '<router-link to="${1:url}" exact>${2:title}</router-link>\n\t$3'
-  'Localization retrieval':
-    'prefix' : 'translate'
-    'body': '{{ __(\'${1}\') }}'
+	'bstext':
+		'prefix' : 'bstext'
+		'body': '
\n\t$2:\n\t<input type="text" class="form-control" name="$1" id="$1">\n
\n$3'
+	'Vue JS Router':
+		'prefix' : 'router'
+		'body': '<router-link to="${1:url}" exact>${2:title}</router-link>\n\t$3'
+	'Localization retrieval':
+		'prefix' : 'translate'
+		'body': '{{ __(\'${1}\') }}'
 '.source.js':
-  'VueJS component':
-    'prefix' : 'component'
-    'body': 'Vue.component (\'${1:name}\', {\n\tprops: [\n\t\t\'${2:property}\',\n\t],\n\ttemplate: `\n\t\t${3:html}\n\t`,\n\tdata: function(){\n\t\treturn {\n\t\t\t${4:key}: ${5:value}\n\t\t}\n\t},\n\tmethods: {\n\t\t${6:method_name}() {\n\t\t\t${7:// code}\n\t\t}\n\t}\n});\n$8'
-  'new vue':
-    'prefix' : 'new vue'
-    'body': 'new Vue({\n\tel: \'${1:#app}\',\n\tdata: {\n\t\t${2:name} : \'${3:value}\',\n\t}\n});\n$7'
+	'VueJS component':
+		'prefix' : 'component'
+		'body': 'Vue.component (\'${1:name}\', {\n\tprops: [\n\t\t\'${2:property}\',\n\t],\n\ttemplate: `\n\t\t${3:html}\n\t`,\n\tdata: function(){\n\t\treturn {\n\t\t\t${4:key}: ${5:value}\n\t\t}\n\t},\n\tmethods: {\n\t\t${6:method_name}() {\n\t\t\t${7:// code}\n\t\t}\n\t}\n});\n$8'
+	'new vue':
+		'prefix' : 'new vue'
+		'body': 'new Vue({\n\tel: \'${1:#app}\',\n\tdata: {\n\t\t${2:name} : \'${3:value}\',\n\t}\n});\n$7'
+'.vue':
+	'VueJS Slot':
+		'prefix' : 'slot'
+		'body': '<slot name=\"${1:name}\">${2:data}</slot>${3}'


json response

json response

--- app/assets/javascripts/dash.js.coffee
+++ app/assets/javascripts/dash.js.coffee
@@ -66,4 +66,5 @@
   data = JSON.stringify(rpc)
   $.ajax({type:"post", url:url, data:data, contentType:"application/json", success: json_done})

-json_done = ->
+json_done = (data, msg)->
+  console.log(data)


Default workspace classes when array is empty

--- src/menu-manager.coffee
+++ src/menu-manager.coffee
@@ -59,7 +59,8 @@
       testBody.classList.add(@classesForElement(document.body)...)

       testWorkspace = document.createElement('body')
-      workspaceClasses = @classesForElement(document.body.querySelector('.workspace')) ? ['.workspace']
+      workspaceClasses = @classesForElement(document.body.querySelector('.workspace'))
+      workspaceClasses = ['workspace'] if workspaceClasses.length is 0
       testWorkspace.classList.add(workspaceClasses...)

       testBody.appendChild(testWorkspace)


change cards storing on hash basis

change cards storing on hash basis

--- app/assets/javascripts/game.js.coffee
+++ app/assets/javascripts/game.js.coffee
@@ -10,8 +10,8 @@

   state = undefined

-  p1_cards_obj = []
-  p2_cards_obj = []
+  p1_cards_obj = {}
+  p2_cards_obj = {}

   p1_card_selector = []
   p2_card_selector = []
@@ -42,7 +42,8 @@
         while(Object.keys(comp_cards).length < 24)
           comp_cards[Math.floor(Math.random() * 82)] = true

-        p1_cards_obj = Object.keys(comp_cards)
+        for key in Object.keys(comp_cards)
+          p1_cards_obj[key] = game_faces().faces[Number(key)]

         p1_face_index = p1_cards_obj[Math.floor(Math.random() * 24)]
       else
@@ -51,15 +52,13 @@
       p1_card_selector = p1_cards
       p2_card_selector = p2_cards

-      cards = []
       $.each(
         $(p2_card_selector),
         ->
-          cards.push($(@).attr('card_id'))
+          key = $(@).attr('card_id')
+          p2_cards_obj[key] = game_faces().faces[Number(key)]
       )

-      p2_cards_obj = cards
-
       state = states['inited']
       $('body').on 'click', p2_card_selector, choose_target
     else


extracting module of cafeTownsend.employee

--- app/assets/javascripts/modules.coffee
+++ app/assets/javascripts/modules.coffee
@@ -5,9 +5,14 @@
   'ngResource'
   'rails'
   'ng-rails-csrf'
-  'cafeTownsend.employee'
+])
+
+angular.module('cafeTownsend.employee', [
+  'ngRoute'
+  'cafeTownsend.services'
 ])

 angular.module('cafeTownsend', [
+  'cafeTownsend.employee'
   'cafeTownsend.services'
 ])


background rectangle

background rectangle

--- app/assets/javascripts/zvg/zvg.coffee
+++ app/assets/javascripts/zvg/zvg.coffee
@@ -291,10 +291,18 @@
     @chart     = @container.append('div').attr('class', 'zvg-chart')
     @svg = @chart.append('svg')
       .attr('height', @height + 200).attr('width', @width + 200)
+    @renderBackgroundRectangle()
     @background = (new ZVG.Background(@svg, @height, @width, 0)).background
+
+  # a white cover that backgrounds everything (distinct from gray background rectangle)
+  renderBackgroundRectangle: ->
+    @_background_rectangle or= @svg.append('rect').style('fill', 'white').style('stroke','none')
+    @_background_rectangle.attr('width', @width + 200 + @legend_width).attr('height', @height + 200)

   render_legend: ->
     null
+
+  legend_width: 0

 class ZVG.ColumnarLayoutChart extends ZVG.BasicChart
   constructor: (element, options = {}) ->
@@ -314,6 +322,7 @@
     @width = width
     @svg.attr('width', @width + @legend_width)
     @background.attr('width', @width)
+    @renderBackgroundRectangle()
     @set_legend_x()
     @set_series_1_spacing()


hide filter legend if only one value is present

--- app/assets/javascripts/zvg/zvg.coffee
+++ app/assets/javascripts/zvg/zvg.coffee
@@ -330,10 +330,12 @@

   renderFilterLegend: =>
+    d = @series_2_domain().slice(0).reverse()
+    return if d.length is 1
     @legend.selectAll('div.filter_legend_item').remove()

     items = @legend.selectAll('div.filter_legend_item')
-      .data(@series_2_domain().slice(0).reverse())
+      .data(d)
     items.enter()
       .append('div')
       .attr('class', 'filter_legend_item legend_item')


remove unused function

remove unused function

--- services/track-changes/app/coffee/DocArchiveManager.coffee
+++ services/track-changes/app/coffee/DocArchiveManager.coffee
@@ -63,6 +63,3 @@
 					MongoManager.markDocHistoryAsUnarchived doc_id, (error) ->
 						return callback(error) if error?
 						callback()
-
-	getProjectsDocs: (project_id, callback)->
-		db.docs.find project_id: ObjectId(project_id.toString()), {}, callback


Add the standard output from qpdf on error

--- app/coffee/OutputFileOptimiser.coffee
+++ app/coffee/OutputFileOptimiser.coffee
@@ -25,7 +25,7 @@
 			stdout += chunk.toString()
 		callback = _.once(callback) # avoid double call back for error and close event
 		proc.on "error", (err) ->
-			logger.warn {err, args}, "qpdf failed"
+			logger.warn {err, args}, "qpdf failed", stdout
 			callback(null) # ignore the error
 		proc.on "close", (code) ->
 			if code != 0


replace codes of event handler.

replace codes of event handler.

--- chat/grails-app/assets/javascripts/chat.coffee
+++ chat/grails-app/assets/javascripts/chat.coffee
@@ -36,6 +36,18 @@
 })

+$('#log-fast-backward').on 'click', (event) ->
+    $('#area_log').scrollTop(0)
+    $('#chatMessage').focus()
+    event.stopPropagation()
+
+
+$('#log-fast-forward').on 'click', (event) ->
+    $('#area_log').scrollTop(($("#area_log")[0].scrollHeight))
+    $('#chatMessage').focus()
+    event.stopPropagation()
+
+
 $('#now-fast-backward').on 'click', (event) ->
     $('#area_now').scrollTop(0)
     $('#chatMessage').focus()
@@ -44,18 +56,6 @@

 $('#now-fast-forward').on 'click', (event) ->
     $('#area_now').scrollTop(($("#area_now")[0].scrollHeight))
-    $('#chatMessage').focus()
-    event.stopPropagation()
-
-
-$('#log-fast-backward').on 'click', (event) ->
-    $('#area_log').scrollTop(0)
-    $('#chatMessage').focus()
-    event.stopPropagation()
-
-
-$('#log-fast-forward').on 'click', (event) ->
-    $('#area_log').scrollTop(($("#area_log")[0].scrollHeight))
     $('#chatMessage').focus()
     event.stopPropagation()


naming

naming

--- src/mix.it/index.coffee
+++ src/mix.it/index.coffee
@@ -4,7 +4,7 @@
 HELPERS = require('./helpers')

-module_kw = [
+postmixin_hooks = [
   'post_classmixin'
   'post_protomixin'
 ]
@@ -14,7 +14,7 @@
   Function::mixinto_class = (mixin) ->
     HELPERS.validate_mixin(mixin)

-    for key, value of mixin when key not in module_kw
+    for key, value of mixin when key not in postmixin_hooks
       @[key] = value
     if typeof mixin.post_classmixin == 'function'
       mixin.post_classmixin.call(@, (HELPERS.rest_of.apply @, arguments)...)
@@ -25,7 +25,7 @@
   Function::mixinto_proto = (mixin) ->
     HELPERS.validate_mixin(mixin)

-    for key, value of mixin when key not in module_kw
+    for key, value of mixin when key not in postmixin_hooks
       @::[key] = value
     if typeof mixin.post_protomixin == 'function'
       mixin.post_protomixin.call(@::, (HELPERS.rest_of.apply @, arguments)...)


don't need the extra friction anymore

don't need the extra friction anymore

--- VisualGraph.coffee
+++ VisualGraph.coffee
@@ -73,7 +73,6 @@
       .charge(-300)
       .linkDistance(100)
       .size([800, 400])
-      .friction(0.4)

   createInitialState: ->
     nodeCount = @initParams.nodesLength


oh those wonderful async race conditions

--- content/better-bibtex.coffee
+++ content/better-bibtex.coffee
@@ -65,7 +65,7 @@
   INIT
 ###

-benchmark = Zotero.Promise.coroutine((options, code) ->
+benchmark = Zotero.Promise.coroutine((options) ->
   start = new Date()

   debug("waiting for #{options.msg}...")
@@ -86,25 +86,26 @@
   Zotero.BetterBibTeX.ready = ready.promise

   yield benchmark({
-    msg: 'schema'
-    async: Zotero.Schema.schemaUpdatePromise
+    msg: 'Zotero initialization'
+    async: Zotero.initializationPromise
     flash: true
   })

-  # must start after the schemaUpdatePromise
+  # must start after the initializationPromise
   yield benchmark({
     msg: 'keymanager'
     async: KeyManager.init()
   })

   yield benchmark({
+    msg: 'abbreviater'
+    code: -> JournalAbbrev.init()
+  })
+
+  # must start after journal abbrev
+  yield benchmark({
     msg: 'serializer'
     code: -> Serializer.init()
-  })
-
-  yield benchmark({
-    msg: 'abbreviater'
-    code: -> JournalAbbrev.init()
   })

   if Prefs.get('testing')


Urls are not for the eyes of others.

Urls are not for the eyes of others.

--- scripts/ayp.coffee
+++ scripts/ayp.coffee
@@ -38,6 +38,9 @@
   if text.length > limit
     text = text.slice(0, (limit - suffix.length))
     text += suffix
+
+  # Urls are secret. Not for you. Not for anyone.
+  text = test.replace(/(https?:\/\/[^\s]+)/, "[redacted]")

   text


ugh commas

ugh commas

Tada!,

--- scripts/ayp.coffee
+++ scripts/ayp.coffee
@@ -167,7 +167,7 @@
                     "Despite my best efforts",
                     "Bleep, Bloop, Bop:",
                     "I have done the thing,",
-                    "Tada!"
+                    "Tada!",
                   ]
                   msg.reply "#{prefix} #{AYP_SITE}at/#{now}/ is now -> #{strip_url}"


Changed Pausing to Work on KeyUp

Changed Pausing to Work on KeyUp

--- js/main.coffee
+++ js/main.coffee
@@ -36,13 +36,16 @@
       x: -e.originalEvent.deltaX
       y: -e.originalEvent.deltaY

-  $(window).keydown (e) ->
+  $(window).keyup (e) ->
     e.preventDefault()
     if e.keyCode == 32
       if timeScale == 0
         timeScale = 1
       else
         timeScale = 0
+
+  $(window).keydown (e) ->
+    e.preventDefault()
     if e.keyCode == 88
       scale *= SCALE_SPEED
     if e.keyCode == 90


links that are linking to a figure found in itself should have target='_self', check link that are not [link] text for media linking as well,  update to use book_id

--- src/components/book-content-mixin.cjsx
+++ src/components/book-content-mixin.cjsx
@@ -1,6 +1,7 @@
 _ = require 'underscore'
 S = require '../helpers/string'
 dom = require '../helpers/dom'
+{CourseStore} = require '../flux/course'

 # According to the tagging legend exercises with a link should have `a.os-embed`
 # but in the content they are just a vanilla link.
@@ -50,14 +51,17 @@
     S.capitalize(tag)

   buildReferenceBookLink: (cnxId) ->
-    referenceBookParams = _.clone(@context.router.getCurrentParams())
-    referenceBookParams.cnxId = cnxId or @getCnxId()
+    {courseId} = @context.router.getCurrentParams()
+    course = CourseStore.get(courseId)
+    referenceBookParams =
+      bookId: course.book_id
+      cnxId: cnxId or @getCnxId()
     pageUrl = @context.router.makeHref('viewReferenceBookPage', referenceBookParams)

     pageUrl

   isMediaLink: (link) ->
-    link.innerText is '[link]' and link.hash.length > 0 and link.hash.search('/') is -1
+    link.hash.length > 0 and link.hash.search('/') is -1

   hasCNXId: (link) ->
     trueHref = link.getAttribute('href')
@@ -94,7 +98,8 @@
     root = @getDOMNode()
     media = root.querySelector(link.hash)
     tag = @getMediaTag(media)
-    link.innerText = tag if tag?
+    link.innerText = tag if link.innerText is '[link]' and tag?
+    link.target = '_self'

   processLinks: ->
     root = @getDOMNode()


Simplify permalink property

Simplify permalink property

This mimics the `return 'none'` style as per @jnordberg's [comment][1] and
allows a global permalink style to be set in `config.json`.

It removes the *date* shorthand; I think its better to be explicit.

Related to #134.

  [1]: https://github.com/jnordberg/wintersmith/pull/147#discussion-diff-5628990

--- src/plugins/page.coffee
+++ src/plugins/page.coffee
@@ -41,15 +41,15 @@
         basename = path.join path.basename(dirname), path.basename regularFilename()
         dirname = path.dirname dirname

-        basename = @permalinkTemplate
+        basename = @permalink
           .replace(":year", @date.getFullYear())
           .replace(":month", ('0' + (@date.getMonth()+1)).slice(-2))
           .replace(":day", ('0' + @date.getDate()).slice(-2))
           .replace(":title", basename)
-
+
         path.join dirname, basename

-      if @metadata.permalink? then permalinkFilename() else regularFilename()
+      if @permalink isnt 'none' then permalinkFilename() else regularFilename()

     getUrl: (base) ->
@@ -93,11 +93,8 @@
     @property 'rfc822date', ->
       env.utils.rfc822(@date)

-    @property 'permalinkTemplate', ->
-      switch @metadata.permalink
-        when undefined then ":title"
-        when "date"    then ":year/:month/:day/:title"
-        else           @metadata.permalink
+    @property 'permalink', ->
+      @metadata.permalink or env.config.defaultPermalink or 'none'

     @property 'basename', ->
       @metadata.filename or path.basename(env.utils.stripExtension(@filepath.relative) + '.html')


Implement new pinout definition

Implement new pinout definition

--- src/qeda-element.coffee
+++ src/qeda-element.coffee
@@ -14,13 +14,19 @@
     @refDes = 'REF' # Should be overriden in element handler
     @symbol = new QedaSymbol this
     @symbol.settings = @library.symbol
+    @symbols = []
     @patterns = []

     @pins = []
+    @groups = []
     for pinName of @pinout
-      pinNumbers = if Array.isArray @pinout[pinName] then @pinout[pinName] else [@pinout[pinName]]
+      pinNumbers = @_pinNumbers @pinout[pinName]
+      @groups[pinName] = pinNumbers
       for pinNumber in pinNumbers
-        @pins[pinNumber] = @_pinObj pinNumber, pinName
+        unless @pins[pinNumber]?
+          @pins[pinNumber] = @_pinObj pinNumber, pinName
+        else
+          @pins[pinNumber].name += ' / ' + pinName

     unless Array.isArray @housing
       @housing = [@housing]
@@ -78,7 +84,9 @@
           handler(pattern, cap[1..]...)
     @_calculated = true

-
+  #
+  # Check whether number is float
+  #
   isFloat: (n) ->
     Number(n) and (n % 1 isnt 0)

@@ -105,6 +113,28 @@
         housing[key] = { min: min,  max: max,  nom: nom, tol: tol }

   #
+  # Convert pin numbers definition to array
+  #
+  _pinNumbers: (inputs) ->
+    numbers = []
+    unless Array.isArray inputs then inputs = [inputs]
+    for input in inputs
+      if typeof input is 'number'
+        numbers.push input.toString()
+      else if typeof input is 'string'
+        input = input.replace /\s+/g, ''
+        subs = input.split ','
+        for sub in subs
+          cap = /([A-Z]*)(\d+)\.{2,3}([A-Z]*)(\d+)/.exec sub
+          unless cap
+            numbers.push sub
+          else
+            for i in [cap[1]..cap[3]] # TODO: Improve
+              for j in [cap[2]..cap[4]]
+                numbers.push i + j
+    numbers
+
+  #
   # Generate pin object
   #
   _pinObj: (number, name) ->


Based HUBOT_9GAG_NO_GIFS on variable definition and existential operator.

--- src/scripts/9gag.coffee
+++ src/scripts/9gag.coffee
@@ -6,7 +6,7 @@
 #   "soupselect": "0.2.0"
 #
 # Configuration:
-#   HUBOT_9GAG_NO_GIFS (optional; default is "false")
+#   HUBOT_9GAG_NO_GIFS (optional, skips GIFs if defined; default is undefined)
 #
 # Commands:
 #   hubot 9gag me - Returns a random meme image
@@ -40,9 +40,8 @@
       location = response.headers['location']
       return send_meme( message, location, response_handler )

-    no_gifs = process.env.HUBOT_9GAG_NO_GIFS
     selectors = ["a img.badge-item-img"]
-    if no_gifs != '0' && no_gifs != 't' && no_gifs != 'true'
+    if ! process.env.HUBOT_9GAG_NO_GIFS?
       selectors.unshift("div.badge-animated-container-animated img")

     img_src = get_meme_image( body, selectors )


added some interaction to do e2e using protractor

--- src/scripts/main.coffee
+++ src/scripts/main.coffee
@@ -2,3 +2,39 @@
 text.innerHTML = 'This text was added by my awesome module!'
 text.id = 'content'
 document.body.appendChild(text)
+
+
+
+# protractor code for sample test
+div = document.createElement 'div'
+div.id = 'mydiv'
+document.body.appendChild div
+
+input = document.createElement 'input'
+input.type = 'text'
+input.name = 'myinput'
+input.id = 'myinput'
+document.body.appendChild  input
+
+button = document.createElement 'button'
+button.innerText = 'press me'
+
+
+
+
+showText = ->
+  _input = document.getElementById("myinput")
+  if _input.value.length
+    div.innerText = _input.value
+    div.style.color = '#f00'
+    div.style.border = 'black solid 1px'
+    div.style.width = "500px"
+    div.style.background = '#eee'
+    div.style.margin = '15px 0 15px'
+    div.style.padding = '10px'
+
+button.onclick = showText
+
+
+
+document.body.appendChild  button


Changed default camera location

Changed default camera location

--- source/Main.coffee
+++ source/Main.coffee
@@ -201,7 +201,8 @@
 		# set location from url hash
 		if not parseLocationString(window.location.hash)
 			# else, use a default location
-			parseLocationString("#go:-25.552404403686523:-30.029766082763672:-63.47420883178711:-15872:5888:11008:0.036:0.687:0.683:0.247")
+			#parseLocationString("#go:-25.552404403686523:-30.029766082763672:-63.47420883178711:-15872:5888:11008:0.036:0.687:0.683:0.247")
+			parseLocationString("#go:-137.62518310546875:13.487885475158691:-41.893638610839844:6784:-6272:16128:0.551:-0.258:0.194:0.769")

 		# remove hash from URL
 		history.pushState("", document.title, window.location.pathname + window.location.search)
@@ -245,7 +246,7 @@
 	vec3.transformQuat(moveVec, moveVec, smoothRotation)
 	vec3.add(camera.position, camera.position, moveVec)

-	# when near planets, orient the camera upward
+	# when near planets, orient the camera upright
 	distToPlanet = planetfield.getDistanceToClosestPlanet()
 	if distToPlanet < 0.1
 		planetVec = planetfield.getClosestPlanet()


Remove unnecessary requirement

Remove unnecessary requirement

--- varify/static/scripts/coffeescript/ui/tables/header.coffee
+++ varify/static/scripts/coffeescript/ui/tables/header.coffee
@@ -1,9 +1,8 @@
 define [
     'underscore'
     'marionette'
-    './row'
     'tpl!templates/varify/tables/header.html'
-], (_, Marionette, row, templates...) ->
+], (_, Marionette, templates...) ->

     templates = _.object ['header'], templates


parsing

parsing


Social: refactor get functions

Social: refactor get functions

--- workers/social/lib/social/models/socialapi/requests.coffee
+++ workers/social/lib/social/models/socialapi/requests.coffee
@@ -23,35 +23,22 @@
   if not data.channelId or not data.accountId
     return callback { message: "Request is not valid for creating channel"}

-  request
-    url    : "#{SOCIAL_API_URL}/channel/#{data.channelId}/history"
-    qs     : data
-    json   : true
-    body   : data
-    method : 'GET'
-  , wrapCallback callback
+  url = "#{SOCIAL_API_URL}/channel/#{data.channelId}/history"
+  get url, data, callback

 fetchGroupChannels = (data, callback)->
   if not data.groupName or not data.accountId
     return callback { message: "Request is not valid for creating channel"}

-  request
-    url    : "#{SOCIAL_API_URL}/channel"
-    qs     : data
-    json   : true
-    body   : data
-    method : 'GET'
-  , wrapCallback callback
+  url = "#{SOCIAL_API_URL}/channel"
+  get url, data, callback

 fetchMessage = (data, callback)->
   if not data.id
     return callback { message: "Message id is not set"}

-  request
-    url    : "#{SOCIAL_API_URL}/message/#{data.id}"
-    json   : true
-    method : 'GET'
-  , wrapCallback callback
+  url = "#{SOCIAL_API_URL}/message/#{data.id}"
+  get url, data, callback

 postToChannel = (data, callback)->
   if not data.channelId or not data.accountId or not data.body


Add missing query types

Add missing query types

--- lib/app.coffee
+++ lib/app.coffee
@@ -89,7 +89,7 @@
     rows.push(row.split("|"))
   rows

-share.queryTypes = ["in", "out", "inweb", "outweb", "inicmp", "outicmp", "innull", "outnull"]
+share.queryTypes = ["in", "out", "inweb", "outweb", "inicmp", "outicmp", "innull", "outnull", "int2int", "ext2ext", "other"]
 share.inputFields = [
   "interface"
   "cmd"


don't run multiple fix commands at the same time

they will sometimes overlap & cause weird errors because they write to
the disk

--- lib/cli.coffee
+++ lib/cli.coffee
@@ -106,28 +106,34 @@
     process.exit(exitCode)
   )
 else if argv.action is 'fix'
-  promises = []
-  Object.keys(Rules).forEach (ruleName) ->
+  results = []
+  promise = W.resolve()
+  for ruleName in Object.keys(Rules)
     Rule = Rules[ruleName]
-    argv.files.forEach (filePath) ->
-      if fs.lstatSync(filePath).isDirectory() then return
-      property = new Rule(filePath)
-      promises.push(
-        property.fix().then(
+    for filePath in argv.files
+      if fs.lstatSync(filePath).isDirectory() then continue
+      do (Rule, filePath) ->
+        property = new Rule(filePath)
+        promise = promise.then( ->
+          property.fix()
+        ).then(
           (res) ->
-            res: res
-            file: filePath
-            rule: property.propertyName
+            results.push(
+              res: res
+              file: filePath
+              rule: property.propertyName
+            )
           (err) ->
-            file: filePath
-            rule: property.propertyName
-            error: err
+            results.push(
+              file: filePath
+              rule: property.propertyName
+              error: err
+            )
         )
-      )

-  W.all(promises).done (res) ->
+  promise.done ->
     verbose = true
-    for result in res
+    for result in results
       if result.error?
         console.log "#{result.file} #{result.error.message}"
       else if verbose


run: move plugin discovery

run: move plugin discovery

--- lib/run.coffee
+++ lib/run.coffee
@@ -70,7 +70,6 @@
     options = {}
   new Run options, config

-
 # Configuration
 load_module = (ctx, parent, default_command, filter_command) ->
   middlewares = []
@@ -86,6 +85,7 @@
     parent.handler = undefined
     parent[k] ?= v for k, v of mod
   if plugin
+    middlewares.push module: parent.module, plugin: true
     commands = parent.handler.call ctx
     return unless commands
     return if commands is ctx
@@ -109,7 +109,6 @@
         else
           throw Error "Invalid handler: #{child.handler}"
         child.command ?= command
-        middlewares.push module: parent.module, plugin: true
         m = load_module(ctx, child, default_command, command)
         middlewares.push m... if m
   else


beautify

beautify

--- matrix.coffee
+++ matrix.coffee
@@ -36,7 +36,7 @@
     @height == @width

   map: (f, T) ->
-    @zip ((a, b) -> f(a)), @, T
+    @zip ((a) -> f(a)), @, T # function wrapped to hide following arguments

   clone: (T) ->
     @map id, T


StaticPage: Update Activity link in homepage

--- client/Main/CommonViews/footerview.coffee
+++ client/Main/CommonViews/footerview.coffee
@@ -36,7 +36,7 @@

COMMUNITY

-        ACTIVITY
+        ACTIVITY
         KODING BLOG
         MEETUPS
         TESTIMONIALS


AdminModal: Make height dynamic.

AdminModal: Make height dynamic.

if window.innerHeight < 600 then 100% else 90%

--- client/admin/lib/adminappview.coffee
+++ client/admin/lib/adminappview.coffee
@@ -26,7 +26,16 @@
     @setListeners()

+  _windowDidResize: (e) ->
+
+    height = if window.innerHeight < 600 then 100 else 90
+    @setHeight height, '%'
+    @setPositions()
+
+
   setListeners: ->
+
+    @listenWindowResize()

     @on 'groupSettingsUpdated', (group)->
       @setData group


fix typo that prevented from replying to a msg

--- client/app/components/compose.coffee
+++ client/app/components/compose.coffee
@@ -237,7 +237,7 @@

         # new draft
         else
-            state = MessageUtils.makeReplyMessage @props.selectedAccountLogin,
+            state = messageUtils.makeReplyMessage @props.selectedAccountLogin,
                 @props.inReplyTo, @props.action,
                 @props.settings.get('composeInHTML')
             state.accountID ?= @props.selectedAccountID


login: loginview is hidden when out of viewport

--- client/app/MainApp/login/loginview.coffee
+++ client/app/MainApp/login/loginview.coffee
@@ -7,6 +7,7 @@
   constructor:(options = {}, data)->

     {entryPoint} = KD.config
+    options.cssClass = 'hidden'

     super options, data

@@ -282,6 +283,7 @@

       @emit "LoginViewHidden"
       @hidden = yes
+      @hideTimer = @utils.wait 2000, => @setClass 'hidden'
       callback?()

     unless @hidden then do cb
@@ -289,15 +291,17 @@

   show:(callback)->

-    @setY 0
-
+    @utils.killWait @hideTimer
     cb = =>
       @emit "LoginViewShown"
       @hidden = no
       callback?()

-    unless @hidden then do cb
-    else @once "transitionend", cb
+    @unsetClass 'hidden'
+    @utils.defer =>
+      @setY 0
+      unless @hidden then do cb
+      else @once "transitionend", cb

   click:(event)->
     if $(event.target).is('.login-screen')


Improve messages selection

Improve messages selection

--- client/app/components/message-list.coffee
+++ client/app/components/message-list.coffee
@@ -21,8 +21,6 @@
 MessageList = React.createClass
     displayName: 'MessageList'

-    _selected: {}
-
     mixins: [RouterMixin]

     shouldComponentUpdate: (nextProps, nextState) ->
@@ -34,13 +32,22 @@
             loading: false
             filterFlag: false
             filterUnsead: false
+            selected: {}
+            allSelected: false
         }

     componentWillReceiveProps: (props) ->
         @setState loading: false
         if props.mailboxID isnt @props.mailboxID
-            @setState edited: false
-            @_selected = {}
+            @setState allSelected: false, edited: false, selected: {}
+        else
+            selected = @state.selected
+            Object.keys(selected).forEach (id) ->
+                if not props.messages.get(id)
+                    delete selected[id]
+            @setState selected: selected
+            if Object.keys(selected).length is 0
+                @setState allSelected: false, edited: false

     render: ->
         compact = @props.settings.get('listStyle') is 'compact'
@@ -53,15 +60,17 @@
                 isActive: isActive,
                 edited: @state.edited,
                 settings: @props.settings,
+                selected: @state.selected[id]?,
                 onSelect: (val) =>
+                    selected = _.clone @state.selected
                     if val
-                        @_selected[id] = val
+                        selected[id] = val
                     else
-                        delete @_selected[id]
-                    if Object.keys(@_selected).length > 0
-                        @setState edited: true
+                        delete selected[id]
+                    if Object.keys(selected).length > 0
+                        @setState edited: true, selected: selected
                     else
-                        @setState edited: false
+                        @setState allSelected: false, edited: false, selected: {}

         .toJS()
         nbMessages = parseInt @props.counterMessage, 10
@@ -84,7 +93,8 @@
             parameters: [@props.accountID, 'account']
             fullWidth: true

-        advanced = @props.settings.get('advanced')
+        advanced   = @props.settings.get('advanced')
+        nbSelected = if Object.keys(@state.selected).length > 0 then null else true

         toggleFilterFlag = =>
             filter = if @state.filterFlag then MessageFilter.ALL else MessageFilter.FLAGGED
@@ -162,6 +172,7 @@
                                 button
                                     className: 'btn btn-default trash',
                                     type: 'button',
+                                    disabled: null,
                                     onClick: @refresh,
                                         span
                                             className: 'fa fa-refresh'
@@ -175,8 +186,16 @@
                         if @state.edited
                             div className: 'btn-group btn-group-sm message-list-option',
                                 button
+                                    type: "button"
+                                    className: "btn btn-default " + classEdited
+                                    onClick: @toggleAll,
+                                        i className: 'fa fa-square-o'
+                        if @state.edited
+                            div className: 'btn-group btn-group-sm message-list-option',
+                                button
                                     className: 'btn btn-default trash',
                                     type: 'button',
+                                    disabled: nbSelected
                                     onClick: @onDelete,
                                         span
                                             className: 'fa fa-trash-o'
@@ -219,10 +238,23 @@
         LayoutActionCreator.refreshMessages()

     toggleEdited: ->
-        @setState edited: not @state.edited
+        if @state.edited
+            @setState allSelected: false, edited: false, selected: {}
+        else
+            @setState edited: true
+
+    toggleAll: ->
+        if @state.allSelected
+            @setState allSelected: false, edited: false, selected: {}
+        else
+            selected = {}
+            @props.messages.map (message, key) ->
+                selected[key] = true
+            .toJS()
+            @setState allSelected: true, edited: true, selected: selected

     onDelete: ->
-        selected = Object.keys @_selected
+        selected = Object.keys @state.selected
         if selected.length is 0
             alertError t 'list mass no message'
         else
@@ -235,7 +267,7 @@
                             window.cozyMails.messageNavigate()

     onMove: (args) ->
-        selected = Object.keys @_selected
+        selected = Object.keys @state.selected
         if selected.length is 0
             alertError t 'list mass no message'
         else
@@ -259,7 +291,7 @@
                             window.cozyMails.messageNavigate()

     onMark: (args) ->
-        selected = Object.keys @_selected
+        selected = Object.keys @state.selected
         if selected.length is 0
             alertError t 'list mass no message'
         else
@@ -281,7 +313,7 @@
                         alertError "#{t("message action mark ko")} #{error}"

     onConversation: (args) ->
-        selected = Object.keys @_selected
+        selected = Object.keys @state.selected
         if selected.length is 0
             alertError t 'list mass no message'
         else
@@ -359,11 +391,6 @@

     mixins: [RouterMixin]

-    getInitialState: ->
-        return {
-            selected: @props.message.get('selected') is true
-        }
-
     render: ->
         message = @props.message
         flags = message.get('flags')
@@ -419,9 +446,10 @@
                     div
                         className: 'avatar-wrapper',
                         input
+                            ref: 'select'
                             className: 'select',
                             type: 'checkbox',
-                            checked: @state.selected
+                            checked: @props.selected,
                             onChange: @onSelect
                         if avatar?
                             img className: 'avatar', src: avatar
@@ -436,13 +464,30 @@
                         i className: 'attach fa fa-paperclip'
                         i className: 'fav fa fa-star'

+    _doCheck: ->
+        # please don't ask me why this **** react needs this
+        if @props.selected
+            setTimeout =>
+                @refs.select.getDOMNode().checked = true
+            , 50
+        else
+            setTimeout =>
+                @refs.select.getDOMNode().checked = false
+            , 50
+    componentDidMount: ->
+        @_doCheck()
+    componentDidUpdate: ->
+        @_doCheck()
     onSelect: (e) ->
-        @props.onSelect(not @state.selected)
-        @setState selected: not @state.selected
+        @props.onSelect(not @props.selected)
+        e.preventDefault()
+        e.stopPropagation()

     onMessageClick: (event) ->
         if @props.edited
-            @onSelect event
+            @props.onSelect(not @props.selected)
+            event.preventDefault()
+            event.stopPropagation()
         else
             if not @props.settings.get('displayPreview')
                 event.preventDefault()


realtime: emit accountId with like realtime updates

--- client/app/lib/messageeventmanager.coffee
+++ client/app/lib/messageeventmanager.coffee
@@ -57,7 +57,7 @@
     like.actorsPreview.unshift accountOldId  if accountOldId not in like.actorsPreview
     like.isInteracted = yes  if whoami().getId() is accountOldId

-    message.emit "LikeAdded"
+    message.emit "LikeAdded", { accountId: accountOldId }
     message.emit "update"

@@ -73,7 +73,7 @@

     like.isInteracted = no  if whoami().getId() is accountOldId

-    message.emit "LikeRemoved"
+    message.emit "LikeRemoved", { accountId: accountOldId }
     message.emit "update"