Subversion Repositories DevTools

Rev

Rev 2439 | Rev 2478 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2439 Rev 2450
Line 71... Line 71...
71
my $opt_ignoreProjectBaseErrors;
71
my $opt_ignoreProjectBaseErrors;
72
my $opt_ignoreMakeProjectErrors;
72
my $opt_ignoreMakeProjectErrors;
73
my $opt_delete;
73
my $opt_delete;
74
my $opt_recentAge = 14;             # Days
74
my $opt_recentAge = 14;             # Days
75
my $opt_relabel = 0;
75
my $opt_relabel = 0;
-
 
76
my $opt_protected;
-
 
77
my $opt_useSvn = 1;
-
 
78
my $opt_testRmDatabase;
76
 
79
 
77
################################################################################
80
################################################################################
78
#   List of Projects Suffixes and Branch Names to be used within SVN
81
#   List of Projects Suffixes and Branch Names to be used within SVN
79
#
82
#
80
#       Name        - Name of branch for the project
83
#       Name        - Name of branch for the project
Line 130... Line 133...
130
    '.pxxx.sydddd'  => '.syd',
133
    '.pxxx.sydddd'  => '.syd',
131
    '.oslo'         => '.oso',
134
    '.oslo'         => '.oso',
132
    '.osl'          => '.oso',
135
    '.osl'          => '.oso',
133
);
136
);
134
 
137
 
135
my @excludeFromImport = (
-
 
136
 
-
 
137
    # 22-Oct-12: Excluded on request from Kasun Sirikumara
-
 
138
    # Pending VSS work
-
 
139
    'agency_website',
-
 
140
    'alx',
-
 
141
    'alx-api',
-
 
142
    'cardholder_website',
-
 
143
    'loginmodule-ad',
-
 
144
    'ols-enquiry',
-
 
145
    'ols-enquiry-api',
-
 
146
    'olsrpc4j',
-
 
147
    'orca-middleware',
-
 
148
    'orca-middleware-api',
-
 
149
    'orca-salesEngine',
-
 
150
    'orca-web-api',
-
 
151
    'orca-web-utils',
-
 
152
    'TestPaymentGateway',
-
 
153
    'tgen4j',
-
 
154
    'web-cd-client',
-
 
155
 
-
 
156
 
-
 
157
    # 05-Nov-12: Pending fixup for include.txt files that escape the VOB
-
 
158
    #
-
 
159
#    'ddu_app_manager',
-
 
160
#    'ddu_dog',
-
 
161
#    'ddu_dog_lib',
-
 
162
#    'ddu_fim',
-
 
163
#    'ddu_logging_lib',
-
 
164
#    'ddu_management',
-
 
165
#    'ddu_mccain',
-
 
166
#    'ddu_mon',
-
 
167
#    'ddu_rcu',
-
 
168
#    'ddu_status_logging',
-
 
169
    
-
 
170
);
-
 
171
 
-
 
172
my %specialPackages = (
138
my %specialPackages = (
173
    'core_devl'           =>  ',all,protected,',
139
    'core_devl'           =>  ',all,protected,',
174
    'daf_utils_mos'       => ',flat,',
140
    'daf_utils_mos'       => ',flat,',
175
    'mos_packager'        => ',all,',
141
    'mos_packager'        => ',all,',
176
    'cfmgr-cfmgr'         => ',flat,',
142
    'cfmgr-cfmgr'         => ',flat,',
Line 182... Line 148...
182
    'db_cda'              => ',utf8,',
148
    'db_cda'              => ',utf8,',
183
    'CommandServer'       => ',IgnoreMakeProject,',
149
    'CommandServer'       => ',IgnoreMakeProject,',
184
    'TDSExporterControl'  => ',IgnoreMakeProject,',
150
    'TDSExporterControl'  => ',IgnoreMakeProject,',
185
    'cdagui'              => ',IgnoreMakeProject,',
151
    'cdagui'              => ',IgnoreMakeProject,',
186
 
152
 
-
 
153
    'daf_bvt'                 => ',IgnoreMakeProject,',  # Look OK
-
 
154
    'daf_dll'                 => ',IgnoreMakeProject,',  # MakeProject not in used makefile
-
 
155
    'PFTPi'                   => ',IgnoreMakeProject,',  # Looks OK
-
 
156
    'PFTPu'                   => ',IgnoreMakeProject,',  # Looks OK
-
 
157
    'WinCEBlocker'            => ',IgnoreMakeProject,',  # Looks OK
-
 
158
    'WinCEDeviceAutoInject'   => ',IgnoreMakeProject,',  # Looks OK
-
 
159
    'WinCEReboot'             => ',IgnoreMakeProject,',  # Looks OK
187
 
160
 
188
    # Need to be handled in a special manner
-
 
189
    # Not done by this utility
-
 
190
    #
-
 
191
    'linux_drivers_eb5600'  => ',protected,',
-
 
192
    'linux_drivers_viper'   => ',protected,',
-
 
193
    'linux_drivers_cobra'   => ',protected,',
-
 
194
    'linux_drivers_bcp4600' => ',protected,',
-
 
195
    'linux_drivers_etx86'   => ',protected,',
-
 
196
    'linux_drivers_tp5600'  => ',protected,',
-
 
197
 
-
 
198
# Not in the ukHops migration at the moment
-
 
199
    'cs'                        => ',protected,',
-
 
200
 
-
 
201
    'DBA-Common'                => ',protected,',
-
 
202
    'DBA-DatabaseInstall'       => ',protected,',
-
 
203
    'DBA-ExternalPerlModules'   => ',protected,',
-
 
204
    'DBA-OraUserBuild'          => ',protected,',
-
 
205
    'DBA-OST'                   => ',protected,',
-
 
206
#    'orahops-install'           => ',protected,',
-
 
207
#    'orahops-patch'             => ',protected,',
-
 
208
#    'orahops-ssw-install'       => ',protected,',
-
 
209
#    'orahops-ssw-patch'         => ',protected,',
-
 
210
# End of ukHops migration exclussion
-
 
211
 
161
 
212
    'ftp'                   => 'SetProjectBase,',
162
    'ftp'                   => 'SetProjectBase,',
213
    'ddu_app_manager'       => 'SetProjectBase,',
163
    'ddu_app_manager'       => 'SetProjectBase,',
-
 
164
    'ddu_afc'               => 'SetProjectBase,IgnoreMakeProject,',
214
 
165
 
215
    'icl'                   => 'IgnoreProjectBase,',
166
    'icl'                   => 'IgnoreProjectBase,',
216
    'itso'                  => 'IgnoreProjectBase,',
167
    'itso'                  => 'IgnoreProjectBase,',
217
    'daf_osa_mos'           => 'IgnoreProjectBase,',
168
#    'daf_osa_mos'           => 'IgnoreProjectBase,',
218
    'daf_utils_mos'         => 'IgnoreProjectBase,',
169
    'daf_utils_mos'         => 'IgnoreProjectBase,',
219
    'itso_ud'               => 'IgnoreProjectBase,',
170
    'itso_ud'               => 'IgnoreProjectBase,',
220
#    'mos_api'               => 'IgnoreProjectBase,',
171
#    'mos_api'               => 'IgnoreProjectBase,',
221
#    'mos_fonts'             => 'IgnoreProjectBase,',
172
#    'mos_fonts'             => 'IgnoreProjectBase,',
222
#    'sntp'                  => 'IgnoreProjectBase,',
173
#    'sntp'                  => 'IgnoreProjectBase,',
Line 327... Line 278...
327
                "log!"          => \$opt_log,
278
                "log!"          => \$opt_log,
328
                "delete!"       => \$opt_delete,
279
                "delete!"       => \$opt_delete,
329
                "postimage!"    => \$opt_postimage,
280
                "postimage!"    => \$opt_postimage,
330
                'workdir:s'     => \$opt_workDir,
281
                'workdir:s'     => \$opt_workDir,
331
                'relabel!'      => \$opt_relabel,
282
                'relabel!'      => \$opt_relabel,
-
 
283
                'svn!'          => \$opt_useSvn,
-
 
284
                'testRmDatabase'    => \$opt_testRmDatabase,
332
                );
285
                );
333
 
286
 
334
#
287
#
335
#   Process help and manual options
288
#   Process help and manual options
336
#
289
#
Line 350... Line 303...
350
Error("Specify a package as 'name'" ) unless ( defined $ARGV[0] );
303
Error("Specify a package as 'name'" ) unless ( defined $ARGV[0] );
351
EnvImport('GBE_RM_URL');
304
EnvImport('GBE_RM_URL');
352
$cwd = Getcwd();
305
$cwd = Getcwd();
353
 
306
 
354
#
307
#
-
 
308
#   Allow use of the test database
-
 
309
#   Defaut is live data, but some error recovery stuff can be done via
-
 
310
#   the test database.
-
 
311
#
-
 
312
if ( $opt_testRmDatabase )
-
 
313
{
-
 
314
    Warning ("Using Test Database");
-
 
315
    $ENV{GBE_RM_USERNAME} = 'RELEASE_MANAGER';
-
 
316
    $ENV{GBE_RM_PASSWORD} = 'RELEASE_MANAGER';
-
 
317
    $ENV{GBE_RM_LOCATION} = 'jdbc:oracle:thin:@auperaora07.vix.local:1521:RELMANU1';
-
 
318
}
-
 
319
 
-
 
320
#
355
#   Init the pruning mode
321
#   Init the pruning mode
356
#
322
#
357
setPruneMode( $opt_pruneModeString || 'ripple');
323
setPruneMode( $opt_pruneModeString || 'ripple');
358
 
324
 
359
#
325
#
Line 484... Line 450...
484
 
450
 
485
    #
451
    #
486
    #   Going to do serious work
452
    #   Going to do serious work
487
    #   Need to ensure we have more arguments
453
    #   Need to ensure we have more arguments
488
    #
454
    #
-
 
455
    if ( $opt_protected )
-
 
456
    {
-
 
457
        Warning("Protected Package not transferred: $packageNames[0] - $opt_protected",
-
 
458
                "See cc2svn_protected.txt for details");
-
 
459
        exit 0;
-
 
460
    }
-
 
461
 
489
    if ( $noTransfer )
462
    if ( $noTransfer )
490
    {
463
    {
491
        Warning("Protected Package not transferred: $packageNames[0]");
464
        Warning("Protected Package not transferred: $packageNames[0]",
-
 
465
                "Configured within this program");
492
        exit 0;
466
        exit 0;
493
    }
467
    }
494
 
468
 
495
    #
469
    #
496
    #   Perform all the work in a package specific subdirectory
470
    #   Perform all the work in a package specific subdirectory
Line 650... Line 624...
650
    if ( $packageNames[0] =~ m'^br_applet_' )
624
    if ( $packageNames[0] =~ m'^br_applet_' )
651
    {
625
    {
652
      $opt_flat = 1 unless defined $opt_flat;
626
      $opt_flat = 1 unless defined $opt_flat;
653
    }
627
    }
654
 
628
 
655
    foreach  ( @excludeFromImport )
-
 
656
    {
-
 
657
         $specialPackages{$_} .= 'protected,';
-
 
658
    }
-
 
659
 
-
 
660
    if ( exists $specialPackages{$packageNames[0]} )
629
    if ( exists $specialPackages{$packageNames[0]} )
661
    {
630
    {
662
        my $data = $specialPackages{$packageNames[0]};
631
        my $data = $specialPackages{$packageNames[0]};
663
        if ( index( $data, ',all' ) >= 0) {
632
        if ( index( $data, ',all' ) >= 0) {
664
            setPruneMode('none') unless (defined $opt_pruneModeString);
633
            setPruneMode('none') unless (defined $opt_pruneModeString);
Line 1642... Line 1611...
1642
    #   Delete the created view
1611
    #   Delete the created view
1643
    #   Its just a directory, so delete it
1612
    #   Its just a directory, so delete it
1644
    #
1613
    #
1645
    if ( $data{ViewRoot} && -d $data{ViewRoot})
1614
    if ( $data{ViewRoot} && -d $data{ViewRoot})
1646
    {
1615
    {
1647
        if ( !$opt_reuse || ($rv && ($rv != 4 && $rv != 12 )) )
1616
        if ( !$opt_reuse || ($rv && ($rv != 4 && $rv != 12 && $rv != 5 )) )
1648
        {
1617
        {
1649
            Message ("Delete View: $data{ViewRoot}");
1618
            Message ("Delete View: $data{ViewRoot}");
1650
            RmDirTree ($data{ViewRoot} );
1619
            RmDirTree ($data{ViewRoot} );
1651
        }
1620
        }
1652
        else
1621
        else
Line 1694... Line 1663...
1694
#                   $entry              - Package entry to process
1663
#                   $entry              - Package entry to process
1695
#
1664
#
1696
# Returns         : Error Code
1665
# Returns         : Error Code
1697
#                         0 - All is well
1666
#                         0 - All is well
1698
#                       <10 - Recoverable error
1667
#                       <10 - Recoverable error
-
 
1668
#                               1 - Bad VCS Tag
-
 
1669
#                               2 - No Files in the extracted view
-
 
1670
#                                   Label not found
-
 
1671
#                                   Failed to extract files from CC
-
 
1672
#                                   No Files in the extracted view after labeling dirs
-
 
1673
#                               3 - Deadwood
-
 
1674
#                               4 - Bad usage of ProjectBase detected
-
 
1675
#                                   Use of MakeProject detected
-
 
1676
#                               5  - Subversion Import disabled
1699
#                       >10 - Fatal error
1677
#                       >10 - Fatal error
1700
#
1678
#
1701
sub newPackageVersionBody
1679
sub newPackageVersionBody
1702
{
1680
{
1703
    my ($data, $entry) = @_;
1681
    my ($data, $entry) = @_;
Line 1853... Line 1831...
1853
            Message ("Adjust Base Dir: $testDir");
1831
            Message ("Adjust Base Dir: $testDir");
1854
            $data->{adjustedPath} = $data->{ViewPath};
1832
            $data->{adjustedPath} = $data->{ViewPath};
1855
            $data->{ViewPath} = $testDir;
1833
            $data->{ViewPath} = $testDir;
1856
        }
1834
        }
1857
    }
1835
    }
-
 
1836
    Message ("BaseDir: $data->{ViewPath}");
1858
    
1837
    
1859
    #
1838
    #
1860
    #   Some really ugly packages make use of a Jats feature called 'SetProjectBase'
1839
    #   Some really ugly packages make use of a Jats feature called 'SetProjectBase'
1861
    #   Detect such packages as we will need to handle them differently
1840
    #   Detect such packages as we will need to handle them differently
1862
    #   Can't really handle it on the fly
1841
    #   Can't really handle it on the fly
1863
    #   All we can do is detect it and report it - at the moment
1842
    #   All we can do is detect it and report it - at the moment
1864
    #
1843
    #
1865
    if (detectProjectBaseUsage($data, $cc_path) )
1844
    if (detectProjectBaseUsage($data) )
1866
    {
1845
    {
1867
        unless ( $opt_ignoreProjectBaseErrors )
1846
        unless ( $opt_ignoreProjectBaseErrors )
1868
        {
1847
        {
1869
            $data->{BadProjectBase}++;
1848
            $data->{BadProjectBase}++;
1870
            $data->{errStr} = 'Bad usage of ProjectBase detected';
1849
            $data->{errStr} = 'Bad usage of ProjectBase detected';
Line 1928... Line 1907...
1928
    #
1907
    #
1929
    #   Have a CC view
1908
    #   Have a CC view
1930
    #   Now we can create the SVN package and branching point before we
1909
    #   Now we can create the SVN package and branching point before we
1931
    #   import the CC data into SVN
1910
    #   import the CC data into SVN
1932
    #
1911
    #
-
 
1912
    if ( !$opt_useSvn )
-
 
1913
    {
-
 
1914
            $data->{errStr} = 'Subversion Import disabled';
-
 
1915
            return 5;
-
 
1916
    }
-
 
1917
 
1933
    my @args;
1918
    my @args;
1934
 
1919
 
1935
    #
1920
    #
1936
    #   Calculate args for functions
1921
    #   Calculate args for functions
1937
    #
1922
    #
Line 2693... Line 2678...
2693
# Function        : detectProjectBaseUsage
2678
# Function        : detectProjectBaseUsage
2694
#
2679
#
2695
# Description     : Detect and report usage of the SetProjectBase directive
2680
# Description     : Detect and report usage of the SetProjectBase directive
2696
#
2681
#
2697
# Inputs          : $data               - Ref to a hash of bits
2682
# Inputs          : $data               - Ref to a hash of bits
2698
#                   $cc_path            - Packages cc_path
-
 
2699
#
2683
#
2700
# Returns         : true    - Bad usage (Really good usage not detected)
2684
# Returns         : true    - Bad usage (Really good usage not detected)
2701
#                   false   - Good usage detected
2685
#                   false   - Good usage detected
2702
#
2686
#
2703
sub detectProjectBaseUsage
2687
sub detectProjectBaseUsage
2704
{
2688
{
2705
    my ($data, $cc_path) = @_;
2689
    my ($data) = @_;
2706
    my $retval = 0;
2690
    my $retval = 0;
2707
    my $eSuf = $opt_ignoreProjectBaseErrors ? '' : 'Error';
2691
    my $eSuf = $opt_ignoreProjectBaseErrors ? '' : 'Error';
2708
 
2692
 
2709
    #
2693
    #
2710
    #   Find makefile.pl
2694
    #   Find makefile.pl
Line 2715... Line 2699...
2715
    my $definitionError = 0;
2699
    my $definitionError = 0;
2716
 
2700
 
2717
    my $search = JatsLocateFiles->new("--Recurse=1",
2701
    my $search = JatsLocateFiles->new("--Recurse=1",
2718
                                       "--FilterIn=makefile.pl",
2702
                                       "--FilterIn=makefile.pl",
2719
                                       );
2703
                                       );
2720
    my @makefiles = $search->search($data->{ViewRoot});
2704
    my @makefiles = $search->search($data->{ViewPath});
2721
    foreach my $file ( @makefiles )
2705
    foreach my $file ( @makefiles )
2722
    {
2706
    {
2723
        if ( open( my $fh, '<', "$data->{ViewRoot}/$file" ) )
2707
        if ( open( my $fh, '<', "$data->{ViewPath}/$file" ) )
2724
        {
2708
        {
2725
            while ( <$fh> )
2709
            while ( <$fh> )
2726
            {
2710
            {
2727
                s~\s+$~~;
2711
                s~\s+$~~;
2728
                s~^\s+~~;
2712
                s~^\s+~~;
Line 2738... Line 2722...
2738
                if ( m~^SetProjectBase~ )
2722
                if ( m~^SetProjectBase~ )
2739
                {
2723
                {
2740
                    $definesProjectBase++;
2724
                    $definesProjectBase++;
2741
                    $data->{DefinesProjectBase}++;
2725
                    $data->{DefinesProjectBase}++;
2742
                    Warning ("Package initialises SetProjectBase:",
2726
                    Warning ("Package initialises SetProjectBase:",
2743
                             "Line: " . $_,
2727
                             "Line : " . $_,
2744
                             "Root: " . "$data->{ViewRoot}",
2728
                             "Root : " . "$data->{ViewRoot}",
-
 
2729
                             "Path : " . "$data->{ViewPath}",
2745
                             "File: " . "$data->{ViewRoot}/$file",
2730
                             "File : " . "$data->{ViewPath}/$file",
2746
                            );
2731
                            );
2747
 
2732
 
2748
                    # The only problem is if the user attempts to escape
2733
                    # The only problem is if the user attempts to escape
2749
                    # from the root of the view.
2734
                    # from the root of the view.
2750
                    #
2735
                    #
Line 2755... Line 2740...
2755
                    # Locate the build.pl file
2740
                    # Locate the build.pl file
2756
                    # This is the basis for for the directive
2741
                    # This is the basis for for the directive
2757
                    #
2742
                    #
2758
                    my $blevel;
2743
                    my $blevel;
2759
                    my @bpaths = split ('/', $file );
2744
                    my @bpaths = split ('/', $file );
-
 
2745
                    my $buildFile;
2760
                    while ( @bpaths )
2746
                    while ( @bpaths )
2761
                    {
2747
                    {
2762
                        $bpaths[-1] = 'build.pl';
2748
                        $bpaths[-1] = 'build.pl';
2763
                        my $bfile = join '/', @bpaths ;
2749
                        my $bfile = join '/', @bpaths ;
2764
                        if ( -f "$data->{ViewRoot}/$bfile" )
2750
                        $buildFile = "$data->{ViewPath}/$bfile";
-
 
2751
                        if ( -f $buildFile )
2765
                        {
2752
                        {
2766
                            $blevel = scalar @bpaths;
2753
                            $blevel = scalar @bpaths;
2767
                            last;
2754
                            last;
2768
                        }
2755
                        }
2769
                        pop @bpaths;
2756
                        pop @bpaths;
Line 2776... Line 2763...
2776
                    }
2763
                    }
2777
                    else
2764
                    else
2778
                    {
2765
                    {
2779
                        #
2766
                        #
2780
                        #   Determine the depth of the view root
2767
                        #   Determine the depth of the view root
2781
                        #   This is given by cc_path, but cc_path has a leading /
-
 
2782
                        #
2768
                        #
-
 
2769
                        Warning ("Build: $buildFile");
2783
                        my @cpaths = split ('/', $cc_path );
2770
                        my $countPath = ($data->{ViewPath} =~ tr~/~/~);
2784
                        my $clevel = (scalar @cpaths) - 1;
2771
                        my $countBuild = ($buildFile =~ tr~/~/~);
2785
                        my $max_up = $blevel - $clevel - 1;
2772
                        my $max_up = $countBuild - $countPath -1;
2786
 
2773
 
2787
                        m~--Up=(\d+)~i;
2774
                        m~--Up=(\d+)~i;
2788
                        my $ulevel = $1;
2775
                        my $ulevel = $1;
2789
                        if ( defined $ulevel )
2776
                        if ( defined $ulevel )
2790
                        {
2777
                        {
Line 2794... Line 2781...
2794
#print "--- blevel: $blevel\n";
2781
#print "--- blevel: $blevel\n";
2795
#print "--- bpaths: @bpaths\n";
2782
#print "--- bpaths: @bpaths\n";
2796
#print "--- ulevel: $ulevel\n";
2783
#print "--- ulevel: $ulevel\n";
2797
#print "--- paths: @paths\n";
2784
#print "--- paths: @paths\n";
2798
#print "--- plevel: $plevel\n";
2785
#print "--- plevel: $plevel\n";
2799
#print "--- cpaths: @cpaths\n";
-
 
2800
#print "--- clevel: $clevel\n";
-
 
2801
#print "--- max_up: $max_up\n";
2786
#print "--- max_up: $max_up\n";
2802
 
2787
 
2803
                            if ( $ulevel > $max_up )
2788
                            if ( $ulevel > $max_up )
2804
                            {
2789
                            {
2805
                                Warning ("SetProjectBase escapes view. MaxUp: $max_up, Up: $ulevel");
2790
                                Warning ("SetProjectBase escapes view. MaxUp: $max_up, Up: $ulevel");
Line 3958... Line 3943...
3958
        unless ( keys(%ScmRepoMap) >= 0 );
3943
        unless ( keys(%ScmRepoMap) >= 0 );
3959
 
3944
 
3960
    $opt_vobMap = $ScmRepoMap{$packageNames}{repo}
3945
    $opt_vobMap = $ScmRepoMap{$packageNames}{repo}
3961
        if (exists $ScmRepoMap{$packageNames});
3946
        if (exists $ScmRepoMap{$packageNames});
3962
 
3947
 
-
 
3948
    $opt_protected = $ScmRepoMap{$packageNames}{protected}
-
 
3949
        if (exists $ScmRepoMap{$packageNames}{protected});
-
 
3950
 
3963
    #
3951
    #
3964
    #   Free the memory
3952
    #   Free the memory
3965
    #
3953
    #
3966
    %ScmRepoMap = ();
3954
    %ScmRepoMap = ();
3967
 
3955
 
Line 4345... Line 4333...
4345
    -[no]log           - Write output to log file. Def: -nolog
4333
    -[no]log           - Write output to log file. Def: -nolog
4346
    -[no]postimage     - Create image after transger: Def: -post
4334
    -[no]postimage     - Create image after transger: Def: -post
4347
    -workdir=path      - Use for temp storage (def:/work)
4335
    -workdir=path      - Use for temp storage (def:/work)
4348
    -delete            - Delete SVN package before test
4336
    -delete            - Delete SVN package before test
4349
    -[no]relabel       - Attempt to relabel dirs in packages that don't extract
4337
    -[no]relabel       - Attempt to relabel dirs in packages that don't extract
-
 
4338
    -testRmDatabase    - Use test database
4350
 
4339
 
4351
=head1 OPTIONS
4340
=head1 OPTIONS
4352
 
4341
 
4353
=over 8
4342
=over 8
4354
 
4343