MODULE display !----------------------------------------------------------------------- ! NAME ! display ! ! DESCRIPTION ! Contains wrappers to print information. ! ! AUTHORS & DATE ! JB Clement, 12/2025 ! ! NOTES ! !----------------------------------------------------------------------- ! DEPENDENCIES ! ------------ use, intrinsic :: iso_fortran_env, only: stdout => output_unit use, intrinsic :: iso_fortran_env, only: stderr => error_unit use, intrinsic :: iso_fortran_env, only: stdin => input_unit use numerics, only: dp, di, li, k4, minieps ! DECLARATION ! ----------- implicit none ! PARAMETERS ! ---------- integer(di), parameter :: LVL_ERR = 0_di ! Only errors integer(di), parameter :: LVL_WRN = 1_di ! Warnings integer(di), parameter :: LVL_NFO = 2_di ! Information (default) integer(di), parameter :: LVL_DBG = 3_di ! Debug character(11), parameter, private :: logfile_name = 'pem_run.log' character(128), protected, private :: curr_dir = ' ' ! Current directory character(32), protected, private :: username = ' ' ! User name character(32), protected, private :: hostname = ' ' ! Machine/station name integer(di), protected, private :: verbosity_lvl = LVL_NFO logical(k4), protected, private :: out2term = .true. ! Flag to output to terminal logical(k4), protected, private :: out2log = .false. ! Flag to output to log file integer(di), protected, private :: logunit = -1_di ! Log file unit contains !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !======================================================================= SUBROUTINE set_display_config(out2term_in,out2log_in,verbosity_lvl_in) !----------------------------------------------------------------------- ! NAME ! set_display_config ! ! DESCRIPTION ! Setter for 'display' configuration parameters. ! ! AUTHORS & DATE ! JB Clement, 03/2026 ! ! NOTES ! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! ARGUMENTS ! --------- logical(k4), intent(in) :: out2term_in, out2log_in integer(di), intent(in) :: verbosity_lvl_in ! LOCAL VARIABLES ! --------------- integer(di) :: ierr character(100) :: msg ! CODE ! ---- out2term = out2term_in out2log = out2log_in verbosity_lvl = verbosity_lvl_in call print_msg('out2term = '//merge('true ','false',out2term),LVL_NFO) call print_msg('out2log = '//merge('true ','false',out2log),LVL_NFO) write(msg,'(a,i1)') 'verbosity_lvl = ',verbosity_lvl call print_msg(msg,LVL_NFO) if (verbosity_lvl < 0 .or. verbosity_lvl > 3) then write(stderr,'(a,i5,a)') '[ERROR] Stopping in "'//__FILE__//'" at line ',__LINE__,'.' write(stderr,'(a)') '[ERROR] Reason: ''verbosity_lvl'' outside admissible range [0,3]!' write(stderr,'(a)') '[ERROR] Houston, we have a problem! Error code = 1' error stop 1 end if if (out2log) then open(newunit = logunit,file = logfile_name,status = 'replace',form = 'formatted',action = 'write',iostat = ierr) if (ierr /= 0) then write(stderr,'(a,i5,a)') '[ERROR] Stopping in "'//__FILE__//'" at line ',__LINE__,'.' write(stderr,'(a)') '[ERROR] Reason: error opening file "'//logfile_name//'"!' write(stderr,'(a,i3)') '[ERROR] Houston, we have a problem! Error code = ',ierr error stop ierr endif endif if (.not. out2term .and. .not. out2log) write(stdout,*) 'Warning: no output is set!' END SUBROUTINE set_display_config !======================================================================= !======================================================================= SUBROUTINE print_ini() !----------------------------------------------------------------------- ! NAME ! print_ini ! ! DESCRIPTION ! Print the initial display for the PEM. ! ! AUTHORS & DATE ! JB Clement, 12/2025 ! ! NOTES ! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! LOCAL VARIABLES ! --------------- character(8) :: date character(10) :: time character(5) :: zone character(100) :: msg integer(di), dimension(8) :: values ! CODE ! ---- call print_msg(' * . . + . * . + . . . ',LVL_NFO) call print_msg(' + _______ ________ ____ ____ * + ',LVL_NFO) call print_msg(' + . * |_ __ \|_ __ ||_ \ / _| . *',LVL_NFO) call print_msg(' . . | |__) | | |_ \_| | \/ | * * . ',LVL_NFO) call print_msg(' . | ___/ | _| _ | |\ /| | . . ',LVL_NFO) call print_msg('. * * _| |_ _| |__/ | _| |_\/_| |_ * ',LVL_NFO) call print_msg(' + |_____| |________||_____||_____| + . ',LVL_NFO) call print_msg(' . * . * . + * . + .',LVL_NFO) ! Some user info call date_and_time(date,time,zone,values) call getcwd(curr_dir) call getlog(username) call hostnm(hostname) call print_msg('',LVL_NFO) call print_msg('********* PEM information *********',LVL_NFO) call print_msg('+ User : '//trim(username),LVL_NFO) call print_msg('+ Machine : '//trim(hostname),LVL_NFO) call print_msg('+ Directory: '//trim(curr_dir),LVL_NFO) write(msg,'(a,i2,a,i2,a,i4)') '+ Date : ',values(3),'/',values(2),'/',values(1) call print_msg(msg,LVL_NFO) write(msg,'(a,i2,a,i2,a,i2,a)') '+ Time : ',values(5),':',values(6),':',values(7) call print_msg(msg,LVL_NFO) call print_msg('',LVL_NFO) call print_msg('********* Initialization *********',LVL_NFO) END SUBROUTINE print_ini !======================================================================= !======================================================================= SUBROUTINE print_end(i_pem_run,n_yr_run,n_yr_sim,dur_secs,pem_ini_date,r_plnt2earth_yr) !----------------------------------------------------------------------- ! NAME ! print_end ! ! DESCRIPTION ! Print the ending display for the PEM. ! ! AUTHORS & DATE ! JB Clement, 01/2026 ! ! NOTES ! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! ARGUMENTS ! --------- real(dp), intent(in) :: n_yr_run, n_yr_sim, dur_secs, pem_ini_date, r_plnt2earth_yr integer(di), intent(in) :: i_pem_run ! LOCAL VARIABLES ! --------------- character(100) :: msg ! CODE ! ---- call print_msg('',LVL_NFO) call print_msg('****** PEM final information *******',LVL_NFO) write(msg,'(a,i0,a,f16.4,a)') '+ The run PEM #',i_pem_run,' achieved ', n_yr_run, ' Planetary years, completed in '//format_duration(dur_secs)//'.' call print_msg(msg,LVL_NFO) write(msg,'(a,f16.4,a,f16.4,a)') '+ The workflow has achieved ', n_yr_sim, ' Planetary years =', n_yr_sim*r_plnt2earth_yr, ' Earth years.' call print_msg(msg,LVL_NFO) write(msg,'(a,f16.4,a)') '+ The reached date is now ', (pem_ini_date + n_yr_sim)*r_plnt2earth_yr, ' Earth years.' call print_msg(msg,LVL_NFO) call print_msg('+ PEM: so far, so good!',LVL_NFO) call print_msg('************************************',LVL_NFO) call but_why(n_yr_run) ! Close log file if (out2log) close(logunit) END SUBROUTINE print_end !======================================================================= !======================================================================= SUBROUTINE print_msg(message,lvl) !----------------------------------------------------------------------- ! NAME ! print_msg ! ! DESCRIPTION ! Print a message (string) based on verbosity. ! ! AUTHORS & DATE ! JB Clement, 03/2026 ! ! NOTES ! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! ARGUMENTS ! --------- character(*), intent(in) :: message integer(di), intent(in) :: lvl ! LOCAL VARIABLES ! --------------- character(:), allocatable :: prefix integer(di) :: outunit ! CODE ! ---- ! Filter based on verbosity if (lvl > verbosity_lvl) return ! Prefix selection select case (lvl) case (LVL_ERR) prefix = '[ERROR] ' case (LVL_WRN) prefix = '[WARNING] ' case (LVL_NFO) prefix = '' case (LVL_DBG) prefix = '[DEBUGGING] ' case default write(stderr,'(a,i5,a)') '[ERROR] Stopping in "'//__FILE__//'" at line ',__LINE__,'.' write(stderr,'(a)') '[ERROR] Reason: unknown verbosity level for the message!' write(stderr,'(a)') '[ERROR] Houston, we have a problem! Error code = 1' error stop 1 end select ! Terminal output if (out2term) then if (lvl == LVL_ERR) then outunit = stderr else outunit = stdout end if write(outunit,'(a)') prefix//message end if ! Log file output if (out2log) write(logunit,'(a)') prefix//message END SUBROUTINE print_msg !======================================================================= !======================================================================= FUNCTION format_duration(secs) RESULT(str) !----------------------------------------------------------------------- ! NAME ! format_duration ! ! DESCRIPTION ! Converts a duration in seconds into a compact Xd HH:MM:SS format. ! ! AUTHORS & DATE ! JB Clement, 01/2026 ! ! NOTES ! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! ARGUMENTS ! --------- real(dp), intent(in) :: secs ! LOCAL VARIABLES ! --------------- integer(di) :: days, hours, minutes, seconds character(:), allocatable :: str character(32) :: tmp ! Work buffer ! CODE ! ---- days = int(secs/86400._dp,di) hours = int(mod(secs,86400._dp)/3600._dp,di) minutes = int(mod(secs,3600._dp)/60._dp,di) seconds = int(mod(secs,60._dp),di) if (days > 0_li) then write(tmp,'(i0,"d ",i2.2,":",i2.2,":",i2.2)') days, hours, minutes, seconds else write(tmp,'(i2.2,":",i2.2,":",i2.2)') hours, minutes, seconds end if str = trim(adjustl(tmp)) END FUNCTION format_duration !======================================================================= !======================================================================= SUBROUTINE but_why(n_yr_run) !----------------------------------------------------------------------- ! NAME ! but_why ! ! DESCRIPTION ! Print a cool surprise. ! ! AUTHORS & DATE ! JB Clement, 02/2026 ! ! NOTES ! \(^o^)/ ! A rare egg may be hidden somewhere in this module... True trainers ! will know better than to consult an AI to hatch it. !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! ARGUMENTS ! --------- real(dp), intent(in) :: n_yr_run ! LOCAL VARIABLES ! --------------- integer(di), dimension(5,50), parameter :: exeggcute = transpose(reshape([ & 87,104,97,116,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 68,69,65,68,66,69,65,84,45,80,76,65,78,69,84,32,105,115,32,101,118,111,108,118,105,110,103,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 84,97,45,100,97,32,46,46,46,32,84,97,45,100,97,32,46,46,46,32,84,97,45,100,97,32,46,46,46,32,84,97,32,116,97,45,100,97,32,116,97,45,100,97,33,0,0,0,0,0,0, & 67,111,110,103,114,97,116,117,108,97,116,105,111,110,115,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 89,111,117,114,32,68,69,65,68,66,69,65,84,45,80,76,65,78,69,84,32,101,118,111,108,118,101,100,32,105,110,116,111,32,70,65,66,85,76,79,85,83,45,80,76,65,78,69,84,33 & ],[50,5])) integer(di), dimension(20,42), parameter :: exeggutor = transpose(reshape([ & 73,32,119,97,110,110,97,32,98,101,32,116,104,101,32,118,101,114,121,32,98,101,115,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 76,105,107,101,32,110,111,32,109,111,100,101,108,32,101,118,101,114,32,119,97,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 84,111,32,98,117,105,108,100,32,116,104,101,109,32,114,105,103,104,116,44,32,116,104,97,116,226,128,153,115,32,109,121,32,114,101,97,108,32,116,101,115,116,0,0, & 84,111,32,115,105,109,117,108,97,116,101,32,116,104,101,109,32,105,115,32,109,121,32,99,97,117,115,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 73,32,119,105,108,108,32,116,114,97,118,101,108,32,103,114,105,100,115,32,97,110,100,32,108,97,110,100,115,0,0,0,0,0,0,0,0,0,0,0,0,0, & 70,114,111,109,32,99,111,114,101,32,116,111,32,115,107,121,32,115,111,32,119,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 84,101,97,99,104,32,112,108,97,110,101,116,115,32,104,111,119,32,116,111,32,117,110,100,101,114,115,116,97,110,100,0,0,0,0,0,0,0,0,0,0,0, & 84,104,101,32,112,104,121,115,105,99,115,32,100,101,101,112,32,105,110,115,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 80,76,65,78,69,84,83,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 71,111,116,116,97,32,109,111,100,101,108,32,116,104,101,109,32,97,108,108,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 73,116,226,128,153,115,32,115,99,105,101,110,99,101,32,97,110,100,32,99,111,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 73,32,107,110,111,119,32,105,116,226,128,153,115,32,109,121,32,99,97,108,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 80,76,65,78,69,84,83,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 70,114,111,109,32,100,117,115,116,32,116,111,32,103,108,111,119,105,110,103,32,115,112,104,101,114,101,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 87,105,116,104,32,116,105,109,101,32,97,110,100,32,114,101,115,111,108,118,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, & 73,226,128,153,108,108,32,101,118,111,108,118,101,32,116,104,101,109,32,116,104,114,111,117,103,104,32,121,101,97,114,115,0,0,0,0,0,0,0,0,0,0, & 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,226,128,148,32,74,66,67,0,0,0,0 & ],[42,20])) real(dp), parameter :: first_gen = 151._dp character(256), dimension(59) :: why_not character(256), dimension(11) :: surprise integer(di) :: i ! CODE ! ---- why_not(37) = '⠀⠀⠀⠀⠈⢧⣭⠡⣤⢿⣿⣟⣷⡀⠀⢧⣻⡇⠘⣿⣟⡇⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⢿⣿⣿⣷⣤⣈⠙⠿⠿⣿⣿⣿⣥⣯⣤⣾⡿⠚⠁⠀⢻⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(12) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠹⡀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣽⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(55) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠓⠦⣤⣀⠀⠉⠉⠉⠀⠀⠉⠉⠉⠍⠀⠀⣀⣤⠴⠀⠉⠛⠂⢿⣷⣦⣌⣙⠛⠻⠿⠿⠿⠷⠙⠛⢁⣴⣿⣷⡇⠀' why_not(4) = '⠀⠀⠀⠀⢀⡴⠚⡉⠍⢉⣉⣉⡁⠒⢂⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(29) = '⠀⠀⢀⣠⣶⠶⣶⣶⣶⣶⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(46) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡎⢇⢻⣿⣇⠘⠆⠱⢄⠀⠙⢿⣦⣈⠻⣿⣮⣛⣷⣄⠑⠶⣶⣦⣐⣮⣽⣿⣿⣿⣯⣶⣾⠻⡿⢟⡹⠃⠀⢁⠀⠀⠀⣠⣶⠇⡀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(8) = '⠀⠀⠀⠀⠀⠱⡠⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(21) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠉⠛⠋⠛⢟⡚⠍⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠴⡀⠀⠀⠀⠀' why_not(3) = ' ' why_not(41) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡄⠻⣿⣄⠙⣿⣷⡹⣦⡈⠻⣿⣷⡌⠙⢿⣷⣦⣀⠂⢄⣀⡀⠀⠀⠀⡉⠲⠶⠶⠟⠻⠿⣷⣾⣿⣿⣱⠟⠉⠉⠐⢀⣴⢯⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(18) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠺⣑⠮⡝⢷⡞⡘⢎⠼⡙⢬⠓⡬⠣⢄⠩⢐⠡⡘⡰⢭⣞⡿⠋⠀⠀⠀⠀⠀⠀⠀⠢⠀⠀⠀⠀⠀⠀⠀⠀' why_not(52) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠂⠀⠀⠀⠀⠀⠀⠛⢿⣿⣷⡽⡢⠙⢿⣿⣿⣿⣶⣤⣀⠀⠬⢄⣀⣀⣠⠔⢁⣾⣿⠇⣰⡄⢿⢀⡏⡇' why_not(9) = '⠀⠀⠀⠀⠀⠀⠳⡡⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(33) = '⠀⠸⡏⣾⣿⡄⢻⣿⣿⢱⣿⠁⡔⠋⠉⠉⠐⠀⣩⡴⠋⢹⠁⢸⣿⣜⢿⡌⢻⣦⣿⣷⣄⠙⠦⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(1) = trim(confusion(exeggcute(1,:))) why_not(58) = trim(confusion(exeggcute(4,:))) why_not(26) = ' ' why_not(14) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⢿⣻⣿⡿⣿⣾⢷⣯⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(47) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⠈⠢⡙⢿⢷⣤⣄⡀⠑⠠⡀⠛⢿⣷⣌⠛⢿⣷⣝⢿⣦⡈⠙⠛⠛⠛⠒⠒⠂⠀⠀⠈⠛⠛⠉⡠⠒⡉⠉⣦⣴⡴⠋⡾⣀⢿⣄⠀⠀⠀⠀⠀⠀⠀' why_not(6) = '⠀⠀⠀⠀⢹⢸⠘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠰⠠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(40) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣧⡈⢿⣿⣝⢷⣄⠙⢧⡀⣈⠻⣿⣿⣵⠀⠈⠛⠦⡀⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⣠⢤⣦⣄⣸⣿⡿⣫⣽⣿⣯⠟⠀⣸⣾⡆⠀⠀⠀⠀⠀⠀⠀⠀' why_not(24) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⠢⢖⡠⠄⢀⠠⠤⠤⠤⠀⢂⠤⢁⡞⠀⠀⠀⠀' why_not(35) = '⠀⠀⠘⣇⢻⣿⣇⠸⣿⣿⣿⡀⠇⠀⠀⡼⣿⣿⡇⠀⠀⠀⡀⠀⠻⣟⢿⣿⣿⣤⡀⠘⢿⣿⣿⣿⣿⣤⣄⣀⠀⠀⠀⠠⠄⠀⣀⣠⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(10) = '⠀⠀⠀⠀⠀⠀⠀⠱⡁⡂⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(59) = trim(confusion(exeggcute(5,:))) why_not(16) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣟⣾⡁⡧⣧⢵⣮⣵⣥⣼⣧⣥⢯⡾⣥⣤⡟⣯⢤⡛⢤⢎⣙⡽⣯⣿⠇⠀⠐⠠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(44) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣦⡀⠀⠀⠀⠙⢛⣦⡈⠻⣷⣎⡻⣦⡈⠻⣿⣿⣶⣯⣝⣿⣿⣿⣖⣲⣶⣤⣤⣤⣄⣤⣤⣴⣶⣶⣶⠻⣉⣠⡴⠟⠁⡰⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(2) = trim(confusion(exeggcute(2,:))) why_not(31) = '⠀⣼⣿⣼⣿⠏⢠⣾⣿⣿⣿⣿⣿⣷⣶⣬⣝⡛⢷⣦⣄⠀⠀⠀⠀⣀⣤⢤⣴⣶⡶⠛⣛⢫⣿⣶⣾⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(49) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣯⠀⠀⢀⠰⣤⠙⣿⣷⣤⣀⠀⠀⠀⠀⠉⢳⣶⣌⠻⢿⣷⣽⡿⣦⣄⠀⠀⠀⣀⣠⣤⣤⣥⡴⣾⠿⠒⠁⣠⣾⠃⢂⢻⣿⣧⡙⣿⣧⠀⠀⠀⠀' why_not(19) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠶⣩⠖⣭⠻⣷⣨⡑⣢⢉⠔⡡⢊⢄⡃⣖⣡⢗⡯⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⡀⠀⠀⠀⠀⠀⠀' why_not(27) = trim(confusion(exeggcute(3,:))) why_not(53) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⣄⡈⠐⠠⣑⠢⢤⣄⣀⠁⠒⠒⠲⠦⠄⠀⠀⠀⠈⠛⢿⣷⣦⣌⠛⢿⣾⣿⣻⣿⣿⣿⣶⣦⡤⠤⠒⣐⣴⣿⡏⣿⡇⢸⣿⡆⠀' why_not(7) = '⠀⠀⠀⠀⠸⡄⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣥⣤⣶⣶⣶⣶⣶⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(42) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠱⠀⠈⠻⣷⣌⠻⣿⣮⡻⣦⡈⠻⣿⣦⡈⠻⢿⣿⣿⣶⣍⣙⠷⠾⣿⣿⣷⣶⣶⣾⣿⠿⠿⠋⡩⠽⠛⠒⠁⠀⢀⣨⣴⢏⣻⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(25) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠓⠒⠳⠬⠭⡥⠴⠞⠋⠀⠀⠀⠀⠀' why_not(57) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠛⠛⠉⠉⠁⠀⠀⠀' why_not(11) = '⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(34) = '⠀⠀⢻⡸⣿⣷⠈⣿⣿⣟⣿⠀⠀⠀⠀⠀⣠⣾⣇⠀⠀⠈⠀⠸⣿⣿⣿⣾⡢⠙⠻⣿⣿⣿⣦⣈⠙⠛⠿⢶⣭⣍⠉⠯⠭⠔⠃⠈⣻⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(20) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠶⣋⢮⣓⢷⡴⡍⢾⣔⣫⢦⣽⡶⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠒⡀⠀⠀⠀⠀⠀' why_not(45) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢷⠻⣯⢦⠀⠀⠀⠀⠙⢿⣦⡈⠻⣿⣮⡻⣦⣀⠙⠪⠝⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢟⣻⣿⣿⣷⠿⢛⠉⠀⠀⠈⠀⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(5) = '⠀⠀⠀⠀⣼⢁⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠒⠠⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(50) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⠀⠈⠢⣙⢷⡜⢧⡉⠛⠿⣦⡀⠀⢄⠈⠛⢧⡷⢆⡙⠻⣿⣿⣿⣿⣦⣄⡉⠉⠉⠉⠀⠈⠀⣠⠴⠋⡴⠁⠀⠀⡄⣿⣿⣧⠘⣿⡄⠀⠀⠀' why_not(28) = ' ' why_not(17) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⡽⣹⣷⢮⡓⠮⣝⢾⣹⠽⣞⢧⡝⢶⣡⠛⡤⢃⠎⡱⢊⢶⣹⣿⠟⠀⠀⠀⠀⠐⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(39) = '⠀⠀⠀⠀⠀⠀⠀⠹⣿⡄⣒⠈⣿⣯⡻⣦⡈⢻⣎⠈⠻⣿⣿⣦⣄⠈⠢⣤⡀⠀⠀⠀⠀⠀⢌⡙⠒⠀⠈⠙⠛⠛⠛⠛⠛⠉⣠⣤⣦⣤⣤⣿⠟⠀⢿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(13) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠄⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⡽⣾⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(56) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠒⠲⠒⠶⠒⠒⠛⠋⠉⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⠿⢿⣿⣶⣶⣶⣶⣶⡿⠿⣿⡿⠋⠀⠀' why_not(22) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠚⢴⡠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢠⢃⠀⠀⠀⠀' why_not(32) = '⠀⢹⢻⢻⣿⠀⣿⣿⣿⡿⣭⣶⠾⠟⠺⠿⢿⣿⣷⣦⠝⣫⡴⢺⣿⢿⡇⢻⣿⢿⣧⠀⢿⣮⡿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(54) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠦⣄⡀⠉⠓⠢⣭⣿⣷⣶⣾⣿⣟⣛⣓⣀⣀⣀⣠⡌⠙⠻⣿⣦⣤⠙⠛⠿⣶⣭⣿⣛⡿⠿⠿⠿⠟⣫⣾⡿⠁⣼⡿⡇⠀' why_not(15) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡟⢿⣏⡟⡿⣻⢿⡫⡟⣿⣯⡟⣿⢭⣯⡏⣦⡛⣽⢝⡻⣝⣿⣷⣿⣿⡧⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(36) = '⠀⠀⠀⠘⣇⠻⣿⣄⠻⣿⣿⣷⡈⠀⠞⡁⣿⡜⣿⣶⢦⠀⠐⠀⠀⠙⢮⡛⢿⣿⣿⣷⣦⣌⡙⠻⢿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣿⣿⡿⡩⢷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(48) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣷⡀⠹⡀⠙⠲⣬⣛⢦⡀⠀⠀⠀⠈⠻⣷⣄⠙⠻⣿⣮⡻⣶⣄⡉⠀⠈⠃⠀⠀⠀⠀⠀⠀⠀⠰⠏⢂⣼⠟⠋⠀⣼⢡⣿⣦⠻⣮⣳⡀⠀⠀⠀⠀' why_not(23) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠣⣄⡄⡀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡈⠰⢸⠀⠀⠀⠀' why_not(38) = '⠀⠀⠀⠀⠀⠈⢻⣷⡉⣤⠻⣿⣿⣿⣄⠈⣿⡿⡌⢾⣿⣧⡀⠀⠀⡀⠀⠀⠀⠀⠀⠙⠷⣮⣙⠛⠿⣿⣿⣿⣿⣿⣿⣿⠿⠟⣋⡀⠀⠀⠁⣠⣾⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(30) = '⠀⢠⣿⢟⣵⣿⡿⠛⠛⠛⠛⠛⠻⠿⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(43) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣄⠁⠀⠀⠉⢿⣧⡈⠻⣿⣮⡻⣦⡈⠻⣿⣦⣕⡿⢿⣶⣭⣉⡛⠒⠦⠄⠉⠉⠑⠛⠻⠗⠒⠀⢀⣤⠶⢀⣴⡾⣿⠟⣡⠏⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀' why_not(51) = '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣷⡄⠀⠀⠉⠁⠀⠙⣦⠀⠂⡍⠑⠀⠉⠀⠀⠉⢻⠓⣶⡄⠈⠹⣿⣿⣿⣿⣶⣤⠀⠀⠐⠉⠀⢠⡞⠁⠀⠀⠀⡇⢸⣿⡟⣧⢱⢸⣿⡆⠀' surprise(10) = '⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀' surprise(9) = '⠀⠀⠀⢿⣶⣿⣿⣿⣿⣿⡻⣿⡿⣿⣿⣿⣿⣶⣶⣾⣿⣿⠀⠀' surprise(3) = '⠀⠘⢿⣿⣿⣿⣿⣦⣀⣀⣀⣄⣀⣀⣠⣀⣤⣶⣿⣿⣿⣿⣿⠇' surprise(11) = '⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀' surprise(5) = '⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠋⠀⠀⠀' surprise(8) = '⠀⠀⠀⡁⠀⠈⣿⣿⣿⣿⢟⣛⡻⣿⣿⣿⣟⠀⠀⠈⣿⡇⠀⠀' surprise(6) = '⠀⠀⠀⢠⣿⣿⡏⠆⢹⣿⣿⣿⣿⣿⣿⠒⠈⣿⣿⣿⣇⠀⠀⠀' surprise(4) = '⠀⠀⠈⠻⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀' surprise(7) = '⠀⠀⠀⣼⣿⣿⣷⣶⣿⣿⣛⣻⣿⣿⣿⣶⣾⣿⣿⣿⣿⡀⠀⠀' surprise(2) = '⠀⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿' surprise(1) = '⢰⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀' if (gottacatch_emall_()) then call print_msg('',LVL_NFO) if (abs(n_yr_run - first_gen) < minieps) then do i = 1,size(surprise) call print_msg(trim(surprise(i)),LVL_NFO) end do call print_msg('',LVL_NFO) do i = 1,size(exeggutor,1) call print_msg(trim(confusion(exeggutor(i,:))),LVL_NFO) end do else do i = 1,size(why_not) call print_msg(trim(why_not(i)),LVL_NFO) end do end if end if END SUBROUTINE but_why !======================================================================= !======================================================================= FUNCTION gottacatch_emall_() RESULT(flag) !----------------------------------------------------------------------- ! NAME ! gottacatch_emall_ ! ! DESCRIPTION ! Find the egg. ! ! AUTHORS & DATE ! JB Clement, 02/2026 ! ! NOTES ! Oh? An egg is about to hatch! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! LOCAL VARIABLES ! --------------- integer(di), dimension(13), parameter :: egg = [80,82,79,70,69,83,83,79,82,95,79,65,75] integer(di), dimension(43), parameter :: who = [79,104,63,32,73,116,32,115,101,101,109,115,32,121,111,117,39,114,101,32,110,111,116,32,116,104,101,32,114,105,103,104,116,32,112,101,114,115,111,110,46,46,46] character(20) :: why_yes integer(di) :: ierr logical(k4) :: flag ! CODE ! ---- flag = .false. call get_environment_variable(trim(confusion(egg)),why_yes,status = ierr) if (ierr == 0) then flag = trim(why_yes) == 'yes' if (.not. flag) then call print_msg('',LVL_NFO) call print_msg(trim(confusion(who)),LVL_NFO) end if end if END FUNCTION gottacatch_emall_ !======================================================================= !======================================================================= FUNCTION confusion(code) RESULT(msg) !----------------------------------------------------------------------- ! NAME ! confusion ! ! DESCRIPTION ! PEM used confusion! ! ! AUTHORS & DATE ! JB Clement, 02/2026 ! ! NOTES ! USER is confused! It hurt itself in its confusion! !----------------------------------------------------------------------- ! DECLARATION ! ----------- implicit none ! ARGUMENTS ! --------- integer(di), dimension(:), intent(in) :: code ! LOCAL VARIABLES ! --------------- integer(di) :: i character(:), allocatable :: msg ! CODE ! ---- msg = '' do i = 1,size(code) if (code(i) /= 0) msg = msg//achar(code(i)) end do END FUNCTION confusion !======================================================================= END MODULE display