glimmer-dsl-swt 4.20.13.7 → 4.20.13.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e20d1ff3e84168b2937444cf859e28249a859789adbd3d24993e0087a51addf5
4
- data.tar.gz: 272ffc7415a569b4ef635da5919128399c19cd2077c11b280e34357d37b1ac09
3
+ metadata.gz: 59508a178a1694489ba4ec995672f08a0997b01c8ebaeb39cecd2db250d0f88b
4
+ data.tar.gz: 9610a96bf71aa15a581dedda77f9c11942286f1ff5f7ac96369624c97a798f28
5
5
  SHA512:
6
- metadata.gz: 1057ae99a81ceb633ff2ed436ef150036ab3475ca663a4b0514173f6af1e136ec0a4a822898ef3c320b4f285180d65ef1c254a245959e219667e12beca1353a6
7
- data.tar.gz: 7d62cc987fe8bbd20972d33ef7a7331844635f28f3d19273d99e4305ded7bdb60f1cb2d2b021d27f598f916fb501689017ff90208864026e5345a219778b7717
6
+ metadata.gz: 1f2219231093b33e6c32637dd2a6ee2249e3c64daf3f92355c57ab170d15c6bfd4930d540c3703c0a4c926ff9e6c322ddc4dd119938be9bc23ccf19935c84675
7
+ data.tar.gz: 98c6a6e4b2f26fde8d9741eb04054866c145366c27a728343f71f6f960c5eba411fa127167101da055d96241b3c66fb7c7d8dbba91256fa9688d694165158cdc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.20.13.8
4
+
5
+ - Glimmer Klondike Solitaire elaborate sample
6
+
3
7
  ### 4.20.13.7
4
8
 
5
9
  - Support accepting ImageProxy objects in Canvas Shape DSL (not just image paths)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.20.13.7
1
+ 4.20.13.8
Binary file
@@ -0,0 +1,86 @@
1
+ require 'glimmer-dsl-swt'
2
+
3
+ require_relative 'klondike_solitaire/model/game'
4
+
5
+ require_relative 'klondike_solitaire/view/action_panel'
6
+ require_relative 'klondike_solitaire/view/tableau'
7
+
8
+ class KlondikeSolitaire
9
+ include Glimmer::UI::CustomShell
10
+
11
+ PLAYING_CARD_WIDTH = 50
12
+ PLAYING_CARD_HEIGHT = 80
13
+ PLAYING_CARD_SPACING = 5
14
+
15
+ ## Add options like the following to configure CustomShell by outside consumers
16
+ #
17
+ # options :title, :background_color
18
+ # option :width, default: 320
19
+ # option :height, default: 240
20
+
21
+ ## Use before_body block to pre-initialize variables to use in body
22
+ #
23
+ #
24
+ before_body {
25
+ @game = Model::Game.new
26
+ Display.app_name = 'Glimmer Klondike Solitaire'
27
+ @display = display {
28
+ on_about {
29
+ display_about_dialog
30
+ }
31
+ on_preferences {
32
+ display_about_dialog
33
+ }
34
+ }
35
+ }
36
+
37
+ ## Use after_body block to setup observers for widgets in body
38
+ #
39
+ # after_body {
40
+ #
41
+ # }
42
+
43
+ ## Add widget content inside custom shell body
44
+ ## Top-most widget must be a shell or another custom shell
45
+ #
46
+ body {
47
+ shell(:no_resize) {
48
+ row_layout(:vertical) {
49
+ fill true
50
+ center true
51
+ }
52
+ minimum_size 400, 400
53
+ text "Glimmer Klondike Solitaire"
54
+ background :dark_green
55
+
56
+ action_panel(game: @game)
57
+ tableau(game: @game) {
58
+ layout_data {
59
+ width 380
60
+ height 400
61
+ }
62
+ }
63
+
64
+ menu_bar {
65
+ menu {
66
+ text '&Help'
67
+ menu_item {
68
+ text '&About...'
69
+ on_widget_selected {
70
+ display_about_dialog
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ def display_about_dialog
79
+ message_box(body_root) {
80
+ text 'About'
81
+ message "Glimmer Klondike Solitaire\nGlimmer DSL for SWT Elaborate Sample"
82
+ }.open
83
+ end
84
+ end
85
+
86
+ KlondikeSolitaire.launch
@@ -0,0 +1,60 @@
1
+ class KlondikeSolitaire
2
+ module Model
3
+ class ColumnPile
4
+ include Glimmer::DataBinding::ObservableModel
5
+ attr_reader :count
6
+
7
+ def initialize(game, count)
8
+ @game = game
9
+ @count = count
10
+ reset!
11
+ end
12
+
13
+ def reset!
14
+ playing_cards.clear
15
+ populate!(count.times.map { @game.deck.pop })
16
+ notify_observers(:playing_cards)
17
+ end
18
+
19
+ # this method does not validate
20
+ def populate!(new_playing_cards)
21
+ new_playing_cards.each_with_index do |playing_card, index|
22
+ playing_card.hidden = true if index < (new_playing_cards.size - 1)
23
+ playing_cards.push(playing_card)
24
+ end
25
+ end
26
+
27
+ # this method validates that playing card fits at the bottom of the column (opposite color and one number smaller)
28
+ # throws an error if it does not fit
29
+ def add!(new_playing_card)
30
+ bottom_card = playing_cards.last
31
+ if (playing_cards.empty? && new_playing_card.rank == 13) ||
32
+ (new_playing_card.color != bottom_card.color && new_playing_card.rank == (bottom_card.rank - 1))
33
+ playing_cards.push(new_playing_card)
34
+ else
35
+ raise "Cannot add #{new_playing_card} to #{self}"
36
+ end
37
+ end
38
+
39
+ def remove!(card)
40
+ remove_cards_starting_at(playing_cards.index(card)).tap do |result|
41
+ playing_cards.last&.hidden = false
42
+ end
43
+ end
44
+
45
+ def remove_cards_starting_at(index)
46
+ removed_cards = playing_cards[index...playing_cards.size]
47
+ playing_cards[index...playing_cards.size] = []
48
+ removed_cards
49
+ end
50
+
51
+ def playing_cards
52
+ @playing_cards ||= []
53
+ end
54
+
55
+ def to_s
56
+ "Column Pile #{count} (#{playing_cards.map {|card| "#{card.rank}#{card.suit.to_s[0].upcase}"}.join(" | ")})"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+ class KlondikeSolitaire
2
+ module Model
3
+ class DealingPile
4
+ DEALING_INITIAL_COUNT = 24
5
+
6
+ def initialize(game)
7
+ @game = game
8
+ reset!
9
+ end
10
+
11
+ def reset!
12
+ playing_cards.clear
13
+ DEALING_INITIAL_COUNT.times { playing_cards << @game.deck.pop }
14
+ end
15
+
16
+ def deal!
17
+ playing_card = playing_cards.shift
18
+ if playing_card.nil?
19
+ @game.dealt_pile.playing_cards.each do |a_playing_card|
20
+ playing_cards << a_playing_card
21
+ end
22
+ @game.dealt_pile.playing_cards.clear
23
+ else
24
+ @game.dealt_pile.push!(playing_card)
25
+ end
26
+ end
27
+
28
+ def playing_cards
29
+ @playing_cards ||= []
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ class KlondikeSolitaire
2
+ module Model
3
+ class DealtPile
4
+ def initialize(game)
5
+ @game = game
6
+ end
7
+
8
+ def reset!
9
+ playing_cards.clear
10
+ end
11
+
12
+ def push!(playing_card)
13
+ playing_cards.push(playing_card)
14
+ end
15
+
16
+ def remove!(card)
17
+ playing_cards.delete(card)
18
+ end
19
+
20
+ def playing_cards
21
+ @playing_cards ||= []
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,40 @@
1
+ class KlondikeSolitaire
2
+ module Model
3
+ class FoundationPile
4
+ attr_reader :suit
5
+
6
+ def initialize(game, suit)
7
+ @game = game
8
+ @suit = suit
9
+ reset!
10
+ end
11
+
12
+ def reset!
13
+ playing_cards.clear
14
+ end
15
+
16
+ # adds a card
17
+ # validates if it is a card that belongs to the suit
18
+ def add!(playing_card)
19
+ if playing_card.suit == suit &&
20
+ (
21
+ (playing_cards.empty? && playing_card.rank == 1) ||
22
+ playing_card.rank == (playing_cards.last.rank + 1)
23
+ )
24
+ playing_cards.push(playing_card)
25
+ else
26
+ raise "Cannot add #{playing_card} to #{self}"
27
+ end
28
+ end
29
+
30
+ def playing_cards
31
+ @playing_cards ||= []
32
+ end
33
+
34
+ def to_s
35
+ "Foundation Pile #{suit} (#{playing_cards.map {|card| "#{card.rank}#{card.suit.to_s[0].upcase}"}.join(" | ")})"
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'playing_card'
2
+ require_relative 'dealt_pile'
3
+ require_relative 'dealing_pile'
4
+ require_relative 'column_pile'
5
+ require_relative 'foundation_pile'
6
+
7
+ class KlondikeSolitaire
8
+ module Model
9
+ class Game
10
+ COLUMN_PILE_COUNT = 7
11
+
12
+ attr_reader :deck, :dealing_pile, :dealt_pile, :column_piles, :foundation_piles
13
+
14
+ def initialize
15
+ @deck = new_deck
16
+ @dealt_pile = DealtPile.new(self)
17
+ @dealing_pile = DealingPile.new(self)
18
+ @column_piles = COLUMN_PILE_COUNT.times.map {|n| ColumnPile.new(self, n + 1)}
19
+ @foundation_piles = PlayingCard::SUITS.map {|suit| FoundationPile.new(self, suit)}
20
+ end
21
+
22
+ def restart!
23
+ @deck = new_deck
24
+ @dealt_pile.reset!
25
+ @dealing_pile.reset!
26
+ @column_piles.each(&:reset!)
27
+ @foundation_piles.each(&:reset!)
28
+ end
29
+
30
+ private
31
+
32
+ def new_deck
33
+ PlayingCard.deck.shuffle
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,50 @@
1
+ class KlondikeSolitaire
2
+ module Model
3
+ class PlayingCard
4
+ SUITS = [:spades, :hearts, :clubs, :diamonds]
5
+ BLACK_SUITS = [:spades, :clubs]
6
+ RED_SUITS = [:hearts, :diamonds]
7
+ RANK_COUNT = 13
8
+
9
+ class << self
10
+ def deck
11
+ suit_decks.flatten
12
+ end
13
+
14
+ def suit_decks
15
+ SUITS.map do |suit|
16
+ suit_deck(suit)
17
+ end
18
+ end
19
+
20
+ def suit_deck(suit)
21
+ 1.upto(RANK_COUNT).map do |rank|
22
+ new(rank, suit)
23
+ end
24
+ end
25
+ end
26
+
27
+ attr_reader :rank, :suit
28
+ attr_accessor :hidden
29
+ alias hidden? hidden
30
+
31
+ def initialize(rank, suit, hidden = false)
32
+ @rank = rank
33
+ @suit = suit
34
+ @hidden = hidden
35
+ end
36
+
37
+ def color
38
+ if BLACK_SUITS.include?(suit)
39
+ :black
40
+ elsif RED_SUITS.include?(suit)
41
+ :red
42
+ end
43
+ end
44
+
45
+ def to_s
46
+ "Playing Card #{rank}#{suit.to_s[0].upcase}"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ class KlondikeSolitaire
2
+ module View
3
+ class ActionPanel
4
+ include Glimmer::UI::CustomWidget
5
+
6
+ option :game
7
+
8
+ body {
9
+ composite {
10
+ grid_layout(1, false) {
11
+ margin_width 0
12
+ margin_height 0
13
+ }
14
+
15
+ background :dark_green
16
+
17
+ button {
18
+ layout_data :center, :center, true, false
19
+
20
+ text 'Restart Game'
21
+
22
+ on_widget_selected {
23
+ game.restart!
24
+ }
25
+ }
26
+ }
27
+ }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,66 @@
1
+ require_relative '../model/column_pile'
2
+
3
+ require_relative 'playing_card'
4
+
5
+ class KlondikeSolitaire
6
+ module View
7
+ class ColumnPile
8
+ include Glimmer::UI::CustomShape
9
+
10
+ IMAGE_EMPTY = image(50, 80) {
11
+ rectangle(0, 0, 50, 80) {
12
+ background :dark_green
13
+
14
+ rectangle(0, 0, 49, 79, 15, 15) {
15
+ foreground :gray
16
+ }
17
+ }
18
+ }
19
+
20
+ options :pile_x, :pile_y, :model
21
+
22
+ after_body {
23
+ observe(model, 'playing_cards.last.hidden') do
24
+ build_column_pile(model.playing_cards)
25
+ end
26
+ build_column_pile(model.playing_cards)
27
+ }
28
+
29
+ body {
30
+ shape(pile_x, pile_y) {
31
+ on_drop do |drop_event|
32
+ begin
33
+ card_shape = drop_event.dragged_shape.get_data('custom_shape')
34
+ card = card_shape.model
35
+ model.add!(card)
36
+ card_parent_pile = card_shape.parent_pile
37
+ card_source_model = card_parent_pile.model
38
+ cards = card_source_model.remove!(card)
39
+ if cards.is_a?(Array) # if it is a column pile
40
+ cards[1..-1].each do |card|
41
+ model.add!(card)
42
+ end
43
+ end
44
+ drop_event.dragged_shape.dispose
45
+ rescue => e
46
+ # pd e
47
+ drop_event.doit = false
48
+ end
49
+ end
50
+ }
51
+ }
52
+
53
+ def build_column_pile(playing_cards)
54
+ body_root.shapes.to_a.each(&:dispose)
55
+ current_parent = body_root
56
+ playing_cards.each_with_index do |card, i|
57
+ current_parent.content {
58
+ current_parent = playing_card(card_x: 0, card_y: 20, model: card, parent_pile: self) {
59
+ drag_source true unless card.hidden?
60
+ }.body_root
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,36 @@
1
+ require_relative '../model/dealing_pile'
2
+
3
+ require_relative 'empty_playing_card'
4
+ require_relative 'hidden_playing_card'
5
+
6
+ class KlondikeSolitaire
7
+ module View
8
+ class DealingPile
9
+ include Glimmer::UI::CustomShape
10
+
11
+ options :pile_x, :pile_y, :model
12
+
13
+ after_body {
14
+ observe(model, 'playing_cards.empty?') do |empty_value|
15
+ body_root.shapes.to_a.each(&:dispose)
16
+ if empty_value
17
+ body_root.content {
18
+ empty_playing_card
19
+ }
20
+ else
21
+ body_root.content {
22
+ hidden_playing_card
23
+ }
24
+ end
25
+ end
26
+ }
27
+
28
+ body {
29
+ shape(pile_x, pile_y) {
30
+ hidden_playing_card
31
+ }
32
+ }
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../model/dealt_pile'
2
+
3
+ require_relative 'empty_playing_card'
4
+ require_relative 'playing_card'
5
+
6
+ class KlondikeSolitaire
7
+ module View
8
+ class DealtPile
9
+ include Glimmer::UI::CustomShape
10
+
11
+ options :pile_x, :pile_y, :model
12
+
13
+ after_body do
14
+ observe(model, 'playing_cards.empty?') do |empty_value|
15
+ if empty_value
16
+ body_root.shapes.to_a.dup.each(&:dispose)
17
+ body_root.content {
18
+ empty_playing_card
19
+ }
20
+ else
21
+ body_root.content {
22
+ playing_card(model: model.playing_cards.last, parent_pile: self) {
23
+ drag_source true
24
+ }
25
+ }
26
+ end
27
+ end
28
+ end
29
+
30
+ body {
31
+ shape(pile_x, pile_y) {
32
+ empty_playing_card
33
+ }
34
+ }
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ class KlondikeSolitaire
2
+ module View
3
+ class EmptyPlayingCard
4
+ include Glimmer::UI::CustomShape
5
+
6
+ option :suit
7
+
8
+ body {
9
+ rectangle(0, 0, 49, 79, 15, 15) {
10
+ foreground :gray
11
+
12
+ if suit
13
+ text {
14
+ string suit.to_s[0].upcase
15
+ x :default
16
+ y :default
17
+ is_transparent true
18
+ }
19
+ end
20
+ }
21
+ }
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ require_relative '../model/playing_card'
2
+ require_relative '../model/foundation_pile'
3
+
4
+ class KlondikeSolitaire
5
+ module View
6
+ class FoundationPile
7
+ include Glimmer::UI::CustomShape
8
+
9
+ options :pile_x, :pile_y, :game, :suit
10
+
11
+ attr_accessor :current_image, :model
12
+
13
+ before_body {
14
+ self.current_image = image(50, 80) {empty_playing_card(suit: suit)}
15
+ self.model = game.foundation_piles[Model::PlayingCard::SUITS.index(suit)]
16
+ }
17
+
18
+ after_body {
19
+ observe(model, 'playing_cards.last') do |last_card|
20
+ if last_card
21
+ body_root.content {
22
+ playing_card(model: last_card)
23
+ }
24
+ else
25
+ body_root.clear_shapes
26
+ body_root.content {
27
+ empty_playing_card(suit: suit)
28
+ }
29
+ end
30
+ end
31
+ }
32
+
33
+ body {
34
+ shape(pile_x, pile_y) {
35
+ empty_playing_card(suit: suit)
36
+
37
+ on_drop do |drop_event|
38
+ begin
39
+ # TODO make sure one cannot drag a column pile of cards here
40
+ card_shape = drop_event.dragged_shape.get_data('custom_shape')
41
+ card = card_shape.model
42
+ card_parent_pile = card_shape.parent_pile
43
+ card_source_model = card_parent_pile.model
44
+ raise 'Cannot accept multiple cards' if card_source_model.playing_cards.index(card) != (card_source_model.playing_cards.size - 1)
45
+ model.add!(card)
46
+ card_source_model.remove!(card)
47
+ drop_event.dragged_shape.dispose
48
+ rescue => e
49
+ # pd e
50
+ drop_event.doit = false
51
+ end
52
+ end
53
+ }
54
+ }
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,19 @@
1
+ class KlondikeSolitaire
2
+ module View
3
+ class HiddenPlayingCard
4
+ include Glimmer::UI::CustomShape
5
+
6
+ body {
7
+ rectangle(0, 0, 49, 79, 15, 15) {
8
+ background :red
9
+
10
+ # border
11
+ rectangle(0, 0, 49, 79, 15, 15) {
12
+ foreground :black
13
+ }
14
+ }
15
+ }
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ class KlondikeSolitaire
2
+ module View
3
+ class PlayingCard
4
+ include Glimmer::UI::CustomShape
5
+
6
+ options :card_x, :card_y, :model, :parent_pile
7
+
8
+ before_body {
9
+ self.card_x ||= 0
10
+ self.card_y ||= 0
11
+ }
12
+
13
+ body {
14
+ rectangle(card_x, card_y, 49, 79, 15, 15) {
15
+ background model.hidden ? :red : :white
16
+
17
+ # border
18
+ rectangle(0, 0, 49, 79, 15, 15) {
19
+ foreground :black
20
+ }
21
+
22
+ unless model.hidden?
23
+ text {
24
+ string model ? "#{model.rank} #{model.suit.to_s[0].upcase}" : ""
25
+ x 5
26
+ y 5
27
+ foreground model ? model.color : :transparent
28
+ }
29
+ end
30
+ }
31
+ }
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,41 @@
1
+ require_relative 'dealing_pile'
2
+ require_relative 'dealt_pile'
3
+ require_relative 'column_pile'
4
+ require_relative 'foundation_pile'
5
+
6
+ require_relative '../model/game'
7
+
8
+ class KlondikeSolitaire
9
+ module View
10
+ class Tableau
11
+ include Glimmer::UI::CustomWidget
12
+
13
+ option :game
14
+
15
+ body {
16
+ canvas {
17
+ background :dark_green
18
+
19
+ # row 1
20
+ @foundation_piles = Model::PlayingCard::SUITS.each_with_index.map do |suit, i|
21
+ foundation_pile(pile_x: i*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, game: game, suit: suit)
22
+ end
23
+ @dealt_pile = dealt_pile(pile_x: 5*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, model: game.dealt_pile)
24
+ @dealing_pile = dealing_pile(pile_x: 6*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, model: game.dealing_pile)
25
+
26
+ # row 2
27
+ @column_piles = 7.times.map do |n|
28
+ column_pile(pile_x: n*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: PLAYING_CARD_HEIGHT + PLAYING_CARD_SPACING, model: game.column_piles[n])
29
+ end
30
+
31
+ on_mouse_up do |event|
32
+ if @dealing_pile.body_root.include?(event.x, event.y)
33
+ game.dealing_pile.deal!
34
+ end
35
+ end
36
+ }
37
+ }
38
+
39
+ end
40
+ end
41
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-swt
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.20.13.7
4
+ version: 4.20.13.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
@@ -545,6 +545,22 @@ files:
545
545
  - samples/elaborate/contact_manager/contact.rb
546
546
  - samples/elaborate/contact_manager/contact_manager_presenter.rb
547
547
  - samples/elaborate/contact_manager/contact_repository.rb
548
+ - samples/elaborate/klondike_solitaire.rb
549
+ - samples/elaborate/klondike_solitaire/model/column_pile.rb
550
+ - samples/elaborate/klondike_solitaire/model/dealing_pile.rb
551
+ - samples/elaborate/klondike_solitaire/model/dealt_pile.rb
552
+ - samples/elaborate/klondike_solitaire/model/foundation_pile.rb
553
+ - samples/elaborate/klondike_solitaire/model/game.rb
554
+ - samples/elaborate/klondike_solitaire/model/playing_card.rb
555
+ - samples/elaborate/klondike_solitaire/view/action_panel.rb
556
+ - samples/elaborate/klondike_solitaire/view/column_pile.rb
557
+ - samples/elaborate/klondike_solitaire/view/dealing_pile.rb
558
+ - samples/elaborate/klondike_solitaire/view/dealt_pile.rb
559
+ - samples/elaborate/klondike_solitaire/view/empty_playing_card.rb
560
+ - samples/elaborate/klondike_solitaire/view/foundation_pile.rb
561
+ - samples/elaborate/klondike_solitaire/view/hidden_playing_card.rb
562
+ - samples/elaborate/klondike_solitaire/view/playing_card.rb
563
+ - samples/elaborate/klondike_solitaire/view/tableau.rb
548
564
  - samples/elaborate/login.rb
549
565
  - samples/elaborate/mandelbrot_fractal.rb
550
566
  - samples/elaborate/meta_sample.rb