summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/drakfloppy
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/standalone/drakfloppy')
-rwxr-xr-xperl-install/standalone/drakfloppy475
1 files changed, 215 insertions, 260 deletions
diff --git a/perl-install/standalone/drakfloppy b/perl-install/standalone/drakfloppy
index f2aa9378f..d9cc103c6 100755
--- a/perl-install/standalone/drakfloppy
+++ b/perl-install/standalone/drakfloppy
@@ -5,6 +5,7 @@
#
# Copyright (C) 2001-2003 MandrakeSoft
# Yves Duret
+# Thierry Vignaud
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -26,209 +27,178 @@ use strict;
use diagnostics;
use lib qw(/usr/lib/libDrakX);
-use standalone; #- warning, standalone must be loaded very first, for 'explanations'
-
+use standalone; #- warning, standalone must be loaded very first, for 'explanations'
use common;
-use my_gtk qw(:helpers);
-use ugtk qw(:helpers);
+use ugtk2 qw(:helpers :create :wrappers);
use detect_devices;
#- languages that can't be displayed with gtk1, so we unset translations
#- for them until this tool is ported to gtk2
-if ($ENV{LANGUAGE} =~ /\b(ar|he|hi|ta)/) { $ENV{LANGUAGE} = "C" };
+$ENV{LANGUAGE} = "C" if $ENV{LANGUAGE} =~ /\b(ar|he|hi|ta)/;
require_root_capability();
my $expert_mode = $::expert;
-# we have put here the list in order to do $list->clear() when we have to do
-my $fixed_font = Gtk::Gdk::Font->fontset_load(N("-misc-Fixed-Medium-r-*-*-*-140-*-*-*-*-*-*,*"));
-my $list = new_with_titles Gtk::CList(N("Module name"), N("Size"));
-my $window = my_gtk->new('drakfloppy');
+my $list_model = Gtk2::ListStore->new((Gtk2::GType->STRING) x 2);
+my $list = Gtk2::TreeView->new_with_model($list_model);
+each_index {
+ $list->append_column(my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i));
+ $col->set_min_width((200, 50)[$::i]);
+ # $col->set_alignment(1.0) if $::i == 1;
+} (N("Module name"), N("Size"));
+
+my $window = ugtk2->new('drakfloppy');
unless ($::isEmbedded) {
- $window->{rwindow}->signal_connect(delete_event => sub { my_gtk->exit(0) });
+ $window->{rwindow}->signal_connect(delete_event => sub { ugtk2->exit(0) });
$window->{rwindow}->set_title(N("drakfloppy"));
- $window->{rwindow}->set_policy(1, 1, 1);
- $window->{rwindow}->border_width(5);
+ $window->{rwindow}->set_border_width(5);
+
+ ### menus definition
+ # the menus are not shown but they provides shiny shortcut like C-q
+ create_factory_menu($window->{rwindow}, (
+ {
+ path => N("/_File"), type => '<Branch>' },
+ {
+ path => N("/File/_Quit"), accelerator => N("<control>Q"), callback => sub { ugtk2->exit(0) } },
+ )
+ );
}
-### menus definition
-# the menus are not shown
-# but they provides shiny shortcut like C-q
-my @menu_items = (
- { path => N("/_File"), type => '<Branch>' },
- { path => N("/File/_Quit"), accelerator => N("<control>Q"), callback => sub { my_gtk->exit(0) } },
- );
-ugtk::create_factory_menu($window->{rwindow}, @menu_items) unless $::isEmbedded;
-
-######### menus end
-
-my $global_vbox = new Gtk::VBox();
-
-$global_vbox->pack_start(new Gtk::Label(N("boot disk creation")), 0, 0, 0) unless $::isEmbedded;
######## up part
-my $up_vbox = new Gtk::VBox(0, 0);
# device part
-my $dev_hbox = new Gtk::HBox(1, 0);
-my $device_combo = new Gtk::Combo();
-my $device_button = new Gtk::Button(N("default"));
-
+my $device_combo = new Gtk2::Combo();
+$device_combo->entry->set_editable(0);
$device_combo->set_popdown_strings(map { "/dev/" . $_->{device} } detect_devices::floppies());
-$device_button->signal_connect(clicked => sub { $device_combo->entry->set_text("/dev/fd0") });
-$dev_hbox->pack_start(new Gtk::Label(N("device")), 0, 0, 0);
-$dev_hbox->pack_start($device_combo, 0, 0, 0);
-$dev_hbox->pack_start($device_button, 0, 0, 0);
-$up_vbox->pack_start($dev_hbox, 0, 0, 0);
# kernel part
-my $ker_hbox = new Gtk::HBox(1, 0);
-my $kernel_combo = new Gtk::Combo();
-my $kernel_button = new Gtk::Button(N("default"));
+my $kernel_combo = new Gtk2::Combo();
$kernel_combo->disable_activate();
-$kernel_combo->set_popdown_strings(do {
- opendir YREP, "/lib/modules" or die N("DrakFloppy Error: %s", $!);
- my @files_modules = grep !/^\.\.?$/, readdir YREP;
- closedir YREP;
- @files_modules;
-});
-#$kernel_combo->entry->set_text(`uname -r`);
-$kernel_combo->entry->signal_connect(changed => sub { change_tree($kernel_combo->entry->get_text()); $list->clear() });
-$kernel_button->signal_connect(clicked => sub { $kernel_combo->entry->set_text(chomp_(`uname -r`)); $list->clear() });
-
-$ker_hbox->pack_start(new Gtk::Label(N("kernel version")), 0, 0, 0);
-$ker_hbox->pack_start($kernel_combo, 0, 0, 0);
-$ker_hbox->pack_start($kernel_button, 0, 0, 0);
-$up_vbox->pack_start($ker_hbox, 0, 0, 5);
-
-# vbox part
-my $up_frame = new Gtk::Frame(N("General"));
-$up_frame->add($up_vbox);
-$global_vbox->pack_start($up_frame, 0, 0, 0);
-
-### expert mode
-my $expert_main_frame = new Gtk::Frame(N("Expert Area"));
-my $expert_dedans = new Gtk::VBox(0, 5);
-$expert_dedans->border_width(5);
-my $expert_button_frame = new Gtk::Frame(N("mkinitrd optional arguments"));
-my $expert_mod_frame = new Gtk::Frame(N("Add a module"));
-my $expert_pane = new Gtk::HPaned();
-$expert_pane->set_handle_size(10);
-$expert_pane->set_gutter_size(8);
-
-my $expert_button = new Gtk::Button("");
-$expert_button->signal_connect(clicked => sub {
- $expert_mode = !$expert_mode;
- toggle_expert_button();
-});
-
-my $expert_button_vbox = new Gtk::VBox(0, 5);
-my $expert_button_hbox = new Gtk::HBox(0, 5);
-my $expert_button_hbox2 = new Gtk::HBox(0, 5);
-my $force_button = new Gtk::ToggleButton(N("force"));
-my $needed_button = new Gtk::ToggleButton(N("if needed"));
-my $scsi_button = new Gtk::ToggleButton(N("omit scsi modules"));
-my $raid_button = new Gtk::ToggleButton(N("omit raid modules"));
-$expert_button_hbox->pack_start($force_button, 0, 0, 0);
-$expert_button_hbox->pack_start($raid_button, 0, 0, 0);
-
-$expert_button_hbox2->pack_start($needed_button, 0, 0, 0);
-$expert_button_hbox2->pack_start($scsi_button, 0, 0, 0);
-
-$expert_button_vbox->pack_start($expert_button_hbox, 0, 0, 0);
-$expert_button_vbox->pack_start($expert_button_hbox2, 0, 0, 0);
-$expert_button_frame->add($expert_button_vbox);
-$expert_dedans->pack_start($expert_button_frame, 0, 0, 0);
-$expert_mod_frame->add($expert_pane);
-$expert_dedans->pack_start($expert_mod_frame, 1, 1, 0);
-$expert_main_frame->add($expert_dedans);
-$global_vbox->pack_start($expert_main_frame, 1, 1, 0);
-
-### the tree
-
-# Create a ScrolledWindow for the tree
-my $tree_scrolled_win = new Gtk::ScrolledWindow();
-$tree_scrolled_win->set_usize(200, $::isEmbedded ? 0 : 175);
-$expert_pane->add1($tree_scrolled_win);
-$tree_scrolled_win->set_policy('automatic', 'automatic');
+$kernel_combo->set_popdown_strings(sort grep { !/^\.\.?$/ } all("/lib/modules"));
+$kernel_combo->entry->set_text(chomp_(`uname -r`));
+$kernel_combo->entry->signal_connect(changed => sub {
+ change_tree($kernel_combo->entry->get_text());
+ $list_model->clear();
+ });
+
# Create root tree
-my $tree = new Gtk::Tree();
-my $leaf;
-my $root_dir;
-$tree_scrolled_win->add_with_viewport($tree);
-$tree->set_selection_mode('single');
-$tree->set_view_mode('item');
+my $tree_model = Gtk2::TreeStore->new((Gtk2::GType->STRING) x 2);
+my $tree = Gtk2::TreeView->new_with_model($tree_model);
+#$tree->get_selection->set_mode('browse');
+$tree->set_headers_visible(0);
+$tree->append_column(my $textcolumn = Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0));
+#$tree->append_column(my $dummy_textcolumn = Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0));
+$tree->signal_connect('row-expanded', \&expand_tree);
+$tree->get_selection()->signal_connect('changed' => \&selected_tree);
+
fill_tree($kernel_combo->entry->get_text());
-# Create a ScrolledWindow for the list
-my $list_scrolled_win = new Gtk::ScrolledWindow(undef, undef);
-my $rmmod_button = new Gtk::Button(N("Remove a module"));
-my $expert_inside_pane2 = new Gtk::VBox(0, 0);
-my $list_selected_row;
-$expert_inside_pane2->pack_start($list_scrolled_win, 1, 1, 0);
-$expert_inside_pane2->pack_start($rmmod_button, 0, 0, 0);
-$expert_pane->add2($expert_inside_pane2);
-$list_scrolled_win->set_policy('automatic', 'automatic');
-$rmmod_button->signal_connect(clicked => sub { $list->remove($list_selected_row) });
+###
+my ($output, @modules);
+
# Create list box
########################################################## from here my $list
-$list->signal_connect(select_row => sub { (undef, $list_selected_row) = @_ });
-$list_scrolled_win->add($list);
-$list->set_column_justification(1, 'right');
-$list->set_column_width(0, 200);
-$list->set_column_width(1, 50);
-$list->set_selection_mode('single');
-$list->set_shadow_type('none');
-$list->show();
-
-### output
-my $output_frame = new Gtk::Frame(N("Output"));
-my $output = new Gtk::Text(undef, undef);
-my $vscrollbar = new Gtk::VScrollbar($output->vadj);
-my $output_hbox = new Gtk::HBox(0, 0);
-$output_hbox->border_width(5);
-$output_hbox->set_usize(30, 75);
-$output_hbox->pack_start($output, 1, 1, 0);
-$output_hbox->pack_start($vscrollbar, 0, 0, 0);
-$output_frame->add($output_hbox);
-$global_vbox->pack_start($output_frame, 1, 10, 0);
-
-### final buttons
-my $build_button = new Gtk::Button(N("Build the disk"));
-my $cancel_button = new Gtk::Button(N("Cancel"));
-my $fin_hbox = new Gtk::HBox(0, 0);
-$cancel_button->signal_connect(clicked => sub { my_gtk->exit(0) });
-$build_button->signal_connect(clicked => \&build_it);
-$fin_hbox->pack_end($cancel_button, 0, 0, 0);
-$fin_hbox->pack_end($build_button, 0, 0, 10);
-$fin_hbox->pack_end($expert_button, 0, 0, 10);
-$global_vbox->pack_start($fin_hbox, 0, 0, 0);
-
-### back to window
-$window->{window}->add($global_vbox);
+
+
+### main window
+$window->{window}->add(
+ gtkpack_(Gtk2::VBox->new,
+ if_($::isEmbedded, 0, new Gtk2::Label(N("boot disk creation"))),
+ 0, gtkadd(Gtk2::Frame->new(N("General")),
+ gtkpack__(new Gtk2::VBox(0, 0),
+ gtkpack__(new Gtk2::HBox(1, 0),
+ Gtk2::Label->new(N("device")),
+ $device_combo,
+ gtksignal_connect(Gtk2::Button->new(N("default")),
+ clicked => sub { $device_combo->entry->set_text("/dev/fd0") }),
+ ),
+ gtkpack__(new Gtk2::HBox(1, 0),
+ Gtk2::Label->new(N("kernel version")),
+ $kernel_combo,
+ gtksignal_connect(Gtk2::Button->new("default"),
+ clicked => sub {
+ $kernel_combo->entry->set_text(chomp_(`uname -r`));
+ $list_model->clear();
+ }),
+ ),
+ ),
+ ),
+ 1, gtkadd(my $expert_mod_frame = new Gtk2::Frame(N("Expert Area")),
+ gtkpack_(gtkset_border_width(Gtk2::VBox->new(0, 5), 5),
+ 0, gtkadd(Gtk2::Frame->new(N("mkinitrd optional arguments")),
+ gtkpack__(Gtk2::HBox->new(0, 5),
+ my $force_button = new Gtk2::ToggleButton(N("force")),
+ my $raid_button = new Gtk2::ToggleButton(N("omit raid modules")),
+ my $needed_button = new Gtk2::ToggleButton(N("if needed")),
+ my $scsi_button = new Gtk2::ToggleButton(N("omit scsi modules")),
+ ),
+ ),
+ 1, gtkadd(Gtk2::Frame->new(N("Add a module")),
+ create_hpaned(
+ gtkset_size_request(
+ create_scrolled_window($tree),
+ 200, $::isEmbedded ? 0 : 175),
+ gtkpack_(Gtk2::VBox->new(0, 0),
+ 1, gtkadd(Gtk2::ScrolledWindow->new,
+ $list
+ ),
+ 0, gtksignal_connect(Gtk2::Button->new(N("Remove a module")),
+ clicked => sub {
+ my $iter = ($list->get_selection->get_selected)[1];
+ return unless $iter;
+ $list_model->remove($iter);
+ }),
+ ),
+ ),
+ ),
+ ),
+ ),
+ 1, gtkadd(Gtk2::Frame->new(N("Output")),
+ gtkpack_(gtkset_size_request(
+ gtkset_border_width(
+ Gtk2::HBox->new(0, 0),
+ 5),
+ 30, 75),
+ 1, $output = new Gtk2::Text(undef, undef),
+ 0, Gtk2::VScrollbar->new($output->vadj),
+ ),
+ ),
+ 0, gtkpack__(new Gtk2::HBox(0, 0),
+ gtksignal_connect(Gtk2::Button->new(N("Cancel")),
+ clicked => sub { ugtk2->exit(0) }
+ ),
+ gtksignal_connect(Gtk2::Button->new(N("Build the disk")),
+ clicked => \&build_it
+ ),
+ gtksignal_connect(my $expert_button = Gtk2::Button->new(""),
+ clicked => sub {
+ $expert_mode = !$expert_mode;
+ toggle_expert_button();
+ }),
+ ),
+ ),
+ );
$window->{rwindow}->show_all();
toggle_expert_button();
-
$window->main;
-my_gtk->exit(0);
+ugtk2->exit(0);
sub toggle_expert_button {
if ($expert_mode) {
$expert_mod_frame->show();
- $expert_button_frame->show();
$expert_button->child->set(N("Normal Mode"));
} else {
$expert_mod_frame->hide();
- $expert_button_frame->hide();
$expert_button->child->set(N("Expert Mode"));
}
}
@@ -239,125 +209,110 @@ sub toggle_expert_button {
### Subroutines
sub fill_tree {
- ($root_dir) = @_;
- $root_dir = "/lib/modules/" . $root_dir;
- # Create root tree item widget
- $leaf = new_with_label Gtk::TreeItem($root_dir);
- $tree->append($leaf);
- $leaf->signal_connect('select', \&select_item, $root_dir);
- $leaf->set_user_data($root_dir);
-
- # Create the subtree
- if (has_sub_trees($root_dir)) {
- my $subtree = new Gtk::Tree();
- $leaf->set_subtree($subtree);
- $leaf->signal_connect('expand', \&expand_tree, $subtree);
- $leaf->signal_connect('collapse', \&collapse_tree);
- $leaf->expand();
- }
+ my ($root_dir) = @_;
+ $root_dir = "/lib/modules/" . $root_dir;
+ # Create root tree item widget
+ my $parent_iter = $tree_model->append_set(undef, [ 0 => $root_dir, 1 => $root_dir ]);
+
+ # Create the subtree
+ expand_tree($tree, $parent_iter, $tree_model->get_path($parent_iter)) if has_sub_trees($root_dir);
}
sub change_tree {
- $leaf->destroy();
- fill_tree(@_);
- $leaf->show();
+ $tree_model->clear;
+ fill_tree(@_);
}
+# Called whenever an item is clicked on the tree widget.
+sub selected_tree {
+ my ($select) = @_;
+ my ($model, $iter) = $select->get_selected();
+ return unless $model; # no real selection
+ my $file = $model->get($iter, 1);
+ $iter->free;
+
+ return if -d $file;
+
+ my $size = (lstat($file))[7];
+
+ return if member($file, @modules);
+ push @modules, $file;
+ $file =~ s|/lib/modules/.*?/||g;
+ $list_model->append_set([ 0 => $file, 1 => $size ])->free;
+}
+
+
# Callback for expanding a tree - find subdirectories, files and add them to tree
sub expand_tree {
- my ($item, $subtree) = @_;
-
- my $path;
- my $item_new;
- my $new_subtree;
-
- my $dir = $item->get_user_data();
-
- chdir($dir);
-
- foreach my $dir_entry (all(".")) {
- if (-d $dir_entry or $dir_entry =~ /\.o(\.gz)?$/) {
- $path = $dir . "/" . $dir_entry;
- $path =~ s|//|/|g;
- $item_new = new_with_label Gtk::TreeItem($dir_entry);
- $item_new->set_user_data($path);
- $item_new->signal_connect('select', \&select_item, $path);
- $subtree->append($item_new);
- $item_new->show();
-
- if (has_sub_trees($path)) {
- $new_subtree = new Gtk::Tree();
- $item_new->set_subtree($new_subtree);
- $item_new->signal_connect('expand', \&expand_tree, $new_subtree);
- $item_new->signal_connect('collapse', \&collapse_tree);
- }
- }
- }
- chdir("..");
- }
+ my ($tree, $parent_iter, $path) = @_;
+ my $dir = $tree_model->get($parent_iter, 1);
+ my $child = $tree_model->iter_children($parent_iter);
-# Callback for collapsing a tree -- removes the subtree
-sub collapse_tree {
- my ($item) = @_;
- my $subtree = new Gtk::Tree();
+ #- hackish: if first child has '' as name, then we need to expand on the fly
+ if ($child && $tree_model->get($child, 0) eq '') {
+ $tree_model->remove($child);
+ }
+ unless ($child && $tree_model->iter_has_child($parent_iter)) {
+ foreach my $dir_entry (all($dir)) {
+ my $entry_path = $dir . "/" . $dir_entry;
+ if (-d $entry_path || $dir_entry =~ /\.o(\.gz)?$/) {
+ $entry_path =~ s|//|/|g;
+
+ my $iter = $tree_model->append_set($parent_iter, [ 0 => $dir_entry, 1 => $entry_path ]);
+ #- hackery for partial displaying of trees, used in rpmdrake:
+ #- if leaf is void, we may create the parent and one child (to have the [+] in front of the parent in the ctree)
+ #- though we use '' as the label of the child; then rpmdrake will connect on tree_expand, and whenever
+ #- the first child has '' as the label, it will remove the child and add all the "right" children
+ $tree_model->append_set($iter, [ 0 => '' ])->free if has_sub_trees($entry_path);
+ }
+ }
+ }
+ $tree->expand_row($path, 0);
+}
- $item->remove_subtree();
- $item->set_subtree($subtree);
- $item->signal_connect('expand', \&expand_tree, $subtree);
- }
-# Called whenever an item is clicked on the tree widget.
-sub select_item {
- my ($widget, $file) = @_;
- return if -d $file;
- my $size = (lstat($file))[7];
- my $lr = $list->rows();
- my $i;
- $file =~ s|/lib/modules/.*?/||g;
- for ($i = 0; $i < $lr; $i++) {
- last if $file eq $list->get_text($i, 0);
- }
- print $file, "\n";
-
- $list->append($file, $size) if $i == $lr or $lr == 0;
-}
#-------------------------------------------------------------
# the function
#-------------------------------------------------------------
sub build_it {
- my $y;
- my $co = "/sbin/mkbootdisk --noprompt --verbose --device " . $device_combo->entry->get_text();
- if ($expert_mode) {
- $co .= " --mkinitrdargs -f" if $force_button->get_active;
- $co .= " --mkinitrdargs --ifneeded" if $needed_button->get_active;
- $co .= " --mkinitrdargs --omit-scsi-modules" if $scsi_button->get_active;
- $co .= " --mkinitrdargs --omit-raid-modules" if $raid_button->get_active;
- for (my $i = 0; $i < $list->rows(); $i++) {
- $y = $list->get_text($i, 0);
- $y =~ s|.*?/||g;
- $co .= " --mkinitrdargs --with=" . $y; #. "/usr/lib/" . $kernel_combo->entry->get_text() . "/" . $y;
+ my $y;
+ my $co = "/sbin/mkbootdisk --noprompt --verbose --device " . $device_combo->entry->get_text();
+ if ($expert_mode) {
+ $co .= " --mkinitrdargs -f" if $force_button->get_active;
+ $co .= " --mkinitrdargs --ifneeded" if $needed_button->get_active;
+ $co .= " --mkinitrdargs --omit-scsi-modules" if $scsi_button->get_active;
+ $co .= " --mkinitrdargs --omit-raid-modules" if $raid_button->get_active;
+ my $val;
+ $list_model->foreach(sub {
+ my ($model, $_path, $iter) = @_;
+ my $module = $model->get($iter, 0);
+ $module =~ s|.*?/||g;
+ $co .= " --mkinitrdargs --with=" . $y; #. "/usr/lib/" . $kernel_combo->entry->get_text() . "/" . $y;
+ return 0;
+ }, $val);
+ }
+ $co .= " " . $kernel_combo->entry->get_text();
+ $co .= " 2>&1 |";
+ create_dialog(N("Be sure a media is present for the device %s", $device_combo->entry->get_text()), 1) or return;
+ # we test if the media is present
+ test:
+ my $a = "dd count=1 if=/dev/null of=" . $device_combo->entry->get_text() . " 2>&1";
+ my $b = `$a`;
+ if ($b =~ /dd/) {
+ create_dialog(N("There is no medium or it is write-protected for device %s.\nPlease insert one.", $device_combo->entry->get_text()), 1) ? goto test : return 0;
}
- }
- $co .= " " . $kernel_combo->entry->get_text();
- $co .= " 2>&1 |";
- create_dialog(N("Be sure a media is present for the device %s", $device_combo->entry->get_text()), 1) or return;
-# we test if the media is present
- test:
- my $a = "dd count=1 if=/dev/null of=" . $device_combo->entry->get_text() . " 2>&1";
- my $b = `$a`;
- if ($b =~ /dd/) { create_dialog(N("There is no medium or it is write-protected for device %s.\nPlease insert one.", $device_combo->entry->get_text()), 1) ? goto test : return 0 }
- local *STATUS;
- open STATUS, $co or do { create_dialog(N("Unable to fork: %s", $!), 0); return };
- local $_;
- while (<STATUS>) {
- $output->insert($fixed_font, undef, undef, $_);
- }
- close STATUS or create_dialog(N("Unable to properly close mkbootdisk: \n %s \n %s", $!, $?), 0);
+ local *STATUS;
+ open STATUS, $co or do { create_dialog(N("Unable to fork: %s", $!), 0); return };
+ local $_;
+ while (<STATUS>) {
+ $output->insert(undef, undef, undef, $_);
+ }
+ close STATUS or create_dialog(N("Unable to properly close mkbootdisk: \n %s \n %s", $!, $?), 0);
- return (0);
+ return (0);
}
####
@@ -372,8 +327,8 @@ sub has_sub_trees {
foreach my $file (glob_("$dir/*")) {
return 1 if -d $file or $file =~ /\.o(\.gz)?$/;
+
}
- return (0);
+ return 0;
}
-