diff --git a/cmake_targets/CMakeLists.txt b/CMakeLists.txt similarity index 97% rename from cmake_targets/CMakeLists.txt rename to CMakeLists.txt index a1abc8f624..0e9ec0e6d5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,10 +21,10 @@ # Author: laurent THOMAS, Lionel GAUTHIER -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.5) project (OpenAirInterface LANGUAGES C CXX) -include("macros.cmake") +include("cmake_targets/macros.cmake") # System packages that are required # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ @@ -55,17 +55,17 @@ if (${RF_BOARD} STREQUAL "OAI_USRP") find_package(Boost REQUIRED) elseif (${RF_BOARD} STREQUAL "OAI_IRIS") - include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") + include_directories("${OPENAIR_DIR}/sdr/IRIS/USERSPACE/LIB/") set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) + ${OPENAIR_DIR}/sdr/IRIS/USERSPACE/LIB/iris_lib.cpp) LINK_DIRECTORIES("/usr/local/lib") set(option_HW_lib "-lSoapySDR -rdynamic -ldl") elseif (${RF_BOARD} STREQUAL "OAI_AW2SORI") - include_directories("${OPENAIR_TARGETS}/ARCH/AW2SORI") + include_directories("${OPENAIR_DIR}/sdr/AW2SORI") set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/AW2SORI/ARCH/AW2SORI/oaiori.c) + ${OPENAIR_DIR}/sdr/AW2SORI/ARCH/AW2SORI/oaiori.c) LINK_DIRECTORIES("/usr/local/lib") set(openair_HW_lib "-shared -fPIC -msse4 -g -ggdb -lori") @@ -761,53 +761,53 @@ set (SHLIB_LOADER_SOURCES ###################################################################### set(HWLIB_USRP_SOURCE - ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp + ${OPENAIR_DIR}/sdr/USRP/USERSPACE/LIB/usrp_lib.cpp ) add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} ) target_include_directories(oai_usrpdevif PRIVATE - "${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/" + "${OPENAIR_DIR}/sdr/USRP/USERSPACE/LIB/" ${Boost_INCLUDE_DIR} ) target_link_libraries(oai_usrpdevif uhd) -include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/") +include_directories("${OPENAIR_DIR}/sdr/BLADERF/USERSPACE/LIB/") set(HWLIB_BLADERF_SOURCE - ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c + ${OPENAIR_DIR}/sdr/BLADERF/USERSPACE/LIB/bladerf_lib.c ) add_library(oai_bladerfdevif MODULE ${HWLIB_BLADERF_SOURCE} ) target_link_libraries(oai_bladerfdevif bladeRF) -include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/") +include_directories("${OPENAIR_DIR}/sdr/LMSSDR/USERSPACE/LIB/") set(HWLIB_LMSSDR_SOURCE - ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp + ${OPENAIR_DIR}/sdr/LMSSDR/USERSPACE/LIB/lms_lib.cpp ) add_library(oai_lmssdrdevif MODULE ${HWLIB_LMSSDR_SOURCE} ) target_include_directories(oai_lmssdrdevif PRIVATE /usr/local/include/lime) target_link_libraries(oai_lmssdrdevif LimeSuite ) -include_directories("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/") +include_directories("${OPENAIR_DIR}/sdr/ETHERNET/USERSPACE/LIB/") set(TPLIB_ETHERNET_SOURCE - ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c + ${OPENAIR_DIR}/sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.c + ${OPENAIR_DIR}/sdr/ETHERNET/USERSPACE/LIB/eth_udp.c + ${OPENAIR_DIR}/sdr/ETHERNET/USERSPACE/LIB/eth_raw.c ) add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} ) -include_directories("${OPENAIR_TARGETS}/ARCH/AW2SORI/") +include_directories("${OPENAIR_DIR}/sdr/AW2SORI/") link_directories("/usr/local/lib") set(HWLIB_AW2SORI_SOURCE - ${OPENAIR_TARGETS}/ARCH/AW2SORI/oaiori.c + ${OPENAIR_DIR}/sdr/AW2SORI/oaiori.c ) add_library(aw2sori_transpro MODULE ${HWLIB_AW2SORI_SOURCE}) target_compile_options(aw2sori_transpro PRIVATE -shared -fPIC -msse4 -g -ggdb -DLITE_COMPILATION) target_link_libraries(aw2sori_transpro libori.so) -include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") +include_directories("${OPENAIR_DIR}/sdr/IRIS/USERSPACE/LIB/") set(option_HWIRISLIB_lib "-l SoapySDR") set(HWLIB_IRIS_SOURCE - ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp + ${OPENAIR_DIR}/sdr/IRIS/USERSPACE/LIB/iris_lib.cpp ) add_library(oai_irisdevif MODULE ${HWLIB_IRIS_SOURCE}) target_include_directories(oai_irisdevif PRIVATE /usr/local/lib/SoapySDR/modules0.7/) @@ -820,11 +820,11 @@ target_link_libraries(oai_irisdevif SoapySDR) include_directories ("/usr/include/dpdk") set(HWLIB_BENETEL_4G_SOURCE - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/benetel.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/shared_buffers.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/low.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/low_dpdk.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/dpdk_driver.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/4g/benetel.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/4g/shared_buffers.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/4g/low.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/4g/low_dpdk.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/4g/dpdk_driver.c ) add_library(benetel_4g MODULE ${HWLIB_BENETEL_4G_SOURCE} ) @@ -838,11 +838,11 @@ TARGET_LINK_LIBRARIES(benetel_4g pthread dl rt m numa) ###################################################################### set(HWLIB_BENETEL_5G_SOURCE - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/benetel.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/shared_buffers.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/low.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/low_dpdk.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/dpdk_driver.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/5g/benetel.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/5g/shared_buffers.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/5g/low.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/5g/low_dpdk.c + ${OPENAIR_DIR}/sdr/ETHERNET/benetel/5g/dpdk_driver.c ) add_library(benetel_5g MODULE ${HWLIB_BENETEL_5G_SOURCE} ) @@ -879,7 +879,7 @@ endif () ########################################################## -include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") +include_directories ("${OPENAIR_DIR}/sdr/COMMON") Message("DEADLINE_SCHEDULER flag is ${DEADLINE_SCHEDULER}") Message("CPU_Affinity flag is ${CPU_AFFINITY}") @@ -1051,7 +1051,7 @@ include_directories("${OPENAIR3_DIR}/ocp-gtpu") include_directories("${OPENAIR3_DIR}/M3AP") include_directories("${OPENAIR3_DIR}/MME_APP") include_directories("${OPENAIR_DIR}/targets/COMMON") -include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON") +include_directories("${OPENAIR_DIR}/sdr/COMMON") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") @@ -1567,7 +1567,6 @@ set(PHY_SRC set(PHY_SRC_RU ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/drs_modulation.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -2560,15 +2559,15 @@ target_link_libraries(nrscope ${XFORMS_LIBRARIES}) add_library(rfsimulator MODULE - ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c - ${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c - ${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c + ${OPENAIR_DIR}/sdr/rfsimulator/simulator.c + ${OPENAIR_DIR}/sdr/rfsimulator/apply_channelmod.c + ${OPENAIR_DIR}/sdr/rfsimulator/new_channel_sim.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ) target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES}) add_library(oai_iqplayer MODULE - ${OPENAIR_TARGETS}/ARCH/iqplayer/iqplayer_lib.c + ${OPENAIR_DIR}/sdr/iqplayer/iqplayer_lib.c ) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") @@ -2629,7 +2628,7 @@ add_executable(nfapi_test ) add_executable(replay_node - ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c + ${OPENAIR_DIR}/sdr/rfsimulator/stored_node.c ) target_link_libraries (replay_node minimal_lib) @@ -2656,8 +2655,8 @@ add_executable(lte-softmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR2_DIR}/F1AP/dummy_enb.c @@ -2696,8 +2695,8 @@ add_executable(ocp-enb ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2725,8 +2724,8 @@ target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m CONFIG_LIB rt cryp add_executable(oairu ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/record_player.c ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c ${OPENAIR_DIR}/executables/main_ru.c @@ -2751,8 +2750,8 @@ add_executable(lte-uesoftmodem ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2797,8 +2796,8 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/executables/nr-softmodem.c ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2842,8 +2841,8 @@ add_executable(nr-uesoftmodem ${OPENAIR_DIR}/executables/nr-ue.c ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c @@ -2898,7 +2897,7 @@ target_link_libraries (dlsim_tm4 add_executable(rftest ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_scope.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_DIR}/sdr/COMMON/common_lib.c ${OPENAIR_DIR}/executables/softmodem-common.c ${SHLIB_LOADER_SOURCES} ) @@ -3221,3 +3220,5 @@ ADD_CUSTOM_TARGET(oarf include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt) include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt) + +add_subdirectory(openair2) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 32d9c48966..fcaa22afed 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -2404,7 +2404,7 @@ class OaiCiTest(): if launchFromTrfContainer: SSH.command('docker exec -it prod-trf-gen /bin/bash -c "killall --signal SIGKILL iperf"', '\$', 5) else: - SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5) + SSH.command('killall --signal SIGKILL iperf', '\$', 5) SSH.close() else: cmd = 'killall --signal SIGKILL iperf' @@ -3894,8 +3894,8 @@ class OaiCiTest(): logging.debug('UHD Version is: ' + UhdVersion) HTML.UhdVersion[idx]=UhdVersion else: - SSH.command('uhd_config_info --version', '\$', 5) - result = re.search('UHD (?P[a-zA-Z0-9\.\-]+)', SSH.getBefore()) + SSH.command('uhd_config_info --abi-version', '\$', 5) + result = re.search('ABI version string: (?P[a-zA-Z0-9\.\-]+)', SSH.getBefore()) if result is not None: UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + UhdVersion) diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 0633d233ef..2df7ed455a 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -198,8 +198,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 0 - att_rx = 0; + att_tx = 6 + att_rx = 6; bands = [38]; max_pdschReferenceSignalPower = -27; max_rxgain = 115; diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 4de8a3f759..5738a65569 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -198,8 +198,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 0 - att_rx = 0; + att_tx = 6 + att_rx = 6; bands = [38]; max_pdschReferenceSignalPower = -27; max_rxgain = 125; diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index df902faf8b..8ea3abf01e 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -198,8 +198,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 0 - att_rx = 0; + att_tx = 6 + att_rx = 6; bands = [38]; max_pdschReferenceSignalPower = -27; max_rxgain = 120; diff --git a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf index 0da4b1181a..926e65eddd 100644 --- a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf @@ -196,8 +196,8 @@ RUs = ( local_rf = "yes" nb_tx = 2 nb_rx = 2 - att_tx = 0 - att_rx = 0; + att_tx = 6 + att_rx = 6; bands = [38]; max_pdschReferenceSignalPower = -27; max_rxgain = 110; diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index 27b079d026..664af9d65e 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -7,7 +7,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf index 5a96090b36..50a3468340 100644 --- a/ci-scripts/conf_files/gNB_SA_DU.conf +++ b/ci-scripts/conf_files/gNB_SA_DU.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf index f0dbbcaf06..e28eab1fb6 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf index ff5e804f19..0902eebaeb 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf @@ -7,7 +7,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf index 5f2e43fbf1..32d49aa22a 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf index ffe5234a21..2911e0f515 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf index 2ca4471c61..b34dc2fbe5 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf index 3b2226eb6b..9f83c3f654 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf index 256dfd5dc8..da26668da8 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 660478ca11..f430f51ebe 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -209,8 +209,8 @@ RUs = ( tr_preference = "udp_if4p5" nb_tx = 1 nb_rx = 1 - att_tx = 0 - att_rx = 0; + att_tx = 6 + att_rx = 6; eNB_instances = [0]; } ); diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 6997c80234..98699aac26 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -209,8 +209,8 @@ RUs = ( tr_preference = "udp_if4p5" nb_tx = 1 nb_rx = 1 - att_tx = 0 - att_rx = 0; + att_tx = 6 + att_rx = 6; eNB_instances = [0]; } ); diff --git a/ci-scripts/datalog_rt_stats.1x1.60.yaml b/ci-scripts/datalog_rt_stats.1x1.60.yaml new file mode 100644 index 0000000000..264b38775a --- /dev/null +++ b/ci-scripts/datalog_rt_stats.1x1.60.yaml @@ -0,0 +1,34 @@ +#this is a configuration file +#used to build real time processing statistics +#for 5G NR phy test (gNB terminate) +Title : Processing Time (us) +ColNames : + - Metric + - Average; Max; Count + - Average vs Reference Deviation (Reference Value; Acceptability Threshold) +Ref : + feprx : 48.0 + feptx_prec : 16.0 + feptx_ofdm : 35.0 + feptx_total : 59.0 + L1 Tx processing : 210.0 + DLSCH encoding : 129.0 + L1 Rx processing : 287.0 + PUSCH inner-receiver : 166.0 + PUSCH decoding : 176.0 + Schedule Response : 42.0 + DL & UL scheduling timing : 13.0 + UL Indication : 55.0 +Threshold : + feprx : 1.25 + feptx_prec : 1.25 + feptx_ofdm : 1.25 + feptx_total : 1.25 + L1 Tx processing : 1.25 + DLSCH encoding : 1.25 + L1 Rx processing : 1.25 + PUSCH inner-receiver : 1.25 + PUSCH decoding : 1.25 + Schedule Response : 1.25 + DL & UL scheduling timing : 1.25 + UL Indication : 1.25 diff --git a/ci-scripts/datalog_rt_stats.default.yaml b/ci-scripts/datalog_rt_stats.default.yaml index 97591a766d..cddb26d531 100644 --- a/ci-scripts/datalog_rt_stats.default.yaml +++ b/ci-scripts/datalog_rt_stats.default.yaml @@ -7,18 +7,18 @@ ColNames : - Average; Max; Count - Average vs Reference Deviation (Reference Value; Acceptability Threshold) Ref : - feprx : 60.0 - feptx_prec : 8.0 - feptx_ofdm : 50.0 - feptx_total : 75.0 - L1 Tx processing : 300.0 - DLSCH encoding : 230.0 - L1 Rx processing : 175.0 - PUSCH inner-receiver : 100.0 - #PUSCH decoding : 180.0 - PUSCH decoding : 240.0 - DL & UL scheduling timing : 37.0 - UL Indication : 38.0 + feprx : 53.0 + feptx_prec : 20.0 + feptx_ofdm : 37.0 + feptx_total : 62.0 + L1 Tx processing : 170.0 + DLSCH encoding : 118.0 + L1 Rx processing : 223.0 + PUSCH inner-receiver : 107.0 + PUSCH decoding : 170.0 + Schedule Response : 15.0 + DL & UL scheduling timing : 10.0 + UL Indication : 27.0 Threshold : feprx : 1.25 feptx_prec : 1.25 @@ -29,5 +29,6 @@ Threshold : L1 Rx processing : 1.25 PUSCH inner-receiver : 1.25 PUSCH decoding : 1.25 + Schedule Response : 1.25 DL & UL scheduling timing : 1.25 UL Indication : 1.25 diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 8363c91461..73d95aadb9 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -379,7 +379,7 @@ VM_TEMPLATE=ci- # look for ASN1 release in cmake directives # It will be the release used when building -ASN1VEROPT=( `grep "set (RRC_ASN1_VERSION" cmake_targets/CMakeLists.txt` ) +ASN1VEROPT=( `grep "set (RRC_ASN1_VERSION" CMakeLists.txt` ) ASN1VER=${ASN1VEROPT[2]//\"} ASN1VER=${ASN1VER//)} unset ASN1VEROPT diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 2472ffe3bc..b596680eb3 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1217,7 +1217,7 @@ function start_rf_sim_nr_ue { then echo "echo \"./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --log_config.global_log_options level,nocolor,time\" > ./my-nr-softmodem-run.sh " >> $1 else # -eq 3 SA test 24PRB - echo "echo \"./nr-uesoftmodem -r 24 -s 24 --numerology 1 --band 78 -C 3604320000 --rfsim --sa --log_config.global_log_options level,nocolor,time\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-uesoftmodem -r 24 --ssb 24 --numerology 1 --band 78 -C 3604320000 --rfsim --sa --log_config.global_log_options level,nocolor,time\" > ./my-nr-softmodem-run.sh " >> $1 fi fi echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml index 5b3a23dbfb..01388a5aa1 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml @@ -111,16 +111,16 @@ Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) - -u -b 20M -t 30 -i 1 -R + iperf (10MHz - UL/18Mbps/UDP)(30 sec)(balanced profile) + -u -b 18M -t 30 -i 1 -R 50 balanced Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R + iperf (10MHz - UL/18Mbps/UDP)(30 sec)(single-ue profile) + -u -b 18M -t 30 -i 1 -R 50 single-ue diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index e7eb651d50..9a184c9e52 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -21,8 +21,8 @@ --> - gNB-PHY-Test - Run-gNB-PHY-Test + gNB-PHY-Test-40 + Timing phytest 40 MHz tasks 1 @@ -33,7 +33,8 @@ Initialize_eNB Initialize gNB USRP - -O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time + -O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 23 -D 130175 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time + datalog_rt_stats.default.yaml NR 192.168.20.2 @@ -41,7 +42,7 @@ IdleSleep Sleep - 300 + 60 diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml new file mode 100644 index 0000000000..d46c1c0caf --- /dev/null +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -0,0 +1,55 @@ + + + gNB-PHY-Test-60 + Timing phytest 60 MHz + tasks + 1 + +190101 000001 190109 + + + + + Initialize_eNB + Initialize gNB USRP + -O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test --gNBs.[0].servingCellConfigCommon.[0].dl_carrierBandwidth 162 --gNBs.[0].servingCellConfigCommon.[0].ul_carrierBandwidth 162 -q -U 787200 -T 162 -t 23 -D 130175 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time + datalog_rt_stats.1x1.60.yaml + NR + 192.168.20.2 + + + + IdleSleep + Sleep + 60 + + + + + Terminate_eNB + Terminate gNB + NR + + + diff --git a/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml index b9db6fe7d5..695a05f2b0 100644 --- a/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml @@ -270,7 +270,7 @@ services: OPC: 'C42449363BBAD02B66D16BC975D77CC1' DNN: oai NSSAI_SST: 1 - USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --band 66 -C 2169080000 --CO -400000000 -s 396 --nokrnmod --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --band 66 -C 2169080000 --CO -400000000 --ssb 396 --nokrnmod --log_config.global_log_options level,nocolor,time depends_on: - oai-gnb networks: diff --git a/ci-scripts/yaml_files/5g_l2sim_tdd/README.md b/ci-scripts/yaml_files/5g_l2sim_tdd/README.md index c3f631cf76..9578d037ca 100644 --- a/ci-scripts/yaml_files/5g_l2sim_tdd/README.md +++ b/ci-scripts/yaml_files/5g_l2sim_tdd/README.md @@ -33,10 +33,10 @@ Now pull images. ```bash $ docker pull mysql:5.7 -$ docker pull oaisoftwarealliance/oai-amf:latest -$ docker pull oaisoftwarealliance/oai-nrf:latest -$ docker pull oaisoftwarealliance/oai-smf:latest -$ docker pull oaisoftwarealliance/oai-spgwu-tiny:latest +$ docker pull oaisoftwarealliance/oai-amf:develop +$ docker pull oaisoftwarealliance/oai-nrf:develop +$ docker pull oaisoftwarealliance/oai-smf:develop +$ docker pull oaisoftwarealliance/oai-spgwu-tiny:develop $ docker pull oaisoftwarealliance/oai-gnb:develop $ docker pull oaisoftwarealliance/oai-nr-ue:develop @@ -46,10 +46,10 @@ $ docker pull oaisoftwarealliance/proxy:latest And **re-tag** them for tutorials' docker-compose file to work. ```bash -$ docker image tag oaisoftwarealliance/oai-amf:latest oai-amf:latest -$ docker image tag oaisoftwarealliance/oai-nrf:latest oai-nrf:latest -$ docker image tag oaisoftwarealliance/oai-smf:latest oai-smf:latest -$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:latest +$ docker image tag oaisoftwarealliance/oai-amf:latest oai-amf:august-dev +$ docker image tag oaisoftwarealliance/oai-nrf:latest oai-nrf:august-dev +$ docker image tag oaisoftwarealliance/oai-smf:latest oai-smf:august-dev +$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:august-dev $ docker image tag oaisoftwarealliance/oai-gnb:develop oai-gnb:develop $ docker image tag oaisoftwarealliance/oai-nr-ue:develop oai-nr-ue:develop diff --git a/ci-scripts/yaml_files/5g_rfsimulator/README.md b/ci-scripts/yaml_files/5g_rfsimulator/README.md index 36169dca8b..f457d4c3f6 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/README.md +++ b/ci-scripts/yaml_files/5g_rfsimulator/README.md @@ -50,10 +50,10 @@ Now pull images. ```bash $ docker pull mysql:5.7 -$ docker pull oaisoftwarealliance/oai-amf:latest -$ docker pull oaisoftwarealliance/oai-nrf:latest -$ docker pull oaisoftwarealliance/oai-smf:latest -$ docker pull oaisoftwarealliance/oai-spgwu-tiny:latest +$ docker pull oaisoftwarealliance/oai-amf:develop +$ docker pull oaisoftwarealliance/oai-nrf:develop +$ docker pull oaisoftwarealliance/oai-smf:develop +$ docker pull oaisoftwarealliance/oai-spgwu-tiny:develop $ docker pull oaisoftwarealliance/oai-gnb:develop $ docker pull oaisoftwarealliance/oai-nr-ue:develop @@ -62,10 +62,10 @@ $ docker pull oaisoftwarealliance/oai-nr-ue:develop And **re-tag** them for tutorials' docker-compose file to work. ```bash -$ docker image tag oaisoftwarealliance/oai-amf:latest oai-amf:latest -$ docker image tag oaisoftwarealliance/oai-nrf:latest oai-nrf:latest -$ docker image tag oaisoftwarealliance/oai-smf:latest oai-smf:latest -$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:latest +$ docker image tag oaisoftwarealliance/oai-amf:latest oai-amf:august-dev +$ docker image tag oaisoftwarealliance/oai-nrf:latest oai-nrf:august-dev +$ docker image tag oaisoftwarealliance/oai-smf:latest oai-smf:august-dev +$ docker image tag oaisoftwarealliance/oai-spgwu-tiny:latest oai-spgwu-tiny:august-dev $ docker image tag oaisoftwarealliance/oai-gnb:develop oai-gnb:develop $ docker image tag oaisoftwarealliance/oai-nr-ue:develop oai-nr-ue:develop diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 88654ac9b5..8158cd4e9e 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -7936,7 +7936,7 @@ c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/ran_build/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/targets/ARCH/LMSSDR/enb_sodera_highband_5MHz_rx19dB_txfull.ini + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/sdr/LMSSDR/enb_sodera_highband_5MHz_rx19dB_txfull.ini @@ -8012,7 +8012,7 @@ c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/ran_build/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/targets/ARCH/LMSSDR/enb_sodera_highband_10MHz_rx19dB_txfull.ini + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/sdr/LMSSDR/enb_sodera_highband_10MHz_rx19dB_txfull.ini @@ -8087,7 +8087,7 @@ c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/ran_build/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/targets/ARCH/LMSSDR/enb_sodera_highband_20MHz_rx19dB_txfull.ini + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/sdr/LMSSDR/enb_sodera_highband_20MHz_rx19dB_txfull.ini @@ -8162,7 +8162,7 @@ c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/ran_build/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/targets/ARCH/LMSSDR/enb_sodera_highband_5MHz_rx19dB_txfull.ini + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/sdr/LMSSDR/enb_sodera_highband_5MHz_rx19dB_txfull.ini @@ -8236,7 +8236,7 @@ c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/ran_build/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/targets/ARCH/LMSSDR/enb_sodera_highband_10MHz_rx19dB_txfull.ini + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/sdr/LMSSDR/enb_sodera_highband_10MHz_rx19dB_txfull.ini @@ -8310,7 +8310,7 @@ c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/ran_build/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/targets/ARCH/LMSSDR/enb_sodera_highband_20MHz_rx19dB_txfull.ini + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf --rf-config-file $OPENAIR_DIR/sdr/LMSSDR/enb_sodera_highband_20MHz_rx19dB_txfull.ini diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 09029c285a..ac15f58662 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -126,10 +126,6 @@ Options: Adds a debgging facility to the binary files: GUI with major internal synchronization events -x | --xforms Will compile with software oscilloscope features ---HWLAT - Makes test program for haw latency tests ---HWLAT_TEST - Compiles a hw latency test program --verbose-ci Compile with verbose instructions in CI Docker env --verbose-compile @@ -345,14 +341,6 @@ function main() { EXE_ARGUMENTS="$EXE_ARGUMENTS -d" echo_info "Will generate the software oscilloscope features" shift;; - --HWLAT) - HWLAT=1 - echo_info "Will compile hw latency test program" - shift;; - --HWLAT_TEST) - HWLAT_TEST=1 - echo_info "Will compile hw latency test program" - shift;; --verbose-ci) VERBOSE_CI=1 echo_info "Will compile with verbose instructions in CI Docker env" @@ -502,12 +490,6 @@ function main() { echo_info "No transport protocol has been selected (TP set to $TP)" fi fi - - if [ "$HWLAT" = "1" ] ; then - if [ "$HW" = "None" ] ; then - echo_info "No radio head has been selected (HW set to $HW)" - fi - fi echo_info "RF HW set to $HW" # If the user doesn't specify the Linux scheduler to use, we set a value @@ -632,9 +614,11 @@ function main() { cd $DIR/$BUILD_DIR/build if [[ ${#CMAKE_C_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_C_FLAGS=\"${CMAKE_C_FLAGS[*]}\""; fi if [[ ${#CMAKE_CXX_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS[*]}\""; fi - CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\"" + # for historical reasons we build in a subdirectory cmake_targets/XYZ/build, + # e.g., cmake_targets/ran_build/build, hence the ../../.. + CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\" ../../.." echo_info "running $CMAKE_CMD" - eval $CMAKE_CMD ../.. + eval $CMAKE_CMD for f in $execlist ; do echo_info "Compiling $f..." @@ -775,67 +759,11 @@ function main() { lib${oklib}.so $dbin/lib${oklib}.so done fi - - ##################### - # HWLAT compilation # - ##################### - if [ "$HWLAT" = "1" ] ; then - - hwlat_exec=lte-hwlat - hwlat_build_dir=lte-hwlat - - echo_info "Compiling $hwlat_exec ..." - - [ "$CLEAN" = "1" ] && rm -rf $DIR/lte-hwlat/build - mkdir -p $DIR/$hwlat_build_dir/build - cmake_file=$DIR/$hwlat_build_dir/CMakeLists.txt - echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file - echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file - echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file - echo 'set ( PACKAGE_NAME "\"lte-hwlat\"")' >> $cmake_file - echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >> $cmake_file - echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >> $cmake_file - echo "set ( HWLAT \"${HWLAT}\" )" >> $cmake_file - echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file - cd $DIR/$hwlat_build_dir/build - cmake .. - compilations \ - lte-hwlat lte-hwlat \ - lte-hwlat $dbin/lte-hwlat - fi - - ########################## - # HWLAT_TEST compilation # - ########################## - if [ "$HWLAT_TEST" = "1" ] ; then - - hwlat_test_exec=lte-hwlat-test - hwlat_test_build_dir=lte-hwlat-test - - echo_info "Compiling $hwlat_test_exec ..." - - [ "$CLEAN" = "1" ] && rm -rf $DIR/lte-hwlat-test/build - mkdir -p $DIR/$hwlat_test_build_dir/build - cmake_file=$DIR/$hwlat_test_build_dir/CMakeLists.txt - echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file - echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file - echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file - echo 'set ( PACKAGE_NAME "\"lte-hwlat-test\"")' >> $cmake_file - echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >> $cmake_file - echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >> $cmake_file - echo "set ( HWLAT \"${HWLAT}\" )" >> $cmake_file - echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file - cd $DIR/$hwlat_test_build_dir/build - cmake .. - compilations \ - lte-hwlat-test lte-hwlat-test \ - lte-hwlat-test $dbin/lte-hwlat-test - fi #################################################### # Build RF device and transport protocol libraries # #################################################### - if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then + if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" ] ; then # build RF device libraries if [ "$HW" != "None" ] ; then diff --git a/cmake_targets/macros.cmake b/cmake_targets/macros.cmake index 0417420af4..3de95580ef 100644 --- a/cmake_targets/macros.cmake +++ b/cmake_targets/macros.cmake @@ -77,7 +77,7 @@ endmacro(add_list_string_option) function(make_version VERSION_VALUE) math(EXPR RESULT "0") foreach (ARG ${ARGN}) - math(EXPR RESULT "${RESULT} * 16 + ${ARG}") + math(EXPR RESULT "${RESULT} * 256 + ${ARG}") endforeach() set(${VERSION_VALUE} "${RESULT}" PARENT_SCOPE) endfunction() diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 608ace0486..f4e206d0eb 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -346,11 +346,34 @@ install_usrp_uhd_driver_from_source(){ rm -rf /tmp/uhd git clone https://github.com/EttusResearch/uhd.git cd uhd + # For our legacy TDD eNB running with a B2xx RF board + # the following patch has to be applied if [[ -v UHD_VERSION ]]; then git checkout tags/v${UHD_VERSION} + # We recommend to use not older than 3.15.0.0 + if [[ "$UHD_VERSION" == "3.15.0.0" ]]; then + # Tested that patch for the following versions: + # - 3.15.0.0 + git apply $OPENAIR_DIR/cmake_targets/tools/uhd-3.15-tdd-patch.diff + ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch" + else + # Tested that patch for the following versions: + # - 4.0.0.0 + # - 4.1.0.0 + # - 4.1.0.5 + # - 4.2.0.0 + # - 4.2.0.1 + # - 4.3.0.0-rc1 + git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff + ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch" + fi else git checkout tags/v4.0.0.0 + git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff + ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch" fi + # Printing out the results of the patch to make sure it was properly applied + git diff mkdir -p host/build cd host/build || true $CMAKE ../ -GNinja diff --git a/cmake_targets/tools/uhd-3.15-tdd-patch.diff b/cmake_targets/tools/uhd-3.15-tdd-patch.diff new file mode 100644 index 0000000000..00746999cf --- /dev/null +++ b/cmake_targets/tools/uhd-3.15-tdd-patch.diff @@ -0,0 +1,34 @@ +diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp +index 1be8c263b..f64546914 100644 +--- a/host/lib/usrp/b200/b200_impl.cpp ++++ b/host/lib/usrp/b200/b200_impl.cpp +@@ -1269,10 +1269,10 @@ void b200_impl::update_atrs(void) + if (enb_rx and not enb_tx) fd = rxonly; + if (not enb_rx and enb_tx) fd = txonly; + gpio_atr_3000::sptr atr = perif.atr; +- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF); +- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly); +- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly); +- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd); ++ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7)); ++ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7)); + } + if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr) + { +@@ -1287,10 +1287,10 @@ void b200_impl::update_atrs(void) + if (enb_rx and not enb_tx) fd = rxonly; + if (not enb_rx and enb_tx) fd = txonly; + gpio_atr_3000::sptr atr = perif.atr; +- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF); +- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly); +- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly); +- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd); ++ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7)); ++ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7)); + } + } + diff --git a/cmake_targets/tools/uhd-4.x-tdd-patch.diff b/cmake_targets/tools/uhd-4.x-tdd-patch.diff new file mode 100644 index 0000000000..64ffaf0c3e --- /dev/null +++ b/cmake_targets/tools/uhd-4.x-tdd-patch.diff @@ -0,0 +1,34 @@ +diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp +index 6de161e87..432af5784 100644 +--- a/host/lib/usrp/b200/b200_impl.cpp ++++ b/host/lib/usrp/b200/b200_impl.cpp +@@ -1410,10 +1410,10 @@ void b200_impl::update_atrs(void) + if (not enb_rx and enb_tx) + fd = txonly; + gpio_atr_3000::sptr atr = perif.atr; +- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF); +- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly); +- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly); +- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd); ++ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7)); ++ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7)); + } + if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr) { + radio_perifs_t& perif = _radio_perifs[_fe2]; +@@ -1431,10 +1431,10 @@ void b200_impl::update_atrs(void) + if (not enb_rx and enb_tx) + fd = txonly; + gpio_atr_3000::sptr atr = perif.atr; +- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF); +- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly); +- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly); +- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd); ++ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7)); ++ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7)); ++ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7)); + } + } + diff --git a/common/utils/DOC/loader/devusage.md b/common/utils/DOC/loader/devusage.md index bd45c88a85..47c4806eac 100644 --- a/common/utils/DOC/loader/devusage.md +++ b/common/utils/DOC/loader/devusage.md @@ -10,7 +10,7 @@ As a developer you may need to look at these sections: Loader usage examples can be found in oai sources: -* device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91) +* device and transport initialization code: [function `load_lib` in *sdr/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/sdr/COMMON/common_lib.c#L91) * turbo encoder and decoder initialization: [function `load_codinglib`in *openair1/PHY/CODING/__coding_load.c__*](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c#L113) [loader home page](../loader.md) diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md index 41a0807a24..59623e256b 100644 --- a/common/utils/DOC/loader/devusage/api.md +++ b/common/utils/DOC/loader/devusage/api.md @@ -6,7 +6,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) * Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters. * loads the shared library, using the dlopen system call * looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function. -* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function. +* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function. * If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields). * looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 509c4581a9..be5d6ac7fe 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -80,7 +80,7 @@ extern "C" { * @brief the macros that describe the maximum length of LOG * @{*/ -#define MAX_LOG_TOTAL 1500 /*!< \brief the maximum length of a log */ +#define MAX_LOG_TOTAL 16384 /*!< \brief the maximum length of a log */ /* @}*/ /** @defgroup _log_level Message levels defined by LOG @@ -219,6 +219,7 @@ typedef enum { SPGW, S1AP, F1AP, + E1AP, SCTP, HW, OSA, diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 8ec3538c10..4d18bea384 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1239,6 +1239,27 @@ ID = LEGACY_F1AP_ERROR GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY FORMAT = string,log +ID = LEGACY_E1AP_TRACE + DESC = E1AP TRACE LEVEL + GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log +ID = LEGACY_E1AP_DEBUG + DESC = E1AP DEBUG LEVEL + GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_E1AP_INFO + DESC = E1AP INFO LEVEL + GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_E1AP_WARNING + DESC = E1AP WARNING LEVEL + GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_E1AP_ERROR + DESC = E1AP ERROR LEVEL + GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log + ################# #### UE LOGS #### ################# diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 9f1fcd1741..a8518af660 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -339,6 +339,8 @@ void *rrc_enb_process_msg(void *); TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\ TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_CUCP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_CUUP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_NSA_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ diff --git a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h index ed8b5e2301..7ba4444abf 100644 --- a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h +++ b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h @@ -50,11 +50,6 @@ {"dlsch_turbo_encod_prep", &(phyvars->dlsch_turbo_encoding_preperation_stats),0,1},\ {"dlsch_turbo_encod_segm", &(phyvars->dlsch_turbo_encoding_segmentation_stats),0,1},\ {"dlsch_turbo_encod", &(phyvars->dlsch_turbo_encoding_stats),0,1},\ - {"dlsch_turbo_encod_waiting", &(phyvars->dlsch_turbo_encoding_waiting_stats),0,1},\ - {"dlsch_turbo_encod_signal", &(phyvars->dlsch_turbo_encoding_signal_stats),0,1},\ - {"dlsch_turbo_encod_main", &(phyvars->dlsch_turbo_encoding_main_stats),0,1},\ - {"dlsch_turbo_encod_wakeup0", &(phyvars->dlsch_turbo_encoding_wakeup_stats0),0,1},\ - {"dlsch_turbo_encod_wakeup1", &(phyvars->dlsch_turbo_encoding_wakeup_stats1),0,1},\ {"dlsch_interleaving", &(phyvars->dlsch_interleaving_stats),0,1},\ {"rx_dft", &(phyvars->rx_dft_stats),0,1},\ {"ulsch_channel_estimation", &(phyvars->ulsch_channel_estimation_stats),0,1},\ diff --git a/common/utils/time_meas.c b/common/utils/time_meas.c index 15766b5a3f..9577968bc4 100644 --- a/common/utils/time_meas.c +++ b/common/utils/time_meas.c @@ -85,21 +85,21 @@ void print_meas(time_stats_t *ts, first_time=1; if ((total_exec_time == NULL) || (sf_exec_time== NULL)) - fprintf(stderr, "%25s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz); + fprintf(stderr, "%30s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz); else - fprintf(stderr, "%25s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz); + fprintf(stderr, "%30s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz); } if (ts->trials>0) { //printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials); if ((total_exec_time == NULL) || (sf_exec_time== NULL)) { - fprintf(stderr, "%25s: %15.3f us; %15d; %15.3f us;\n", + fprintf(stderr, "%30s: %15.3f us; %15d; %15.3f us;\n", name, (ts->diff/ts->trials/cpu_freq_GHz/1000.0), ts->trials, ts->max/cpu_freq_GHz/1000.0); } else { - fprintf(stderr, "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n", + fprintf(stderr, "%30s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n", name, (ts->diff/cpu_freq_GHz/1000000.0), ((ts->diff/cpu_freq_GHz/1000000.0)/(total_exec_time->diff/cpu_freq_GHz/1000000.0))*100, // percentage diff --git a/doc/BUILD.md b/doc/BUILD.md index 70d69f5afd..dee55599cc 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -39,7 +39,7 @@ Running the [build_oai](../cmake_targets/build_oai) script also generates some - `rb_tool`: radio bearer utility - `genids` T Tracer utility, used at build time to generate T_IDs.h include file. This binary is located in the [T Tracer source file directory](../common/utils/T) . -The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../cmake_targets/CMakeLists.txt), it is used as input by cmake to generate the makefiles. +The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../CMakeLists.txt), it is used as input by cmake to generate the makefiles. The oai softmodem supports many use cases, and new ones are regularly added. Most of them are accessible using the configuration file or the command line options and continuous effort is done to avoid introducing build options as it makes tests and usage more complicated than run-time options. The following functionalities, originally requiring a specific build are now accessible by configuration or command line options: @@ -78,7 +78,7 @@ cd cmake_targets/ ``` - The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. -- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be specifically built using `-w SIMU` option, but is also built during any softmodem build. +- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../sdr/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be specifically built using `-w SIMU` option, but is also built during any softmodem build. - `--eNB` is to build the `lte-softmodem` executable and all required shared libraries - `--gNB` is to build the `nr-softmodem` executable and all required shared libraries - `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries @@ -88,12 +88,19 @@ You can build any oai softmodem executable separately, you may not need all of t After completing the build, the binaries are available in the `cmake_targets/ran_build/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel15. -When installing the pre-requisites, especially the `UHD` driver, you can now specify if you want to install from source or not. +## Installing UHD from source + +Previously for Ubuntu distributions, when installing the pre-requisites, most of the packages are installed from PPA. + +Especially the `UHD` driver, but you could not easily manage the version of `libuhd` that will be installed. + +Now, when installing the pre-requisites, especially the `UHD` driver, you can now specify if you want to install from source or not. - For `fedora`-based OS, it was already the case all the time. But now you can specify which version to install. -- For `ubuntu` OS, the Ettus PPA currently installs the following versions: - * `Ubuntu16.04`: --> version `3.15.0.0` - * `Ubuntu18.04`: --> version `4.1.0.0` +- For `ubuntu` OS, you can still install from the Ettus PPA or select a version to install from source. + * In case of PPA installation, you do nothing special, the script will install the latest version available on the PPA. + - `./build_oai -I -w USRP` + * In case of a installation from source, you do as followed: ```bash export BUILD_UHD_FROM_SOURCE=True @@ -103,49 +110,15 @@ export UHD_VERSION=3.15.0.0 The `UHD_VERSION` env variable `SHALL` be a valid tag (minus `v`) from the `https://github.com/EttusResearch/uhd.git` repository. -## Issue when building `nasmeh` module ## +**CAUTION: Note that if you are using the OAI eNB in TDD mode with B2xx boards, a patch is mandatory.** -A lot of users and contributors have faced the issue: `nasmesh` module does not build. +Starting this commit, the patch is applied automatically in our automated builds. -The reason is that the linux headers are not properly installed. For example: +See: -```bash -$ uname -r -4.4.0-145-lowlatency -$ dpkg --list | grep 4.4.0-145-lowlatency | grep headers -ii linux-headers-4.4.0-145-lowlatency 4.4.0-145.171 -``` - -In my example it is properly installed. - -Check on your environment: - -```bash -$ uname -r -your-version -$ dpkg --list | grep your-version | grep headers -$ -``` - -Install it: - -```bash -$ sudo apt-get install --yes linux-headers-your-version -``` - -On CentOS or RedHat Entreprise Linux: - -```bash -$ uname -r -3.10.0-1062.9.1.rt56.1033.el7.x86_64 -$ yum list installed | grep kernel | grep devel -kernel-devel.x86_64 3.10.0-1062.9.1.el7 @rhel-7-server-rpms -kernel-rt-devel.x86_64 3.10.0-1062.9.1.rt56.1033.el7 -``` - -If your kernel is generic, install `kernel-devel` package: `sudo yum install kernel-devel` - -In most case, your kernel is real-time. Install `kernel-rt-devel` package: `sudo yum install kernel-rt-devel` +* `cmake_targets/tools/uhd-3.15-tdd-patch.diff` +* `cmake_targets/tools/uhd-4.x-tdd-patch.diff` +* `cmake_targets/tools/build_helper` --> function `install_usrp_uhd_driver_from_source` # Building Optional Binaries diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 2dc4fd2ff5..11f8d2caf7 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -23,7 +23,7 @@ It is planned to enhance this simulator with the following functionalities: - Support for multiple UE connections,each UE being a `lte-uesoftmodem` or `nr_uesoftmodem` instance. - Support for multiple eNodeB's or gNodeB's for hand-over tests - This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../targets/ARCH/rfsimulator/README.md ) contains the detailed documentation. + This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../sdr/rfsimulator/README.md ) contains the detailed documentation. # L2 nFAPI Simulator @@ -102,7 +102,7 @@ Some other useful paramters of the UE are Instead of randomly generated payload, in the phy-test mode we can also inject/receive user-plane traffic over a TUN interface. This is the so-called noS1 mode. -This setup is described in the [rfsimulator page](../targets/ARCH/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested. +This setup is described in the [rfsimulator page](../sdr/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested. ## do-ra setup with OAI @@ -169,15 +169,15 @@ gNB on machine 1: UE on machine 2: -`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 -s 516 --sa` +`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --sa` With the RF simulator (on the same machine): `sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --sa` -`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 -s 516 --rfsim --sa` +`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --rfsim --sa` -where `-r` sets the transmission bandwidth configuration in terms of RBs, `-C` sets the downlink carrier frequency and `-s` sets the SSB start subcarrier. +where `-r` sets the transmission bandwidth configuration in terms of RBs, `-C` sets the downlink carrier frequency and `--ssb` sets the SSB start subcarrier. Additionally, at UE side `--uecap_file` option can be used to pass the UE Capabilities input file (path location + filename), e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap.xml` diff --git a/doc/TESTING_5GSA_setup.md b/doc/TESTING_5GSA_setup.md index 1e27e1616d..b12b3478e8 100644 --- a/doc/TESTING_5GSA_setup.md +++ b/doc/TESTING_5GSA_setup.md @@ -214,4 +214,21 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3 --rfsim --sa --nokrnmod -O ``` +If you get the following error: + +```bash +Assertion (k2 >= ((5))) failed! +In get_k2() /home/mir/workspace/openairinterface5g/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c:147 +Slot offset K2 (2) cannot be less than DURATION_RX_TO_TX (5). K2 set according to min_rxtxtime in config file. +``` + +Add the following parameter (i.e., min_rxtxtime) in the gNB configuration file, just after nr_cellid. + +```bash +nr_cellid = 12345678L; +min_rxtxtime=6; +``` +or --gNBs.[0].min_rxtxtime 6 to the gNB command line + + The IP address at the execution command of the OAI UE corresponds to the target IP of the gNB host that the RFSIMULATOR at the UE will connect to. In the above example, we assume that the gNB and UE are running on the same host so the specified address (127.0.0.1) is the one of the loopback interface. diff --git a/doc/tutorial_resources/docker-compose-basic-nrf.yaml b/doc/tutorial_resources/docker-compose-basic-nrf.yaml index 1c78bf37f9..b88020e6b0 100644 --- a/doc/tutorial_resources/docker-compose-basic-nrf.yaml +++ b/doc/tutorial_resources/docker-compose-basic-nrf.yaml @@ -51,13 +51,6 @@ services: networks: public_net: ipv4_address: 192.168.70.136 - volumes: - - ./healthscripts/udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh" - interval: 10s - timeout: 5s - retries: 5 oai-udm: container_name: "oai-udm" image: oai-udm:develop @@ -86,13 +79,6 @@ services: networks: public_net: ipv4_address: 192.168.70.137 - volumes: - - ./healthscripts/udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh" - interval: 10s - timeout: 5s - retries: 5 oai-ausf: container_name: "oai-ausf" image: oai-ausf:develop @@ -120,13 +106,6 @@ services: networks: public_net: ipv4_address: 192.168.70.138 - volumes: - - ./healthscripts/ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh" - interval: 10s - timeout: 5s - retries: 5 oai-nrf: container_name: "oai-nrf" image: oai-nrf:develop @@ -141,13 +120,6 @@ services: networks: public_net: ipv4_address: 192.168.70.130 - volumes: - - ./healthscripts/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh" - interval: 10s - timeout: 5s - retries: 5 oai-amf: container_name: "oai-amf" image: oai-amf:develop @@ -213,13 +185,6 @@ services: - mysql - oai-nrf - oai-ausf - volumes: - - ./healthscripts/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh" - interval: 10s - timeout: 15s - retries: 5 networks: public_net: ipv4_address: 192.168.70.132 @@ -270,13 +235,6 @@ services: depends_on: - oai-nrf - oai-amf - volumes: - - ./healthscripts/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh" - interval: 10s - timeout: 5s - retries: 5 networks: public_net: ipv4_address: 192.168.70.133 @@ -325,13 +283,6 @@ services: cap_drop: - ALL privileged: true - volumes: - - ./healthscripts/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh - healthcheck: - test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh" - interval: 10s - timeout: 5s - retries: 5 networks: public_net: ipv4_address: 192.168.70.134 diff --git a/executables/main_ru.c b/executables/main_ru.c index 3b1ce1116b..9db2e95576 100644 --- a/executables/main_ru.c +++ b/executables/main_ru.c @@ -45,8 +45,8 @@ #include "common/utils/load_module_shlib.h" -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" #include "PHY/phy_vars.h" @@ -66,6 +66,7 @@ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; static int DEFBFW[] = {0x00007fff}; +static int DEFRUTPCORES[] = {2,4,6,8}; THREAD_STRUCT thread_struct; pthread_cond_t sync_cond; diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 6c4a7fabfe..e5f24c98d8 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -38,6 +38,7 @@ #include "assertions.h" #include #include +#include "rt_profiling.h" #include "PHY/types.h" @@ -54,12 +55,11 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "../../ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/phy_extern.h" @@ -115,10 +115,17 @@ void tx_func(void *param) { int frame_tx = info->frame; int slot_tx = info->slot; + int absslot_tx = info->timestamp_tx/info->gNB->frame_parms.get_samples_per_slot(slot_tx,&info->gNB->frame_parms); + int absslot_rx = absslot_tx-info->gNB->RU_list[0]->sl_ahead; + int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; + + clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.start_L1_TX[rt_prof_idx]); phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1); + clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]); + } void rx_func(void *param) { @@ -130,6 +137,11 @@ void rx_func(void *param) { int slot_tx = info->slot_tx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + int absslot_tx = info->timestamp_tx/gNB->frame_parms.get_samples_per_slot(slot_rx,&gNB->frame_parms); + int absslot_rx = absslot_tx - gNB->RU_list[0]->sl_ahead; + int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; + + clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.start_L1_RX[rt_prof_idx]); start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* @@ -228,6 +240,7 @@ void rx_func(void *param) { stop_meas( &softmodem_stats_rxtx_sf ); LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); + clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_RX[rt_prof_idx]); // Call the scheduler start_meas(&gNB->ul_indication_stats); @@ -383,6 +396,8 @@ void *tx_reorder_thread(void* param) { AssertFatal(resL1Reserve != NULL, "pullTpool() did not return start message in %s\n", __func__); int next_tx_slot=((processingData_L1tx_t *)NotifiedFifoData(resL1Reserve))->slot; + LOG_I(PHY,"tx_reorder_thread started\n"); + while (!oai_exit) { notifiedFIFO_elt_t *resL1; if (resL1Reserve) { @@ -419,6 +434,7 @@ void *tx_reorder_thread(void* param) { pushNotifiedFIFO(&gNB->L1_tx_free, resL1); if (resL1==resL1Reserve) resL1Reserve=NULL; + LOG_D(PHY,"gNB: %d.%d : calling RU TX function\n",syncMsgL1->frame,syncMsgL1->slot); ru_tx_func((void*)&syncMsgRU); } return(NULL); @@ -457,7 +473,9 @@ void init_gNB_Tpool(int inst) { if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT)) threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); - threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder", -1, OAI_PRIORITY_RT_MAX); + LOG_I(PHY,"Creating thread for TX reordering and dispatching to RU\n"); + threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder", + gNB->RU_list[0] ? gNB->RU_list[0]->tpcores[1] : -1, OAI_PRIORITY_RT_MAX); } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index baff757312..71e7a4f4b1 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -35,12 +35,12 @@ #include "common/utils/assertions.h" #include "common/utils/system.h" #include "common/ran_context.h" +#include "rt_profiling.h" -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/types.h" #include "PHY/defs_nr_common.h" @@ -59,11 +59,12 @@ unsigned short config_frames[4] = {2,9,11,13}; #endif + /* these variables have to be defined before including ENB_APP/enb_paramdef.h and GNB_APP/gnb_paramdef.h */ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; static int DEFBFW[] = {0x00007fff}; - +static int DEFRUTPCORES[] = {-1,-1,-1,-1}; //static int DEFNRBANDS[] = {7}; //static int DEFGNBS[] = {0}; @@ -276,8 +277,21 @@ int connect_rau(RU_t *ru) { // southbound IF5 fronthaul for 16-bit OAI format void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + int offset = ru->nr_frame_parms->get_samples_slot_timestamp(slot,ru->nr_frame_parms,0); + void *buffs[ru->nb_tx]; + for (int aid=0;aidnb_tx;aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset]; + struct timespec txmeas; + clock_gettime(CLOCK_MONOTONIC, &txmeas); + LOG_D(PHY,"IF5 TX %d.%d, TS %llu, buffs[0] %p, buffs[1] %p ener0 %f dB, tx start %d\n",frame,slot,(unsigned long long)timestamp,buffs[0],buffs[1], + 10*log10((double)signal_energy(buffs[0],ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms))),(int)txmeas.tv_nsec); + ru->ifdevice.trx_write_func2(&ru->ifdevice, + timestamp, + buffs, + 0, + ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms), + 0, + ru->nb_tx); - send_IF5(ru, timestamp, slot, &ru->seqno, IF5_RRH_GW_DL); } // southbound IF4p5 fronthaul @@ -297,19 +311,19 @@ void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { // Synchronous if5 from south -uint64_t ts_rx[20]; void fh_if5_south_in(RU_t *ru, int *frame, int *tti) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; RU_proc_t *proc = &ru->proc; - recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); + start_meas(&ru->rx_fhaul); + + ru->ifdevice.trx_read_func2(&ru->ifdevice,&proc->timestamp_rx,NULL,fp->get_samples_per_slot(*tti,fp)); if (proc->first_rx == 1) ru->ts_offset = proc->timestamp_rx; proc->frame_rx = ((proc->timestamp_rx-ru->ts_offset) / (fp->samples_per_subframe*10))&1023; proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx-ru->ts_offset,fp); -//(idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); - ts_rx[*tti] = proc->timestamp_rx; - LOG_D(PHY,"IF5 %d.%d => RX %d.%d first_rx %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx); + if (proc->first_rx == 0) { if (proc->tti_rx != *tti) { @@ -327,7 +341,15 @@ void fh_if5_south_in(RU_t *ru, *tti = proc->tti_rx; } + stop_meas(&ru->rx_fhaul); + struct timespec rxmeas; + clock_gettime(CLOCK_MONOTONIC, &rxmeas); + double fhtime = ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0); + if (fhtime > 800) LOG_W(PHY,"IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx,ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0),(int)rxmeas.tv_nsec); + else LOG_D(PHY,"IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx,ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0),(int)rxmeas.tv_nsec); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); + } // Synchronous if4p5 from south @@ -476,7 +498,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { RU_proc_t *proc = &ru->proc; int tti_tx,frame_tx; openair0_timestamp timestamp_tx; - recv_IF5(ru, ×tamp_tx, *slot, IF5_RRH_GW_DL); + AssertFatal(1==0,"Shouldn't get here\n"); // printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); frame_tx = (timestamp_tx / (fp->samples_per_subframe*10))&1023; uint32_t idx_sf = timestamp_tx / fp->samples_per_subframe; @@ -553,11 +575,9 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { } void fh_if5_north_out(RU_t *ru) { - RU_proc_t *proc=&ru->proc; - uint8_t seqno=0; /// **** send_IF5 of rxdata to BBU **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); - send_IF5(ru, proc->timestamp_rx, proc->tti_rx, &seqno, IF5_RRH_GW_UL); + AssertFatal(1==0,"Shouldn't get here\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); } @@ -827,6 +847,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->num_rb_dl=N_RB; cfg->tx_num_channels=ru->nb_tx; cfg->rx_num_channels=ru->nb_rx; + LOG_I(PHY,"Setting RF config for N_RB %d, NB_RX %d, NB_TX %d\n",cfg->num_rb_dl,cfg->rx_num_channels,cfg->tx_num_channels); for (i=0; inb_tx; i++) { if (ru->if_frequency == 0) { @@ -957,17 +978,17 @@ void *ru_stats_thread(void *param) { sleep(1); if (opp_enabled == 1) { - if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); + if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx (all ports)",NULL,NULL); if (ru->feptx_ofdm) { - print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL); + print_meas(&ru->precoding_stats,(ru->half_slot_parallelization==0)?"feptx_prec (per port)":"feptx_prec (per port, half_slot)",NULL,NULL); + print_meas(&ru->ofdm_mod_stats,(ru->half_slot_parallelization==0)?"feptx_ofdm (per port)":"feptx_ofdm (per port, half_slot)",NULL,NULL); print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL); - print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL); } - print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); - print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); + if (ru->if_south == REMOTE_IF5) print_meas(&ru->ifdevice.tx_fhaul,"tx_fhaul (IF5)",NULL,NULL); + else print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); if (ru->fh_north_out) { print_meas(&ru->compression,"compression",NULL,NULL); @@ -987,7 +1008,13 @@ void ru_tx_func(void *param) { int slot_tx = info->slot_tx; int print_frame = 8; char filename[40]; + + // note that this will break for 60/120 kHz, to be handled + int absslot_tx = info->timestamp_tx/fp->get_samples_per_slot(slot_tx,fp); + int absslot_rx = absslot_tx-ru->sl_ahead; + int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; + clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]); // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx); @@ -1030,6 +1057,11 @@ void ru_tx_func(void *param) { }//for (i=0; inb_tx; i++) }//if(frame_tx == print_frame) }//else emulate_rf + clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_TX[rt_prof_idx]); + struct timespec *t0=&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]; + struct timespec *t1=&ru->rt_ru_profiling.return_RU_TX[rt_prof_idx]; + + LOG_D(PHY,"rt_prof_idx %d : RU_TX time %d\n",rt_prof_idx,(int)(1e9 * (t1->tv_sec - t0->tv_sec) + (t1->tv_nsec-t0->tv_nsec))); } void *ru_thread( void *param ) { @@ -1054,9 +1086,9 @@ void *ru_thread( void *param ) { memcpy((void *)&ru->config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru->config)); if(emulate_rf) { - fill_rf_config(ru,ru->rf_config_file); nr_init_frame_parms(&ru->config, fp); nr_dump_frame_parms(fp); + fill_rf_config(ru,ru->rf_config_file); nr_phy_init_RU(ru); if (setup_RU_buffers(ru)!=0) { @@ -1071,7 +1103,7 @@ void *ru_thread( void *param ) { // Start IF device if any if (ru->nr_start_if) { - LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); + LOG_I(PHY,"Starting IF interface for RU %d, nb_rx %d\n",ru->idx,ru->nb_rx); AssertFatal(ru->nr_start_if(ru,NULL) == 0, "Could not start the IF device\n"); if (ru->has_ctrl_prt > 0) { @@ -1111,7 +1143,7 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); } else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - LOG_I(PHY,"RU %d RF started\n",ru->idx); + LOG_I(PHY,"RU %d RF started opp_enabled %d\n",ru->idx,opp_enabled); // start trx write thread if(usrp_tx_thread == 1) { if (ru->start_write_thread) { @@ -1166,6 +1198,7 @@ void *ru_thread( void *param ) { if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); + if (initial_wait == 1 && proc->frame_rx < 300 && ru->fh_south_in == rx_rf) { if (proc->frame_rx>0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx==0) { LOG_I(PHY,"delay processing to let RX stream settle, frame %d (trials %d)\n",proc->frame_rx,ru->rx_fhaul.trials); @@ -1178,13 +1211,20 @@ void *ru_thread( void *param ) { initial_wait=0; opp_enabled = opp_enabled0; } - if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) reset_meas(&ru->rx_fhaul); + if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) { + reset_meas(&ru->rx_fhaul); + /*if (ru->if_south == REMOTE_IF5) reset_meas(&ru->ifdevice.tx_fhaul); + else*/ reset_meas(&ru->tx_fhaul); + } proc->timestamp_tx = proc->timestamp_rx; int sl=proc->tti_tx; for (int slidx=0;slidxsl_ahead;slidx++) proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp); proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(ru->sl_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; proc->tti_tx = (proc->tti_rx + ru->sl_ahead)%fp->slots_per_frame; + int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp); + int rt_prof_idx = absslot_rx % RT_PROF_DEPTH; + clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]); LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n", frame,slot, proc->frame_rx,proc->tti_rx, @@ -1200,15 +1240,9 @@ void *ru_thread( void *param ) { if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { if (ru->feprx) { ru->feprx(ru,proc->tti_rx); + clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx]); //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1); LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); -/* - LOG_D(PHY,"Copying rxdataF from RU to gNB\n"); - - for (int aa=0; aanb_rx; aa++) - memcpy((void *)RC.gNB[0]->common_vars.rxdataF[aa], - (void *)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); -*/ if (IS_SOFTMODEM_DOSCOPE && RC.gNB[0]->scopeData) ((scopeData_t *)RC.gNB[0]->scopeData)->slotFunc(ru->common.rxdataF[0],proc->tti_rx, RC.gNB[0]->scopeData); @@ -1216,24 +1250,12 @@ void *ru_thread( void *param ) { int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST); uint8_t prachStartSymbol,N_dur; if (prach_id>=0) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); + T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0), T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2)); N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt); - /* - get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value, - proc->frame_rx,proc->tti_rx, - ru->config.carrier_config.dl_frequency.value, - fp->numerology_index, - fp->frame_type, - &format, - &start_symbol, - &N_t_slot, - &N_dur, - &RA_sfn_index, - &N_RA_slot, - &config_period); - */ for (int prach_oc = 0; prach_ocprach_list[prach_id].num_prach_ocas; prach_oc++) { prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. @@ -1244,11 +1266,16 @@ void *ru_thread( void *param ) { prach_oc, proc->frame_rx,proc->tti_rx); } - + clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx]); free_nr_ru_prach_entry(ru,prach_id); - } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); + } // end if (prach_id > 0) + } // end if (ru->feprx) + else { + memset(&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx],0,sizeof(struct timespec)); + memset(&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx],0,sizeof(struct timespec)); } - } + } // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { // At this point, all information for subframe has been received on FH interface res = pullTpool(&gNB->resp_L1, &gNB->threadPool); @@ -1283,6 +1310,9 @@ int start_streaming(RU_t *ru) { } int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) { + for (int i=0;inb_rx;i++) ru->openair0_cfg.rxbase[i] = ru->common.rxdata[i]; + ru->openair0_cfg.rxsize = ru->nr_frame_parms->samples_per_subframe*10; + reset_meas(&ru->ifdevice.tx_fhaul); return(ru->ifdevice.trx_start_func(&ru->ifdevice)); } @@ -1312,21 +1342,18 @@ void init_RU_proc(RU_t *ru) { proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; - proc->feptx_mask = 0; for (i=0; i<10; i++) proc->symbol_mask[i]=0; pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_cond_init( &proc->cond_emulateRF, NULL); - threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX ); + threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "ru_thread", ru->tpcores[0], OAI_PRIORITY_RT_MAX ); if(emulate_rf) threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT ); - + if (opp_enabled == 1) + threadCreate( &ru->ru_stats_thread, ru_stats_thread, (void *)ru,"ru_stats", -1, OAI_PRIORITY_RT ); if (get_thread_worker_conf() == WORKER_ENABLE) { - if (ru->feprx) nr_init_feprx_thread(ru); - - if (ru->feptx_ofdm) nr_init_feptx_thread(ru); } } @@ -1340,17 +1367,16 @@ void kill_NR_RU_proc(int inst) { * mutex_fep/cond_fep. Thus, we unlocked above for pthread_FH above and do * the same for FEP thread below again (using broadcast() to ensure both * threads get the signal). This one will also destroy the mutex and cond. */ - pthread_mutex_lock(&proc->mutex_fep); - proc->instance_cnt_fep = 0; - pthread_cond_broadcast(&proc->cond_fep); - pthread_mutex_unlock( &proc->mutex_fep ); + pthread_mutex_lock(&proc->mutex_fep[0]); + proc->instance_cnt_fep[0] = 0; + pthread_cond_broadcast(&proc->cond_fep[0]); + pthread_mutex_unlock( &proc->mutex_fep[0] ); pthread_join(proc->pthread_FH, NULL); - if (ru->feprx) - nr_kill_feprx_thread(ru); - - if (ru->feptx_ofdm) - nr_kill_feptx_thread(ru); + if (opp_enabled) { + LOG_D(PHY, "Joining ru_stats_thread\n"); + pthread_join(ru->ru_stats_thread, NULL); + } } int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { @@ -1554,8 +1580,8 @@ void set_function_spec_param(RU_t *ru) { ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception ru->fh_south_out = tx_rf; // send output to RF ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU) + ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs + ru->feptx_ofdm = nr_feptx_tp; // this is fep with idft only (no precoding in RRU) ru->feptx_prec = NULL; ru->nr_start_if = nr_start_if; // need to start the if interface for if4p5 ru->ifdevice.host_type = RRU_HOST; @@ -1575,9 +1601,9 @@ void set_function_spec_param(RU_t *ru) { malloc_IF4p5_buffer(ru); } else if (ru->function == gNodeB_3GPP) { ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding - ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // this is fep with idft and precoding + ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs + ru->feptx_ofdm = nr_feptx_tp; // this is fep with idft and precoding + ru->feptx_prec = NULL; ru->fh_north_in = NULL; // no incoming fronthaul from north ru->fh_north_out = NULL; // no outgoing fronthaul to north ru->nr_start_if = NULL; // no if interface @@ -1606,11 +1632,12 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF5: // the remote unit is IF5 RRU ru->do_prach = 0; - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs + ru->txfh_in_fep = 0; + ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs + ru->feptx_prec = NULL; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = nr_feptx_tp; // need to do transmit Precoding + IDFTs ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_out = (ru->txfh_in_fep>0) ? NULL : fh_if5_south_out; // synchronous IF5 transmission ru->fh_south_asynch_in = NULL; // no asynchronous UL ru->start_rf = ru->eth_params.transp_preference == ETH_UDP_IF5_ECPRI_MODE ? start_streaming : NULL; ru->stop_rf = NULL; @@ -1619,6 +1646,8 @@ void set_function_spec_param(RU_t *ru) { ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; ru->ifdevice.configure_rru = configure_ru; + + printf("starting transport : rx_num_antennas %d, tx_num_antennas %d\n",ru->openair0_cfg.rx_num_channels,ru->openair0_cfg.tx_num_channels); ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); printf("openair0_transport_init returns %d for ru_id %u\n", ret, ru->idx); @@ -1632,7 +1661,7 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF4p5: ru->do_prach = 0; ru->feprx = NULL; // DFTs - ru->feptx_prec = nr_feptx_prec; // Precoding operation + ru->feptx_prec = NULL; // Precoding operation ru->feptx_ofdm = NULL; // no OFDM mod ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission @@ -1709,7 +1738,6 @@ void init_NR_RU(char *rf_config_file) { ru->gNB_list[0] = RC.gNB[0]; ru->num_gNB=1; // - // DJP - feptx_prec() / feptx_ofdm() parses the gNB_list (based on num_gNB) and copies the txdata_F to txdata in RU // } else { LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); @@ -1739,11 +1767,29 @@ void init_NR_RU(char *rf_config_file) { } } } - + ru->openair0_cfg.rx_num_channels = ru->nb_rx; + ru->openair0_cfg.tx_num_channels = ru->nb_tx; //LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],NB_timing[ru->if_timing],ru->function); set_function_spec_param(ru); LOG_I(PHY,"Starting ru_thread %d\n",ru_id); init_RU_proc(ru); + int threadCnt = ru->num_tpcores; + if (threadCnt < 2) LOG_E(PHY,"Number of threads for gNB should be more than 1. Allocated only %d\n",threadCnt); + else LOG_I(PHY,"RU Thread pool size %d\n",threadCnt); + char pool[80]; + int s_offset = sprintf(pool,"%d",ru->tpcores[0]); + for (int icpu=1; icputpcores[icpu]); + } + LOG_I(PHY,"RU thread-pool core string %s\n",pool); + ru->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); + initTpool(pool, ru->threadPool, cpumeas(CPUMEAS_GETSTATE)); + // FEP RX result FIFO + ru->respfeprx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initNotifiedFIFO(ru->respfeprx); + // FEP TX result FIFO + ru->respfeptx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initNotifiedFIFO(ru->respfeptx); } // for ru_id // sleep(1); @@ -1918,6 +1964,13 @@ static void NRRCconfig_RU(void) { RC.ru[j]->openair0_cfg.nr_band = RC.ru[j]->band[0]; RC.ru[j]->openair0_cfg.nr_scs_for_raster = *(RUParamList.paramarray[j][RU_NR_SCS_FOR_RASTER].iptr); printf("[RU %d] Setting nr_flag %d, nr_band %d, nr_scs_for_raster %d\n",j,RC.ru[j]->openair0_cfg.nr_flag,RC.ru[j]->openair0_cfg.nr_band,RC.ru[j]->openair0_cfg.nr_scs_for_raster); + RC.ru[j]->openair0_cfg.rxfh_cores[0] = *(RUParamList.paramarray[j][RU_RXFH_CORE_ID].iptr); + RC.ru[j]->openair0_cfg.txfh_cores[0] = *(RUParamList.paramarray[j][RU_TXFH_CORE_ID].iptr); + RC.ru[j]->num_tpcores = *(RUParamList.paramarray[j][RU_NUM_TP_CORES].iptr); + RC.ru[j]->half_slot_parallelization = *(RUParamList.paramarray[j][RU_HALF_SLOT_PARALLELIZATION].iptr); + printf("[RU %d] Setting half-slot parallelization to %d\n",j,RC.ru[j]->half_slot_parallelization); + AssertFatal(RC.ru[j]->num_tpcores <= RUParamList.paramarray[j][RU_TP_CORES].numelt, "Number of TP cores should be <=16\n"); + for (i=0; inum_tpcores; i++) RC.ru[j]->tpcores[i] = RUParamList.paramarray[j][RU_TP_CORES].iptr[i]; if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index ff5042bd95..36eedd2d3b 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -24,7 +24,7 @@ #include #include -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" #undef MALLOC #include "assertions.h" #include "PHY/types.h" diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 5da5fe42f5..e3998975e8 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -39,8 +39,8 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -313,12 +313,12 @@ int create_gNB_tasks(uint32_t gnb_nb) { } } - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { - char* gnb_ipv4_address_for_NGU = NULL; - uint32_t gnb_port_for_NGU = 0; - char* gnb_ipv4_address_for_S1U = NULL; - uint32_t gnb_port_for_S1U = 0; + char* gnb_ipv4_address_for_NGU = NULL; + uint32_t gnb_port_for_NGU = 0; + char* gnb_ipv4_address_for_S1U = NULL; + uint32_t gnb_port_for_S1U = 0; paramdef_t NETParams[] = GNBNETPARAMS_DESC; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); @@ -326,23 +326,17 @@ int create_gNB_tasks(uint32_t gnb_nb) { for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++) { if( NETParams[i].strptr == NULL) { - LOG_E(NGAP, "No configuration in the file.\n"); - NGAP_CONF_MODE = 0; + LOG_E(NGAP, "No AMF configuration in the file.\n"); } else { LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr); } } - + if (gnb_nb > 0) { - if(NGAP_CONF_MODE) { - if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) { - LOG_E(NGAP, "Create task for NGAP failed\n"); - return -1; - } - } else { - LOG_I(NGAP, "Ngap task not created\n"); + if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) { + LOG_E(NGAP, "Create task for NGAP failed\n"); + return -1; } - } } @@ -359,8 +353,8 @@ int create_gNB_tasks(uint32_t gnb_nb) { return -1; } - //Use check on x2ap to consider the NSA scenario and check on AMF_MODE_ENABLED for the SA scenario - if(is_x2ap_enabled() || AMF_MODE_ENABLED) { + //Use check on x2ap to consider the NSA scenario and check for SA scenario + if(is_x2ap_enabled() || get_softmodem_params()->sa) { if (itti_create_task (TASK_GTPV1_U, >pv1uTask, NULL) < 0) { LOG_E(GTPU, "Create task for GTPV1U failed\n"); return -1; @@ -630,8 +624,6 @@ int main( int argc, char **argv ) { } openair0_cfg[0].threequarter_fs = threequarter_fs; - AMF_MODE_ENABLED = get_softmodem_params()->sa; - NGAP_CONF_MODE = get_softmodem_params()->sa; if (get_softmodem_params()->do_ra) AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 546fe7bee0..22b213a8d9 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -29,8 +29,8 @@ {"D" , CONFIG_HLP_DLBM_PHYTEST,0, u64ptr:&dlsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \ {"U" , CONFIG_HLP_ULBM_PHYTEST,0, u64ptr:&ulsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ - {"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, 0, iptr:&ldpc_offload_flag, defstrval:0, TYPE_INT, 0}, \ - {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \ + {"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, 0, iptr:&ldpc_offload_flag, defstrval:0, TYPE_INT, 0}, \ + {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 2686f35b16..a3a3fac12b 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -35,8 +35,8 @@ //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "common/utils/nr/nr_common.h" -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "openair1/PHY/MODULATION/nr_modulation.h" diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 5c8dafc9af..f8ce6c1f27 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -67,7 +67,7 @@ {"A" , CONFIG_HLP_TADV, 0, iptr:&(UE->timing_advance), defintval:0, TYPE_INT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \ {"r" , CONFIG_HLP_PRB_SA, 0, iptr:&(fp->N_RB_DL), defintval:106, TYPE_UINT, 0}, \ - {"s" , CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \ + {"ssb", CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"if_freq" , CONFIG_HLP_IF_FREQ, 0, u64ptr:&(UE->if_freq), defuintval:0, TYPE_UINT64,0}, \ {"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, iptr:&(UE->if_freq_off), defuintval:0, TYPE_INT, 0}, \ diff --git a/executables/rt_profiling.h b/executables/rt_profiling.h new file mode 100644 index 0000000000..e37c37bb1e --- /dev/null +++ b/executables/rt_profiling.h @@ -0,0 +1,64 @@ + +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file time_profiling.h + * \brief Definitions for proflling real-time scheduling + * \author + * \date 2022 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ +#ifndef TIME_PROFILING_H +#define TIME_PROFILING_H +#ifdef __cplusplus +extern "C" +{ +#endif + +// depth of trace in slots +#define RT_PROF_DEPTH 100 +typedef struct { + int absslot_rx[RT_PROF_DEPTH]; + struct timespec return_RU_south_in[RT_PROF_DEPTH]; + struct timespec return_RU_feprx[RT_PROF_DEPTH]; + struct timespec return_RU_prachrx[RT_PROF_DEPTH]; + struct timespec return_RU_pushL1[RT_PROF_DEPTH]; + struct timespec start_RU_TX[RT_PROF_DEPTH]; + struct timespec return_RU_TX[RT_PROF_DEPTH]; +} rt_ru_profiling_t; + +typedef struct { + int absslot_ux[RT_PROF_DEPTH]; + struct timespec start_L1_RX[RT_PROF_DEPTH]; + struct timespec return_L1_RX[RT_PROF_DEPTH]; + struct timespec start_L1_TX[RT_PROF_DEPTH]; + struct timespec return_L1_TX[RT_PROF_DEPTH]; + struct timespec return_L1_prachrx[RT_PROF_DEPTH]; + struct timespec return_L1_puschL1[RT_PROF_DEPTH]; +} rt_L1_profiling_t; +#ifdef __cplusplus +} +#endif +#endif diff --git a/openair1/PHY/CODING/TESTBENCH/pdcch_test.c b/openair1/PHY/CODING/TESTBENCH/pdcch_test.c index b301959fbb..f4574bb0c5 100644 --- a/openair1/PHY/CODING/TESTBENCH/pdcch_test.c +++ b/openair1/PHY/CODING/TESTBENCH/pdcch_test.c @@ -26,7 +26,6 @@ #include "PHY/defs.h" #include "PHY/vars.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" #include "MAC_INTERFACE/vars.h" #include "PHY/CODING/defs.h" //#include "PHY/CODING/lte_interleaver_inline.h" diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index a5aff0974e..b658dc1043 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -245,43 +245,6 @@ void *te_thread(void *param) { return(NULL); } -int dlsch_encoding_all(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - unsigned char *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *te_wait_stats, - time_stats_t *te_main_stats, - time_stats_t *te_wakeup_stats0, - time_stats_t *te_wakeup_stats1, - time_stats_t *i_stats) { - uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe]; - if(harq_pid >= dlsch->Mdlharq) { - LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid); - return(-1); - } - - LOG_D(PHY,"B %d, harq_pid %d\n", - dlsch->harq_processes[harq_pid]->B, - dlsch->harq_ids[frame%2][subframe]); - - return dlsch_encoding(eNB, - proc, - a, - num_pdcch_symbols, - dlsch, - frame, - subframe, - rm_stats, - te_stats, - i_stats); - -} - static void TPencode(void * arg) { turboEncode_t * rdata=(turboEncode_t *) arg; unsigned char harq_pid = rdata->harq_pid; @@ -358,8 +321,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, num_pdcch_symbols, frame,subframe,beamforming_mode); - proc->nbEncode=0; - + int nbEncode = 0; // if (hadlsch->Ndi == 1) { // this is a new packet if (hadlsch->round == 0) { // this is a new packet @@ -386,11 +348,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, &hadlsch->F)<0) return(-1); } - + + notifiedFIFO_t respEncode; + initNotifiedFIFO(&respEncode); for (int r=0, r_offset=0; rC; r++) { union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}}; - notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode); + notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, &respEncode, TPencode); turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req); rdata->input=hadlsch->c[r]; rdata->Kr_bytes= ( rCminus ? hadlsch->Kminus : hadlsch->Kplus) >>3; @@ -404,15 +368,10 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, rdata->round=hadlsch->round; rdata->r_offset=r_offset; rdata->G=G; - - if ( proc->threadPool->activated ) { - pushTpool(proc->threadPool,req); - proc->nbEncode++; - } else { - TPencode(rdata); - delNotifiedFIFO_elt(req); - } - + + pushTpool(proc->threadPool, req); + nbEncode++; + int Qm=hadlsch->Qm; int C=hadlsch->C; int Nl=hadlsch->Nl; @@ -423,6 +382,14 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, else r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); } + // Wait all other threads finish to process + while (nbEncode) { + notifiedFIFO_elt_t *res = pullTpool(&respEncode, proc->threadPool); + if (res == NULL) + break; // Tpool has been stopped + delNotifiedFIFO_elt(res); + nbEncode--; + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } @@ -462,8 +429,6 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB, num_pdcch_symbols, frame,subframe,beamforming_mode); - proc->nbEncode=0; - // if (hadlsch->Ndi == 1) { // this is a new packet if (hadlsch->round == 0) { // this is a new packet // Add 24-bit crc (polynomial A) to payload @@ -489,11 +454,13 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB, &hadlsch->F)<0) return(-1); } - + int nbEncode = 0; + notifiedFIFO_t respEncode; + initNotifiedFIFO(&respEncode); for (int r=0, r_offset=0; rC; r++) { union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}}; - notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode); + notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, &respEncode, TPencode); turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req); rdata->input=hadlsch->c[r]; rdata->Kr_bytes= ( rCminus ? hadlsch->Kminus : hadlsch->Kplus) >>3; @@ -507,15 +474,10 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB, rdata->round=hadlsch->round; rdata->r_offset=r_offset; rdata->G=G; - - if ( proc->threadPool->activated ) { - pushTpool(proc->threadPool,req); - proc->nbEncode++; - } else { - TPencode(rdata); - delNotifiedFIFO_elt(req); - } - + + pushTpool(proc->threadPool, req); + nbEncode++; + int Qm=hadlsch->Qm; int C=hadlsch->C; int Nl=hadlsch->Nl; @@ -526,7 +488,14 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB, else r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); } - + // Wait all other threads finish to process + while (nbEncode) { + notifiedFIFO_elt_t *res = pullTpool(&respEncode, proc->threadPool); + if (res == NULL) + break; // Tpool has been stopped + delNotifiedFIFO_elt(res); + nbEncode--; + } return(0); } diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index 09c0b4ba0f..a161a3ba28 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -38,8 +38,7 @@ //#include "SCHED/sched_eNB.h" lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); -//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "common/utils/LOG/vcd_signal_dumper.h" const uint8_t lin2alaw_if4p5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 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, 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, 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, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c deleted file mode 100644 index 76d62f34a2..0000000000 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file PHY/LTE_TRANSPORT/if5_tools.c -* \brief -* \author S. Sandeep Kumar, Raymond Knopp, Tien-Thinh Nguyen -* \date 2016 -* \version 0.1 -* \company Eurecom -* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr, tien-thinh.nguyen@eurecom.fr -* \note -* \warning -*/ - -#include -#include "PHY/defs_eNB.h" -#include "PHY/defs_gNB.h" -#include -#include "PHY/defs_RU.h" -#include "PHY/TOOLS/alaw_lut.h" -//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" -#include "common/utils/LOG/vcd_signal_dumper.h" - -const uint8_t lin2alaw_if5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, -214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, -210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, -223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, -219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, -199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, -195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, -204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, -200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, -245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, -247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, -241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, -243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, -253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, -254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, -248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, -250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, -229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, -228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, -231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, -230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, -225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, -224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, -227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, -226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, -237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, -236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, -239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, -238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, -233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, -233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, -232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, -235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, -234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, -149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, -149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, -148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, -148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, -151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, -151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, -150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, -150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, -145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, -145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, -144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, -144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, -144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, -147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, -147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, -146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, -146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, -157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, -157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, -156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, -156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, -159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, -159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, -153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, -153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, -152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, -152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, -152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, -155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, -155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, -154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, -154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, -133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, -133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, -133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, -133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, -132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, -132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, -132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, -132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, -135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, -135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, -135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, -135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, -135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, -134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, -134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, -134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, -134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, -129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, -129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, -129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, -129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, -128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, -128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, -128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, -128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, -131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, -131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, -131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, -131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, -131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, -130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, -130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, -130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, -130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, -141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, -141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, -141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, -141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, -140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, -140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, -140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, -140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, -140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, -143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, -143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, -143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, -143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, -142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, -142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, -142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, -142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, -137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, -136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, -136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, -136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, -136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, -136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, -139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, -139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, -139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, -139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, -138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, -138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, -138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, -138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, -181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, -180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, -183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, -177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, -179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, -178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, -189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, -191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, -190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, -185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, -184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, -186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, -167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, -166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, -161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, -160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, -162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, -173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, -175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, -169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, -168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, -171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, -170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, -47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, -38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, -36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, -59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, -56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, -57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, -62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, -62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, -62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, -62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, -62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, -62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, -60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, -50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, -48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, -49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, -55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 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, 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, 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, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, -4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, -30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, -30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, -19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, -19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, -20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, -106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, -107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, -104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, -105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, -110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, -111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, -108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, -109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, -98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, -99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, -96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, -97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, -102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, -103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, -100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, -101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, -122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, -120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, -126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, -124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, -114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, -112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, -118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, -119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, -117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, -78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, -66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, -71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, -88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, -81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; - -const uint16_t alaw2lin_if5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, -48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, -65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, -64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, -30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, -152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; - -struct timespec start_comp, start_decomp, end_comp, end_decomp; -int dummy_cnt = 0; -int subframe_skip_extra = 0; -int start_flag = 1; -int offset_cnt = 1; - -static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end) -{ - struct timespec temp; - int64_t temp_ns; - - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - temp_ns = (int64_t)(temp.tv_sec) * (int64_t)1000000000 + (temp.tv_nsec); - return temp_ns; -} - -void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int tti, uint8_t *seqno, uint16_t packet_type) { - - LTE_DL_FRAME_PARMS *fp=ru->frame_parms; - int32_t *txp[ru->nb_tx], *rxp[ru->nb_rx]; - int32_t *tx_buffer=NULL; - uint16_t packet_id=0, i=0; - - uint32_t spp_eth = (uint32_t) ru->ifdevice.openair0_cfg->samples_per_packet; - uint32_t spsf = (uint32_t) ru->ifdevice.openair0_cfg->samples_per_frame/10; - eth_state_t *eth = (eth_state_t*) (ru->ifdevice.priv); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); - if (packet_type == IF5_RRH_GW_DL) { - if (eth->compression == ALAW_COMPRESS) { - AssertFatal(1==0,"IF5 compression needs reworking\n"); -/* - void *alaw_buffer = ru->ifbuffer.tx[subframe&1]; - int element_id=0; - - uint16_t *data_block = NULL; - uint16_t *j = NULL; - - if (eth->flags == ETH_RAW_MODE) { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); - } else { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); - } - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - for (i=0; i < fp->nb_antennas_tx; i++) { - for (element_id=0; element_id< spp_eth; element_id++){ - j = (uint16_t*) &ru->common.txdata[i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; - data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8); - } - } - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - ru->ifdevice.trx_write_func(&ru->ifdevice, - (proc_timestamp + packet_id*spp_eth), - (void**)&data_block, - spp_eth, - fp->nb_antennas_tx, - 0); - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); - } -*/ - } else if (eth->compression == NO_COMPRESS) { - - NR_DL_FRAME_PARMS *nrfp = ru->nr_frame_parms; - - int offset,siglen,factor=1; - if (nrfp) { - offset = nrfp->get_samples_slot_timestamp(tti,nrfp,0); - siglen = nrfp->get_samples_per_slot(tti,nrfp); - } - else { - offset = tti*fp->samples_per_subframe; - siglen = spsf; - } - - if (ru->openair0_cfg.nr_flag==1) { - if (nrfp->N_RB_DL <= 162 && nrfp->N_RB_DL >= 106) factor = 2; - else if (nrfp->N_RB_DL < 106) factor=4; - } - else { - factor = 30720/spsf; - } - for (i=0; i < ru->nb_tx; i++) - txp[i] = (int32_t*)&ru->common.txdata[i][offset]; - - for (packet_id=0; packet_id < siglen / spp_eth; packet_id++) { - for (int aid=0; aidnb_tx;aid++) { - //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - - ru->ifdevice.trx_write_func2(&ru->ifdevice, - (proc_timestamp + packet_id*spp_eth-600)*factor, - (void*)txp[aid], - spp_eth, - aid, - 0); - LOG_D(HW,"TTI %d : packet %d, TS %llu\n",tti,packet_id,(unsigned long long)(proc_timestamp-ru->ts_offset+packet_id*spp_eth)); - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[TTI %d] IF_Write_Time: %"PRId64"\n",tti,clock_difftime_ns(start_comp, end_comp)); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); - txp[aid] += spp_eth; - - } - } - } - } else if (packet_type == IF5_RRH_GW_UL) { - if (eth->compression == ALAW_COMPRESS) { - AssertFatal(1==0,"ALAW IF5 requires work\n"); - /* if (eth->flags == ETH_RAW_MODE) { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); - } else { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); - } - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - for (i=0; i < fp->nb_antennas_rx; i++) { - for (element_id=0; element_id< spp_eth; element_id++){ - j = (uint16_t*) &ru->common.rxdata[i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; - data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8); - } - } - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - ru->ifdevice.trx_write_func(&ru->ifdevice, - (proc_timestamp + packet_id*spp_eth), - (void**)&data_block, - spp_eth, - fp->nb_antennas_rx, - 0); - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); - } -*/ - } else if (eth->compression == NO_COMPRESS) { - for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] = (void*)&ru->common.rxdata[i][tti*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - ru->ifdevice.trx_write_func(&ru->ifdevice, - (proc_timestamp + packet_id*spp_eth), - (void**)rxp, - spp_eth, - fp->nb_antennas_rx, - 0); - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",tti,clock_difftime_ns(start_comp, end_comp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); - for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] += spp_eth; - - } - } - } else { - AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type); - } - - free(tx_buffer); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); - return; -} - -void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int tti, uint16_t packet_type) { - - LTE_DL_FRAME_PARMS *fp=ru->frame_parms; - int32_t *txp[ru->nb_tx], *rxp[ru->nb_rx]; - - uint16_t packet_id=0, i=0; - - - int32_t spp_eth = (int32_t) ru->ifdevice.openair0_cfg->samples_per_packet; - int32_t spsf = (int32_t) ru->ifdevice.openair0_cfg->samples_per_frame/10; - - openair0_timestamp timestamp[ru->nb_rx*spsf / spp_eth]; - long timein[ru->nb_rx*spsf/spp_eth]; - long timeout[ru->nb_rx*spsf/spp_eth]; - struct timespec if_time; - - memset(timestamp, 0, sizeof(timestamp)); - eth_state_t *eth = (eth_state_t*) (ru->ifdevice.priv); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); - - if (packet_type == IF5_RRH_GW_DL) { - if (eth->compression == ALAW_COMPRESS) { - AssertFatal(1==0,"IF5 compression needs reworking\n"); - -/* - if (eth->flags == ETH_RAW_MODE) { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); - } else { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); - } - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_decomp); - ru->ifdevice.trx_read_func(&ru->ifdevice, - ×tamp[packet_id], - (void**)&data_block, - spp_eth, - fp->nb_antennas_tx); - - clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_decomp); - for (i=0; i < fp->nb_antennas_tx; i++) { - for (element_id=0; element_id< spp_eth; element_id++) { - j = (uint16_t*) &ru->common.txdata[i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; - *j = alaw2lin_if5[ (data_block[element_id] & 0xff) ]; - *(j+1) = alaw2lin_if5[ (data_block[element_id]>>8) ]; - } - } - clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); - } -*/ - } else if (eth->compression == NO_COMPRESS) { - int subframe = tti; - for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id ); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_decomp); - ru->ifdevice.trx_read_func(&ru->ifdevice, - ×tamp[packet_id], - (void**)txp, - spp_eth, - fp->nb_antennas_tx); - clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); - for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] += spp_eth; - - } - } - *proc_timestamp = timestamp[0]; - - } else if (packet_type == IF5_RRH_GW_UL) { - if (eth->compression == ALAW_COMPRESS) { - AssertFatal(1==0,"IF5 compression needs reworking\n"); -/* - if (eth->flags == ETH_RAW_MODE) { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); - } else { - data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); - } - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_decomp); - ru->ifdevice.trx_read_func(&ru->ifdevice, - ×tamp[packet_id], - (void**)&data_block, - spp_eth, - fp->nb_antennas_rx); - clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_decomp); - for (i=0; i < fp->nb_antennas_rx; i++) { - for (element_id=0; element_id< spp_eth; element_id++) { - j = (uint16_t*) &ru->common.rxdata[i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; - *j = alaw2lin_if5[ (data_block[element_id] & 0xff) ]; - *(j+1) = alaw2lin_if5[ (data_block[element_id]>>8) ]; - } - } - clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); - } -*/ - } else if (eth->compression == NO_COMPRESS) { - int16_t temp_rx[spp_eth*2] __attribute__((aligned(32))); - NR_DL_FRAME_PARMS *nrfp = ru->nr_frame_parms; - - int offset,siglen; - int factor=1; - int ts_offset; - if (nrfp) { - offset = nrfp->get_samples_slot_timestamp(tti,nrfp,0); - siglen = nrfp->get_samples_per_slot(tti,nrfp); - } - else { - offset = tti*fp->samples_per_subframe; - siglen = spsf; - } - if (ru->openair0_cfg.nr_flag==1) { // This check if RRU knows about NR numerologies - if (nrfp->N_RB_DL <= 162 && nrfp->N_RB_DL >= 106) factor = 2; - else if (nrfp->N_RB_DL < 106) factor=4; - ts_offset = 64; - } - else { - factor = 30720/spsf; - ts_offset = 256; - } - for (i=0; i < ru->nb_rx; i++) - rxp[i] = &ru->common.rxdata[i][offset]; - int aid; - int firstTS=1; - openair0_timestamp oldTS=0; - - for (packet_id=0; packet_id < ru->nb_rx*siglen / spp_eth; packet_id++) { - //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &if_time); - timein[packet_id] = if_time.tv_nsec; - ru->ifdevice.trx_read_func2(&ru->ifdevice, - ×tamp[packet_id], - (void*)temp_rx, - spp_eth, - &aid); - clock_gettime( CLOCK_MONOTONIC, &if_time); - timeout[packet_id] = if_time.tv_nsec; - timestamp[packet_id] /= factor; // for LTE this is the sample rate reduction w.r.t 30.72, for NR 122.88 - LOG_D(PHY,"TTI %d: factor = %d Received packet %d: aid %d, TS %llu, oldTS %llu, diff %lld, \n",tti,factor,packet_id,aid,(unsigned long long)timestamp[packet_id],(unsigned long long)oldTS,(unsigned long long)(timestamp[packet_id]-timestamp[0])); - - if (aid==0) { - if (firstTS==1) firstTS=0; - else if (oldTS + ts_offset != timestamp[packet_id]) { - LOG_I(PHY,"oldTS %llu, newTS %llu, diff %llu, timein %lu, timeout %lu\n",(long long unsigned int)oldTS,(long long unsigned int)timestamp[packet_id],(long long unsigned int)timestamp[packet_id]-oldTS,timein[packet_id],timeout[packet_id]); - for (int i=0;i<=packet_id;i++) LOG_I(PHY,"packet %d TS %llu, timein %lu, timeout %lu\n",i,(long long unsigned int)timestamp[i],timein[i],timeout[i]); - AssertFatal(1==0,"fronthaul problem\n"); - } - - oldTS = timestamp[packet_id]; - } - - - // HYPOTHESIS: first packet per subframe has lowest timestamp of subframe - // should detect out of order and act accordingly .... - AssertFatal(aid==0 || aid==1 || aid==2 || aid==3,"aid %d != 0,1,2 or 3\n",aid); - LOG_D(PHY,"rxp[%d] %p, dest %p, offset %d (%llu,%llu)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(int)(timestamp[packet_id]-timestamp[0]),(long long unsigned int)timestamp[packet_id],(long long unsigned int)timestamp[0]); - memcpy((void*)(rxp[aid]+(timestamp[packet_id]-timestamp[0])), - (void*)temp_rx, - spp_eth<<2); - clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[TTI %d] IF_Read_Time: %"PRId64"\n",tti,clock_difftime_ns(start_decomp, end_decomp)); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); - - } - } - *proc_timestamp = timestamp[0]; - } else { - AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); - - return; -} - -void malloc_IF5_buffer(RU_t *ru) { - // Keep the size large enough, 3840 is the number of samples in a packet for 20MHz BW - int i; - eth_state_t *eth = (eth_state_t*) (ru->ifdevice.priv); - if (eth->compression == ALAW_COMPRESS) { - if (eth->flags == ETH_RAW_MODE) { - for (i=0;i<10;i++) - ru->ifbuffer.tx[i] = malloc(RAW_PACKET_SIZE_BYTES_ALAW(3840)); - ru->ifbuffer.rx = malloc(RAW_PACKET_SIZE_BYTES_ALAW(3840)); - } else { - for (i=0;i<10;i++) - ru->ifbuffer.tx[i] = malloc(UDP_PACKET_SIZE_BYTES_ALAW(3840)); - ru->ifbuffer.rx = malloc(UDP_PACKET_SIZE_BYTES_ALAW(3840)); - } - } else if (eth->compression == NO_COMPRESS) { - if (eth->flags == ETH_RAW_MODE) { - for (i=0;i<10;i++) - ru->ifbuffer.tx[i] = malloc(RAW_PACKET_SIZE_BYTES(3840)); - ru->ifbuffer.rx = malloc(RAW_PACKET_SIZE_BYTES(3840)); - } else { - for (i=0;i<10;i++) - ru->ifbuffer.tx[i] = malloc(UDP_PACKET_SIZE_BYTES(3840)); - ru->ifbuffer.rx = malloc(UDP_PACKET_SIZE_BYTES(3840)); - } - } -} diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 1fbd1266d7..c4f49823df 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -72,21 +72,6 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch); LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); -int dlsch_encoding_all(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - unsigned char *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *te_wait_stats, - time_stats_t *te_main_stats, - time_stats_t *te_wakeup_stats0, - time_stats_t *te_wakeup_stats1, - time_stats_t *i_stats); - /** \fn dlsch_encoding(PHY_VARS_eNB *eNB, uint8_t *input_buffer, LTE_DL_FRAME_PARMS *frame_parms, @@ -543,15 +528,6 @@ void rx_ulsch(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, uint8_t UE_id); - -int ulsch_decoding_data_all(PHY_VARS_eNB *eNB, - - L1_rxtx_proc_t *proc, - int UE_id, - int harq_pid, - int llr8_flag); - - /*! \brief Decoding of PUSCH/ACK/RI/ACK from 36-212. @param phy_vars_eNB Pointer to eNB top-level descriptor @@ -570,19 +546,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB, uint8_t Nbundled, uint8_t llr8_flag); -/*! - \brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread. - @param phy_vars_eNB Pointer to eNB top-level descriptor - @param UE_id ID of UE transmitting this PUSCH - @param harq_pid HARQ process ID - @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used - @returns 0 on success -*/ -int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB, - int UE_id, - int harq_pid, - int llr8_flag); - /*! \brief Decoding of ULSCH data component from 36-212. This one is single thread. @param phy_vars_eNB Pointer to eNB top-level descriptor diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index f71ca76b71..5a203ab331 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -367,11 +367,6 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, return(ret); } -int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, - int UE_id,int harq_pid,int llr8_flag) { - return ulsch_decoding_data(eNB,proc,UE_id,harq_pid,llr8_flag); -} - static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) { int n; @@ -1116,7 +1111,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB, LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]); // Do ULSCH Decoding for data portion - ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag); + ret = ulsch_decoding_data(eNB, proc, UE_id, harq_pid, llr8_flag); return(ret); } diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 4f089562f6..45078d7398 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -137,29 +137,33 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, if (config_type > 1) LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type); - if ((p>=1000) && (p<((config_type==NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) { - if (ue->frame_parms.Ncp == NORMAL) { + if ((p >= 1000) && (p < ((config_type == NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) { + if (ue->frame_parms.Ncp == NORMAL) { + for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) { + w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); + mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table; - for (int i=0; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdsch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + idx = ((((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1); + ((int16_t *)output)[i << 1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx) << 1]; + ((int16_t *)output)[(i << 1) + 1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1]; #ifdef DEBUG_PDSCH - printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb); - printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); - printf("i %d idx %d pdsch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pdsch[(i<<1)>>5], (((nr_gold_pdsch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pdsch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]); + printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb); + printf("wf[%d] = %d wt[%d]= %d\n", i & 1, wf[p - 1000][i & 1], lp, wt[p - 1000][lp]); + printf("i %d idx %d pdsch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", + i, + idx, + nr_gold_pdsch[(i << 1) >> 5], + (((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), + (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), + ((int16_t *)output)[i << 1], + ((int16_t *)output)[(i << 1) + 1]); #endif - } - } else { - LOG_E(PHY,"extended cp not supported for PDSCH DMRS yet\n"); } + } else { + LOG_E(PHY, "extended cp not supported for PDSCH DMRS yet\n"); + } } else { - LOG_E(PHY,"Illegal p %d PDSCH DMRS port\n",p); + LOG_E(PHY, "Illegal p %d PDSCH DMRS port\n", p); } return(0); @@ -167,7 +171,6 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, unsigned int Ns, unsigned int *nr_gold_pdcch, int32_t *output, diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 9667105be9..bdd1f50069 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -39,7 +39,6 @@ int nr_pbch_dmrs_rx(int dmrss, @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables */ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, unsigned int Ns, unsigned int *nr_gold_pdcch, int32_t *output, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index c8b5af6ea5..c6156d63bc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -87,7 +87,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; - int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(n_rb+rb_offset)*6] __attribute__((aligned(16))); // 3 for the max coreset duration + int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(((n_rb+rb_offset+pdcch_pdu_rel15->BWPStart)*6+15)>>4)<<4] __attribute__((aligned(16))); // 3 for the max coreset duration for (int d=0;dnumDlDci;d++) { /*The coreset is initialised @@ -109,7 +109,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, LOG_D(PHY, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n",rb_offset,n_rb,pdcch_pdu_rel15->BWPStart); LOG_D(PHY, "pdcch: Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); // DMRS length is per OFDM symbol - uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE) + uint32_t dmrs_length = (n_rb+pdcch_pdu_rel15->BWPStart)*6; //2(QPSK)*3(per RB)*6(REG per CCE) uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE) if (dci_pdu->RNTI != 0xFFFF) LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n", @@ -210,7 +210,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 int eff_reg_idx = cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx/pdcch_pdu_rel15->DurationSymbols; if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) - dmrs_idx = eff_reg_idx * 3; + dmrs_idx = (eff_reg_idx + pdcch_pdu_rel15->BWPStart) * 3; else dmrs_idx = (eff_reg_idx + rb_offset) * 3; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index be2afed94d..658bae243f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -117,6 +117,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, a_segments = a_segments/273 +1; } + LOG_I(PHY,"Allocating %d segments (MAX %d, N_PRB %d)\n",a_segments,MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER,N_RB); uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment NR_gNB_DLSCH_t *dlsch = malloc16(sizeof(NR_gNB_DLSCH_t)); AssertFatal(dlsch, "cannot allocate dlsch\n"); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index d935e8c0bc..ecef5e53cd 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -410,7 +410,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/ bool no_conf=false; if (nr_sequences>1) { - if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < uci_stats->pucch0_thres) { + if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) { no_conf=true; LOG_D(PHY,"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n", frame, slot, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 68c29ce3d0..2de95698dd 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -29,6 +29,7 @@ #include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "common/utils/nr/nr_common.h" #include "filt16a_32.h" #include "T.h" #include @@ -996,16 +997,16 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, return(0); } -int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, - unsigned char symbol, - unsigned short scrambling_id, - unsigned short coreset_start_subcarrier, - unsigned short nb_rb_coreset, - int32_t pdcch_est_size, - int32_t pdcch_dl_ch_estimates[][pdcch_est_size]) +void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t gNB_id, + unsigned char Ns, + unsigned char symbol, + fapi_nr_coreset_t *coreset, + uint16_t first_carrier_offset, + uint16_t BWPStart, + int32_t pdcch_est_size, + int32_t pdcch_dl_ch_estimates[][pdcch_est_size]) { unsigned char aarx; @@ -1020,6 +1021,17 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + int nb_rb_coreset=0; + int coreset_start_rb=0; + get_coreset_rballoc(coreset->frequency_domain_resource,&nb_rb_coreset,&coreset_start_rb); + if(nb_rb_coreset==0) return; + +#ifdef DEBUG_PDCCH + printf(PHY, "pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d, coreset_nb_rb %d\n", + first_carrier_offset, BWPStart, coreset_start_rb, nb_rb_coreset); +#endif + + unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12; #ifdef DEBUG_PDCCH printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n", @@ -1032,28 +1044,32 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int16_t *fr = filt16a_r1; #endif + unsigned short scrambling_id = coreset->pdcch_dmrs_scrambling_id; // checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC) if (scrambling_id != ue->scramblingID_pdcch){ ue->scramblingID_pdcch = scrambling_id; nr_gold_pdcch(ue,ue->scramblingID_pdcch); } - // generate pilot - int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); - nr_pdcch_dmrs_rx(ue,gNB_id,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,nb_rb_coreset); + int dmrs_ref = 0; + if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) + dmrs_ref = BWPStart; + // generate pilot + int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); + nr_pdcch_dmrs_rx(ue,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,(nb_rb_coreset+dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { k = coreset_start_subcarrier; - pil = (int16_t *)&pilot[0]; + pil = (int16_t *)&pilot[dmrs_ref*3]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; dl_ch = (int16_t *)&pdcch_dl_ch_estimates[aarx][ch_offset]; memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); #ifdef DEBUG_PDCCH - printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL); + printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[dmrs_ref*3], ue->frame_parms.N_RB_DL); printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); printf("rxF addr %p\n", rxF); @@ -1220,8 +1236,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //} } - - return(0); } int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index dc87625b7c..f01a2af606 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -50,16 +50,16 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t \param Ns slot number (0..19) \param symbol symbol within slot */ -int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, - unsigned char symbol, - unsigned short scrambling_id, - unsigned short coreset_start_subcarrier, - unsigned short nb_rb_coreset, - int32_t pdcch_est_size, - int32_t pdcch_dl_ch_estimates[][pdcch_est_size]); +void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t gNB_id, + unsigned char Ns, + unsigned char symbol, + fapi_nr_coreset_t *coreset, + uint16_t first_carrier_offset, + uint16_t BWPStart, + int32_t pdcch_est_size, + int32_t pdcch_dl_ch_estimates[][pdcch_est_size]); int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 88cc419dc1..93bbfd1737 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -1599,19 +1599,20 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, // Extraction functions //============================================================================================== -unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - uint8_t n_dmrs_cdm_groups, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos, - int chest_time_type) +void nr_dlsch_extract_rbs(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos, + int chest_time_type) { if (config_type == NFAPI_NR_DMRS_TYPE1) { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, @@ -1631,178 +1632,91 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - int32_t *dl_ch0 = &dl_ch_estimates[aarx][validDmrsEst * frame_parms->ofdm_symbol_size]; - int32_t *dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB]; - int32_t *rxF_ext = &rxdataF_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB]; - int32_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; + int32_t *rxF_ext = &rxdataF_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB]; + int32_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; - if (pilots == 0) { //data symbol only - if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { - memcpy((void*)rxF_ext, (void*)&rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); - } else { - int neg_length = frame_parms->ofdm_symbol_size - start_re; - int pos_length = nb_rb_pdsch * NR_NB_SC_PER_RB - neg_length; + for (unsigned char aatx = 0; aatx < Nl; aatx++) { - memcpy((void*)rxF_ext, (void*)&rxF[start_re], neg_length * sizeof(int32_t)); - memcpy((void*)&rxF_ext[neg_length], (void*)rxF, pos_length * sizeof(int32_t)); + int32_t *dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][validDmrsEst * frame_parms->ofdm_symbol_size]; + int32_t *dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB]; + + if (pilots == 0) { //data symbol only + if (aatx == 0) { + if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { + memcpy(rxF_ext, &rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); + } else { + int neg_length = frame_parms->ofdm_symbol_size - start_re; + int pos_length = nb_rb_pdsch * NR_NB_SC_PER_RB - neg_length; + + memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(int32_t)); + memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(int32_t)); + } + } + memcpy(dl_ch0_ext, dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); } - memcpy((void*)dl_ch0_ext, (void*)dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t)); - } - else if (config_type == NFAPI_NR_DMRS_TYPE1){ - if (n_dmrs_cdm_groups == 1) { //data is multiplexed - unsigned short k = start_re; - for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) { - rxF_ext[j] = rxF[k+1]; - rxF_ext[j+1] = rxF[k+3]; - rxF_ext[j+2] = rxF[k+5]; - dl_ch0_ext[j] = dl_ch0[1]; - dl_ch0_ext[j+1] = dl_ch0[3]; - dl_ch0_ext[j+2] = dl_ch0[5]; - dl_ch0 += 6; - k += 6; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; + else if (config_type == NFAPI_NR_DMRS_TYPE1){ + if (n_dmrs_cdm_groups == 1) { //data is multiplexed + if (aatx == 0) { + unsigned short k = start_re; + for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) { + rxF_ext[j] = rxF[k+1]; + rxF_ext[j+1] = rxF[k+3]; + rxF_ext[j+2] = rxF[k+5]; + k += 6; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } + } + for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) { + dl_ch0_ext[j] = dl_ch0[1]; + dl_ch0_ext[j+1] = dl_ch0[3]; + dl_ch0_ext[j+2] = dl_ch0[5]; + dl_ch0 += 6; + } } } - } - else {//NFAPI_NR_DMRS_TYPE2 - if (n_dmrs_cdm_groups == 1) { //data is multiplexed - unsigned short k = start_re; - for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) { - rxF_ext[j] = rxF[k+2]; - rxF_ext[j+1] = rxF[k+3]; - rxF_ext[j+2] = rxF[k+4]; - rxF_ext[j+3] = rxF[k+5]; - dl_ch0_ext[j] = dl_ch0[2]; - dl_ch0_ext[j+1] = dl_ch0[3]; - dl_ch0_ext[j+2] = dl_ch0[4]; - dl_ch0_ext[j+3] = dl_ch0[5]; - dl_ch0 += 6; - k += 6; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; + else {//NFAPI_NR_DMRS_TYPE2 + if (n_dmrs_cdm_groups == 1) { //data is multiplexed + if (aatx == 0) { + unsigned short k = start_re; + for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) { + rxF_ext[j] = rxF[k+2]; + rxF_ext[j+1] = rxF[k+3]; + rxF_ext[j+2] = rxF[k+4]; + rxF_ext[j+3] = rxF[k+5]; + k += 6; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } + } + for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) { + dl_ch0_ext[j] = dl_ch0[2]; + dl_ch0_ext[j+1] = dl_ch0[3]; + dl_ch0_ext[j+2] = dl_ch0[4]; + dl_ch0_ext[j+3] = dl_ch0[5]; + dl_ch0 += 6; + } } - } - else if (n_dmrs_cdm_groups == 2) { //data is multiplexed - unsigned short k = start_re; - for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) { - rxF_ext[j] = rxF[k+4]; - rxF_ext[j+1] = rxF[k+5]; - dl_ch0_ext[j] = dl_ch0[4]; - dl_ch0_ext[j+1] = dl_ch0[5]; - dl_ch0 += 6; - k += 6; - if (k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; + else if (n_dmrs_cdm_groups == 2) { //data is multiplexed + if (aatx == 0) { + unsigned short k = start_re; + for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) { + rxF_ext[j] = rxF[k+4]; + rxF_ext[j+1] = rxF[k+5]; + k += 6; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } + } + for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) { + dl_ch0_ext[j] = dl_ch0[4]; + dl_ch0_ext[j+1] = dl_ch0[5]; + dl_ch0 += 6; + } } } } } - - return nb_rb_pdsch; -} - -void nr_dlsch_extract_rbs(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - uint8_t n_dmrs_cdm_groups, - uint8_t Nl, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos, - int chest_time_type) -{ - - unsigned short k,rb; - unsigned char nushift,j,i,aarx,aatx; - int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - int8_t validDmrsEst = 0; //store last DMRS Symbol index - - if (config_type==NFAPI_NR_DMRS_TYPE1) { - AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, - "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); - nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 - } else { - AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, - "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); - nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 - } - - if (chest_time_type == 0) - validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); - else - validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index - - for (aarx=0; aarxnb_antennas_rx; aarx++) { - - k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; - if (k>=frame_parms->ofdm_symbol_size) - k = k-frame_parms->ofdm_symbol_size; - - rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; - rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - - for (aatx=0; aatxnb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; - dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)]; - - for (rb = 0; rb < nb_rb_pdsch; rb++) - { - if (pilots==0) {//data symbol only - if (aatx==0) {//Extract Rx signal only - memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); - rxF_ext+=12; - } - memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate - dl_ch0_ext+=12; - } - else {//the symbol contains DMRS - j=0; - if (config_type==NFAPI_NR_DMRS_TYPE1) { - if (nushift == 0) {//data is multiplexed - for (i = (1-nushift); i<12; i+=2) { - if (aatx==0) rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - dl_ch0_ext+=6; - if (aatx==0) rxF_ext+=6; - } - } - else {//NFAPI_NR_DMRS_TYPE2 - for (i = (2+nushift); i<6; i++) { - if (aatx==0) rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - for (i = (8+nushift); i<12; i++) { - if (aatx==0) rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - dl_ch0_ext+= j; - if (aatx==0) rxF_ext+= j; - } - } - - dl_ch0+=12; - if (aatx==0) { - rxF+=12; - k+=12; - if (k>=frame_parms->ofdm_symbol_size) { - k=k-(frame_parms->ofdm_symbol_size); - rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; - } - } - }//rb - }//aatx - }//aarx } void nr_dlsch_detection_mrc(int **rxdataF_comp, @@ -2439,9 +2353,9 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, switch (Nl) { case 1: if (codeword_TB1 == -1) - memcpy((void*)llr_cw[0], (void*)llr_layers[0], (length)*sizeof(int16_t)); + memcpy(llr_cw[0], llr_layers[0], (length)*sizeof(int16_t)); else if (codeword_TB0 == -1) - memcpy((void*)llr_cw[1], (void*)llr_layers[0], (length)*sizeof(int16_t)); + memcpy(llr_cw[1], llr_layers[0], (length)*sizeof(int16_t)); break; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index aa2d617112..ce9cd9bfba 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -529,8 +529,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, if (sa==1 && ret==0) { bool dec = false; int gnb_id = 0; //FIXME - int coreset_nb_rb=0; - int coreset_start_rb=0; // Hold the channel estimates in frequency domain. int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16); @@ -540,7 +538,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, for(int n_ss = 0; n_sssamples_per_frame+phy_pdcch_config.sfn*fp->samples_per_frame+ue->rx_offset); - if (coreset_nb_rb > 0) - nr_pdcch_channel_estimation(ue, - proc, - 0, - phy_pdcch_config.slot, - l, - fp->Nid_cell, - fp->first_carrier_offset+(phy_pdcch_config.pdcch_config[n_ss].BWPStart + coreset_start_rb)*12, - coreset_nb_rb, - pdcch_est_size, - pdcch_dl_ch_estimates); + nr_pdcch_channel_estimation(ue, + proc, + 0, + phy_pdcch_config.slot, + l, + &phy_pdcch_config.pdcch_config[n_ss].coreset, + fp->first_carrier_offset, + phy_pdcch_config.pdcch_config[n_ss].BWPStart, + pdcch_est_size, + pdcch_dl_ch_estimates); } int dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_pdcch_config, n_ss); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 6d99ac9b8c..82b56754ec 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -680,39 +680,7 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, unsigned short nb_rb, unsigned char dual_stream_UE); -/** \fn dlsch_extract_rbs_single(int32_t **rxdataF, - int32_t **dl_ch_estimates, - int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - uint32_t *rb_alloc, - uint8_t symbol, - NR_DL_FRAME_PARMS *frame_parms) - \brief This function extracts the received resource blocks, both channel estimates and data symbols, - for the current allocation and for single antenna eNB transmission. - @param rxdataF Raw FFT output of received signal - @param dl_ch_estimates Channel estimates of current slot - @param rxdataF_ext FFT output for RBs in this allocation - @param dl_ch_estimates_ext Channel estimates for RBs in this allocation - @param rb_alloc RB allocation vector - @param symbol Symbol to extract - @param n_dmrs_cdm_groups - @param frame_parms Pointer to frame descriptor -*/ -unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - uint8_t n_dmrs_cdm_groups, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos, - int chest_time_type); - -/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF, +/** \fn dlsch_extract_rbs(int32_t **rxdataF, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, @@ -737,19 +705,19 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, @param frame_parms Pointer to frame descriptor */ void nr_dlsch_extract_rbs(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - uint8_t n_dmrs_cdm_groups, - uint8_t Nl, - NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos, - int chest_time_type); + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos, + int chest_time_type); /** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF, int32_t **dl_bf_ch_estimates, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index dba1fd194d..2e8344acfe 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -495,15 +495,34 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t pmi=pusch_pdu->Tpmi; if (pmi == 0) {//unitary Precoding - if(ap< pusch_pdu->nrOfLayers) - memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - (void*)&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], - NR_NB_SC_PER_RB*sizeof(int32_t)); - else - memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - 0, - NR_NB_SC_PER_RB*sizeof(int32_t)); - + if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC + if (apnrOfLayers) + memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], + &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], + NR_NB_SC_PER_RB*sizeof(int32_t)); + else + memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], + 0, + NR_NB_SC_PER_RB*sizeof(int32_t)); + } else { // RB does cross DC + int neg_length = frame_parms->ofdm_symbol_size - k; + int pos_length = NR_NB_SC_PER_RB - neg_length; + if (apnrOfLayers) { + memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], + &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], + neg_length*sizeof(int32_t)); + memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size], + &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)], + pos_length*sizeof(int32_t)); + } else { + memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], + 0, + neg_length*sizeof(int32_t)); + memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size], + 0, + pos_length*sizeof(int32_t)); + } + } k += NR_NB_SC_PER_RB; if (k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; diff --git a/openair1/PHY/TOOLS/Makefile b/openair1/PHY/TOOLS/Makefile index 9f8b9934cf..d7b14d5010 100644 --- a/openair1/PHY/TOOLS/Makefile +++ b/openair1/PHY/TOOLS/Makefile @@ -1,15 +1,15 @@ oai_dfts_sse4: oai_dfts.c - gcc -O3 -std=gnu99 -msse4.1 -o oai_dfts_sse4 oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS + gcc -O3 -std=gnu99 -msse4.1 -o oai_dfts_sse4 oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_HOME/sdr/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS oai_dfts_avx2: oai_dfts.c - gcc -O2 -std=gnu99 -mavx2 -g -ggdb -o oai_dfts_avx2 oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS + gcc -O2 -std=gnu99 -mavx2 -g -ggdb -o oai_dfts_avx2 oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_HOME/sdr/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS oai_dfts_avx2.s: oai_dfts.c - gcc -O2 -std=gnu99 -mavx2 -S oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS + gcc -O2 -std=gnu99 -mavx2 -S oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_HOME/sdr/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS oai_dfts_sse4.s: oai_dfts.c - gcc -O2 -std=gnu99 -msse4.1 -S oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_TARGETS/ARCH/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS + gcc -O2 -std=gnu99 -msse4.1 -S oai_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR_TARGETS/COMMON -I$$OPENAIR_HOME/sdr/COMMON -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -I$$OPENAIR_HOME/common/utils/msc -I$$OPENAIR_HOME/nfapi/open-nFAPI/nfapi/public_inc -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS dft_cycles_avx2: oai_dfts_avx2 diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c index 650d5e420c..9e611b6766 100644 --- a/openair1/PHY/TOOLS/calibration_test.c +++ b/openair1/PHY/TOOLS/calibration_test.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index b4aee78310..4e7b2c7bb7 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -136,7 +136,7 @@ static inline void* malloc16_clear( size_t size ) #include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" #include -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" #include "openairinterface5g_limits.h" #define NUM_DCI_MAX_NB_IoT 32 diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 0320697ecf..627ad7d27f 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -39,6 +39,8 @@ #include "time_meas.h" #include "defs_common.h" #include "nfapi_nr_interface_scf.h" +#include +#include #define MAX_BANDS_PER_RRU 4 #define MAX_RRU_CONFIG_SIZE 1024 @@ -168,25 +170,21 @@ typedef struct RU_prec_t_s{ int index; } RU_prec_t; -typedef struct RU_feptx_t_s{ - /// \internal This variable is protected by \ref mutex_feptx_prec - int instance_cnt_feptx; - /// pthread struct for RU TX FEP PREC worker thread - pthread_t pthread_feptx; - /// pthread attributes for worker feptx prec thread - pthread_attr_t attr_feptx; - /// condition varible for RU TX FEP PREC thread - pthread_cond_t cond_feptx; - /// mutex for fep PREC TX worker thread - pthread_mutex_t mutex_feptx; - struct RU_t_s *ru; - int aa;//physical MAX nb_tx - int half_slot;//first or second half of a slot - int slot;//current slot - int symbol;//current symbol - int nb_antenna_ports;//number of logical port - int index; -}RU_feptx_t; +typedef struct { + int aid; + struct RU_t_s *ru; + int startSymbol; + int endSymbol; + int slot; +} feprx_cmd_t; + +typedef struct { + int aid; + struct RU_t_s *ru; + int slot; + int startSymbol; + int numSymbols; +} feptx_cmd_t; typedef struct { int frame; @@ -246,7 +244,7 @@ typedef struct RU_proc_t_s { /// \internal This variable is protected by \ref mutex_asynch_rxtx. int instance_cnt_asynch_rxtx; /// \internal This variable is protected by \ref mutex_fep - int instance_cnt_fep; + int instance_cnt_fep[8]; /// \internal This variable is protected by \ref mutex_feptx int instance_cnt_feptx; /// \internal This variable is protected by \ref mutex_ru_thread @@ -265,7 +263,7 @@ typedef struct RU_proc_t_s { /// pthread struct for RU synch thread pthread_t pthread_synch; /// pthread struct for RU RX FEP worker thread - pthread_t pthread_fep; + pthread_t pthread_fep[8]; /// pthread struct for RU TX FEP worker thread pthread_t pthread_feptx; /// pthread struct for emulated RF @@ -318,7 +316,7 @@ typedef struct RU_proc_t_s { /// condition variable for asynch RX/TX thread pthread_cond_t cond_asynch_rxtx; /// condition varible for RU RX FEP thread - pthread_cond_t cond_fep; + pthread_cond_t cond_fep[8]; /// condition varible for RU TX FEP thread pthread_cond_t cond_feptx; /// condition varible for emulated RF @@ -345,7 +343,7 @@ typedef struct RU_proc_t_s { /// mutex for asynch RX/TX thread pthread_mutex_t mutex_asynch_rxtx; /// mutex for fep RX worker thread - pthread_mutex_t mutex_fep; + pthread_mutex_t mutex_fep[8]; /// mutex for fep TX worker thread pthread_mutex_t mutex_feptx; /// mutex for ru_thread @@ -395,10 +393,6 @@ typedef struct RU_proc_t_s { /// structure for precoding thread RU_prec_t prec[16]; - /// structure for feptx thread - RU_feptx_t feptx[16]; - /// mask for checking process finished - int feptx_mask; } RU_proc_t; typedef enum { @@ -433,6 +427,8 @@ typedef enum { typedef struct RU_t_s { + /// ThreadPool for RU + tpool_t *threadPool; /// index of this ru uint32_t idx; /// pointer to first RU @@ -507,6 +503,10 @@ typedef struct RU_t_s { int sf_ahead; /// TX processing advance in slots (for NR) int sl_ahead; + /// flag to indicate TX FH is embedded in TX FEP + int txfh_in_fep; + /// flag to indicate half-slot parallelization + int half_slot_parallelization; /// FAPI confiuration nfapi_nr_config_request_scf_t config; /// Frame parameters @@ -645,6 +645,22 @@ typedef struct RU_t_s { uint64_t if_frequency; /// UL IF frequency offset to DL IF frequency in Hz int if_freq_offset; + /// to signal end of feprx + notifiedFIFO_t *respfeprx; + /// to signal end of feptx + notifiedFIFO_t *respfeptx; + /// core id for RX fhaul (IF5 ECPRI) + int rxfh_core_id; + /// core id for RX fhaul (IF5 ECPRI) + int txfh_core_id; + /// number of RU interfaces + int num_fd; + /// list of cores for RU ThreadPool + int tpcores[16]; + /// number of cores for RU ThreadPool + int num_tpcores; + /// structure for analyzing high-level RT measurements + rt_ru_profiling_t rt_ru_profiling; } RU_t; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index d5ad705f4e..b7d9cd4473 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -253,11 +253,9 @@ typedef struct { /// mutex for RXn-TXnp4 processing thread pthread_mutex_t mutex_RUs; tpool_t *threadPool; - int nbEncode; int nbDecode; - notifiedFIFO_t *respEncode; notifiedFIFO_t *respDecode; - pthread_mutex_t mutex_emulateRF; + pthread_mutex_t mutex_emulateRF; int instance_cnt_emulateRF; pthread_t pthread_emulateRF; pthread_attr_t attr_emulateRF; @@ -731,11 +729,6 @@ typedef struct PHY_VARS_eNB_s { time_stats_t dlsch_turbo_encoding_preperation_stats; time_stats_t dlsch_turbo_encoding_segmentation_stats; time_stats_t dlsch_turbo_encoding_stats; - time_stats_t dlsch_turbo_encoding_waiting_stats; - time_stats_t dlsch_turbo_encoding_signal_stats; - time_stats_t dlsch_turbo_encoding_main_stats; - time_stats_t dlsch_turbo_encoding_wakeup_stats0; - time_stats_t dlsch_turbo_encoding_wakeup_stats1; time_stats_t dlsch_interleaving_stats; time_stats_t rx_dft_stats; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 9a0e35827a..0048cf5f75 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -42,6 +42,7 @@ #include "PHY/defs_common.h" #include "PHY/CODING/nrLDPC_extern.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "executables/rt_profiling.h" #include "nfapi_nr_interface_scf.h" @@ -849,6 +850,7 @@ typedef struct PHY_VARS_gNB_s { int pucch0_thres; int pusch_thres; int prach_thres; + int srs_thres; uint64_t bad_pucch; int num_ulprbbl; int ulprbbl[275]; @@ -906,6 +908,8 @@ typedef struct PHY_VARS_gNB_s { int number_of_nr_dlsch_max; int number_of_nr_ulsch_max; void * scopeData; + /// structure for analyzing high-level RT measurements + rt_L1_profiling_t rt_L1_profiling; } PHY_VARS_gNB; typedef struct LDPCDecode_s { diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 58c5e015e7..b5d1814077 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -108,7 +108,8 @@ #include "PHY/NR_UE_TRANSPORT/dci_nr.h" #include -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" +#include "NR_IF_Module.h" /// Context data structure for gNB subframe processing typedef struct { @@ -656,8 +657,6 @@ typedef struct NR_UL_TIME_ALIGNMENT { uint8_t tag_id; } NR_UL_TIME_ALIGNMENT_t; -#include "NR_IF_Module.h" - /// Top-level PHY Data Structure for UE typedef struct { /// \brief Module ID indicator for this instance diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 87d193b4a3..742f77186d 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -344,11 +344,6 @@ typedef struct { #define MAX_NR_OF_DL_ALLOCATIONS 16 #define MAX_NR_OF_UL_ALLOCATIONS (16) -typedef enum { - typeA = 0, - typeB = 1 -} mappingType_t; - typedef enum { pdsch_dmrs_pos0 = 0, pdsch_dmrs_pos1 = 1, @@ -368,12 +363,7 @@ typedef enum { pusch_dmrs_type1 = 0, pusch_dmrs_type2 = 1 } pusch_dmrs_type_t; -typedef enum { - pusch_dmrs_pos0 = 0, - pusch_dmrs_pos1 = 1, - pusch_dmrs_pos2 = 2, - pusch_dmrs_pos3 = 3, -} pusch_dmrs_AdditionalPosition_t; + typedef enum { pusch_len1 = 1, pusch_len2 = 2 diff --git a/openair1/PHY/thread_NR_UE.h b/openair1/PHY/thread_NR_UE.h index a3cc2d9782..8fbcc75083 100644 --- a/openair1/PHY/thread_NR_UE.h +++ b/openair1/PHY/thread_NR_UE.h @@ -1,7 +1,7 @@ #ifndef __thread_NR_UE__ #define __thread_NR_UE__ #include -#include +#include /// Context data structure for RX/TX portion of subframe processing typedef struct { /// index of the current UE RX/TX thread diff --git a/openair1/PHY/types.h b/openair1/PHY/types.h index 8d8d9db2de..913db62231 100644 --- a/openair1/PHY/types.h +++ b/openair1/PHY/types.h @@ -23,6 +23,6 @@ #define __openair_TYPES_H__ #include -#define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+c) +#define MAKE_VERSION(a,b,c) ((a)*65536+(b)*256+c) #endif /*__openair_TYPES_H__ */ diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index db03a9dc43..759162eda4 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -413,33 +413,9 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB, } start_meas(&eNB->dlsch_encoding_stats); - dlsch_encoding_all(eNB, - proc, - dlsch_harq->pdu, - dlsch_harq->pdsch_start, - dlsch, - frame, - subframe, - &eNB->dlsch_rate_matching_stats, - &eNB->dlsch_turbo_encoding_stats, - &eNB->dlsch_turbo_encoding_waiting_stats, - &eNB->dlsch_turbo_encoding_main_stats, - &eNB->dlsch_turbo_encoding_wakeup_stats0, - &eNB->dlsch_turbo_encoding_wakeup_stats1, - &eNB->dlsch_interleaving_stats); + dlsch_encoding(eNB, proc, dlsch_harq->pdu, dlsch_harq->pdsch_start, dlsch, frame, subframe, &eNB->dlsch_rate_matching_stats, &eNB->dlsch_turbo_encoding_stats, &eNB->dlsch_interleaving_stats); stop_meas(&eNB->dlsch_encoding_stats); - if ( proc->threadPool->activated ) { - // Wait all other threads finish to process - while (proc->nbEncode) { - notifiedFIFO_elt_t *res = pullTpool(proc->respEncode, proc->threadPool); - if (res == NULL) - break; // Tpool has been stopped - delNotifiedFIFO_elt(res); - proc->nbEncode--; - } - } - if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) { print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); } diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 443b1c7989..2f60dde0a2 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -57,7 +57,6 @@ #include "SCHED/sched_eNB.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" @@ -566,15 +565,15 @@ static void *fep_thread(void *param) while (!oai_exit) { - if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break; + if (wait_on_condition(&proc->mutex_fep[0],&proc->cond_fep[0],&proc->instance_cnt_fep[0],"fep thread")<0) break; if (oai_exit) break; //stop_meas(&ru->ofdm_demod_wakeup_stats); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); fep0(ru,0); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); - if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break; + if (release_thread(&proc->mutex_fep[0],&proc->instance_cnt_fep[0],"fep thread")<0) break; - if (pthread_cond_signal(&proc->cond_fep) != 0) { + if (pthread_cond_signal(&proc->cond_fep[0]) != 0) { printf("[eNB] ERROR pthread_cond_signal for fep thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); return NULL; @@ -607,12 +606,12 @@ void init_fep_thread(RU_t *ru, { RU_proc_t *proc = &ru->proc; - proc->instance_cnt_fep = -1; + proc->instance_cnt_fep[0] = -1; - pthread_mutex_init( &proc->mutex_fep, NULL); - pthread_cond_init( &proc->cond_fep, NULL); + pthread_mutex_init( &proc->mutex_fep[0], NULL); + pthread_cond_init( &proc->cond_fep[0], NULL); - threadCreate(&proc->pthread_fep, fep_thread, (void*)ru, "fep", -1, OAI_PRIORITY_RT); + threadCreate(&proc->pthread_fep[0], fep_thread, (void*)ru, "fep", -1, OAI_PRIORITY_RT); } @@ -621,14 +620,14 @@ void kill_fep_thread(RU_t *ru) RU_proc_t *proc = &ru->proc; if (proc->pthread_fep == 0) return; - pthread_mutex_lock( &proc->mutex_fep ); - proc->instance_cnt_fep = 0; - pthread_cond_signal(&proc->cond_fep); - pthread_mutex_unlock( &proc->mutex_fep ); + pthread_mutex_lock( &proc->mutex_fep[0] ); + proc->instance_cnt_fep[0] = 0; + pthread_cond_signal(&proc->cond_fep[0]); + pthread_mutex_unlock( &proc->mutex_fep[0] ); LOG_D(PHY, "Joining pthread_fep\n"); - pthread_join(proc->pthread_fep, NULL); - pthread_mutex_destroy( &proc->mutex_fep ); - pthread_cond_destroy( &proc->cond_fep ); + pthread_join(proc->pthread_fep[0], NULL); + pthread_mutex_destroy( &proc->mutex_fep[0] ); + pthread_cond_destroy( &proc->cond_fep[0] ); } @@ -670,35 +669,35 @@ void ru_fep_full_2thread(RU_t *ru, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 ); start_meas(&ru->ofdm_demod_stats); - if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) { - printf("[RU] ERROR pthread_mutex_lock for fep thread (IC %d)\n", proc->instance_cnt_fep); + if (pthread_mutex_timedlock(&proc->mutex_fep[0],&wait) != 0) { + printf("[RU] ERROR pthread_mutex_lock for fep thread (IC %d)\n", proc->instance_cnt_fep[0]); exit_fun( "error locking mutex_fep" ); return; } - if (proc->instance_cnt_fep==0) { + if (proc->instance_cnt_fep[0]==0) { printf("[RU] FEP thread busy\n"); exit_fun("FEP thread busy"); - pthread_mutex_unlock( &proc->mutex_fep ); + pthread_mutex_unlock( &proc->mutex_fep[0] ); return; } - ++proc->instance_cnt_fep; + ++proc->instance_cnt_fep[0]; - if (pthread_cond_signal(&proc->cond_fep) != 0) { + if (pthread_cond_signal(&proc->cond_fep[0]) != 0) { printf("[RU] ERROR pthread_cond_signal for fep thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return; } //start_meas(&ru->ofdm_demod_wakeup_stats); - pthread_mutex_unlock( &proc->mutex_fep ); + pthread_mutex_unlock( &proc->mutex_fep[0] ); // call second slot in this symbol fep0(ru,1); start_meas(&ru->ofdm_demod_wait_stats); - wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread"); + wait_on_busy_condition(&proc->mutex_fep[0],&proc->cond_fep[0],&proc->instance_cnt_fep[0],"fep thread"); stop_meas(&ru->ofdm_demod_wait_stats); if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index a93ac0ded2..003871df64 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -35,7 +35,6 @@ #include "PHY/MODULATION/modulation_common.h" #include "PHY/MODULATION/nr_modulation.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "common/utils/LOG/log.h" #include "common/utils/system.h" @@ -46,12 +45,14 @@ #include "assertions.h" #include + + // RU OFDM Modulator gNodeB -extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int oai_exit; +// OFDM modulation core routine, generates a first_symbol to first_symbol+num_symbols on a particular slot and TX antenna port void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; @@ -62,6 +63,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); + if (aa==0 && first_symbol == 0) start_meas(&ru->ofdm_mod_stats); slot_offset = fp->get_samples_slot_timestamp(slot,fp,0); slot_offsetF = first_symbol*fp->ofdm_symbol_size; @@ -72,16 +74,16 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { slot_offset += fp->ofdm_symbol_size*first_symbol; - LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d (first_symbol %d num_symbols %d)\n",ru->proc.frame_tx, ru->proc.tti_tx,slot,first_symbol,num_symbols); + LOG_D(PHY,"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",ru->proc.frame_tx, ru->proc.tti_tx,aa,slot,first_symbol,num_symbols,slot_offset,slot_offsetF); - if (fp->Ncp == 1) + if (fp->Ncp == 1) { PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, num_symbols, fp->nb_prefix_samples, CYCLIC_PREFIX); - else { + } else { if (fp->numerology_index != 0) { if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) { // case where first symbol in slot has longer prefix @@ -130,280 +132,16 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size; slot_offsetF += fp->ofdm_symbol_size; } - } - } + } // for(idx_symbol.. + } // numerology 0 } + if (aa==0 && first_symbol==0) stop_meas(&ru->ofdm_mod_stats); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); } -void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { - - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; - RU_proc_t *proc = &ru->proc; - RU_feptx_t *feptx = proc->feptx; - - PHY_VARS_gNB *gNB; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - - int slot = tti_tx; - - int i = 0; - int j = 0;//symbol - int aa = 0;//physical antenna number - int ret = 0; - int ofdm_mask_full = (1<<(ru->nb_tx*2))-1; - int txdataF_offset = (tti_tx*fp->samples_per_slot_wCP); - - if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; - for (aa=0; aanb_tx; aa++) memset(ru->common.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); - - start_meas(&ru->ofdm_total_stats); - - //if (nr_slot_select(cfg,frame_tx,slot)==NR_DOWNLINK_SLOT) { - if(ru->num_gNB != 0){//L1 RU on same machine - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); - for(j=0; j<2; ++j){//half slot - for(i=0; inb_tx; ++i){ - if(j == 0){ - AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); - feptx[i].aa = i; - feptx[i].index = i; - feptx[i].ru = ru; - feptx[i].symbol = 0; - feptx[i].slot = slot; - feptx[i].nb_antenna_ports = ru->nb_tx; - feptx[i].instance_cnt_feptx = 0; - AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); - AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); - }//first half - else{ - AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); - feptx[i+ru->nb_tx].aa = i; - feptx[i+ru->nb_tx].index = i+ru->nb_tx; - feptx[i+ru->nb_tx].ru = ru; - feptx[i+ru->nb_tx].symbol = fp->symbols_per_slot>>1; - feptx[i+ru->nb_tx].slot = slot; - feptx[i+ru->nb_tx].nb_antenna_ports = ru->nb_tx; - feptx[i+ru->nb_tx].instance_cnt_feptx = 0; - AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); - AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); - }//second half - }//physical antenna - }//half slot - }//if L1 RU on same machine - else{//(RU only machine) - for(j=0; jsymbols_per_slot; ++j){ - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); - start_meas(&ru->txdataF_copy_stats); - AssertFatal(ru->num_gNB==1,"num_gNB>1, help\n"); - gNB = ru->gNB_list[0]; - cfg = &gNB->gNB_config; - - for(i=0; inb_tx; ++i){ - memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size], - (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], - fp->ofdm_symbol_size*sizeof(int32_t)); - - } - - stop_meas(&ru->txdataF_copy_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); - - if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) { - // If this is not an S-tti - for(i=0; inb_tx; ++i){ - if(j%2 == 0){ - while(feptx[i].instance_cnt_feptx != -1){ - usleep(5); - } - AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); - feptx[i].aa = i; - feptx[i].index = i; - feptx[i].ru = ru; - feptx[i].symbol = j; - feptx[i].slot = slot; - feptx[i].nb_antenna_ports = ru->nb_tx; - feptx[i].instance_cnt_feptx = 0; - AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); - AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); - } - else{ - while(feptx[i+ru->nb_tx].instance_cnt_feptx != -1){ - usleep(5); - } - AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); - feptx[i+ru->nb_tx].aa = i; - feptx[i+ru->nb_tx].index = i+ru->nb_tx; - feptx[i+ru->nb_tx].ru = ru; - feptx[i+ru->nb_tx].symbol = j; - feptx[i+ru->nb_tx].slot = slot; - feptx[i+ru->nb_tx].nb_antenna_ports = ru->nb_tx; - feptx[i+ru->nb_tx].instance_cnt_feptx = 0; - AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); - AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); - } - } - }//if == SF_DL - else { - proc->feptx_mask = ofdm_mask_full; - } - }//jsymbols_per_slot - }//else (RU only machine) - //} - // wait all process to finish - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); - while (proc->feptx_mask != ofdm_mask_full) { - // most of the time the thread is waiting here - // proc->instance_cnt_rxtx is -1 - pthread_cond_wait(&proc->cond_feptx,&proc->mutex_feptx); // this unlocks mutex_rxtx while waiting and then locks it again - } - proc->feptx_mask = 0; - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, proc->feptx_mask ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); - - - stop_meas(&ru->ofdm_total_stats); - -} - -static void *nr_feptx_thread(void *param) { - - RU_feptx_t *feptx = (RU_feptx_t *)param; - RU_t *ru; - int aa, slot, start, l, ret; - int i; - int32_t ***bw; - NR_DL_FRAME_PARMS *fp; - int ofdm_mask_full; - int txdataF_offset; - while (!oai_exit) { - ret = 0; - if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 1 ); - - AssertFatal(feptx->ru->nb_log_antennas>0 && feptx->ru->nb_log_antennas < 13,"ru->nb_log_antennas is %d\n", feptx->ru->nb_log_antennas); - - ru = feptx->ru; - slot = feptx->slot; - aa = feptx->aa; - l = feptx->symbol; - fp = ru->nr_frame_parms; - start = feptx->symbol; - ofdm_mask_full = (1<<(ru->nb_tx*2))-1; - - if(ru->num_gNB != 0){ - txdataF_offset = (slot*fp->samples_per_slot_wCP); - ////////////precoding//////////// - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); - - if (aa==0 && l==0) start_meas(&ru->precoding_stats); - - if (ru->do_precoding == 1) { - for(i=0; inb_log_antennas; ++i) { - memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l], - (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l], - (fp->symbols_per_slot>>1)*sizeof(uint8_t)); - } - } - - if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { - memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], - (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], - (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); - } - else if (ru->do_precoding == 0) { - int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx; - memcpy((void*)&ru->common.txdataF_BF[aa][l*fp->ofdm_symbol_size], - (void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset + l*fp->ofdm_symbol_size], - (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); - } - else { - bw = ru->beam_weights[0]; - for(i=0; isymbols_per_slot>>1; ++i){ - nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF, - ru->common.txdataF_BF, - fp, - bw, - slot, - l+i, - aa, - ru->nb_log_antennas, - txdataF_offset);//here - } - } - if (aa==0 && l==0) stop_meas(&ru->precoding_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); - - ////////////FEPTX//////////// - if (aa==0 && l==0) start_meas(&ru->ofdm_mod_stats); - nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa); - if (aa==0 && l==0) stop_meas(&ru->ofdm_mod_stats); - - if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; - - AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); - ru->proc.feptx_mask |= 1<<(feptx->index); - if(ru->proc.feptx_mask == ofdm_mask_full) - AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); - AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); - }// if L1 RU on same machine - - else{ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); - start_meas(&ru->precoding_stats); - if (ru->nb_tx == 1 && ru->nb_log_antennas) { - memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], - (void*)&ru->common.txdataF[0][l*fp->ofdm_symbol_size], - fp->ofdm_symbol_size*sizeof(int32_t)); - } - else { - bw = ru->beam_weights[0]; - nr_beam_precoding(ru->common.txdataF, - ru->common.txdataF_BF, - fp, - bw, - slot, - l, - aa, - ru->nb_log_antennas, - 0); - } - stop_meas(&ru->precoding_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); - - - start_meas(&ru->ofdm_mod_stats); - nr_feptx0(ru,slot,start,1,aa); - stop_meas(&ru->ofdm_mod_stats); - - if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; - - if(l >= fp->symbols_per_slot -2){ - AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); - ru->proc.feptx_mask |= 1<<(feptx->index); - if(ru->proc.feptx_mask == ofdm_mask_full) - AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); - AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); - }// else (RU only machine) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 0 ); - }// while (oai_exit) - return(NULL); -} - - -// is this supposed to generate a slot or a subframe??? -// seems to be hardcoded to numerology 1 (2 slots=1 subframe) +// RU FEP TX OFDM modulation, single-thread void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; @@ -419,7 +157,6 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); - start_meas(&ru->ofdm_mod_stats); // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); @@ -427,7 +164,6 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { nr_feptx0(ru,slot,0,NR_NUMBER_OF_SYMBOLS_PER_SLOT,aa); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); - stop_meas(&ru->ofdm_mod_stats); LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n", frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->get_samples_per_slot( @@ -435,43 +171,6 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { } -void nr_init_feptx_thread(RU_t *ru) { - - RU_proc_t *proc = &ru->proc; - RU_feptx_t *feptx = proc->feptx; - int i = 0; - - for(i=0; i<(ru->nb_tx*2); i++){ - feptx[i].instance_cnt_feptx = -1; - - pthread_mutex_init( &feptx[i].mutex_feptx, NULL); - pthread_cond_init( &feptx[i].cond_feptx, NULL); - - threadCreate(&feptx[i].pthread_feptx, nr_feptx_thread, (void*)&feptx[i], "feptx", -1, OAI_PRIORITY_RT); - LOG_I(PHY,"init feptx thread %d\n", i); - } - -} - -void nr_kill_feptx_thread(RU_t *ru) { - RU_proc_t *proc = &ru->proc; - - for (int i = 0; i < ru->nb_tx * 2; i++) { - RU_feptx_t *feptx = &proc->feptx[i]; - if (feptx->pthread_feptx == 0) - continue; - - pthread_mutex_lock(&feptx->mutex_feptx); - feptx->instance_cnt_feptx = 0; - pthread_mutex_unlock(&feptx->mutex_feptx); - pthread_cond_signal(&feptx->cond_feptx); - LOG_I(PHY, "Joining pthread_feptx %d\n", i); - pthread_join(feptx->pthread_feptx, NULL); - pthread_mutex_destroy(&feptx->mutex_feptx); - pthread_cond_destroy(&feptx->cond_feptx); - } -} - void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) { int l,aa; @@ -530,157 +229,6 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) { stop_meas(&ru->precoding_stats); } -void nr_fep0(RU_t *ru, int first_half) { - - uint8_t start_symbol, end_symbol, l, aa; - RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - - if(first_half == 1) { - start_symbol = 0; - end_symbol = NR_SYMBOLS_PER_SLOT/2; - } else { - start_symbol = NR_SYMBOLS_PER_SLOT/2; - end_symbol = NR_SYMBOLS_PER_SLOT; - } - - LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d, nb_antennas_rx = %d,N_TA_offset = %d\n", - proc->tti_rx, first_half, start_symbol, end_symbol,fp->nb_antennas_rx,ru->N_TA_offset); - // printf("fep0: slot %d\n",slot); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1); - - int offset = (proc->tti_rx&3) * fp->symbols_per_slot * fp->ofdm_symbol_size; - for (l = start_symbol; l < end_symbol; l++) { - for (aa = 0; aa < fp->nb_antennas_rx; aa++) { - nr_slot_fep_ul(fp, - ru->common.rxdata[aa], - &ru->common.rxdataF[aa][offset], - l, - proc->tti_rx, - ru->N_TA_offset); - } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0); -} - - -static void *nr_feprx_thread(void *param) { - - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - - - while (!oai_exit) { - - if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"NR feprx thread")<0) break; - - if (oai_exit) break; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); - - nr_fep0(ru, 0); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); - - if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"nr_feprx thread")<0) break; - - if (pthread_cond_signal(&proc->cond_fep) != 0) { - printf("[gNB] ERROR pthread_cond_signal for nr_feprx thread exit\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return NULL; - } - } - - return NULL; -} - - -void nr_init_feprx_thread(RU_t *ru) { - - RU_proc_t *proc = &ru->proc; - - proc->instance_cnt_fep = -1; - - pthread_mutex_init( &proc->mutex_fep, NULL); - pthread_cond_init( &proc->cond_fep, NULL); - - threadCreate(&proc->pthread_fep, nr_feprx_thread, (void*)ru, "feprx", -1, OAI_PRIORITY_RT); -} - -void nr_kill_feprx_thread(RU_t *ru) { - RU_proc_t *proc = &ru->proc; - if (proc->pthread_fep == 0) - return; - LOG_I(PHY, "Joining pthread_feprx\n"); - pthread_mutex_lock(&proc->mutex_fep); - proc->instance_cnt_fep = 0; - pthread_mutex_unlock(&proc->mutex_fep); - pthread_cond_signal(&proc->cond_fep); - pthread_join(proc->pthread_fep, NULL); - pthread_mutex_destroy(&proc->mutex_fep); - pthread_cond_destroy(&proc->cond_fep); -} - -void nr_fep_full_2thread(RU_t *ru, int slot) { - - RU_proc_t *proc = &ru->proc; - - struct timespec wait; - - // NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - - // if ((fp->frame_type == TDD) && - // (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return; - - if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); - start_meas(&ru->ofdm_demod_stats); - - if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) { - printf("[RU] ERROR pthread_mutex_lock for nr_feprx thread (IC %d)\n", proc->instance_cnt_fep); - exit_fun( "error locking mutex_fep" ); - return; - } - - if (proc->instance_cnt_fep==0) { - LOG_E(PHY, "RU FEP thread busy, exiting %s\n", __func__); - pthread_mutex_unlock( &proc->mutex_fep ); - return; - } - - ++proc->instance_cnt_fep; - - - if (pthread_cond_signal(&proc->cond_fep) != 0) { - printf("[RU] ERROR pthread_cond_signal for nr_feprx thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - //start_meas(&ru->ofdm_demod_wakeup_stats); - - pthread_mutex_unlock( &proc->mutex_fep ); - - // call second slot in this symbol - nr_fep0(ru, 1); - - start_meas(&ru->ofdm_demod_wait_stats); - wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"nr_feprx thread"); - stop_meas(&ru->ofdm_demod_wait_stats); - if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ - print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); - printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->tti_rx); - } - - stop_meas(&ru->ofdm_demod_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); -} - - void nr_fep_full(RU_t *ru, int slot) { @@ -716,3 +264,170 @@ void nr_fep_full(RU_t *ru, int slot) { } + +// core routine for FEP TX, called from threads in RU TX thread-pool +void nr_feptx(void *arg) { + + feptx_cmd_t *feptx = (feptx_cmd_t *)arg; + + RU_t *ru = feptx->ru; + int slot = feptx->slot; + int aa = feptx->aid; + int startSymbol = feptx->startSymbol; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int numSymbols = feptx->numSymbols; + int numSamples = feptx->numSymbols*fp->ofdm_symbol_size; + int txdataF_offset = (slot*fp->samples_per_slot_wCP) + startSymbol*fp->ofdm_symbol_size; + int txdataF_BF_offset = startSymbol*fp->ofdm_symbol_size; + + ////////////precoding//////////// + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 1); + + if (aa==0) start_meas(&ru->precoding_stats); + + if (ru->do_precoding == 1) { + for(int i=0; inb_log_antennas; ++i) { + memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot], + (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot], + (fp->symbols_per_slot)*sizeof(uint8_t)); + } + } + + if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { + memcpy((void*)&ru->common.txdataF_BF[0][txdataF_BF_offset], + (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset], + numSamples*sizeof(int32_t)); + } + else if (ru->do_precoding == 0) { + int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx; + memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset], + (void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset], + numSamples*sizeof(int32_t)); + } + else { + AssertFatal(1==0,"This needs to be fixed, do not use beamforming.\n"); + int32_t ***bw = ru->beam_weights[0]; + for(int i=0; isymbols_per_slot; ++i){ + nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF, + ru->common.txdataF_BF, + fp, + bw, + slot, + i, + aa, + ru->nb_log_antennas, + txdataF_offset);//here + } + } + if (aa==0) stop_meas(&ru->precoding_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 0); + + ////////////FEPTX//////////// + nr_feptx0(ru,slot,startSymbol,numSymbols,aa); +} + +// RU FEP TX using thread-pool +void nr_feptx_tp(RU_t *ru, int frame_tx, int slot) { + + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + int nbfeptx=0; + if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; +// for (int aa=0; aanb_tx; aa++) memset(ru->common.txdataF[aa],0,ru->nr_frame_parms->samples_per_slot_wCP*sizeof(int32_t)); + + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1 ); + start_meas(&ru->ofdm_total_stats); + for (int aid=0;aidnb_tx;aid++) { + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid,ru->respfeptx,nr_feptx); + feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req); + feptx_cmd->aid = aid; + feptx_cmd->ru = ru; + feptx_cmd->slot = slot; + feptx_cmd->startSymbol = 0; + feptx_cmd->numSymbols = (ru->half_slot_parallelization>0)?ru->nr_frame_parms->symbols_per_slot>>1:ru->nr_frame_parms->symbols_per_slot; + pushTpool(ru->threadPool,req); + nbfeptx++; + if (ru->half_slot_parallelization>0) { + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx,ru->respfeptx,nr_feptx); + feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req); + feptx_cmd->aid = aid; + feptx_cmd->ru = ru; + feptx_cmd->slot = slot; + feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot>>1; + feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot>>1; + pushTpool(ru->threadPool,req); + nbfeptx++; + } + } + while (nbfeptx>0) { + notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool); + delNotifiedFIFO_elt(req); + nbfeptx--; + } + stop_meas(&ru->ofdm_total_stats); + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0 ); +} + +// core RX FEP routine, called by threads in RU thread-pool +void nr_fep(void* arg) { + + feprx_cmd_t *feprx_cmd = (feprx_cmd_t *)arg; + + RU_t *ru = feprx_cmd->ru; + int aid = feprx_cmd->aid; + int tti_rx = feprx_cmd->slot; + int startSymbol = feprx_cmd->startSymbol; + int endSymbol = feprx_cmd->endSymbol; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + + LOG_D(PHY,"In nr_fep for aid %d, slot = %d, startSymbol %d, endSymbol %d\n", aid, tti_rx,startSymbol,endSymbol); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1); + + int offset = (tti_rx&3) * fp->symbols_per_slot * fp->ofdm_symbol_size; + for (int l = startSymbol; l <= endSymbol; l++) + nr_slot_fep_ul(fp, + ru->common.rxdata[aid], + &ru->common.rxdataF[aid][offset], + l, + tti_rx, + ru->N_TA_offset); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 0); +} + +// RU RX FEP using thread-pool +void nr_fep_tp(RU_t *ru, int slot) { + + int nbfeprx=0; + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); + start_meas(&ru->ofdm_demod_stats); + for (int aid=0;aidnb_rx;aid++) { + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feprx_cmd_t), 1000 + aid,ru->respfeprx,nr_fep); + feprx_cmd_t *feprx_cmd=(feprx_cmd_t*)NotifiedFifoData(req); + feprx_cmd->aid = aid; + feprx_cmd->ru = ru; + feprx_cmd->slot = ru->proc.tti_rx; + feprx_cmd->startSymbol = 0; + feprx_cmd->endSymbol = (ru->half_slot_parallelization > 0)?(ru->nr_frame_parms->symbols_per_slot>>1)-1:(ru->nr_frame_parms->symbols_per_slot-1); + pushTpool(ru->threadPool,req); + nbfeprx++; + if (ru->half_slot_parallelization>0) { + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feprx_cmd_t), 1000 + aid + ru->nb_rx,ru->respfeprx,nr_fep); + feprx_cmd_t *feprx_cmd=(feprx_cmd_t*)NotifiedFifoData(req); + feprx_cmd->aid = aid; + feprx_cmd->ru = ru; + feprx_cmd->slot = ru->proc.tti_rx; + feprx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot>>1; + feprx_cmd->endSymbol = ru->nr_frame_parms->symbols_per_slot-1; + pushTpool(ru->threadPool,req); + nbfeprx++; + } + } + while (nbfeprx>0) { + notifiedFIFO_elt_t *req=pullTpool(ru->respfeprx, ru->threadPool); + delNotifiedFIFO_elt(req); + nbfeprx--; + } + stop_meas(&ru->ofdm_demod_stats); + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); +} + diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 763d938e22..8ff1eed48d 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -842,7 +842,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); } - const int srs_est = nr_get_srs_signal(gNB,frame_rx,slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); + int srs_est = nr_get_srs_signal(gNB, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); if (srs_est >= 0) { nr_srs_channel_estimation(gNB, @@ -863,31 +863,41 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { &snr); } - T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); + if ((snr * 10) < gNB->srs_thres) { + srs_est = -1; + } - T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); + T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, + T_INT(0), + T_INT(srs_pdu->rnti), + T_INT(frame_rx), + T_INT(0), + T_INT(0), + T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t))); + + T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, + T_INT(0), + T_INT(srs_pdu->rnti), + T_INT(frame_rx), + T_INT(0), + T_INT(0), + T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t))); - const uint16_t num_srs = gNB->UL_INFO.srs_ind.number_of_pdus; gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0]; gNB->UL_INFO.srs_ind.sfn = frame_rx; gNB->UL_INFO.srs_ind.slot = slot_rx; - gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle; - gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; - gNB->srs_pdu_list[num_srs].timing_advance = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, - srs_estimated_channel_time[0]) : 0xFFFF; - gNB->srs_pdu_list[num_srs].num_symbols = 1<num_symbols; - gNB->srs_pdu_list[num_srs].wide_band_snr = srs_est >= 0 ? (snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid - gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<num_symbols; - if(!gNB->srs_pdu_list[num_srs].reported_symbol_list) { - gNB->srs_pdu_list[num_srs].reported_symbol_list = (nfapi_nr_srs_indication_reported_symbol_t*) calloc(1, gNB->srs_pdu_list[num_srs].num_reported_symbols*sizeof(nfapi_nr_srs_indication_reported_symbol_t)); + + nfapi_nr_srs_indication_pdu_t *srs_indication = &gNB->srs_pdu_list[gNB->UL_INFO.srs_ind.number_of_pdus]; + srs_indication->handle = srs_pdu->handle; + srs_indication->rnti = srs_pdu->rnti; + srs_indication->timing_advance = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF; + srs_indication->num_symbols = 1 << srs_pdu->num_symbols; + srs_indication->wide_band_snr = srs_est >= 0 ? (snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid + srs_indication->num_reported_symbols = 1 << srs_pdu->num_symbols; + if (!srs_indication->reported_symbol_list) { + srs_indication->reported_symbol_list = (nfapi_nr_srs_indication_reported_symbol_t *)calloc(1, srs_indication->num_reported_symbols * sizeof(nfapi_nr_srs_indication_reported_symbol_t)); } - fill_srs_reported_symbol_list(&gNB->srs_pdu_list[num_srs].reported_symbol_list[0], - srs_pdu, - frame_parms->N_RB_UL, - snr_per_rb, - srs_est); + fill_srs_reported_symbol_list(&srs_indication->reported_symbol_list[0], srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est); gNB->UL_INFO.srs_ind.number_of_pdus += 1; @@ -900,9 +910,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].wide_band_snr = %i\n", num_srs, gNB->srs_pdu_list[num_srs].wide_band_snr); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_reported_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_reported_symbols); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].num_rbs = %i\n", num_srs, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs); - for(int rb = 0; rb < gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs; rb++) { - LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].rb_list[%3i].rb_snr = %i\n", - num_srs, rb, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].rb_list[rb].rb_snr); + for (int rb = 0; rb < gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs; rb++) { + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].rb_list[%3i].rb_snr = %i\n", num_srs, rb, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].rb_list[rb].rb_snr); } #endif diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index eff8a9fbcd..32b1e67162 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -41,18 +41,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); -void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); -void nr_init_feptx_thread(RU_t *ru); -void nr_kill_feptx_thread(RU_t *ru); + void fep_full(RU_t *ru,int slot); void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx); -void nr_init_feptx_prec_thread(RU_t *ru); void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx); -void nr_init_feprx_thread(RU_t *ru); -void nr_kill_feprx_thread(RU_t *ru); void nr_fep_full(RU_t *ru, int slot); -void nr_fep_full_2thread(RU_t *ru, int slot); +void nr_fep_tp(RU_t *ru, int slot); +void nr_feptx_tp(RU_t *ru, int frame_tx, int slot); void feptx_prec(RU_t *ru,int frame_tx,int tti_tx); int nr_phy_init_RU(RU_t *ru); void nr_phy_free_RU(RU_t *ru); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 05278b781a..366ab0ee77 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1467,31 +1467,22 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16); __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size]; - int coreset_nb_rb=0; - int coreset_start_rb=0; - - if (phy_pdcch_config->nb_search_space > 0) - get_coreset_rballoc(phy_pdcch_config->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb); - uint8_t dci_cnt = 0; for(int n_ss = 0; n_ssnb_search_space; n_ss++) { for (uint16_t l=0; lfirst_carrier_offset, phy_pdcch_config->pdcch_config[n_ss].BWPStart, coreset_start_rb, coreset_nb_rb); - if (coreset_nb_rb > 0) - nr_pdcch_channel_estimation(ue, - proc, - gNB_id, - nr_slot_rx, - l, - phy_pdcch_config->pdcch_config[n_ss].coreset.pdcch_dmrs_scrambling_id, - fp->first_carrier_offset+(phy_pdcch_config->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12, - coreset_nb_rb, - pdcch_est_size, - pdcch_dl_ch_estimates); + nr_pdcch_channel_estimation(ue, + proc, + gNB_id, + nr_slot_rx, + l, + &phy_pdcch_config->pdcch_config[n_ss].coreset, + fp->first_carrier_offset, + phy_pdcch_config->pdcch_config[n_ss].BWPStart, + pdcch_est_size, + pdcch_dl_ch_estimates); stop_meas(&ue->ofdm_demod_stats); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 8aff47c86b..fef67c3b92 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1306,11 +1306,9 @@ int main(int argc, char **argv) { } L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc; - proc_eNB->threadPool=(tpool_t*)malloc(sizeof(tpool_t)); - proc_eNB->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + proc_eNB->threadPool = (tpool_t *)malloc(sizeof(tpool_t)); proc_eNB->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); initTpool("n", proc_eNB->threadPool, true); - initNotifiedFIFO(proc_eNB->respEncode); initNotifiedFIFO(proc_eNB->respDecode); proc_eNB->frame_tx=0; diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c index b9f0221b2d..9203f0a095 100644 --- a/openair1/SIMULATION/LTE_PHY/framegen.c +++ b/openair1/SIMULATION/LTE_PHY/framegen.c @@ -36,7 +36,6 @@ #include "SCHED/defs.h" #include "SCHED/vars.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" #include "LAYER2/MAC/defs.h" #include "PHY_INTERFACE/defs.h" diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index e8ee7d3d5e..dfcce8fd0b 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -41,9 +41,7 @@ #endif #include "SCHED/defs.h" #include "SCHED/vars.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/cbmimo1_device.h" -#include "ARCH/COMMON/defs.h" +#include "sdr/COMMON/defs.h" #include "LAYER2/MAC/vars.h" #ifdef XFORMS diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 0f98eb337a..b72ed441f6 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -814,11 +814,9 @@ int main(int argc, char **argv) { proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; - proc_rxtx->threadPool=(tpool_t*)malloc(sizeof(tpool_t)); - proc_rxtx->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + proc_rxtx->threadPool = (tpool_t *)malloc(sizeof(tpool_t)); proc_rxtx->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - initTpool("n",proc_rxtx->threadPool, true); - initNotifiedFIFO(proc_rxtx->respEncode); + initTpool("n", proc_rxtx->threadPool, true); initNotifiedFIFO(proc_rxtx->respDecode); printf("Init UL hopping UE\n"); @@ -1533,7 +1531,7 @@ int main(int argc, char **argv) { }//ch realization oai_exit=1; - pthread_cond_signal(&ru->proc.cond_fep); + pthread_cond_signal(&ru->proc.cond_fep[0]); if (abstx) { // ABSTRACTION fprintf(csv_fdUL,"];"); diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index f429409d5a..6cc9c84ea3 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -85,31 +85,22 @@ nrUE_params_t *get_nrUE_params(void) { int main(int argc, char **argv) { char c; - int i; //,j,l,aa; + int i; double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0; double snr_step = 0.1; uint8_t snr1set = 0; int **txdata; double **s_re, **s_im, **r_re, **r_im; - // int sync_pos, sync_pos_slot; - // FILE *rx_frame_file; FILE *output_fd = NULL; //uint8_t write_output_file = 0; - // int subframe_offset; - // char fname[40], vname[40]; int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; uint8_t n_tx = 1, n_rx = 1; - //uint8_t transmission_mode = 1; uint16_t Nid_cell = 0; channel_desc_t *gNB2UE; uint8_t extended_prefix_flag = 0; - //int8_t interf1 = -21, interf2 = -21; FILE *input_fd = NULL, *pbch_file_fd = NULL; - //char input_val_str[50],input_val_str2[50]; - //uint16_t NB_RB=25; SCM_t channel_model = AWGN; //Rayleigh1_anticorr; uint16_t N_RB_DL = 106, mu = 1; - //unsigned char frame_type = 0; unsigned char pbch_phase = 0; int frame = 0, slot = 0; int frame_length_complex_samples; @@ -120,7 +111,6 @@ int main(int argc, char **argv) double sigma; unsigned char qbits = 8; int ret; - //int run_initial_sync=0; int loglvl = OAILOG_WARNING; uint8_t dlsch_threads = 0; float target_error_rate = 0.01; @@ -195,14 +185,6 @@ int main(int argc, char **argv) break; - /*case 'i': - interf1 = atoi(optarg); - break; - - case 'j': - interf2 = atoi(optarg); - break;*/ - case 'n': n_trials = atoi(optarg); break; @@ -312,13 +294,10 @@ int main(int argc, char **argv) gNBthreads[sizeof(gNBthreads)-1]=0; break; - /*case 'x': - transmission_mode = atoi(optarg); - break;*/ default: case 'h': - printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]); + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]); printf("-h This message\n"); printf("-p Use extended prefix mode\n"); printf("-V Enable VCD dumb functions\n"); @@ -333,7 +312,7 @@ int main(int argc, char **argv) printf("-z Number of RX antennas used in UE\n"); //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-M Multiple SSB positions in burst\n"); + printf("-M Multiple SSB positions in burst\n"); printf("-N Nid_cell\n"); printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 4836a570f3..cd699adfd9 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -314,15 +314,6 @@ void nr_dlsim_preprocessor(module_id_t module_id, AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti); sched_ctrl->cce_index = CCEIndex; - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - - nr_set_pdsch_semi_static(current_BWP, - scc, - /* tda = */ 0, - g_nrOfLayers, - sched_ctrl, - ps); - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->rbStart = g_rbStart; sched_pdsch->rbSize = g_rbSize; @@ -331,17 +322,26 @@ void nr_dlsim_preprocessor(module_id_t module_id, /* the following might override the table that is mandated by RRC * configuration */ current_BWP->mcsTableIdx = g_mcsTableIdx; + sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], scc, slot); + AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); + + sched_pdsch->tda_info = nr_get_pdsch_tda_info(current_BWP, sched_pdsch->time_domain_allocation); + + sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, + current_BWP, + &sched_pdsch->tda_info, + sched_pdsch->nrOfLayers); sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, sched_pdsch->R, sched_pdsch->rbSize, - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->N_DMRS_SLOT, + sched_pdsch->tda_info.nrOfSymbols, + sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - ps->nrOfLayers) >> 3; + sched_pdsch->nrOfLayers) >> 3; /* the simulator assumes the HARQ PID is equal to the slot number */ sched_pdsch->dl_harq_pid = slot; diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index d3af2acd77..c556f66361 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -63,7 +63,6 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_R void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap); void prepare_scc(NR_ServingCellConfigCommon_t *scc); void prepare_scd(NR_ServingCellConfig_t *scd); -ngap_gNB_config_t ngap_config; uint32_t ngap_generate_gNB_id(void) {return 0;} void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;} void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;} diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 43ac3fc145..fb15cc1c87 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1063,7 +1063,6 @@ int main(int argc, char **argv) double blerStats[4][100]; double berStats[4][100]; double snrStats[100]; - double ldpcDecStats[100] = {0}; memset(errors_scrambling, 0, sizeof(uint32_t)*4*100); memset(n_errors, 0, sizeof(int)*4*100); memset(round_trials, 0, sizeof(int)*4*100); @@ -1633,8 +1632,6 @@ int main(int argc, char **argv) printf("\n"); } - ldpcDecStats[snrRun] = gNB->ulsch_decoding_stats.trials?inMicroS(gNB->ulsch_decoding_stats.diff/gNB->ulsch_decoding_stats.trials):0; - if(n_trials==1) break; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeLists.txt b/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeLists.txt index 836af4540a..849b483ec6 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeLists.txt +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/build/CMakeLists.txt @@ -43,7 +43,7 @@ set(DEBUG_DLSCH True) set(T_TRACER False) # standard cmake file for nr ue build -include(../../../../../cmake_targets/CMakeLists.txt) +include(../../../../../CMakeLists.txt) set(SRC_UNIT_TESTS diff --git a/openair1/SIMULATION/TOOLS/DOC/rtusage.md b/openair1/SIMULATION/TOOLS/DOC/rtusage.md index 37fc62b496..13a54c258c 100644 --- a/openair1/SIMULATION/TOOLS/DOC/rtusage.md +++ b/openair1/SIMULATION/TOOLS/DOC/rtusage.md @@ -63,7 +63,7 @@ softmodem_enb> -The [rfsimulator documentation](../../../../targets/ARCH/rfsimulator/README.md ) has also some specific information when using the channel simulation via this tool. +The [rfsimulator documentation](../../../../sdr/rfsimulator/README.md ) has also some specific information when using the channel simulation via this tool. [channel simulation main page](channel_simulation.md) -[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/openair2/CMakeLists.txt b/openair2/CMakeLists.txt new file mode 100644 index 0000000000..323c3a2ee1 --- /dev/null +++ b/openair2/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(E1AP) diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt new file mode 100644 index 0000000000..b9516fc91d --- /dev/null +++ b/openair2/E1AP/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(MESSAGES) + +add_library(E1AP e1ap.c) +target_link_libraries(E1AP + PUBLIC asn1_e1ap + PRIVATE UTIL) +target_include_directories(E1AP PUBLIC ${CMAKE_CURRENT_DIR}) diff --git a/openair2/E1AP/MESSAGES/ASN.1/38463-g80.R16.78.0.asn b/openair2/E1AP/MESSAGES/ASN.1/38463-g80.R16.78.0.asn new file mode 100644 index 0000000000..38d1f141e8 --- /dev/null +++ b/openair2/E1AP/MESSAGES/ASN.1/38463-g80.R16.78.0.asn @@ -0,0 +1,4986 @@ +-- ASN1START +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +E1AP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-PDU-Descriptions (0) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules +-- +-- ************************************************************** + +IMPORTS + Criticality, + ProcedureCode + +FROM E1AP-CommonDataTypes + Reset, + ResetAcknowledge, + ErrorIndication, + GNB-CU-UP-E1SetupRequest, + GNB-CU-UP-E1SetupResponse, + GNB-CU-UP-E1SetupFailure, + GNB-CU-CP-E1SetupRequest, + GNB-CU-CP-E1SetupResponse, + GNB-CU-CP-E1SetupFailure, + GNB-CU-UP-ConfigurationUpdate, + GNB-CU-UP-ConfigurationUpdateAcknowledge, + GNB-CU-UP-ConfigurationUpdateFailure, + GNB-CU-CP-ConfigurationUpdate, + GNB-CU-CP-ConfigurationUpdateAcknowledge, + GNB-CU-CP-ConfigurationUpdateFailure, + BearerContextSetupRequest, + BearerContextSetupResponse, + BearerContextSetupFailure, + BearerContextModificationRequest, + BearerContextModificationResponse, + BearerContextModificationFailure, + BearerContextModificationRequired, + BearerContextModificationConfirm, + BearerContextReleaseCommand, + BearerContextReleaseComplete, + BearerContextReleaseRequest, + BearerContextInactivityNotification, + DLDataNotification, + ULDataNotification, + DataUsageReport, + E1ReleaseRequest, + E1ReleaseResponse, + GNB-CU-UP-CounterCheckRequest, + GNB-CU-UP-StatusIndication, + MRDC-DataUsageReport, + DeactivateTrace, + TraceStart, + PrivateMessage, + ResourceStatusRequest, + ResourceStatusResponse, + ResourceStatusFailure, + ResourceStatusUpdate, + IAB-UPTNLAddressUpdate, + IAB-UPTNLAddressUpdateAcknowledge, + IAB-UPTNLAddressUpdateFailure, + CellTrafficTrace, + EarlyForwardingSNTransfer, + GNB-CU-CPMeasurementResultsInformation + +FROM E1AP-PDU-Contents + id-reset, + id-errorIndication, + id-gNB-CU-UP-E1Setup, + id-gNB-CU-CP-E1Setup, + id-gNB-CU-UP-ConfigurationUpdate, + id-gNB-CU-CP-ConfigurationUpdate, + id-e1Release, + id-bearerContextSetup, + id-bearerContextModification, + id-bearerContextModificationRequired, + id-bearerContextRelease, + id-bearerContextReleaseRequest, + id-bearerContextInactivityNotification, + id-dLDataNotification, + id-uLDataNotification, + id-dataUsageReport, + id-gNB-CU-UP-CounterCheck, + id-gNB-CU-UP-StatusIndication, + id-mRDC-DataUsageReport, + id-DeactivateTrace, + id-TraceStart, + id-privateMessage, + id-resourceStatusReportingInitiation, + id-resourceStatusReporting, + id-iAB-UPTNLAddressUpdate, + id-CellTrafficTrace, + id-earlyForwardingSNTransfer, + id-gNB-CU-CPMeasurementResultsInformation + +FROM E1AP-Constants; + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +E1AP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + +&UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +E1AP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode E1AP-ELEMENTARY-PROCEDURE.&procedureCode ({E1AP-ELEMENTARY-PROCEDURES}), + criticality E1AP-ELEMENTARY-PROCEDURE.&criticality ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value E1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode E1AP-ELEMENTARY-PROCEDURE.&procedureCode ({E1AP-ELEMENTARY-PROCEDURES}), + criticality E1AP-ELEMENTARY-PROCEDURE.&criticality ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value E1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode E1AP-ELEMENTARY-PROCEDURE.&procedureCode ({E1AP-ELEMENTARY-PROCEDURES}), + criticality E1AP-ELEMENTARY-PROCEDURE.&criticality ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value E1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({E1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +E1AP-ELEMENTARY-PROCEDURES E1AP-ELEMENTARY-PROCEDURE ::= { + E1AP-ELEMENTARY-PROCEDURES-CLASS-1 | + E1AP-ELEMENTARY-PROCEDURES-CLASS-2 , + + ... +} + +E1AP-ELEMENTARY-PROCEDURES-CLASS-1 E1AP-ELEMENTARY-PROCEDURE ::= { + reset | + gNB-CU-UP-E1Setup | + gNB-CU-CP-E1Setup | + gNB-CU-UP-ConfigurationUpdate | + gNB-CU-CP-ConfigurationUpdate | + e1Release | + bearerContextSetup | + bearerContextModification | + bearerContextModificationRequired | + bearerContextRelease | + resourceStatusReportingInitiation | + iAB-UPTNLAddressUpdate , + ... +} + +E1AP-ELEMENTARY-PROCEDURES-CLASS-2 E1AP-ELEMENTARY-PROCEDURE ::= { + errorIndication | + bearerContextReleaseRequest | + bearerContextInactivityNotification | + dLDataNotification | + uLDataNotification | + dataUsageReport | + gNB-CU-UP-CounterCheck | + gNB-CU-UP-StatusIndication | + mRDC-DataUsageReport | + deactivateTrace | + traceStart | + privateMessage | + cellTrafficTrace | + resourceStatusReporting | + earlyForwardingSNTransfer | + gNB-CU-CPMeasurementResultsInformation, + ... +} + +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +reset E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-reset + CRITICALITY reject +} + +errorIndication E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-errorIndication + CRITICALITY ignore +} + +gNB-CU-UP-E1Setup E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-UP-E1SetupRequest + SUCCESSFUL OUTCOME GNB-CU-UP-E1SetupResponse + UNSUCCESSFUL OUTCOME GNB-CU-UP-E1SetupFailure + PROCEDURE CODE id-gNB-CU-UP-E1Setup + CRITICALITY reject +} + +gNB-CU-CP-E1Setup E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-CP-E1SetupRequest + SUCCESSFUL OUTCOME GNB-CU-CP-E1SetupResponse + UNSUCCESSFUL OUTCOME GNB-CU-CP-E1SetupFailure + PROCEDURE CODE id-gNB-CU-CP-E1Setup + CRITICALITY reject +} + +gNB-CU-UP-ConfigurationUpdate E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-UP-ConfigurationUpdate + SUCCESSFUL OUTCOME GNB-CU-UP-ConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME GNB-CU-UP-ConfigurationUpdateFailure + PROCEDURE CODE id-gNB-CU-UP-ConfigurationUpdate + CRITICALITY reject +} + +gNB-CU-CP-ConfigurationUpdate E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-CP-ConfigurationUpdate + SUCCESSFUL OUTCOME GNB-CU-CP-ConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME GNB-CU-CP-ConfigurationUpdateFailure + PROCEDURE CODE id-gNB-CU-CP-ConfigurationUpdate + CRITICALITY reject +} + +e1Release E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE E1ReleaseRequest + SUCCESSFUL OUTCOME E1ReleaseResponse + PROCEDURE CODE id-e1Release + CRITICALITY reject +} + +bearerContextSetup E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE BearerContextSetupRequest + SUCCESSFUL OUTCOME BearerContextSetupResponse + UNSUCCESSFUL OUTCOME BearerContextSetupFailure + PROCEDURE CODE id-bearerContextSetup + CRITICALITY reject +} + +bearerContextModification E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE BearerContextModificationRequest + SUCCESSFUL OUTCOME BearerContextModificationResponse + UNSUCCESSFUL OUTCOME BearerContextModificationFailure + PROCEDURE CODE id-bearerContextModification + CRITICALITY reject +} + +bearerContextModificationRequired E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE BearerContextModificationRequired + SUCCESSFUL OUTCOME BearerContextModificationConfirm + PROCEDURE CODE id-bearerContextModificationRequired + CRITICALITY reject +} + +bearerContextRelease E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE BearerContextReleaseCommand + SUCCESSFUL OUTCOME BearerContextReleaseComplete + PROCEDURE CODE id-bearerContextRelease + CRITICALITY reject +} + +bearerContextReleaseRequest E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE BearerContextReleaseRequest + PROCEDURE CODE id-bearerContextReleaseRequest + CRITICALITY ignore +} + +bearerContextInactivityNotification E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE BearerContextInactivityNotification + PROCEDURE CODE id-bearerContextInactivityNotification + CRITICALITY ignore +} + +dLDataNotification E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DLDataNotification + PROCEDURE CODE id-dLDataNotification + CRITICALITY ignore +} + +uLDataNotification E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ULDataNotification + PROCEDURE CODE id-uLDataNotification + CRITICALITY ignore +} + +dataUsageReport E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DataUsageReport + PROCEDURE CODE id-dataUsageReport + CRITICALITY ignore +} + +gNB-CU-UP-CounterCheck E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-UP-CounterCheckRequest + PROCEDURE CODE id-gNB-CU-UP-CounterCheck + CRITICALITY ignore +} + +gNB-CU-UP-StatusIndication E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-UP-StatusIndication + PROCEDURE CODE id-gNB-CU-UP-StatusIndication + CRITICALITY ignore +} + +privateMessage E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore +} + +gNB-CU-CPMeasurementResultsInformation E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNB-CU-CPMeasurementResultsInformation + PROCEDURE CODE id-gNB-CU-CPMeasurementResultsInformation + CRITICALITY ignore +} + +mRDC-DataUsageReport E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MRDC-DataUsageReport + PROCEDURE CODE id-mRDC-DataUsageReport + CRITICALITY ignore +} + +deactivateTrace E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DeactivateTrace + PROCEDURE CODE id-DeactivateTrace + CRITICALITY ignore +} + +traceStart E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE TraceStart + PROCEDURE CODE id-TraceStart + CRITICALITY ignore +} + +resourceStatusReportingInitiation E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ResourceStatusRequest + SUCCESSFUL OUTCOME ResourceStatusResponse + UNSUCCESSFUL OUTCOME ResourceStatusFailure + PROCEDURE CODE id-resourceStatusReportingInitiation + CRITICALITY reject +} + +resourceStatusReporting E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ResourceStatusUpdate + PROCEDURE CODE id-resourceStatusReporting + CRITICALITY ignore +} + +iAB-UPTNLAddressUpdate E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE IAB-UPTNLAddressUpdate + SUCCESSFUL OUTCOME IAB-UPTNLAddressUpdateAcknowledge + UNSUCCESSFUL OUTCOME IAB-UPTNLAddressUpdateFailure + PROCEDURE CODE id-iAB-UPTNLAddressUpdate + CRITICALITY reject +} + +cellTrafficTrace E1AP-ELEMENTARY-PROCEDURE ::={ + INITIATING MESSAGE CellTrafficTrace + PROCEDURE CODE id-CellTrafficTrace + CRITICALITY ignore +} + +earlyForwardingSNTransfer E1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE EarlyForwardingSNTransfer + PROCEDURE CODE id-earlyForwardingSNTransfer + CRITICALITY ignore +} + +END +-- ASN1STOP +-- ASN1START +-- ************************************************************** +-- +-- PDU definitions for E1AP +-- +-- ************************************************************** + +E1AP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-PDU-Contents (1) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules +-- +-- ************************************************************** + +IMPORTS + + Cause, + CriticalityDiagnostics, + GNB-CU-CP-UE-E1AP-ID, + GNB-CU-UP-UE-E1AP-ID, + UE-associatedLogicalE1-ConnectionItem, + GNB-CU-UP-ID, + GNB-CU-UP-Name, + Extended-GNB-CU-UP-Name, + GNB-CU-CP-Name, + Extended-GNB-CU-CP-Name, + CNSupport, + PLMN-Identity, + Slice-Support-List, + NR-CGI-Support-List, + QoS-Parameters-Support-List, + SecurityInformation, + BitRate, + BearerContextStatusChange, + DRB-To-Setup-List-EUTRAN, + DRB-Setup-List-EUTRAN, + DRB-Failed-List-EUTRAN, + DRB-To-Modify-List-EUTRAN, + DRB-Measurement-Results-Information-List, + DRB-Modified-List-EUTRAN, + DRB-Failed-To-Modify-List-EUTRAN, + DRB-To-Remove-List-EUTRAN, + DRB-Required-To-Remove-List-EUTRAN, + DRB-Required-To-Modify-List-EUTRAN, + DRB-Confirm-Modified-List-EUTRAN, + DRB-To-Setup-Mod-List-EUTRAN, + DRB-Setup-Mod-List-EUTRAN, + DRB-Failed-Mod-List-EUTRAN, + ExtendedSliceSupportList, + PDU-Session-Resource-To-Setup-List, + PDU-Session-Resource-Setup-List, + PDU-Session-Resource-Failed-List, + PDU-Session-Resource-To-Modify-List, + PDU-Session-Resource-Modified-List, + PDU-Session-Resource-Failed-To-Modify-List, + PDU-Session-Resource-To-Remove-List, + PDU-Session-Resource-Required-To-Modify-List, + PDU-Session-Resource-Confirm-Modified-List, + PDU-Session-Resource-To-Setup-Mod-List, + PDU-Session-Resource-Setup-Mod-List, + PDU-Session-Resource-Failed-Mod-List, + PDU-Session-To-Notify-List, + DRB-Status-Item, + DRB-Activity-Item, + Data-Usage-Report-List, + TimeToWait, + ActivityNotificationLevel, + ActivityInformation, + New-UL-TNL-Information-Required, + GNB-CU-CP-TNLA-Setup-Item, + GNB-CU-CP-TNLA-Failed-To-Setup-Item, + GNB-CU-CP-TNLA-To-Add-Item, + GNB-CU-CP-TNLA-To-Remove-Item, + GNB-CU-CP-TNLA-To-Update-Item, + GNB-CU-UP-TNLA-To-Remove-Item, + TransactionID, + Inactivity-Timer, + DRBs-Subject-To-Counter-Check-List-EUTRAN, + DRBs-Subject-To-Counter-Check-List-NG-RAN, + PPI, + GNB-CU-UP-Capacity, + GNB-CU-UP-OverloadInformation, + DataDiscardRequired, + PDU-Session-Resource-Data-Usage-List, + RANUEID, + GNB-DU-ID, + TraceID, + TraceActivation, + SubscriberProfileIDforRFP, + AdditionalRRMPriorityIndex, + RetainabilityMeasurementsInfo, + Transport-Layer-Address-Info, + HW-CapacityIndicator, + RegistrationRequest, + ReportCharacteristics, + ReportingPeriodicity, + TNL-AvailableCapacityIndicator, + DLUPTNLAddressToUpdateItem, + ULUPTNLAddressToUpdateItem, + NPNContextInfo, + NPNSupportInfo, + MDTPLMNList, + PrivacyIndicator, + URIaddress, + DRBs-Subject-To-Early-Forwarding-List, + CHOInitiation, + ExtendedSliceSupportList, + TransportLayerAddress, + AdditionalHandoverInfo, + Extended-NR-CGI-Support-List, + DirectForwardingPathAvailability + + +FROM E1AP-IEs + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerList{}, + ProtocolIE-SingleContainer{}, + E1AP-PRIVATE-IES, + E1AP-PROTOCOL-EXTENSION, + E1AP-PROTOCOL-IES + + +FROM E1AP-Containers + + id-Cause, + id-CriticalityDiagnostics, + id-gNB-CU-CP-UE-E1AP-ID, + id-gNB-CU-UP-UE-E1AP-ID, + id-ResetType, + id-UE-associatedLogicalE1-ConnectionItem, + id-UE-associatedLogicalE1-ConnectionListResAck, + id-gNB-CU-UP-ID, + id-gNB-CU-UP-Name, + id-Extended-GNB-CU-UP-Name, + id-gNB-CU-CP-Name, + id-Extended-GNB-CU-CP-Name, + id-CNSupport, + id-SupportedPLMNs, + id-NPNSupportInfo, + id-NPNContextInfo, + id-SecurityInformation, + id-UEDLAggregateMaximumBitRate, + id-BearerContextStatusChange, + id-System-BearerContextSetupRequest, + id-System-BearerContextSetupResponse, + id-System-BearerContextModificationRequest, + id-System-BearerContextModificationResponse, + id-System-BearerContextModificationConfirm, + id-System-BearerContextModificationRequired, + id-DRB-Status-List, + id-Data-Usage-Report-List, + id-TimeToWait, + id-ActivityNotificationLevel, + id-ActivityInformation, + id-New-UL-TNL-Information-Required, + id-GNB-CU-CP-TNLA-Setup-List, + id-GNB-CU-CP-TNLA-Failed-To-Setup-List, + id-GNB-CU-CP-TNLA-To-Add-List, + id-GNB-CU-CP-TNLA-To-Remove-List, + id-GNB-CU-CP-TNLA-To-Update-List, + id-GNB-CU-UP-TNLA-To-Remove-List, + id-DRB-To-Setup-List-EUTRAN, + id-DRB-To-Modify-List-EUTRAN, + id-DRB-To-Remove-List-EUTRAN, + id-DRB-Required-To-Modify-List-EUTRAN, + id-DRB-Required-To-Remove-List-EUTRAN, + id-DRB-Setup-List-EUTRAN, + id-DRB-Failed-List-EUTRAN, + id-DRB-Measurement-Results-Information-List, + id-DRB-Modified-List-EUTRAN, + id-DRB-Failed-To-Modify-List-EUTRAN, + id-DRB-Confirm-Modified-List-EUTRAN, + id-DRB-To-Setup-Mod-List-EUTRAN, + id-DRB-Setup-Mod-List-EUTRAN, + id-DRB-Failed-Mod-List-EUTRAN, + id-PDU-Session-Resource-To-Setup-List, + id-PDU-Session-Resource-To-Modify-List, + id-PDU-Session-Resource-To-Remove-List, + id-PDU-Session-Resource-Required-To-Modify-List, + id-PDU-Session-Resource-Setup-List, + id-PDU-Session-Resource-Failed-List, + id-PDU-Session-Resource-Modified-List, + id-PDU-Session-Resource-Failed-To-Modify-List, + id-PDU-Session-Resource-Confirm-Modified-List, + id-PDU-Session-Resource-Setup-Mod-List, + id-PDU-Session-Resource-Failed-Mod-List, + id-PDU-Session-Resource-To-Setup-Mod-List, + id-PDU-Session-To-Notify-List, + id-TransactionID, + id-Serving-PLMN, + id-UE-Inactivity-Timer, + id-System-GNB-CU-UP-CounterCheckRequest, + id-DRBs-Subject-To-Counter-Check-List-EUTRAN, + id-DRBs-Subject-To-Counter-Check-List-NG-RAN, + id-PPI, + id-gNB-CU-UP-Capacity, + id-GNB-CU-UP-OverloadInformation, + id-UEDLMaximumIntegrityProtectedDataRate, + id-DataDiscardRequired, + id-PDU-Session-Resource-Data-Usage-List, + id-RANUEID, + id-GNB-DU-ID, + id-TraceID, + id-TraceActivation, + id-SubscriberProfileIDforRFP, + id-AdditionalRRMPriorityIndex, + id-RetainabilityMeasurementsInfo, + id-Transport-Layer-Address-Info, + id-gNB-CU-CP-Measurement-ID, + id-gNB-CU-UP-Measurement-ID, + id-RegistrationRequest, + id-ReportCharacteristics, + id-ReportingPeriodicity, + id-TNL-AvailableCapacityIndicator, + id-HW-CapacityIndicator, + id-DLUPTNLAddressToUpdateList, + id-ULUPTNLAddressToUpdateList, + id-ManagementBasedMDTPLMNList, + id-TraceCollectionEntityIPAddress, + id-PrivacyIndicator, + id-URIaddress, + id-DRBs-Subject-To-Early-Forwarding-List, + id-CHOInitiation, + id-ExtendedSliceSupportList, + id-AdditionalHandoverInfo, + id-Extended-NR-CGI-Support-List, + id-DirectForwardingPathAvailability, + + maxnoofErrors, + maxnoofSPLMNs, + maxnoofDRBs, + maxnoofTNLAssociations, + maxnoofIndividualE1ConnectionsToReset, + maxnoofTNLAddresses + + +FROM E1AP-Constants; + +-- ************************************************************** +-- +-- RESET +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Reset +-- +-- ************************************************************** + +Reset ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetIEs} }, + ... +} + +ResetIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... +} + +ResetType ::= CHOICE { + e1-Interface ResetAll, + partOfE1-Interface UE-associatedLogicalE1-ConnectionListRes, + choice-extension ProtocolIE-SingleContainer {{ResetType-ExtIEs}} +} + +ResetType-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +UE-associatedLogicalE1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualE1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalE1-ConnectionItemRes } } + +UE-associatedLogicalE1-ConnectionItemRes E1AP-PROTOCOL-IES ::= { + + { ID id-UE-associatedLogicalE1-ConnectionItem CRITICALITY reject TYPE UE-associatedLogicalE1-ConnectionItem PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- Reset Acknowledge +-- +-- ************************************************************** + +ResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, + ... +} + +ResetAcknowledgeIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-UE-associatedLogicalE1-ConnectionListResAck CRITICALITY ignore TYPE UE-associatedLogicalE1-ConnectionListResAck PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +UE-associatedLogicalE1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualE1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalE1-ConnectionItemResAck } } + +UE-associatedLogicalE1-ConnectionItemResAck E1AP-PROTOCOL-IES ::= { + { ID id-UE-associatedLogicalE1-ConnectionItem CRITICALITY ignore TYPE UE-associatedLogicalE1-ConnectionItem PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- ERROR INDICATION +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ErrorIndication-IEs}}, + ... +} + +ErrorIndication-IEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY ignore TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE optional}| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY ignore TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE optional}| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-UP E1 SETUP +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-CU-UP E1 Setup Request +-- +-- ************************************************************** + +GNB-CU-UP-E1SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-UP-E1SetupRequestIEs} }, + ... +} + +GNB-CU-UP-E1SetupRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-UP-ID CRITICALITY reject TYPE GNB-CU-UP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-Name CRITICALITY ignore TYPE GNB-CU-UP-Name PRESENCE optional }| + { ID id-CNSupport CRITICALITY reject TYPE CNSupport PRESENCE mandatory }| + { ID id-SupportedPLMNs CRITICALITY reject TYPE SupportedPLMNs-List PRESENCE mandatory }| + { ID id-gNB-CU-UP-Capacity CRITICALITY ignore TYPE GNB-CU-UP-Capacity PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }| + { ID id-Extended-GNB-CU-UP-Name CRITICALITY ignore TYPE Extended-GNB-CU-UP-Name PRESENCE optional }, + ... +} + +SupportedPLMNs-List ::= SEQUENCE (SIZE (1..maxnoofSPLMNs)) OF SupportedPLMNs-Item + +SupportedPLMNs-Item ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + slice-Support-List Slice-Support-List OPTIONAL, + nR-CGI-Support-List NR-CGI-Support-List OPTIONAL, + qoS-Parameters-Support-List QoS-Parameters-Support-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SupportedPLMNs-ExtIEs } } OPTIONAL, + ... +} + +SupportedPLMNs-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-NPNSupportInfo CRITICALITY reject EXTENSION NPNSupportInfo PRESENCE optional}| + { ID id-ExtendedSliceSupportList CRITICALITY reject EXTENSION ExtendedSliceSupportList PRESENCE optional}| + { ID id-Extended-NR-CGI-Support-List CRITICALITY ignore EXTENSION Extended-NR-CGI-Support-List PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-UP E1 Setup Response +-- +-- ************************************************************** + +GNB-CU-UP-E1SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-UP-E1SetupResponseIEs} }, + ... +} + +GNB-CU-UP-E1SetupResponseIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-CP-Name CRITICALITY ignore TYPE GNB-CU-CP-Name PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }| + { ID id-Extended-GNB-CU-CP-Name CRITICALITY ignore TYPE Extended-GNB-CU-CP-Name PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-UP E1 Setup Failure +-- +-- ************************************************************** + +GNB-CU-UP-E1SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-UP-E1SetupFailureIEs} }, + ... +} + +GNB-CU-UP-E1SetupFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-CP E1 SETUP +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-CU-CP E1 Setup Request +-- +-- ************************************************************** + +GNB-CU-CP-E1SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-CP-E1SetupRequestIEs} }, + ... +} + +GNB-CU-CP-E1SetupRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-CP-Name CRITICALITY ignore TYPE GNB-CU-CP-Name PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }| + { ID id-Extended-GNB-CU-CP-Name CRITICALITY ignore TYPE Extended-GNB-CU-CP-Name PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-CP E1 Setup Response +-- +-- ************************************************************** + +GNB-CU-CP-E1SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-CP-E1SetupResponseIEs} }, + ... +} + +GNB-CU-CP-E1SetupResponseIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-UP-ID CRITICALITY reject TYPE GNB-CU-UP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-Name CRITICALITY ignore TYPE GNB-CU-UP-Name PRESENCE optional }| + { ID id-CNSupport CRITICALITY reject TYPE CNSupport PRESENCE mandatory }| + { ID id-SupportedPLMNs CRITICALITY reject TYPE SupportedPLMNs-List PRESENCE mandatory }| + { ID id-gNB-CU-UP-Capacity CRITICALITY ignore TYPE GNB-CU-UP-Capacity PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }| + { ID id-Extended-GNB-CU-UP-Name CRITICALITY ignore TYPE Extended-GNB-CU-UP-Name PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-CP E1 Setup Failure +-- +-- ************************************************************** + +GNB-CU-CP-E1SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-CP-E1SetupFailureIEs} }, + ... +} + +GNB-CU-CP-E1SetupFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-UP CONFIGURATION UPDATE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-CU-UP Configuration Update +-- +-- ************************************************************** + +GNB-CU-UP-ConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-UP-ConfigurationUpdateIEs} }, + ... +} + +GNB-CU-UP-ConfigurationUpdateIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-UP-ID CRITICALITY reject TYPE GNB-CU-UP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-Name CRITICALITY ignore TYPE GNB-CU-UP-Name PRESENCE optional }| + { ID id-SupportedPLMNs CRITICALITY reject TYPE SupportedPLMNs-List PRESENCE optional }| + { ID id-gNB-CU-UP-Capacity CRITICALITY ignore TYPE GNB-CU-UP-Capacity PRESENCE optional }| + { ID id-GNB-CU-UP-TNLA-To-Remove-List CRITICALITY reject TYPE GNB-CU-UP-TNLA-To-Remove-List PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }| + { ID id-Extended-GNB-CU-UP-Name CRITICALITY ignore TYPE Extended-GNB-CU-UP-Name PRESENCE optional }, + ... +} + +GNB-CU-UP-TNLA-To-Remove-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF GNB-CU-UP-TNLA-To-Remove-Item + +-- ************************************************************** +-- +-- GNB-CU-UP Configuration Update Acknowledge +-- +-- ************************************************************** + +GNB-CU-UP-ConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-UP-ConfigurationUpdateAcknowledgeIEs} }, + ... +} + +GNB-CU-UP-ConfigurationUpdateAcknowledgeIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-UP Configuration Update Failure +-- +-- ************************************************************** + +GNB-CU-UP-ConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-UP-ConfigurationUpdateFailureIEs} }, + ... +} + +GNB-CU-UP-ConfigurationUpdateFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU-CP CONFIGURATION UPDATE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-CU-CP Configuration Update +-- +-- ************************************************************** + +GNB-CU-CP-ConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-CP-ConfigurationUpdateIEs} }, + ... +} + +GNB-CU-CP-ConfigurationUpdateIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-CP-Name CRITICALITY ignore TYPE GNB-CU-CP-Name PRESENCE optional }| + { ID id-GNB-CU-CP-TNLA-To-Add-List CRITICALITY ignore TYPE GNB-CU-CP-TNLA-To-Add-List PRESENCE optional }| + { ID id-GNB-CU-CP-TNLA-To-Remove-List CRITICALITY ignore TYPE GNB-CU-CP-TNLA-To-Remove-List PRESENCE optional }| + { ID id-GNB-CU-CP-TNLA-To-Update-List CRITICALITY ignore TYPE GNB-CU-CP-TNLA-To-Update-List PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }| + { ID id-Extended-GNB-CU-CP-Name CRITICALITY ignore TYPE Extended-GNB-CU-CP-Name PRESENCE optional }, + ... +} + +GNB-CU-CP-TNLA-To-Add-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF GNB-CU-CP-TNLA-To-Add-Item +GNB-CU-CP-TNLA-To-Remove-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF GNB-CU-CP-TNLA-To-Remove-Item +GNB-CU-CP-TNLA-To-Update-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF GNB-CU-CP-TNLA-To-Update-Item + +-- ************************************************************** +-- +-- GNB-CU-CP Configuration Update Acknowledge +-- +-- ************************************************************** + +GNB-CU-CP-ConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-CP-ConfigurationUpdateAcknowledgeIEs} }, + ... +} + +GNB-CU-CP-ConfigurationUpdateAcknowledgeIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-GNB-CU-CP-TNLA-Setup-List CRITICALITY ignore TYPE GNB-CU-CP-TNLA-Setup-List PRESENCE optional }| + { ID id-GNB-CU-CP-TNLA-Failed-To-Setup-List CRITICALITY ignore TYPE GNB-CU-CP-TNLA-Failed-To-Setup-List PRESENCE optional }| + { ID id-Transport-Layer-Address-Info CRITICALITY ignore TYPE Transport-Layer-Address-Info PRESENCE optional }, + ... +} + +GNB-CU-CP-TNLA-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF GNB-CU-CP-TNLA-Setup-Item +GNB-CU-CP-TNLA-Failed-To-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF GNB-CU-CP-TNLA-Failed-To-Setup-Item + + +-- ************************************************************** +-- +-- GNB-CU-CP Configuration Update Failure +-- +-- ************************************************************** + +GNB-CU-CP-ConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNB-CU-CP-ConfigurationUpdateFailureIEs} }, + ... +} + +GNB-CU-CP-ConfigurationUpdateFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- E1 RELEASE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- E1 Release Request +-- +-- ************************************************************** + +E1ReleaseRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {E1ReleaseRequestIEs} }, + ... +} + +E1ReleaseRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- E1 Release Response +-- +-- ************************************************************** + +E1ReleaseResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {E1ReleaseResponseIEs} }, + ... +} + +E1ReleaseResponseIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- BEARER CONTEXT SETUP +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Bearer Context Setup Request +-- +-- ************************************************************** + +BearerContextSetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextSetupRequestIEs} }, + ... +} + +BearerContextSetupRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-SecurityInformation CRITICALITY reject TYPE SecurityInformation PRESENCE mandatory }| + { ID id-UEDLAggregateMaximumBitRate CRITICALITY reject TYPE BitRate PRESENCE mandatory }| + { ID id-UEDLMaximumIntegrityProtectedDataRate CRITICALITY reject TYPE BitRate PRESENCE optional }| + { ID id-Serving-PLMN CRITICALITY ignore TYPE PLMN-Identity PRESENCE mandatory }| + { ID id-ActivityNotificationLevel CRITICALITY reject TYPE ActivityNotificationLevel PRESENCE mandatory }| + { ID id-UE-Inactivity-Timer CRITICALITY reject TYPE Inactivity-Timer PRESENCE optional }| + { ID id-BearerContextStatusChange CRITICALITY reject TYPE BearerContextStatusChange PRESENCE optional }| + { ID id-System-BearerContextSetupRequest CRITICALITY reject TYPE System-BearerContextSetupRequest PRESENCE mandatory }| + { ID id-RANUEID CRITICALITY ignore TYPE RANUEID PRESENCE optional }| + { ID id-GNB-DU-ID CRITICALITY ignore TYPE GNB-DU-ID PRESENCE optional }| + { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE optional }| + { ID id-NPNContextInfo CRITICALITY reject TYPE NPNContextInfo PRESENCE optional}| + { ID id-ManagementBasedMDTPLMNList CRITICALITY ignore TYPE MDTPLMNList PRESENCE optional}| + { ID id-CHOInitiation CRITICALITY reject TYPE CHOInitiation PRESENCE optional }| + { ID id-AdditionalHandoverInfo CRITICALITY ignore TYPE AdditionalHandoverInfo PRESENCE optional }| + { ID id-DirectForwardingPathAvailability CRITICALITY ignore TYPE DirectForwardingPathAvailability PRESENCE optional }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY ignore TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE optional }, + ... +} + +System-BearerContextSetupRequest ::= CHOICE { + e-UTRAN-BearerContextSetupRequest ProtocolIE-Container {{EUTRAN-BearerContextSetupRequest}}, + nG-RAN-BearerContextSetupRequest ProtocolIE-Container {{NG-RAN-BearerContextSetupRequest}}, + choice-extension ProtocolIE-SingleContainer {{System-BearerContextSetupRequest-ExtIEs}} +} + +System-BearerContextSetupRequest-ExtIEs E1AP-PROTOCOL-IES::= { + ... +} + + +EUTRAN-BearerContextSetupRequest E1AP-PROTOCOL-IES ::= { + { ID id-DRB-To-Setup-List-EUTRAN CRITICALITY reject TYPE DRB-To-Setup-List-EUTRAN PRESENCE mandatory }| + { ID id-SubscriberProfileIDforRFP CRITICALITY ignore TYPE SubscriberProfileIDforRFP PRESENCE optional }| + { ID id-AdditionalRRMPriorityIndex CRITICALITY ignore TYPE AdditionalRRMPriorityIndex PRESENCE optional }, + ... +} + +NG-RAN-BearerContextSetupRequest E1AP-PROTOCOL-IES ::= { + { ID id-PDU-Session-Resource-To-Setup-List CRITICALITY reject TYPE PDU-Session-Resource-To-Setup-List PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- Bearer Context Setup Response +-- +-- ************************************************************** + +BearerContextSetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextSetupResponseIEs} }, + ... +} + + +BearerContextSetupResponseIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-System-BearerContextSetupResponse CRITICALITY ignore TYPE System-BearerContextSetupResponse PRESENCE mandatory }, + ... +} + +System-BearerContextSetupResponse::= CHOICE { + e-UTRAN-BearerContextSetupResponse ProtocolIE-Container {{EUTRAN-BearerContextSetupResponse}}, + nG-RAN-BearerContextSetupResponse ProtocolIE-Container {{NG-RAN-BearerContextSetupResponse}}, + choice-extension ProtocolIE-SingleContainer {{System-BearerContextSetupResponse-ExtIEs}} +} + +System-BearerContextSetupResponse-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +EUTRAN-BearerContextSetupResponse E1AP-PROTOCOL-IES ::= { + { ID id-DRB-Setup-List-EUTRAN CRITICALITY ignore TYPE DRB-Setup-List-EUTRAN PRESENCE mandatory }| + { ID id-DRB-Failed-List-EUTRAN CRITICALITY ignore TYPE DRB-Failed-List-EUTRAN PRESENCE optional }, + ... +} + +NG-RAN-BearerContextSetupResponse E1AP-PROTOCOL-IES ::= { + { ID id-PDU-Session-Resource-Setup-List CRITICALITY ignore TYPE PDU-Session-Resource-Setup-List PRESENCE mandatory }| + { ID id-PDU-Session-Resource-Failed-List CRITICALITY ignore TYPE PDU-Session-Resource-Failed-List PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- Bearer Context Setup Failure +-- +-- ************************************************************** + +BearerContextSetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextSetupFailureIEs} }, + ... +} + +BearerContextSetupFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY ignore TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- BEARER CONTEXT MODIFICATION +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Bearer Context Modification Request +-- +-- ************************************************************** + +BearerContextModificationRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextModificationRequestIEs} }, + ... +} + +BearerContextModificationRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-SecurityInformation CRITICALITY reject TYPE SecurityInformation PRESENCE optional }| + { ID id-UEDLAggregateMaximumBitRate CRITICALITY reject TYPE BitRate PRESENCE optional }| + { ID id-UEDLMaximumIntegrityProtectedDataRate CRITICALITY reject TYPE BitRate PRESENCE optional }| + { ID id-BearerContextStatusChange CRITICALITY reject TYPE BearerContextStatusChange PRESENCE optional }| + { ID id-New-UL-TNL-Information-Required CRITICALITY reject TYPE New-UL-TNL-Information-Required PRESENCE optional }| + { ID id-UE-Inactivity-Timer CRITICALITY reject TYPE Inactivity-Timer PRESENCE optional }| + { ID id-DataDiscardRequired CRITICALITY ignore TYPE DataDiscardRequired PRESENCE optional }| + { ID id-System-BearerContextModificationRequest CRITICALITY reject TYPE System-BearerContextModificationRequest PRESENCE optional }| + { ID id-RANUEID CRITICALITY ignore TYPE RANUEID PRESENCE optional }| + { ID id-GNB-DU-ID CRITICALITY ignore TYPE GNB-DU-ID PRESENCE optional }| + { ID id-ActivityNotificationLevel CRITICALITY ignore TYPE ActivityNotificationLevel PRESENCE optional }, + ... +} + +System-BearerContextModificationRequest ::= CHOICE { + e-UTRAN-BearerContextModificationRequest ProtocolIE-Container {{EUTRAN-BearerContextModificationRequest}}, + nG-RAN-BearerContextModificationRequest ProtocolIE-Container {{NG-RAN-BearerContextModificationRequest}}, + choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationRequest-ExtIEs}} +} + +System-BearerContextModificationRequest-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +EUTRAN-BearerContextModificationRequest E1AP-PROTOCOL-IES ::= { + { ID id-DRB-To-Setup-Mod-List-EUTRAN CRITICALITY reject TYPE DRB-To-Setup-Mod-List-EUTRAN PRESENCE optional }| + { ID id-DRB-To-Modify-List-EUTRAN CRITICALITY reject TYPE DRB-To-Modify-List-EUTRAN PRESENCE optional }| + { ID id-DRB-To-Remove-List-EUTRAN CRITICALITY reject TYPE DRB-To-Remove-List-EUTRAN PRESENCE optional }| + { ID id-SubscriberProfileIDforRFP CRITICALITY ignore TYPE SubscriberProfileIDforRFP PRESENCE optional }| + { ID id-AdditionalRRMPriorityIndex CRITICALITY ignore TYPE AdditionalRRMPriorityIndex PRESENCE optional }, + ... +} + +NG-RAN-BearerContextModificationRequest E1AP-PROTOCOL-IES ::= { + { ID id-PDU-Session-Resource-To-Setup-Mod-List CRITICALITY reject TYPE PDU-Session-Resource-To-Setup-Mod-List PRESENCE optional }| + { ID id-PDU-Session-Resource-To-Modify-List CRITICALITY reject TYPE PDU-Session-Resource-To-Modify-List PRESENCE optional }| + { ID id-PDU-Session-Resource-To-Remove-List CRITICALITY reject TYPE PDU-Session-Resource-To-Remove-List PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- Bearer Context Modification Response +-- +-- ************************************************************** + +BearerContextModificationResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextModificationResponseIEs} }, + ... +} + + +BearerContextModificationResponseIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-System-BearerContextModificationResponse CRITICALITY ignore TYPE System-BearerContextModificationResponse PRESENCE optional }, + ... +} + +System-BearerContextModificationResponse ::= CHOICE { + e-UTRAN-BearerContextModificationResponse ProtocolIE-Container {{EUTRAN-BearerContextModificationResponse}}, + nG-RAN-BearerContextModificationResponse ProtocolIE-Container {{NG-RAN-BearerContextModificationResponse}}, + choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationResponse-ExtIEs}} +} + +System-BearerContextModificationResponse-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +EUTRAN-BearerContextModificationResponse E1AP-PROTOCOL-IES ::= { + { ID id-DRB-Setup-Mod-List-EUTRAN CRITICALITY ignore TYPE DRB-Setup-Mod-List-EUTRAN PRESENCE optional }| + { ID id-DRB-Failed-Mod-List-EUTRAN CRITICALITY ignore TYPE DRB-Failed-Mod-List-EUTRAN PRESENCE optional }| + { ID id-DRB-Modified-List-EUTRAN CRITICALITY ignore TYPE DRB-Modified-List-EUTRAN PRESENCE optional }| + { ID id-DRB-Failed-To-Modify-List-EUTRAN CRITICALITY ignore TYPE DRB-Failed-To-Modify-List-EUTRAN PRESENCE optional }| + { ID id-RetainabilityMeasurementsInfo CRITICALITY ignore TYPE RetainabilityMeasurementsInfo PRESENCE optional }, + ... +} + +NG-RAN-BearerContextModificationResponse E1AP-PROTOCOL-IES ::= { + { ID id-PDU-Session-Resource-Setup-Mod-List CRITICALITY reject TYPE PDU-Session-Resource-Setup-Mod-List PRESENCE optional }| + { ID id-PDU-Session-Resource-Failed-Mod-List CRITICALITY reject TYPE PDU-Session-Resource-Failed-Mod-List PRESENCE optional }| + { ID id-PDU-Session-Resource-Modified-List CRITICALITY reject TYPE PDU-Session-Resource-Modified-List PRESENCE optional }| + { ID id-PDU-Session-Resource-Failed-To-Modify-List CRITICALITY reject TYPE PDU-Session-Resource-Failed-To-Modify-List PRESENCE optional }| + { ID id-RetainabilityMeasurementsInfo CRITICALITY ignore TYPE RetainabilityMeasurementsInfo PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- Bearer Context Modification Failure +-- +-- ************************************************************** + +BearerContextModificationFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextModificationFailureIEs} }, + ... +} + +BearerContextModificationFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- BEARER CONTEXT MODIFICATION REQUIRED +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Bearer Context Modification Required +-- +-- ************************************************************** + +BearerContextModificationRequired ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextModificationRequiredIEs} }, + ... +} + +BearerContextModificationRequiredIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-System-BearerContextModificationRequired CRITICALITY reject TYPE System-BearerContextModificationRequired PRESENCE mandatory }, + ... +} + +System-BearerContextModificationRequired ::= CHOICE { + e-UTRAN-BearerContextModificationRequired ProtocolIE-Container {{EUTRAN-BearerContextModificationRequired}}, + nG-RAN-BearerContextModificationRequired ProtocolIE-Container {{NG-RAN-BearerContextModificationRequired}}, + choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationRequired-ExtIEs}} +} + +System-BearerContextModificationRequired-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +EUTRAN-BearerContextModificationRequired E1AP-PROTOCOL-IES ::= { + { ID id-DRB-Required-To-Modify-List-EUTRAN CRITICALITY reject TYPE DRB-Required-To-Modify-List-EUTRAN PRESENCE optional }| + { ID id-DRB-Required-To-Remove-List-EUTRAN CRITICALITY reject TYPE DRB-Required-To-Remove-List-EUTRAN PRESENCE optional }, + ... +} + +NG-RAN-BearerContextModificationRequired E1AP-PROTOCOL-IES ::= { + { ID id-PDU-Session-Resource-Required-To-Modify-List CRITICALITY reject TYPE PDU-Session-Resource-Required-To-Modify-List PRESENCE optional }| + { ID id-PDU-Session-Resource-To-Remove-List CRITICALITY reject TYPE PDU-Session-Resource-To-Remove-List PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- Bearer Context Modification Confirm +-- +-- ************************************************************** + +BearerContextModificationConfirm ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextModificationConfirmIEs} }, + ... +} + + +BearerContextModificationConfirmIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-System-BearerContextModificationConfirm CRITICALITY ignore TYPE System-BearerContextModificationConfirm PRESENCE optional }, + ... +} + +System-BearerContextModificationConfirm ::= CHOICE { + e-UTRAN-BearerContextModificationConfirm ProtocolIE-Container {{EUTRAN-BearerContextModificationConfirm}}, + nG-RAN-BearerContextModificationConfirm ProtocolIE-Container {{NG-RAN-BearerContextModificationConfirm}}, + choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationConfirm-ExtIEs}} +} + +System-BearerContextModificationConfirm-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +EUTRAN-BearerContextModificationConfirm E1AP-PROTOCOL-IES ::= { + { ID id-DRB-Confirm-Modified-List-EUTRAN CRITICALITY ignore TYPE DRB-Confirm-Modified-List-EUTRAN PRESENCE optional }, + ... +} + +NG-RAN-BearerContextModificationConfirm E1AP-PROTOCOL-IES ::= { + { ID id-PDU-Session-Resource-Confirm-Modified-List CRITICALITY ignore TYPE PDU-Session-Resource-Confirm-Modified-List PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- BEARER CONTEXT RELEASE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Bearer Context Release Command +-- +-- ************************************************************** + +BearerContextReleaseCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextReleaseCommandIEs} }, + ... +} + +BearerContextReleaseCommandIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- Bearer Context Release Complete +-- +-- ************************************************************** + +BearerContextReleaseComplete ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextReleaseCompleteIEs} }, + ... +} + + +BearerContextReleaseCompleteIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-RetainabilityMeasurementsInfo CRITICALITY ignore TYPE RetainabilityMeasurementsInfo PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- BEARER CONTEXT RELEASE REQUEST +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Bearer Context Release Request +-- +-- ************************************************************** + +BearerContextReleaseRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextReleaseRequestIEs} }, + ... +} + +BearerContextReleaseRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-DRB-Status-List CRITICALITY ignore TYPE DRB-Status-List PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +DRB-Status-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF DRB-Status-Item + + +-- ************************************************************** +-- +-- BEARER CONTEXT INACTIVITY NOTIFICATION +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Bearer Context Inactivity Notification +-- +-- ************************************************************** + +BearerContextInactivityNotification ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { BearerContextInactivityNotificationIEs } }, + ... +} + +BearerContextInactivityNotificationIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-ActivityInformation CRITICALITY reject TYPE ActivityInformation PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- DL DATA NOTIFICATION +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- DL Data Notification +-- +-- ************************************************************** + +DLDataNotification ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { DLDataNotificationIEs } }, + ... +} + +DLDataNotificationIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-PPI CRITICALITY ignore TYPE PPI PRESENCE optional }| + { ID id-PDU-Session-To-Notify-List CRITICALITY ignore TYPE PDU-Session-To-Notify-List PRESENCE optional }, + ... +} + +-- ************************************************************** + +-- ************************************************************** +-- +-- UL Data Notification +-- +-- ************************************************************** + +ULDataNotification ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { ULDataNotificationIEs } }, + ... +} + +ULDataNotificationIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-PDU-Session-To-Notify-List CRITICALITY reject TYPE PDU-Session-To-Notify-List PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- DATA USAGE REPORT +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Data Usage Report +-- +-- ************************************************************** + +DataUsageReport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { DataUsageReportIEs } }, + ... +} + +DataUsageReportIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-Data-Usage-Report-List CRITICALITY ignore TYPE Data-Usage-Report-List PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- GNB-CU-UP COUNTER CHECK +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- gNB-CU-UP Counter Check Request +-- +-- ************************************************************** + +GNB-CU-UP-CounterCheckRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNB-CU-UP-CounterCheckRequestIEs } }, + ... +} + +GNB-CU-UP-CounterCheckRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-System-GNB-CU-UP-CounterCheckRequest CRITICALITY reject TYPE System-GNB-CU-UP-CounterCheckRequest PRESENCE mandatory }, + ... +} + +System-GNB-CU-UP-CounterCheckRequest ::= CHOICE { + e-UTRAN-GNB-CU-UP-CounterCheckRequest ProtocolIE-Container {{EUTRAN-GNB-CU-UP-CounterCheckRequest}}, + nG-RAN-GNB-CU-UP-CounterCheckRequest ProtocolIE-Container {{NG-RAN-GNB-CU-UP-CounterCheckRequest}}, + choice-extension ProtocolIE-SingleContainer {{System-GNB-CU-UP-CounterCheckRequest-ExtIEs}} +} + +System-GNB-CU-UP-CounterCheckRequest-ExtIEs E1AP-PROTOCOL-IES::= { + ... +} + +EUTRAN-GNB-CU-UP-CounterCheckRequest E1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Subject-To-Counter-Check-List-EUTRAN CRITICALITY ignore TYPE DRBs-Subject-To-Counter-Check-List-EUTRAN PRESENCE mandatory }, + ... +} + +NG-RAN-GNB-CU-UP-CounterCheckRequest E1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Subject-To-Counter-Check-List-NG-RAN CRITICALITY ignore TYPE DRBs-Subject-To-Counter-Check-List-NG-RAN PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- gNB-CU-UP STATUS INDICATION ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- gNB-CU-UP Status Indication +-- +-- ************************************************************** + + +GNB-CU-UP-StatusIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNB-CU-UP-StatusIndicationIEs} }, + ... +} + + +GNB-CU-UP-StatusIndicationIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-GNB-CU-UP-OverloadInformation CRITICALITY reject TYPE GNB-CU-UP-OverloadInformation PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- gNB-CU-CP MEASUREMENT RESULTS INFORMATION +-- +-- ************************************************************** + +GNB-CU-CPMeasurementResultsInformation ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNB-CU-CPMeasurementResultsInformationIEs } }, + ... +} + +GNB-CU-CPMeasurementResultsInformationIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory}| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory}| + { ID id-DRB-Measurement-Results-Information-List CRITICALITY ignore TYPE DRB-Measurement-Results-Information-List PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- MR-DC DATA USAGE REPORT +-- +-- ************************************************************** + +MRDC-DataUsageReport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { MRDC-DataUsageReportIEs } }, + ... +} + +MRDC-DataUsageReportIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory}| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory}| + { ID id-PDU-Session-Resource-Data-Usage-List CRITICALITY ignore TYPE PDU-Session-Resource-Data-Usage-List PRESENCE mandatory}, + ... +} + + +-- ************************************************************** +-- +-- TRACE ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- TRACE START +-- +-- ************************************************************** + +TraceStart ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {TraceStartIEs} }, + ... +} + +TraceStartIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- DEACTIVATE TRACE +-- +-- ************************************************************** + +DeactivateTrace ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DeactivateTraceIEs} }, + ... +} + +DeactivateTraceIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-TraceID CRITICALITY ignore TYPE TraceID PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- CELL TRAFFIC TRACE +-- +-- ************************************************************** + +CellTrafficTrace ::= SEQUENCE { +protocolIEs ProtocolIE-Container { { CellTrafficTraceIEs } }, +... +} + +CellTrafficTraceIEs E1AP-PROTOCOL-IES ::= { + {ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + {ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + {ID id-TraceID CRITICALITY ignore TYPE TraceID PRESENCE mandatory}| + {ID id-TraceCollectionEntityIPAddress CRITICALITY ignore TYPE TransportLayerAddress PRESENCE mandatory }| + {ID id-PrivacyIndicator CRITICALITY ignore TYPE PrivacyIndicator PRESENCE optional}| +{ID id-URIaddress CRITICALITY ignore TYPE URIaddress PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, + ... +} + +PrivateMessage-IEs E1AP-PRIVATE-IES ::= { + ... +} + +-- ************************************************************** +-- +-- RESOURCE STATUS REQUEST +-- +-- ************************************************************** + +ResourceStatusRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { ResourceStatusRequestIEs } }, + ... +} + +ResourceStatusRequestIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory}| + { ID id-gNB-CU-CP-Measurement-ID CRITICALITY reject TYPE INTEGER (1..4095, ...) PRESENCE mandatory}| + { ID id-gNB-CU-UP-Measurement-ID CRITICALITY ignore TYPE INTEGER (1..4095, ...) PRESENCE optional}| + { ID id-RegistrationRequest CRITICALITY reject TYPE RegistrationRequest PRESENCE mandatory}| + { ID id-ReportCharacteristics CRITICALITY reject TYPE ReportCharacteristics PRESENCE conditional}| + { ID id-ReportingPeriodicity CRITICALITY reject TYPE ReportingPeriodicity PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- RESOURCE STATUS RESPONSE +-- +-- ************************************************************** + + +ResourceStatusResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { ResourceStatusResponseIEs } }, + ... +} + +ResourceStatusResponseIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory}| + { ID id-gNB-CU-CP-Measurement-ID CRITICALITY reject TYPE INTEGER (1..4095, ...) PRESENCE mandatory}| + { ID id-gNB-CU-UP-Measurement-ID CRITICALITY ignore TYPE INTEGER (1..4095, ...) PRESENCE mandatory}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- RESOURCE STATUS FAILURE +-- +-- ************************************************************** + +ResourceStatusFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { ResourceStatusFailureIEs } }, + ... +} + +ResourceStatusFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory}| + { ID id-gNB-CU-CP-Measurement-ID CRITICALITY reject TYPE INTEGER (1..4095, ...) PRESENCE mandatory}| + { ID id-gNB-CU-UP-Measurement-ID CRITICALITY ignore TYPE INTEGER (1..4095, ...) PRESENCE optional}| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- RESOURCE STATUS UPDATE +-- +-- ************************************************************** + +ResourceStatusUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { ResourceStatusUpdateIEs } }, + ... +} + +ResourceStatusUpdateIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory}| + { ID id-gNB-CU-CP-Measurement-ID CRITICALITY reject TYPE INTEGER (1..4095, ...) PRESENCE mandatory}| + { ID id-gNB-CU-UP-Measurement-ID CRITICALITY ignore TYPE INTEGER (1..4095, ...) PRESENCE optional}| + { ID id-TNL-AvailableCapacityIndicator CRITICALITY ignore TYPE TNL-AvailableCapacityIndicator PRESENCE optional}| + { ID id-HW-CapacityIndicator CRITICALITY ignore TYPE HW-CapacityIndicator PRESENCE mandatory}, + + ... +} + +-- ************************************************************** +-- +-- IAB UP TNL ADDRESS UPDATE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- IAB UP TNL Address Update +-- +-- ************************************************************** + +IAB-UPTNLAddressUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { IAB-UPTNLAddressUpdateIEs} }, + ... +} + +IAB-UPTNLAddressUpdateIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-DLUPTNLAddressToUpdateList CRITICALITY ignore TYPE DLUPTNLAddressToUpdateList PRESENCE optional }, + ... +} + +DLUPTNLAddressToUpdateList ::= SEQUENCE (SIZE(1.. maxnoofTNLAddresses)) OF DLUPTNLAddressToUpdateItem + +-- ************************************************************** +-- +-- IAB UP TNL Address Update Acknowledge +-- +-- ************************************************************** + +IAB-UPTNLAddressUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { IAB-UPTNLAddressUpdateAcknowledgeIEs} }, + ... +} + +IAB-UPTNLAddressUpdateAcknowledgeIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-ULUPTNLAddressToUpdateList CRITICALITY ignore TYPE ULUPTNLAddressToUpdateList PRESENCE optional }, + ... +} + +ULUPTNLAddressToUpdateList ::= SEQUENCE (SIZE(1.. maxnoofTNLAddresses)) OF ULUPTNLAddressToUpdateItem + + +-- ************************************************************** +-- +-- IAB UP TNL Address Update Failure +-- +-- ************************************************************** + +IAB-UPTNLAddressUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {IAB-UPTNLAddressUpdateFailureIEs} }, + ... +} + +IAB-UPTNLAddressUpdateFailureIEs E1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- EARLY FORWARDING SN TRANSFER +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Early Forwarding SN Transfer +-- +-- ************************************************************** + +EarlyForwardingSNTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { EarlyForwardingSNTransferIEs } }, + ... +} + +EarlyForwardingSNTransferIEs E1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-CP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-CP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-gNB-CU-UP-UE-E1AP-ID CRITICALITY reject TYPE GNB-CU-UP-UE-E1AP-ID PRESENCE mandatory }| + { ID id-DRBs-Subject-To-Early-Forwarding-List CRITICALITY reject TYPE DRBs-Subject-To-Early-Forwarding-List PRESENCE mandatory }, + ... +} + +END +-- ASN1STOP +-- ASN1START +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +E1AP-IEs { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-IEs (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + + id-CommonNetworkInstance, + id-SNSSAI, + id-OldQoSFlowMap-ULendmarkerexpected, + id-DRB-QoS, + id-endpoint-IP-Address-and-Port, + id-NetworkInstance, + id-QoSFlowMappingIndication, + id-TNLAssociationTransportLayerAddressgNBCUUP, + id-Cause, + id-QoSMonitoringRequest, + id-QosMonitoringReportingFrequency, + id-QoSMonitoringDisabled, + id-PDCP-StatusReportIndication, + id-RedundantCommonNetworkInstance, + id-redundant-nG-UL-UP-TNL-Information, + id-redundant-nG-DL-UP-TNL-Information, + id-RedundantQosFlowIndicator, + id-TSCTrafficCharacteristics, + id-ExtendedPacketDelayBudget, + id-CNPacketDelayBudgetDownlink, + id-CNPacketDelayBudgetUplink, + id-AdditionalPDCPduplicationInformation, + id-RedundantPDUSessionInformation, + id-RedundantPDUSessionInformation-used, + id-QoS-Mapping-Information, + id-MDTConfiguration, + id-TraceCollectionEntityURI, + id-EHC-Parameters, + id-DAPSRequestInfo, + id-EarlyForwardingCOUNTReq, + id-EarlyForwardingCOUNTInfo, + id-AlternativeQoSParaSetList, + id-MCG-OfferedGBRQoSFlowInfo, + id-Number-of-tunnels, + id-DataForwardingtoE-UTRANInformationList, + id-DataForwardingtoNG-RANQoSFlowInformationList, + id-MaxCIDEHCDL, + id-ignoreMappingRuleIndication, + id-EarlyDataForwardingIndicator, + id-QoSFlowsDRBRemapping, + maxnoofQoSParaSets, + maxnoofErrors, + maxnoofSliceItems, + maxnoofEUTRANQOSParameters, + maxnoofNGRANQOSParameters, + maxnoofDRBs, + maxnoofPDUSessionResource, + maxnoofQoSFlows, + maxnoofUPParameters, + maxnoofCellGroups, + maxnooftimeperiods, + maxnoofNRCGI, + maxnoofTLAs, + maxnoofGTPTLAs, + maxnoofSPLMNs, + maxnoofMDTPLMNs, + maxnoofExtSliceItems, + maxnoofDataForwardingTunneltoE-UTRAN, + maxnoofExtNRCGI + +FROM E1AP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage + +FROM E1AP-CommonDataTypes + + ProtocolExtensionContainer{}, + ProtocolIE-SingleContainer{}, + E1AP-PROTOCOL-EXTENSION, + E1AP-PROTOCOL-IES + + +FROM E1AP-Containers; + +-- A + +ActivityInformation ::= CHOICE { + dRB-Activity-List DRB-Activity-List, + pDU-Session-Resource-Activity-List PDU-Session-Resource-Activity-List, + uE-Activity UE-Activity, + choice-extension ProtocolIE-SingleContainer {{ActivityInformation-ExtIEs}} +} + +ActivityInformation-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +ActivityNotificationLevel ::= ENUMERATED { + drb, + pdu-session, + ue, + ... +} + +AdditionalHandoverInfo ::= ENUMERATED { + discard-pdpc-SN, + ... +} + +AdditionalPDCPduplicationInformation ::= ENUMERATED { + three, + four, + ... +} + +AdditionalRRMPriorityIndex ::= BIT STRING (SIZE(32)) + +AveragingWindow ::= INTEGER (0..4095, ...) + +AlternativeQoSParaSetList ::= SEQUENCE (SIZE(1..maxnoofQoSParaSets)) OF AlternativeQoSParaSetItem + +AlternativeQoSParaSetItem ::= SEQUENCE { + alternativeQoSParameterIndex INTEGER(1..8,...), + guaranteedFlowBitRateDL BitRate OPTIONAL, + guaranteedFlowBitRateUL BitRate OPTIONAL, + packetDelayBudget PacketDelayBudget OPTIONAL, + packetErrorRate PacketErrorRate OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {AlternativeQoSParaSetItem-ExtIEs} } OPTIONAL, + ... +} + +AlternativeQoSParaSetItem-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- B + +BearerContextStatusChange ::= ENUMERATED { + suspend, + resume, + ... +} + +BitRate ::= INTEGER (0..4000000000000,...) + +-- C + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + protocol CauseProtocol, + misc CauseMisc, + choice-extension ProtocolIE-SingleContainer {{Cause-ExtIEs}} +} + +Cause-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, + unspecified, + ... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unspecified, + unknown-or-already-allocated-gnb-cu-cp-ue-e1ap-id, + unknown-or-already-allocated-gnb-cu-up-ue-e1ap-id, + unknown-or-inconsistent-pair-of-ue-e1ap-id, + interaction-with-other-procedure, + pPDCP-Count-wrap-around, + not-supported-QCI-value, + not-supported-5QI-value, + encryption-algorithms-not-supported, + integrity-protection-algorithms-not-supported, + uP-integrity-protection-not-possible, + uP-confidentiality-protection-not-possible, + multiple-PDU-Session-ID-Instances, + unknown-PDU-Session-ID, + multiple-QoS-Flow-ID-Instances, + unknown-QoS-Flow-ID, + multiple-DRB-ID-Instances, + unknown-DRB-ID, + invalid-QoS-combination, + procedure-cancelled, + normal-release, + no-radio-resources-available, + action-desirable-for-radio-reasons, + resources-not-available-for-the-slice, + pDCP-configuration-not-supported, + ..., + ue-dl-max-IP-data-rate-reason, + uP-integrity-protection-failure, + release-due-to-pre-emption, + rsn-not-available-for-the-up, + nPN-not-supported, + report-characteristic-empty, + existing-measurement-ID, + measurement-temporarily-not-available, + measurement-not-supported-for-the-object +} + +CauseTransport ::= ENUMERATED { + unspecified, + transport-resource-unavailable, + ..., + unknown-TNL-address-for-IAB +} + +Cell-Group-Information ::= SEQUENCE (SIZE(1.. maxnoofCellGroups)) OF Cell-Group-Information-Item + +Cell-Group-Information-Item ::= SEQUENCE { + cell-Group-ID Cell-Group-ID, + uL-Configuration UL-Configuration OPTIONAL, + dL-TX-Stop DL-TX-Stop OPTIONAL, + rAT-Type RAT-Type OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Cell-Group-Information-Item-ExtIEs } } OPTIONAL, + ... +} + +Cell-Group-Information-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-Number-of-tunnels CRITICALITY ignore EXTENSION Number-of-tunnels PRESENCE optional}, + ... +} + + +Cell-Group-ID ::= INTEGER (0..3, ...) + +CHOInitiation ::= ENUMERATED {true, ...} + +Number-of-tunnels ::= INTEGER (1..4, ...) + +CipheringAlgorithm ::= ENUMERATED { + nEA0, + c-128-NEA1, + c-128-NEA2, + c-128-NEA3, + ... +} + +CNSupport ::= ENUMERATED { + c-epc, + c-5gc, + both, + ... +} + +CommonNetworkInstance ::= OCTET STRING + +ConfidentialityProtectionIndication ::= ENUMERATED { + required, + preferred, + not-needed, + ... +} + + +ConfidentialityProtectionResult ::= ENUMERATED { + performed, + not-performed, + ... +} + + +CP-TNL-Information ::= CHOICE { + endpoint-IP-Address TransportLayerAddress, + choice-extension ProtocolIE-SingleContainer {{CP-TNL-Information-ExtIEs}} +} + +CP-TNL-Information-ExtIEs E1AP-PROTOCOL-IES ::= { + { ID id-endpoint-IP-Address-and-Port CRITICALITY reject TYPE Endpoint-IP-address-and-port PRESENCE mandatory}, + ... +} + + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + transactionID TransactionID OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, + ... +} + + +CriticalityDiagnostics-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxnoofErrors)) OF + SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-List-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- D + +DAPSRequestInfo ::= SEQUENCE { + dapsIndicator ENUMERATED {daps-HO-required, ...}, + iE-Extensions ProtocolExtensionContainer { {DAPSRequestInfo-ExtIEs} } OPTIONAL, + ... +} + +DAPSRequestInfo-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Data-Forwarding-Information-Request ::= SEQUENCE { + data-Forwarding-Request Data-Forwarding-Request, + qoS-Flows-Forwarded-On-Fwd-Tunnels QoS-Flow-Mapping-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Data-Forwarding-Information-Request-ExtIEs } } OPTIONAL, + ... +} + +Data-Forwarding-Information-Request-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Data-Forwarding-Information ::= SEQUENCE { + uL-Data-Forwarding UP-TNL-Information OPTIONAL, + dL-Data-Forwarding UP-TNL-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Data-Forwarding-Information-ExtIEs } } OPTIONAL, + ... +} + +Data-Forwarding-Information-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-DataForwardingtoNG-RANQoSFlowInformationList CRITICALITY ignore EXTENSION DataForwardingtoNG-RANQoSFlowInformationList PRESENCE optional}, + ... +} + +Data-Forwarding-Request ::= ENUMERATED { + uL, + dL, + both, + ... +} + +DataForwardingtoE-UTRANInformationList ::= SEQUENCE (SIZE(1.. maxnoofDataForwardingTunneltoE-UTRAN)) OF DataForwardingtoE-UTRANInformationListItem + +DataForwardingtoE-UTRANInformationListItem ::= SEQUENCE { + data-forwarding-tunnel-information UP-TNL-Information, + qoS-Flows-to-be-forwarded-List QoS-Flows-to-be-forwarded-List, + iE-Extensions ProtocolExtensionContainer { { DataForwardingtoE-UTRANInformationListItem-ExtIEs} } OPTIONAL, + ... +} + +DataForwardingtoE-UTRANInformationListItem-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Data-Usage-per-PDU-Session-Report ::= SEQUENCE { + secondaryRATType ENUMERATED {nR, e-UTRA, ...}, + pDU-session-Timed-Report-List SEQUENCE (SIZE(1..maxnooftimeperiods)) OF MRDC-Data-Usage-Report-Item, + iE-Extensions ProtocolExtensionContainer { { Data-Usage-per-PDU-Session-Report-ExtIEs} } OPTIONAL, +... +} + +Data-Usage-per-PDU-Session-Report-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Data-Usage-per-QoS-Flow-List ::= SEQUENCE (SIZE(1..maxnoofQoSFlows)) OF Data-Usage-per-QoS-Flow-Item + +Data-Usage-per-QoS-Flow-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + secondaryRATType ENUMERATED {nR, e-UTRA, ...}, + qoS-Flow-Timed-Report-List SEQUENCE (SIZE(1..maxnooftimeperiods)) OF MRDC-Data-Usage-Report-Item, + iE-Extensions ProtocolExtensionContainer { { Data-Usage-per-QoS-Flow-Item-ExtIEs} } OPTIONAL, +... +} + +Data-Usage-per-QoS-Flow-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Data-Usage-Report-List ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF Data-Usage-Report-Item + +Data-Usage-Report-Item ::= SEQUENCE { + dRB-ID DRB-ID, + rAT-Type RAT-Type, + dRB-Usage-Report-List DRB-Usage-Report-List, + iE-Extensions ProtocolExtensionContainer { { Data-Usage-Report-ItemExtIEs } } OPTIONAL, + ... +} + +Data-Usage-Report-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DefaultDRB ::= ENUMERATED { + true, + false, + ... +} + +DirectForwardingPathAvailability ::= ENUMERATED { + inter-system-direct-path-available, + ..., + intra-system-direct-path-available +} + +DiscardTimer ::= ENUMERATED {ms10, ms20, ms30, ms40, ms50, ms60, ms75, ms100, ms150, ms200, ms250, ms300, ms500, ms750, ms1500, infinity} + +DLDiscarding ::= SEQUENCE { + dLDiscardingCountVal PDCP-Count, + iE-Extensions ProtocolExtensionContainer { { DLDiscarding-ExtIEs } } OPTIONAL +} + +DLDiscarding-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DLUPTNLAddressToUpdateItem ::= SEQUENCE { + oldTNLAdress TransportLayerAddress, + newTNLAdress TransportLayerAddress, + iE-Extensions ProtocolExtensionContainer { { DLUPTNLAddressToUpdateItemExtIEs } } OPTIONAL, + ... +} + +DLUPTNLAddressToUpdateItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DL-TX-Stop ::= ENUMERATED { + stop, + resume, + ... +} + +DRB-Activity ::= ENUMERATED { + active, + not-active, + ... +} + +DRB-Activity-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF DRB-Activity-Item + +DRB-Activity-Item ::= SEQUENCE { + dRB-ID DRB-ID, + dRB-Activity DRB-Activity, + iE-Extensions ProtocolExtensionContainer { { DRB-Activity-ItemExtIEs } } OPTIONAL, + ... +} + +DRB-Activity-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Confirm-Modified-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Confirm-Modified-Item-EUTRAN + +DRB-Confirm-Modified-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + cell-Group-Information Cell-Group-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Confirm-Modified-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Confirm-Modified-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Confirm-Modified-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Confirm-Modified-Item-NG-RAN + +DRB-Confirm-Modified-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + cell-Group-Information Cell-Group-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Confirm-Modified-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Confirm-Modified-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Failed-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Failed-Item-EUTRAN + +DRB-Failed-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Failed-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Failed-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Failed-Mod-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Failed-Mod-Item-EUTRAN + +DRB-Failed-Mod-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Failed-Mod-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Failed-Mod-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Failed-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Failed-Item-NG-RAN + +DRB-Failed-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Failed-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Failed-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Failed-Mod-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Failed-Mod-Item-NG-RAN + +DRB-Failed-Mod-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Failed-Mod-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Failed-Mod-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Failed-To-Modify-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Failed-To-Modify-Item-EUTRAN + +DRB-Failed-To-Modify-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Failed-To-Modify-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Failed-To-Modify-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Failed-To-Modify-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Failed-To-Modify-Item-NG-RAN + +DRB-Failed-To-Modify-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Failed-To-Modify-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Failed-To-Modify-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-ID ::= INTEGER (1..32, ...) +DRB-Measurement-Results-Information-List ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Measurement-Results-Information-Item +DRB-Measurement-Results-Information-Item ::= SEQUENCE { + dRB-ID DRB-ID, + uL-D1-Result INTEGER (0..10000, ...) OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Measurement-Results-Information-Item-ExtIEs } } OPTIONAL, + ... +} + +DRB-Measurement-Results-Information-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Modified-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Modified-Item-EUTRAN + +DRB-Modified-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + s1-DL-UP-TNL-Information UP-TNL-Information OPTIONAL, + pDCP-SN-Status-Information PDCP-SN-Status-Information OPTIONAL, + uL-UP-Transport-Parameters UP-Parameters OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Modified-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Modified-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Modified-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Modified-Item-NG-RAN + +DRB-Modified-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + uL-UP-Transport-Parameters UP-Parameters OPTIONAL, + pDCP-SN-Status-Information PDCP-SN-Status-Information OPTIONAL, + flow-Setup-List QoS-Flow-List OPTIONAL, + flow-Failed-List QoS-Flow-Failed-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Modified-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Modified-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-EarlyForwardingCOUNTInfo CRITICALITY reject EXTENSION EarlyForwardingCOUNTInfo PRESENCE optional}| + {ID id-OldQoSFlowMap-ULendmarkerexpected CRITICALITY ignore EXTENSION QoS-Flow-List PRESENCE optional}, + ... +} + +DRB-Removed-Item ::= SEQUENCE { + dRB-ID DRB-ID, + dRB-Released-In-Session ENUMERATED {released-in-session, not-released-in-session, ...} OPTIONAL, + dRB-Accumulated-Session-Time OCTET STRING (SIZE(5)) OPTIONAL, + qoS-Flow-Removed-List SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF QoS-Flow-Removed-Item OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Removed-Item-ExtIEs } } OPTIONAL, + ... +} + +DRB-Removed-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Required-To-Modify-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Required-To-Modify-Item-EUTRAN + +DRB-Required-To-Modify-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + s1-DL-UP-TNL-Information UP-TNL-Information OPTIONAL, + gNB-CU-UP-CellGroupRelatedConfiguration GNB-CU-UP-CellGroupRelatedConfiguration OPTIONAL, + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Required-To-Modify-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Required-To-Modify-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Required-To-Modify-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Required-To-Modify-Item-NG-RAN + +DRB-Required-To-Modify-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + gNB-CU-UP-CellGroupRelatedConfiguration GNB-CU-UP-CellGroupRelatedConfiguration OPTIONAL, + flow-To-Remove QoS-Flow-List OPTIONAL, + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Required-To-Modify-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Required-To-Modify-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRB-Setup-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Setup-Item-EUTRAN + +DRB-Setup-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + s1-DL-UP-TNL-Information UP-TNL-Information, + data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + uL-UP-Transport-Parameters UP-Parameters, + s1-DL-UP-Unchanged ENUMERATED {true, ...} OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Setup-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Setup-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Setup-Mod-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Setup-Mod-Item-EUTRAN + +DRB-Setup-Mod-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + s1-DL-UP-TNL-Information UP-TNL-Information, + data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + uL-UP-Transport-Parameters UP-Parameters, + iE-Extensions ProtocolExtensionContainer { { DRB-Setup-Mod-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Setup-Mod-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Setup-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Setup-Item-NG-RAN + +DRB-Setup-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + dRB-data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + uL-UP-Transport-Parameters UP-Parameters, + flow-Setup-List QoS-Flow-List, + flow-Failed-List QoS-Flow-Failed-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Setup-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Setup-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Setup-Mod-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Setup-Mod-Item-NG-RAN + +DRB-Setup-Mod-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + dRB-data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + uL-UP-Transport-Parameters UP-Parameters, + flow-Setup-List QoS-Flow-List, + flow-Failed-List QoS-Flow-Failed-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Setup-Mod-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Setup-Mod-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Status-Item ::= SEQUENCE { + dRB-ID DRB-ID, + pDCP-DL-Count PDCP-Count OPTIONAL, + pDCP-UL-Count PDCP-Count OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Status-ItemExtIEs } } OPTIONAL, + ... +} + +DRB-Status-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Subject-To-Counter-Check-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRBs-Subject-To-Counter-Check-Item-EUTRAN + +DRBs-Subject-To-Counter-Check-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + pDCP-UL-Count PDCP-Count, + pDCP-DL-Count PDCP-Count, + iE-Extensions ProtocolExtensionContainer { { DRBs-Subject-To-Counter-Check-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRBs-Subject-To-Counter-Check-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Subject-To-Counter-Check-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRBs-Subject-To-Counter-Check-Item-NG-RAN + +DRBs-Subject-To-Counter-Check-Item-NG-RAN ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + dRB-ID DRB-ID, + pDCP-UL-Count PDCP-Count, + pDCP-DL-Count PDCP-Count, + iE-Extensions ProtocolExtensionContainer { { DRBs-Subject-To-Counter-Check-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRBs-Subject-To-Counter-Check-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Subject-To-Early-Forwarding-List ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRBs-Subject-To-Early-Forwarding-Item + +DRBs-Subject-To-Early-Forwarding-Item ::= SEQUENCE { + dRB-ID DRB-ID, + dLCountValue PDCP-Count, + iE-Extensions ProtocolExtensionContainer { { DRBs-Subject-To-Early-Forwarding-Item-ExtIEs } } OPTIONAL, + ... +} + +DRBs-Subject-To-Early-Forwarding-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-To-Modify-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Modify-Item-EUTRAN + +DRB-To-Modify-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + pDCP-Configuration PDCP-Configuration OPTIONAL, + eUTRAN-QoS EUTRAN-QoS OPTIONAL, + s1-UL-UP-TNL-Information UP-TNL-Information OPTIONAL, + data-Forwarding-Information Data-Forwarding-Information OPTIONAL, + pDCP-SN-Status-Request PDCP-SN-Status-Request OPTIONAL, + pDCP-SN-Status-Information PDCP-SN-Status-Information OPTIONAL, + dL-UP-Parameters UP-Parameters OPTIONAL, + cell-Group-To-Add Cell-Group-Information OPTIONAL, + cell-Group-To-Modify Cell-Group-Information OPTIONAL, + cell-Group-To-Remove Cell-Group-Information OPTIONAL, + dRB-Inactivity-Timer Inactivity-Timer OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Modify-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Modify-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-To-Modify-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Modify-Item-NG-RAN + +DRB-To-Modify-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + sDAP-Configuration SDAP-Configuration OPTIONAL, + pDCP-Configuration PDCP-Configuration OPTIONAL, + dRB-Data-Forwarding-Information Data-Forwarding-Information OPTIONAL, + pDCP-SN-Status-Request PDCP-SN-Status-Request OPTIONAL, + pdcp-SN-Status-Information PDCP-SN-Status-Information OPTIONAL, + dL-UP-Parameters UP-Parameters OPTIONAL, + cell-Group-To-Add Cell-Group-Information OPTIONAL, + cell-Group-To-Modify Cell-Group-Information OPTIONAL, + cell-Group-To-Remove Cell-Group-Information OPTIONAL, + flow-Mapping-Information QoS-Flow-QoS-Parameter-List OPTIONAL, + dRB-Inactivity-Timer Inactivity-Timer OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Modify-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Modify-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-OldQoSFlowMap-ULendmarkerexpected CRITICALITY reject EXTENSION QoS-Flow-List PRESENCE optional}| + {ID id-DRB-QoS CRITICALITY ignore EXTENSION QoSFlowLevelQoSParameters PRESENCE optional}| + {ID id-EarlyForwardingCOUNTReq CRITICALITY reject EXTENSION EarlyForwardingCOUNTReq PRESENCE optional}| + {ID id-EarlyForwardingCOUNTInfo CRITICALITY reject EXTENSION EarlyForwardingCOUNTInfo PRESENCE optional}| + {ID id-DAPSRequestInfo CRITICALITY ignore EXTENSION DAPSRequestInfo PRESENCE optional}| + {ID id-EarlyDataForwardingIndicator CRITICALITY ignore EXTENSION EarlyDataForwardingIndicator PRESENCE optional}, + ... +} + +DRB-To-Remove-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Remove-Item-EUTRAN + +DRB-To-Remove-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Remove-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Remove-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Required-To-Remove-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Required-To-Remove-Item-EUTRAN + +DRB-Required-To-Remove-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Required-To-Remove-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Required-To-Remove-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-To-Remove-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Remove-Item-NG-RAN + +DRB-To-Remove-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Remove-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Remove-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Required-To-Remove-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Required-To-Remove-Item-NG-RAN + +DRB-Required-To-Remove-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Required-To-Remove-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-Required-To-Remove-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-To-Setup-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Setup-Item-EUTRAN + +DRB-To-Setup-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + pDCP-Configuration PDCP-Configuration, + eUTRAN-QoS EUTRAN-QoS, + s1-UL-UP-TNL-Information UP-TNL-Information, + data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + cell-Group-Information Cell-Group-Information, + dL-UP-Parameters UP-Parameters OPTIONAL, + dRB-Inactivity-Timer Inactivity-Timer OPTIONAL, + existing-Allocated-S1-DL-UP-TNL-Info UP-TNL-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Setup-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Setup-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-To-Setup-Mod-List-EUTRAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Setup-Mod-Item-EUTRAN + +DRB-To-Setup-Mod-Item-EUTRAN ::= SEQUENCE { + dRB-ID DRB-ID, + pDCP-Configuration PDCP-Configuration, + eUTRAN-QoS EUTRAN-QoS, + s1-UL-UP-TNL-Information UP-TNL-Information, + data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + cell-Group-Information Cell-Group-Information, + dL-UP-Parameters UP-Parameters OPTIONAL, + dRB-Inactivity-Timer Inactivity-Timer OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Setup-Mod-Item-EUTRAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Setup-Mod-Item-EUTRAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-To-Setup-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Setup-Item-NG-RAN + +DRB-To-Setup-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + sDAP-Configuration SDAP-Configuration, + pDCP-Configuration PDCP-Configuration, + cell-Group-Information Cell-Group-Information, + qos-flow-Information-To-Be-Setup QoS-Flow-QoS-Parameter-List, + dRB-Data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + dRB-Inactivity-Timer Inactivity-Timer OPTIONAL, + pDCP-SN-Status-Information PDCP-SN-Status-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Setup-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Setup-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-DRB-QoS CRITICALITY ignore EXTENSION QoSFlowLevelQoSParameters PRESENCE optional}| + {ID id-DAPSRequestInfo CRITICALITY ignore EXTENSION DAPSRequestInfo PRESENCE optional}| + {ID id-ignoreMappingRuleIndication CRITICALITY reject EXTENSION IgnoreMappingRuleIndication PRESENCE optional}| + {ID id-QoSFlowsDRBRemapping CRITICALITY reject EXTENSION QoS-Flows-DRB-Remapping PRESENCE optional}, + ... +} + +DRB-To-Setup-Mod-List-NG-RAN ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-To-Setup-Mod-Item-NG-RAN + +DRB-To-Setup-Mod-Item-NG-RAN ::= SEQUENCE { + dRB-ID DRB-ID, + sDAP-Configuration SDAP-Configuration, + pDCP-Configuration PDCP-Configuration, + cell-Group-Information Cell-Group-Information, + flow-Mapping-Information QoS-Flow-QoS-Parameter-List, + dRB-Data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + dRB-Inactivity-Timer Inactivity-Timer OPTIONAL, + pDCP-SN-Status-Information PDCP-SN-Status-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-To-Setup-Mod-Item-NG-RAN-ExtIEs } } OPTIONAL, + ... +} + +DRB-To-Setup-Mod-Item-NG-RAN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-DRB-QoS CRITICALITY ignore EXTENSION QoSFlowLevelQoSParameters PRESENCE optional}| + {ID id-ignoreMappingRuleIndication CRITICALITY reject EXTENSION IgnoreMappingRuleIndication PRESENCE optional}| + {ID id-DAPSRequestInfo CRITICALITY ignore EXTENSION DAPSRequestInfo PRESENCE optional}, + ... +} + +DRB-Usage-Report-List ::= SEQUENCE (SIZE(1..maxnooftimeperiods)) OF DRB-Usage-Report-Item + +DRB-Usage-Report-Item ::= SEQUENCE { + startTimeStamp OCTET STRING (SIZE(4)), + endTimeStamp OCTET STRING (SIZE(4)), + usageCountUL INTEGER (0..18446744073709551615), + usageCountDL INTEGER (0..18446744073709551615), + iE-Extensions ProtocolExtensionContainer { { DRB-Usage-Report-Item-ExtIEs} } OPTIONAL, + ... +} + +DRB-Usage-Report-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Duplication-Activation ::= ENUMERATED { + active, + inactive, + ... +} + + +Dynamic5QIDescriptor ::= SEQUENCE { + qoSPriorityLevel QoSPriorityLevel, + packetDelayBudget PacketDelayBudget, + packetErrorRate PacketErrorRate, + fiveQI INTEGER (0..255, ...) OPTIONAL, + delayCritical ENUMERATED {delay-critical, non-delay-critical} OPTIONAL, + averagingWindow AveragingWindow OPTIONAL, + maxDataBurstVolume MaxDataBurstVolume OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Dynamic5QIDescriptor-ExtIEs } } OPTIONAL +} + +Dynamic5QIDescriptor-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-ExtendedPacketDelayBudget CRITICALITY ignore EXTENSION ExtendedPacketDelayBudget PRESENCE optional }| + { ID id-CNPacketDelayBudgetDownlink CRITICALITY ignore EXTENSION ExtendedPacketDelayBudget PRESENCE optional }| + { ID id-CNPacketDelayBudgetUplink CRITICALITY ignore EXTENSION ExtendedPacketDelayBudget PRESENCE optional }, + ... +} + +DataDiscardRequired ::= ENUMERATED { + required, + ... +} + +-- E + +EarlyDataForwardingIndicator ::= ENUMERATED {stop, ...} + +EarlyForwardingCOUNTInfo ::= CHOICE { + firstDLCount FirstDLCount, + dLDiscardingCount DLDiscarding, + choice-Extension ProtocolIE-SingleContainer { { EarlyForwardingCOUNTInfo-ExtIEs} } +} + +EarlyForwardingCOUNTInfo-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +EarlyForwardingCOUNTReq ::= ENUMERATED { first-dl-count, dl-discarding, ...} + +EHC-Common-Parameters ::= SEQUENCE { + ehc-CID-Length ENUMERATED { bits7, bits15, ...}, + iE-Extensions ProtocolExtensionContainer { { EHC-Common-Parameters-ExtIEs } } OPTIONAL +} + +EHC-Common-Parameters-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EHC-Downlink-Parameters ::= SEQUENCE { + drb-ContinueEHC-DL ENUMERATED { true, ...}, + iE-Extensions ProtocolExtensionContainer { { EHC-Downlink-Parameters-ExtIEs } } OPTIONAL +} + +EHC-Downlink-Parameters-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { +{ID id-MaxCIDEHCDL CRITICALITY ignore EXTENSION MaxCIDEHCDL PRESENCE optional }, + ... +} + +EHC-Uplink-Parameters ::= SEQUENCE { + drb-ContinueEHC-UL ENUMERATED { true, ...}, + iE-Extensions ProtocolExtensionContainer { { EHC-Uplink-Parameters-ExtIEs } } OPTIONAL +} + +EHC-Uplink-Parameters-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EHC-Parameters ::= SEQUENCE { + ehc-Common EHC-Common-Parameters, + ehc-Downlink EHC-Downlink-Parameters OPTIONAL, + ehc-Uplink EHC-Uplink-Parameters OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { EHC-Parameters-ExtIEs } } OPTIONAL +} + +EHC-Parameters-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EncryptionKey ::= OCTET STRING + +Endpoint-IP-address-and-port::= SEQUENCE { + endpoint-IP-Address TransportLayerAddress, + portNumber PortNumber, + iE-Extensions ProtocolExtensionContainer { { Endpoint-IP-address-and-port-ExtIEs} } OPTIONAL +} + +Endpoint-IP-address-and-port-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRANAllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {EUTRANAllocationAndRetentionPriority-ExtIEs} } OPTIONAL, + ... +} + +ExtendedPacketDelayBudget ::= INTEGER (1..65535, ...) + +EUTRANAllocationAndRetentionPriority-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +EUTRAN-QoS-Support-List ::= SEQUENCE (SIZE(1.. maxnoofEUTRANQOSParameters)) OF EUTRAN-QoS-Support-Item + +EUTRAN-QoS-Support-Item ::= SEQUENCE { + eUTRAN-QoS EUTRAN-QoS, + iE-Extensions ProtocolExtensionContainer { { EUTRAN-QoS-Support-Item-ExtIEs } } OPTIONAL +} + +EUTRAN-QoS-Support-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRAN-QoS ::= SEQUENCE { + qCI QCI, + eUTRANallocationAndRetentionPriority EUTRANAllocationAndRetentionPriority, + gbrQosInformation GBR-QosInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { EUTRAN-QoS-ExtIEs } } OPTIONAL, + ... +} + +EUTRAN-QoS-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ExtendedSliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofExtSliceItems)) OF Slice-Support-Item + +-- F + +FirstDLCount ::= SEQUENCE { + firstDLCountVal PDCP-Count, + iE-Extensions ProtocolExtensionContainer { { FirstDLCount-ExtIEs } } OPTIONAL +} + +FirstDLCount-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- G + +GNB-CU-CP-Name ::= PrintableString(SIZE(1..150,...)) + +Extended-GNB-CU-CP-Name ::= SEQUENCE { + gNB-CU-CP-NameVisibleString GNB-CU-CP-NameVisibleString OPTIONAL, + gNB-CU-CP-NameUTF8String GNB-CU-CP-NameUTF8String OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Extended-GNB-CU-CP-Name-ExtIEs } } OPTIONAL, + ... +} + +Extended-GNB-CU-CP-Name-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-CP-NameVisibleString ::= VisibleString(SIZE(1..150,...)) + +GNB-CU-CP-NameUTF8String ::= UTF8String(SIZE(1..150,...)) + + +GNB-CU-CP-UE-E1AP-ID ::= INTEGER (0..4294967295) + +GNB-CU-UP-Capacity ::= INTEGER (0..255) + +GNB-CU-UP-CellGroupRelatedConfiguration ::= SEQUENCE (SIZE(1.. maxnoofUPParameters)) OF GNB-CU-UP-CellGroupRelatedConfiguration-Item + +GNB-CU-UP-CellGroupRelatedConfiguration-Item ::= SEQUENCE { + cell-Group-ID Cell-Group-ID, + uP-TNL-Information UP-TNL-Information, + uL-Configuration UL-Configuration OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {GNB-CU-UP-CellGroupRelatedConfiguration-Item-ExtIEs } } OPTIONAL +} + +GNB-CU-UP-CellGroupRelatedConfiguration-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-UP-ID ::= INTEGER (0..68719476735) + +GNB-CU-UP-Name ::= PrintableString(SIZE(1..150,...)) + +Extended-GNB-CU-UP-Name ::= SEQUENCE { + gNB-CU-UP-NameVisibleString GNB-CU-UP-NameVisibleString OPTIONAL, + gNB-CU-UP-NameUTF8String GNB-CU-UP-NameUTF8String OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Extended-GNB-CU-UP-Name-ExtIEs } } OPTIONAL, + ... +} + +Extended-GNB-CU-UP-Name-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-UP-NameVisibleString ::= VisibleString(SIZE(1..150,...)) + +GNB-CU-UP-NameUTF8String ::= UTF8String(SIZE(1..150,...)) + +GNB-CU-UP-UE-E1AP-ID ::= INTEGER (0..4294967295) + +GNB-CU-CP-TNLA-Setup-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TNL-Information, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-CP-TNLA-Setup-Item-ExtIEs} } OPTIONAL, + ... +} + +GNB-CU-CP-TNLA-Setup-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-CP-TNLA-Failed-To-Setup-Item ::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TNL-Information, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-CP-TNLA-Failed-To-Setup-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-CP-TNLA-Failed-To-Setup-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-CP-TNLA-To-Add-Item ::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TNL-Information, + tNLAssociationUsage TNLAssociationUsage, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-CP-TNLA-To-Add-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-CP-TNLA-To-Add-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-CP-TNLA-To-Remove-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TNL-Information, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-CP-TNLA-To-Remove-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-CP-TNLA-To-Remove-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-TNLAssociationTransportLayerAddressgNBCUUP CRITICALITY reject EXTENSION CP-TNL-Information PRESENCE optional}, + ... +} + +GNB-CU-CP-TNLA-To-Update-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TNL-Information, + tNLAssociationUsage TNLAssociationUsage OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-CP-TNLA-To-Update-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-CP-TNLA-To-Update-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-UP-TNLA-To-Remove-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TNL-Information, + tNLAssociationTransportLayerAddressgNBCUCP CP-TNL-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-UP-TNLA-To-Remove-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-UP-TNLA-To-Remove-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GBR-QosInformation ::= SEQUENCE { + e-RAB-MaximumBitrateDL BitRate, + e-RAB-MaximumBitrateUL BitRate, + e-RAB-GuaranteedBitrateDL BitRate, + e-RAB-GuaranteedBitrateUL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GBR-QoSFlowInformation::= SEQUENCE { + maxFlowBitRateDownlink BitRate, + maxFlowBitRateUplink BitRate, + guaranteedFlowBitRateDownlink BitRate, + guaranteedFlowBitRateUplink BitRate, + maxPacketLossRateDownlink MaxPacketLossRate OPTIONAL, + maxPacketLossRateUplink MaxPacketLossRate OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GBR-QosFlowInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosFlowInformation-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-AlternativeQoSParaSetList CRITICALITY ignore EXTENSION AlternativeQoSParaSetList PRESENCE optional}, + ... +} + +GTP-TEID ::= OCTET STRING (SIZE (4)) + +GTPTLAs ::= SEQUENCE (SIZE(1.. maxnoofGTPTLAs)) OF GTPTLA-Item + +GTPTLA-Item ::= SEQUENCE { + gTPTransportLayerAddresses TransportLayerAddress, + iE-Extensions ProtocolExtensionContainer { { GTPTLA-Item-ExtIEs } } OPTIONAL, + ... +} + +GTPTLA-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GTPTunnel ::= SEQUENCE { + transportLayerAddress TransportLayerAddress, + gTP-TEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { { GTPTunnel-ExtIEs} } OPTIONAL, + ... +} + +GTPTunnel-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-UP-OverloadInformation ::= ENUMERATED {overloaded, not-overloaded} + +GNB-DU-ID ::= INTEGER (0..68719476735) + + +-- H + +HFN ::= INTEGER (0..4294967295) + +HW-CapacityIndicator ::= SEQUENCE { + offeredThroughput INTEGER (1..16777216, ...), + availableThroughput INTEGER (0..100, ...), + iE-Extensions ProtocolExtensionContainer { { HW-CapacityIndicator-ExtIEs } }, + ... +} + +HW-CapacityIndicator-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- I + +IgnoreMappingRuleIndication ::= ENUMERATED { + true, + ... +} + +IntegrityProtectionIndication ::= ENUMERATED { + required, + preferred, + not-needed, + ... +} + +IntegrityProtectionAlgorithm ::= ENUMERATED { + nIA0, + i-128-NIA1, + i-128-NIA2, + i-128-NIA3, + ... +} + +IntegrityProtectionKey ::= OCTET STRING + +IntegrityProtectionResult ::= ENUMERATED { + performed, + not-performed, + ... +} + +Inactivity-Timer ::= INTEGER (1..7200, ...) + +InterfacesToTrace ::= BIT STRING (SIZE(8)) + +ImmediateMDT ::= SEQUENCE { +measurementsToActivate MeasurementsToActivate, + measurementFour M4Configuration OPTIONAL, + measurementSix M6Configuration OPTIONAL, + measurementSeven M7Configuration OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { ImmediateMDT-ExtIEs} } OPTIONAL, + ... +} +ImmediateMDT-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- J + +-- K + +-- L + +Links-to-log ::= ENUMERATED { + uplink, + downlink, + both-uplink-and-downlink, + ... +} + +-- M + +MaxDataBurstVolume ::= INTEGER (0..4095, ..., 4096.. 2000000) + +MaximumIPdatarate ::= SEQUENCE { + maxIPrate MaxIPrate, + iE-Extensions ProtocolExtensionContainer { {MaximumIPdatarate-ExtIEs} } OPTIONAL, + ... +} + +MaximumIPdatarate-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +MaxIPrate ::= ENUMERATED { + bitrate64kbs, + max-UErate, + ... +} + +MaxPacketLossRate ::= INTEGER (0..1000, ...) + +MaxCIDEHCDL ::= INTEGER (1..32767, ...) + +MRDC-Data-Usage-Report-Item ::= SEQUENCE { + startTimeStamp OCTET STRING (SIZE(4)), + endTimeStamp OCTET STRING (SIZE(4)), + usageCountUL INTEGER (0..18446744073709551615), + usageCountDL INTEGER (0..18446744073709551615), + iE-Extensions ProtocolExtensionContainer { { MRDC-Data-Usage-Report-Item-ExtIEs} } OPTIONAL, +... +} + +MRDC-Data-Usage-Report-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +MRDC-Usage-Information ::= SEQUENCE { + data-Usage-per-PDU-Session-Report Data-Usage-per-PDU-Session-Report OPTIONAL, + data-Usage-per-QoS-Flow-List Data-Usage-per-QoS-Flow-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MRDC-Usage-Information-ExtIEs} } OPTIONAL, +... +} + +MRDC-Usage-Information-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +M4Configuration ::= SEQUENCE { + m4period M4period, + m4-links-to-log Links-to-log, + iE-Extensions ProtocolExtensionContainer { { M4Configuration-ExtIEs} } OPTIONAL, + ... +} + +M4Configuration-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +M4period ::= ENUMERATED {ms1024, ms2048, ms5120, ms10240, min1, ... } + +M6Configuration ::= SEQUENCE { + m6report-Interval M6report-Interval, + m6-links-to-log Links-to-log, + iE-Extensions ProtocolExtensionContainer { { M6Configuration-ExtIEs} } OPTIONAL, + ... +} + +M6Configuration-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +M6report-Interval ::= ENUMERATED { ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, ms20480 ,ms40960, min1, min6, min12, min30, ... } + +M7Configuration ::= SEQUENCE { + m7period M7period, + m7-links-to-log Links-to-log, + iE-Extensions ProtocolExtensionContainer { { M7Configuration-ExtIEs} } OPTIONAL, + ... +} + +M7Configuration-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +M7period ::= INTEGER(1..60, ...) + +MDT-Activation ::= ENUMERATED { + immediate-MDT-only, + immediate-MDT-and-Trace, + ... +} + +MDT-Configuration ::= SEQUENCE { + mdt-Activation MDT-Activation, + mDTMode MDTMode, + iE-Extensions ProtocolExtensionContainer { { MDT-Configuration-ExtIEs} } OPTIONAL, + ... +} +MDT-Configuration-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +MDTMode ::= CHOICE { + immediateMDT ImmediateMDT, + choice-extension ProtocolIE-SingleContainer {{MDTMode-ExtIEs}} +} + +MDTMode-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +MeasurementsToActivate ::= BIT STRING (SIZE (8)) + +MDTPLMNList ::= SEQUENCE (SIZE(1..maxnoofMDTPLMNs)) OF PLMN-Identity + +-- N + +NetworkInstance ::= INTEGER (1..256, ...) + +New-UL-TNL-Information-Required::= ENUMERATED { + required, + ... +} +NGRANAllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {NGRANAllocationAndRetentionPriority-ExtIEs} } OPTIONAL +} + +NGRANAllocationAndRetentionPriority-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NG-RAN-QoS-Support-List ::= SEQUENCE (SIZE(1.. maxnoofNGRANQOSParameters)) OF NG-RAN-QoS-Support-Item + +NG-RAN-QoS-Support-Item ::= SEQUENCE { + non-Dynamic5QIDescriptor Non-Dynamic5QIDescriptor, + iE-Extensions ProtocolExtensionContainer { { NG-RAN-QoS-Support-Item-ExtIEs } } OPTIONAL +} + +NG-RAN-QoS-Support-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NID ::= BIT STRING (SIZE (44)) + +Non-Dynamic5QIDescriptor ::= SEQUENCE { + fiveQI INTEGER (0..255, ...), + qoSPriorityLevel QoSPriorityLevel OPTIONAL, + averagingWindow AveragingWindow OPTIONAL, + maxDataBurstVolume MaxDataBurstVolume OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Non-Dynamic5QIDescriptor-ExtIEs } } OPTIONAL +} + +Non-Dynamic5QIDescriptor-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-CNPacketDelayBudgetDownlink CRITICALITY ignore EXTENSION ExtendedPacketDelayBudget PRESENCE optional }| + { ID id-CNPacketDelayBudgetUplink CRITICALITY ignore EXTENSION ExtendedPacketDelayBudget PRESENCE optional }, + ... +} + +NPNSupportInfo ::= CHOICE { + sNPN NPNSupportInfo-SNPN, + choice-extension ProtocolIE-SingleContainer {{NPNSupportInfo-ExtIEs}} +} + +NPNSupportInfo-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +NPNSupportInfo-SNPN ::= SEQUENCE { + nID NID, + iE-Extensions ProtocolExtensionContainer { { NPNSupportInfo-SNPN-ExtIEs } } OPTIONAL +} + + +NPNSupportInfo-SNPN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NPNContextInfo ::= CHOICE { + sNPN NPNContextInfo-SNPN, + choice-extension ProtocolIE-SingleContainer {{NPNContextInfo-ExtIEs}} +} + +NPNContextInfo-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +NPNContextInfo-SNPN ::= SEQUENCE { + nID NID, + iE-Extensions ProtocolExtensionContainer { {NPNContextInfo-SNPN-ExtIEs } } OPTIONAL +} + +NPNContextInfo-SNPN-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NR-Cell-Identity ::= BIT STRING (SIZE(36)) + +NR-CGI ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + nR-Cell-Identity NR-Cell-Identity, + iE-Extensions ProtocolExtensionContainer { { NR-CGI-ExtIEs } } OPTIONAL +} + +NR-CGI-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NR-CGI-Support-List ::= SEQUENCE (SIZE(1.. maxnoofNRCGI)) OF NR-CGI-Support-Item + +NR-CGI-Support-Item ::= SEQUENCE { + nR-CGI NR-CGI, + iE-Extensions ProtocolExtensionContainer { { NR-CGI-Support-Item-ExtIEs } } OPTIONAL +} + +NR-CGI-Support-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Extended-NR-CGI-Support-List ::= SEQUENCE (SIZE(1.. maxnoofExtNRCGI)) OF Extended-NR-CGI-Support-Item + +Extended-NR-CGI-Support-Item ::= SEQUENCE { + nR-CGI NR-CGI, + iE-Extensions ProtocolExtensionContainer { { Extended-NR-CGI-Support-Item-ExtIEs } } OPTIONAL +} + +Extended-NR-CGI-Support-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- O + +OutOfOrderDelivery ::= ENUMERATED { + true, + ... +} + + +-- P + +PacketDelayBudget ::= INTEGER (0..1023, ...) + +PacketErrorRate ::= SEQUENCE { + pER-Scalar PER-Scalar, + pER-Exponent PER-Exponent, + iE-Extensions ProtocolExtensionContainer { {PacketErrorRate-ExtIEs} } OPTIONAL, + ... +} + +PacketErrorRate-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PER-Scalar ::= INTEGER (0..9, ...) +PER-Exponent ::= INTEGER (0..9, ...) + +PDCP-Configuration ::= SEQUENCE { + + pDCP-SN-Size-UL PDCP-SN-Size, + pDCP-SN-Size-DL PDCP-SN-Size, + rLC-Mode RLC-Mode, + rOHC-Parameters ROHC-Parameters OPTIONAL, + t-ReorderingTimer T-ReorderingTimer OPTIONAL, + discardTimer DiscardTimer OPTIONAL, + uLDataSplitThreshold ULDataSplitThreshold OPTIONAL, + pDCP-Duplication PDCP-Duplication OPTIONAL, + pDCP-Reestablishment PDCP-Reestablishment OPTIONAL, + pDCP-DataRecovery PDCP-DataRecovery OPTIONAL, + duplication-Activation Duplication-Activation OPTIONAL, + outOfOrderDelivery OutOfOrderDelivery OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDCP-Configuration-ExtIEs } } OPTIONAL, + ... +} + +PDCP-Configuration-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-PDCP-StatusReportIndication CRITICALITY ignore EXTENSION PDCP-StatusReportIndication PRESENCE optional}| + { ID id-AdditionalPDCPduplicationInformation CRITICALITY ignore EXTENSION AdditionalPDCPduplicationInformation PRESENCE optional }| + { ID id-EHC-Parameters CRITICALITY ignore EXTENSION EHC-Parameters PRESENCE optional}, + ... +} + +PDCP-Count ::= SEQUENCE { + pDCP-SN PDCP-SN, + hFN HFN, + iE-Extensions ProtocolExtensionContainer { { PDCP-Count-ExtIEs } } OPTIONAL, + ... +} + +PDCP-Count-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDCP-SN-Status-Request ::= ENUMERATED { + requested, + ... +} + +PDCP-DataRecovery ::= ENUMERATED { + true, + ... +} + +PDCP-Duplication ::= ENUMERATED { + true, + ... +} + +PDCP-Reestablishment ::= ENUMERATED { + true, + ... +} + +PDU-Session-Resource-Data-Usage-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Data-Usage-Item + +PDU-Session-Resource-Data-Usage-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + mRDC-Usage-Information MRDC-Usage-Information, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Data-Usage-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Data-Usage-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDCP-SN ::= INTEGER (0..262143) + +PDCP-SN-Size ::= ENUMERATED { + s-12, + s-18, + ... +} + +PDCP-SN-Status-Information ::= SEQUENCE { + pdcpStatusTransfer-UL DRBBStatusTransfer, + pdcpStatusTransfer-DL PDCP-Count, + iE-Extension ProtocolExtensionContainer { { PDCP-SN-Status-Information-ExtIEs} } OPTIONAL, + ... +} + +PDCP-StatusReportIndication ::= ENUMERATED { + downlink, + uplink, + both, + ... +} + +PDCP-SN-Status-Information-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBBStatusTransfer ::= SEQUENCE { + receiveStatusofPDCPSDU BIT STRING (SIZE(1..131072)) OPTIONAL, + countValue PDCP-Count, + iE-Extension ProtocolExtensionContainer { {DRBBStatusTransfer-ExtIEs} } OPTIONAL, + ... +} + +DRBBStatusTransfer-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDU-Session-ID ::= INTEGER (0..255) + +PDU-Session-Resource-Activity ::= ENUMERATED { + active, + not-active, + ... +} + +PDU-Session-Resource-Activity-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Activity-Item + +PDU-Session-Resource-Activity-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + pDU-Session-Resource-Activity PDU-Session-Resource-Activity, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Activity-ItemExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Activity-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +PDU-Session-Resource-Confirm-Modified-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Confirm-Modified-Item + +PDU-Session-Resource-Confirm-Modified-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + dRB-Confirm-Modified-List-NG-RAN DRB-Confirm-Modified-List-NG-RAN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Confirm-Modified-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Confirm-Modified-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDU-Session-Resource-Failed-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Failed-Item + +PDU-Session-Resource-Failed-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Failed-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Failed-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDU-Session-Resource-Failed-Mod-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Failed-Mod-Item + +PDU-Session-Resource-Failed-Mod-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Failed-Mod-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Failed-Mod-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDU-Session-Resource-Failed-To-Modify-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Failed-To-Modify-Item + +PDU-Session-Resource-Failed-To-Modify-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Failed-To-Modify-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Failed-To-Modify-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDU-Session-Resource-Modified-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Modified-Item + +PDU-Session-Resource-Modified-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + nG-DL-UP-TNL-Information UP-TNL-Information OPTIONAL, + securityResult SecurityResult OPTIONAL, + pDU-Session-Data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + dRB-Setup-List-NG-RAN DRB-Setup-List-NG-RAN OPTIONAL, + dRB-Failed-List-NG-RAN DRB-Failed-List-NG-RAN OPTIONAL, + dRB-Modified-List-NG-RAN DRB-Modified-List-NG-RAN OPTIONAL, + dRB-Failed-To-Modify-List-NG-RAN DRB-Failed-To-Modify-List-NG-RAN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Modified-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Modified-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-redundant-nG-DL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }, + ... +} + +PDU-Session-Resource-Required-To-Modify-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Required-To-Modify-Item + +PDU-Session-Resource-Required-To-Modify-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + nG-DL-UP-TNL-Information UP-TNL-Information OPTIONAL, + dRB-Required-To-Modify-List-NG-RAN DRB-Required-To-Modify-List-NG-RAN OPTIONAL, + dRB-Required-To-Remove-List-NG-RAN DRB-Required-To-Remove-List-NG-RAN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Required-To-Modify-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Required-To-Modify-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-redundant-nG-DL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }, + ... +} + +PDU-Session-Resource-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Setup-Item + +PDU-Session-Resource-Setup-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + securityResult SecurityResult OPTIONAL, + nG-DL-UP-TNL-Information UP-TNL-Information, + pDU-Session-Data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + nG-DL-UP-Unchanged ENUMERATED {true, ...} OPTIONAL, + dRB-Setup-List-NG-RAN DRB-Setup-List-NG-RAN, + dRB-Failed-List-NG-RAN DRB-Failed-List-NG-RAN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Setup-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Setup-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-redundant-nG-DL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }| + { ID id-RedundantPDUSessionInformation-used CRITICALITY ignore EXTENSION RedundantPDUSessionInformation PRESENCE optional }, + ... +} + +PDU-Session-Resource-Setup-Mod-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-Setup-Mod-Item + +PDU-Session-Resource-Setup-Mod-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + securityResult SecurityResult OPTIONAL, + nG-DL-UP-TNL-Information UP-TNL-Information, + pDU-Session-Data-Forwarding-Information-Response Data-Forwarding-Information OPTIONAL, + dRB-Setup-Mod-List-NG-RAN DRB-Setup-Mod-List-NG-RAN, + dRB-Failed-Mod-List-NG-RAN DRB-Failed-Mod-List-NG-RAN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-Setup-Mod-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-Setup-Mod-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-redundant-nG-DL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }, + ... +} + +PDU-Session-Resource-To-Modify-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-To-Modify-Item + +PDU-Session-Resource-To-Modify-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + securityIndication SecurityIndication OPTIONAL, + pDU-Session-Resource-DL-AMBR BitRate OPTIONAL, + nG-UL-UP-TNL-Information UP-TNL-Information OPTIONAL, + pDU-Session-Data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + pDU-Session-Data-Forwarding-Information Data-Forwarding-Information OPTIONAL, + pDU-Session-Inactivity-Timer Inactivity-Timer OPTIONAL, + networkInstance NetworkInstance OPTIONAL, + dRB-To-Setup-List-NG-RAN DRB-To-Setup-List-NG-RAN OPTIONAL, + dRB-To-Modify-List-NG-RAN DRB-To-Modify-List-NG-RAN OPTIONAL, + dRB-To-Remove-List-NG-RAN DRB-To-Remove-List-NG-RAN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-To-Modify-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-To-Modify-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-SNSSAI CRITICALITY reject EXTENSION SNSSAI PRESENCE optional}| + { ID id-CommonNetworkInstance CRITICALITY ignore EXTENSION CommonNetworkInstance PRESENCE optional }| + {ID id-redundant-nG-UL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }| + {ID id-RedundantCommonNetworkInstance CRITICALITY ignore EXTENSION CommonNetworkInstance PRESENCE optional }| + {ID id-DataForwardingtoE-UTRANInformationList CRITICALITY ignore EXTENSION DataForwardingtoE-UTRANInformationList PRESENCE optional }, + ... +} + +PDU-Session-Resource-To-Remove-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-To-Remove-Item + +PDU-Session-Resource-To-Remove-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-To-Remove-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-To-Remove-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-Cause CRITICALITY ignore EXTENSION Cause PRESENCE optional}, + ... +} + +PDU-Session-Resource-To-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-To-Setup-Item + +PDU-Session-Resource-To-Setup-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + pDU-Session-Type PDU-Session-Type, + sNSSAI SNSSAI, + securityIndication SecurityIndication, + pDU-Session-Resource-DL-AMBR BitRate OPTIONAL, + nG-UL-UP-TNL-Information UP-TNL-Information, + pDU-Session-Data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + pDU-Session-Inactivity-Timer Inactivity-Timer OPTIONAL, + existing-Allocated-NG-DL-UP-TNL-Info UP-TNL-Information OPTIONAL, + networkInstance NetworkInstance OPTIONAL, + dRB-To-Setup-List-NG-RAN DRB-To-Setup-List-NG-RAN, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-To-Setup-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-To-Setup-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-CommonNetworkInstance CRITICALITY ignore EXTENSION CommonNetworkInstance PRESENCE optional }| + { ID id-redundant-nG-UL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }| + { ID id-RedundantCommonNetworkInstance CRITICALITY ignore EXTENSION CommonNetworkInstance PRESENCE optional }| + { ID id-RedundantPDUSessionInformation CRITICALITY ignore EXTENSION RedundantPDUSessionInformation PRESENCE optional }, + ... +} + +PDU-Session-Resource-To-Setup-Mod-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-Resource-To-Setup-Mod-Item + +PDU-Session-Resource-To-Setup-Mod-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + pDU-Session-Type PDU-Session-Type, + sNSSAI SNSSAI, + securityIndication SecurityIndication, + pDU-Session-Resource-AMBR BitRate OPTIONAL, + nG-UL-UP-TNL-Information UP-TNL-Information, + pDU-Session-Data-Forwarding-Information-Request Data-Forwarding-Information-Request OPTIONAL, + pDU-Session-Inactivity-Timer Inactivity-Timer OPTIONAL, + dRB-To-Setup-Mod-List-NG-RAN DRB-To-Setup-Mod-List-NG-RAN, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-Resource-To-Setup-Mod-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-Resource-To-Setup-Mod-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-NetworkInstance CRITICALITY ignore EXTENSION NetworkInstance PRESENCE optional}| + {ID id-CommonNetworkInstance CRITICALITY ignore EXTENSION CommonNetworkInstance PRESENCE optional}| + {ID id-redundant-nG-UL-UP-TNL-Information CRITICALITY ignore EXTENSION UP-TNL-Information PRESENCE optional }| + {ID id-RedundantCommonNetworkInstance CRITICALITY ignore EXTENSION CommonNetworkInstance PRESENCE optional }, + ... +} + +PDU-Session-To-Notify-List ::= SEQUENCE (SIZE(1.. maxnoofPDUSessionResource)) OF PDU-Session-To-Notify-Item + +PDU-Session-To-Notify-Item ::= SEQUENCE { + pDU-Session-ID PDU-Session-ID, + qoS-Flow-List QoS-Flow-List, + iE-Extensions ProtocolExtensionContainer { { PDU-Session-To-Notify-Item-ExtIEs } } OPTIONAL, + ... +} + +PDU-Session-To-Notify-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PDU-Session-Type ::= ENUMERATED { + ipv4, + ipv6, + ipv4v6, + ethernet, + unstructured, + ... +} + +PLMN-Identity ::= OCTET STRING (SIZE(3)) + +PortNumber ::= BIT STRING (SIZE(16)) + +PPI ::= INTEGER (0..7, ...) + +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable +} + +PrivacyIndicator ::= ENUMERATED { + immediate-MDT, + logged-MDT, + ... +} + +-- Q + +QCI ::= INTEGER (0..255) + +QoS-Characteristics ::= CHOICE { + non-Dynamic-5QI Non-Dynamic5QIDescriptor, + dynamic-5QI Dynamic5QIDescriptor, + choice-extension ProtocolIE-SingleContainer {{QoS-Characteristics-ExtIEs}} +} + +QoS-Characteristics-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +QoS-Flow-Identifier ::= INTEGER (0..63) + +QoS-Flow-List ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF QoS-Flow-Item + +QoS-Flow-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + iE-Extensions ProtocolExtensionContainer { { QoS-Flow-Item-ExtIEs } } OPTIONAL, + ... +} + +QoS-Flow-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-QoSFlowMappingIndication CRITICALITY ignore EXTENSION QoS-Flow-Mapping-Indication PRESENCE optional}, + ... +} + +QoS-Flow-Failed-List ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF QoS-Flow-Failed-Item + +QoS-Flow-Failed-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { QoS-Flow-Failed-Item-ExtIEs } } OPTIONAL, + ... +} + +QoS-Flow-Failed-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoS-Flow-Mapping-List ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF QoS-Flow-Mapping-Item + +QoS-Flow-Mapping-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + qoSFlowMappingIndication QoS-Flow-Mapping-Indication OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { QoS-Flow-Mapping-Item-ExtIEs } } OPTIONAL, + ... +} + +QoS-Flow-Mapping-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoS-Flow-Mapping-Indication ::= ENUMERATED {ul, dl, ...} + +QoS-Flows-DRB-Remapping ::= ENUMERATED {update, source-configuration, ...} + +QoS-Parameters-Support-List ::= SEQUENCE { + eUTRAN-QoS-Support-List EUTRAN-QoS-Support-List OPTIONAL, + nG-RAN-QoS-Support-List NG-RAN-QoS-Support-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { QoS-Parameters-Support-List-ItemExtIEs} } OPTIONAL, + ... +} + +QoS-Parameters-Support-List-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoSPriorityLevel ::= INTEGER (0..127, ...) + + +QoS-Flow-QoS-Parameter-List ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF QoS-Flow-QoS-Parameter-Item + +QoS-Flow-QoS-Parameter-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + qoSFlowLevelQoSParameters QoSFlowLevelQoSParameters, + qoSFlowMappingIndication QoS-Flow-Mapping-Indication OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { QoS-Flow-QoS-Parameter-Item-ExtIEs } } OPTIONAL, + ... +} + +QoS-Flow-QoS-Parameter-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-RedundantQosFlowIndicator CRITICALITY ignore EXTENSION RedundantQoSFlowIndicator PRESENCE optional}| + {ID id-TSCTrafficCharacteristics CRITICALITY ignore EXTENSION TSCTrafficCharacteristics PRESENCE optional}, + ... +} + +QoSFlowLevelQoSParameters ::= SEQUENCE { + qoS-Characteristics QoS-Characteristics, + nGRANallocationRetentionPriority NGRANAllocationAndRetentionPriority, + gBR-QoS-Flow-Information GBR-QoSFlowInformation OPTIONAL, + reflective-QoS-Attribute ENUMERATED {subject-to, ...} OPTIONAL, + additional-QoS-Information ENUMERATED {more-likely, ...} OPTIONAL, + paging-Policy-Indicator INTEGER (1..8, ...) OPTIONAL, + reflective-QoS-Indicator ENUMERATED {enabled, ...} OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { QoSFlowLevelQoSParameters-ExtIEs } } OPTIONAL +} + +QoSFlowLevelQoSParameters-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-QoSMonitoringRequest CRITICALITY ignore EXTENSION QosMonitoringRequest PRESENCE optional}| + {ID id-MCG-OfferedGBRQoSFlowInfo CRITICALITY ignore EXTENSION GBR-QoSFlowInformation PRESENCE optional}| + {ID id-QosMonitoringReportingFrequency CRITICALITY ignore EXTENSION QosMonitoringReportingFrequency PRESENCE optional}| + {ID id-QoSMonitoringDisabled CRITICALITY ignore EXTENSION QosMonitoringDisabled PRESENCE optional}, + ... +} + +QosMonitoringRequest ::= ENUMERATED {ul, dl, both} + +QosMonitoringReportingFrequency ::= INTEGER (1..1800, ...) + +QosMonitoringDisabled ::= ENUMERATED {true, ...} + +QoS-Flow-Removed-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + qoS-Flow-Released-In-Session ENUMERATED {released-in-session, not-released-in-session, ...} OPTIONAL, + qoS-Flow-Accumulated-Session-Time OCTET STRING (SIZE(5)) OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { QoS-Flow-Removed-Item-ExtIEs } } OPTIONAL, + ... +} + +QoS-Flow-Removed-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoS-Flows-to-be-forwarded-List ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF QoS-Flows-to-be-forwarded-Item + +QoS-Flows-to-be-forwarded-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + iE-Extensions ProtocolExtensionContainer { { QoS-Flows-to-be-forwarded-Item-ExtIEs } } OPTIONAL, + ... +} + +QoS-Flows-to-be-forwarded-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoS-Mapping-Information ::= SEQUENCE { +dscp BIT STRING (SIZE(6)) OPTIONAL, +flow-label BIT STRING (SIZE(20)) OPTIONAL, +... +} + +DataForwardingtoNG-RANQoSFlowInformationList ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF DataForwardingtoNG-RANQoSFlowInformationList-Item + +DataForwardingtoNG-RANQoSFlowInformationList-Item ::= SEQUENCE { + qoS-Flow-Identifier QoS-Flow-Identifier, + iE-Extensions ProtocolExtensionContainer { { DataForwardingtoNG-RANQoSFlowInformationList-Item-ExtIEs} } OPTIONAL, + ... +} + +DataForwardingtoNG-RANQoSFlowInformationList-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- R + +RANUEID ::= OCTET STRING (SIZE (8)) + +RAT-Type ::= ENUMERATED { + e-UTRA, + nR, + ... +} + +RedundantQoSFlowIndicator::= ENUMERATED {true,false} + +RedundantPDUSessionInformation ::= SEQUENCE { + rSN RSN, + iE-Extensions ProtocolExtensionContainer { {RedundantPDUSessionInformation-ExtIEs} } OPTIONAL, + ... +} + +RedundantPDUSessionInformation-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +RSN ::= ENUMERATED {v1, v2, ...} + +RetainabilityMeasurementsInfo ::= SEQUENCE (SIZE(1.. maxnoofDRBs)) OF DRB-Removed-Item + +RegistrationRequest ::= ENUMERATED { + start, + stop, + ... +} + + +ReportCharacteristics ::= BIT STRING (SIZE(36)) + +ReportingPeriodicity ::= ENUMERATED { + ms500, ms1000, ms2000, ms5000, ms10000, ms20000, ms30000, ms40000, ms50000, ms60000, ms70000, ms80000, ms90000, ms100000, ms110000, ms120000, + ... +} + +RLC-Mode ::= ENUMERATED { + rlc-tm, + rlc-am, + rlc-um-bidirectional, + rlc-um-unidirectional-ul, + rlc-um-unidirectional-dl, + ... +} + + +ROHC-Parameters ::= CHOICE { + rOHC ROHC, + uPlinkOnlyROHC UplinkOnlyROHC, + choice-Extension ProtocolIE-SingleContainer { { ROHC-Parameters-ExtIEs} } +} + +ROHC-Parameters-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +ROHC ::= SEQUENCE { + maxCID INTEGER (0..16383, ...), + rOHC-Profiles INTEGER (0..511, ...), + continueROHC ENUMERATED {true, ...} OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { ROHC-ExtIEs } } OPTIONAL +} + +ROHC-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +-- S + +SecurityAlgorithm ::= SEQUENCE { + cipheringAlgorithm CipheringAlgorithm, + integrityProtectionAlgorithm IntegrityProtectionAlgorithm OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SecurityAlgorithm-ExtIEs } } OPTIONAL, + ... +} + +SecurityAlgorithm-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SecurityIndication ::= SEQUENCE { + integrityProtectionIndication IntegrityProtectionIndication, + confidentialityProtectionIndication ConfidentialityProtectionIndication, + maximumIPdatarate MaximumIPdatarate OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {SecurityIndication-ExtIEs} } OPTIONAL, + ... +} + +SecurityIndication-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SecurityInformation ::= SEQUENCE { + securityAlgorithm SecurityAlgorithm, + uPSecuritykey UPSecuritykey, + iE-Extensions ProtocolExtensionContainer { { SecurityInformation-ExtIEs } } OPTIONAL, + ... +} + +SecurityInformation-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SecurityResult ::= SEQUENCE { + integrityProtectionResult IntegrityProtectionResult, + confidentialityProtectionResult ConfidentialityProtectionResult, + iE-Extensions ProtocolExtensionContainer { {SecurityResult-ExtIEs} } OPTIONAL, + ... +} + +SecurityResult-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Slice-Support-List ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF Slice-Support-Item + +Slice-Support-Item ::= SEQUENCE { + sNSSAI SNSSAI, + iE-Extensions ProtocolExtensionContainer { { Slice-Support-Item-ExtIEs } } OPTIONAL +} + +Slice-Support-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SNSSAI ::= SEQUENCE { + sST OCTET STRING (SIZE(1)), + sD OCTET STRING (SIZE(3)) OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SNSSAI-ExtIEs } } OPTIONAL, + ... +} + +SNSSAI-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SDAP-Configuration ::= SEQUENCE { + defaultDRB DefaultDRB, + sDAP-Header-UL SDAP-Header-UL, + sDAP-Header-DL SDAP-Header-DL, + iE-Extensions ProtocolExtensionContainer { { SDAP-Configuration-ExtIEs } } OPTIONAL, + ... +} + +SDAP-Configuration-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SDAP-Header-DL ::= ENUMERATED { + present, + absent, + ... +} + +SDAP-Header-UL ::= ENUMERATED { + present, + absent, + ... +} + +SubscriberProfileIDforRFP ::= INTEGER (1..256, ...) + +-- T + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TNLAssociationUsage ::= ENUMERATED { + ue, + non-ue, + both, +... +} + +TNL-AvailableCapacityIndicator ::= SEQUENCE { + dL-TNL-OfferedCapacity INTEGER (0..16777216, ...), + dL-TNL-AvailableCapacity INTEGER (0..100, ...), + uL-TNL-OfferedCapacity INTEGER (0..16777216, ...), + uL-TNL-AvailableCapacity INTEGER (0..100, ...), + iE-Extensions ProtocolExtensionContainer { { TNL-AvailableCapacityIndicator-ExtIEs } }, + ... +} + +TNL-AvailableCapacityIndicator-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TSCTrafficCharacteristics ::= SEQUENCE { + tSCTrafficCharacteristicsUL TSCTrafficInformation OPTIONAL, + tSCTrafficCharacteristicsDL TSCTrafficInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { TSCTrafficCharacteristics-ExtIEs } } OPTIONAL +} + +TSCTrafficCharacteristics-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TSCTrafficInformation ::= SEQUENCE { + periodicity Periodicity, + burstArrivalTime BurstArrivalTime OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { TSCTrafficInformation-ExtIEs } } OPTIONAL +} + +TSCTrafficInformation-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Periodicity ::= INTEGER (1..640000, ...) + +BurstArrivalTime ::= OCTET STRING + +TraceActivation ::= SEQUENCE { + traceID TraceID, + interfacesToTrace InterfacesToTrace, + traceDepth TraceDepth, + traceCollectionEntityIPAddress TransportLayerAddress, + iE-Extensions ProtocolExtensionContainer { {TraceActivation-ExtIEs} } OPTIONAL, + ... +} + +TraceActivation-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + { ID id-MDTConfiguration CRITICALITY ignore EXTENSION MDT-Configuration PRESENCE optional }| + { ID id-TraceCollectionEntityURI CRITICALITY ignore EXTENSION URIaddress PRESENCE optional}, + ... +} + +TraceDepth ::= ENUMERATED { + minimum, + medium, + maximum, + minimumWithoutVendorSpecificExtension, + mediumWithoutVendorSpecificExtension, + maximumWithoutVendorSpecificExtension, + ... +} + +TraceID ::= OCTET STRING (SIZE(8)) + +TransportLayerAddress ::= BIT STRING (SIZE(1..160, ...)) + +TransactionID ::= INTEGER (0..255, ...) + +T-Reordering ::= ENUMERATED {ms0, ms1, ms2, ms4, ms5, ms8, ms10, ms15, ms20, ms30, ms40, ms50, ms60, ms80, ms100, ms120, ms140, ms160, ms180, ms200, ms220, ms240, ms260, ms280, ms300, ms500, ms750, ms1000, ms1250, ms1500, ms1750, ms2000, ms2250, ms2500, ms2750, ms3000, ...} + +T-ReorderingTimer ::= SEQUENCE { + t-Reordering T-Reordering, + iE-Extensions ProtocolExtensionContainer { { T-ReorderingTimer-ExtIEs } } OPTIONAL, + ... +} + +T-ReorderingTimer-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + +Transport-Layer-Address-Info ::= SEQUENCE { + transport-UP-Layer-Addresses-Info-To-Add-List Transport-UP-Layer-Addresses-Info-To-Add-List OPTIONAL, + transport-UP-Layer-Addresses-Info-To-Remove-List Transport-UP-Layer-Addresses-Info-To-Remove-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Transport-Layer-Address-Info-ExtIEs} } OPTIONAL, + ... + } + +Transport-Layer-Address-Info-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Transport-UP-Layer-Addresses-Info-To-Add-List ::= SEQUENCE (SIZE(1.. maxnoofTLAs)) OF Transport-UP-Layer-Addresses-Info-To-Add-Item + +Transport-UP-Layer-Addresses-Info-To-Add-Item ::= SEQUENCE { + iP-SecTransportLayerAddress TransportLayerAddress, + gTPTransportLayerAddressesToAdd GTPTLAs OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Transport-UP-Layer-Addresses-Info-To-Add-ItemExtIEs } } OPTIONAL, + ... +} + +Transport-UP-Layer-Addresses-Info-To-Add-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Transport-UP-Layer-Addresses-Info-To-Remove-List ::= SEQUENCE (SIZE(1.. maxnoofTLAs)) OF Transport-UP-Layer-Addresses-Info-To-Remove-Item + +Transport-UP-Layer-Addresses-Info-To-Remove-Item ::= SEQUENCE { + iP-SecTransportLayerAddress TransportLayerAddress, + gTPTransportLayerAddressesToRemove GTPTLAs OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Transport-UP-Layer-Addresses-Info-To-Remove-ItemExtIEs } } OPTIONAL, + ... +} + +Transport-UP-Layer-Addresses-Info-To-Remove-ItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} +-- U + +UE-Activity ::= ENUMERATED { + active, + not-active, + ... +} + +UE-associatedLogicalE1-ConnectionItem ::= SEQUENCE { + gNB-CU-CP-UE-E1AP-ID GNB-CU-CP-UE-E1AP-ID OPTIONAL, + gNB-CU-UP-UE-E1AP-ID GNB-CU-UP-UE-E1AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { UE-associatedLogicalE1-ConnectionItemExtIEs} } OPTIONAL, + ... +} + +UE-associatedLogicalE1-ConnectionItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +UL-Configuration ::= ENUMERATED { + no-data, + shared, + only, + ... +} + +ULUPTNLAddressToUpdateItem ::= SEQUENCE { + oldTNLAdress TransportLayerAddress, + newTNLAdress TransportLayerAddress, + iE-Extensions ProtocolExtensionContainer { { ULUPTNLAddressToUpdateItemExtIEs } } OPTIONAL, + ... +} + +ULUPTNLAddressToUpdateItemExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ULDataSplitThreshold ::= ENUMERATED {b0, b100, b200, b400, b800, b1600, b3200, b6400, b12800, b25600, b51200, b102400, b204800, b409600, b819200, b1228800, b1638400, b2457600, b3276800, b4096000, b4915200, b5734400, b6553600, infinity, ...} + +UP-Parameters ::= SEQUENCE (SIZE(1.. maxnoofUPParameters)) OF UP-Parameters-Item + +UP-Parameters-Item ::= SEQUENCE { + uP-TNL-Information UP-TNL-Information, + cell-Group-ID Cell-Group-ID, + iE-Extensions ProtocolExtensionContainer { { UP-Parameters-Item-ExtIEs } } OPTIONAL, + ... +} + +UP-Parameters-Item-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + {ID id-QoS-Mapping-Information CRITICALITY reject EXTENSION QoS-Mapping-Information PRESENCE optional}, + ... +} + +UPSecuritykey ::= SEQUENCE { + encryptionKey EncryptionKey, + integrityProtectionKey IntegrityProtectionKey OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { UPSecuritykey-ExtIEs } } OPTIONAL, + ... +} + +UPSecuritykey-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +UP-TNL-Information ::= CHOICE { + gTPTunnel GTPTunnel, + choice-extension ProtocolIE-SingleContainer {{UP-TNL-Information-ExtIEs}} +} + +UP-TNL-Information-ExtIEs E1AP-PROTOCOL-IES ::= { + ... +} + +UplinkOnlyROHC ::= SEQUENCE { + maxCID INTEGER (0..16383, ...), + rOHC-Profiles INTEGER (0..511, ...), + continueROHC ENUMERATED {true, ...} OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { UplinkOnlyROHC-ExtIEs } } OPTIONAL +} + +UplinkOnlyROHC-ExtIEs E1AP-PROTOCOL-EXTENSION ::= { + ... +} + +URIaddress ::= VisibleString + +-- V + +-- W + +-- X + +-- Y + +-- Z + +END +-- ASN1STOP +-- ASN1START +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +E1AP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-CommonDataTypes (3)} + + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 + +-- ************************************************************** +-- +-- Common Data Types +-- +-- ************************************************************** + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0.. maxPrivateIEs), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + +ProtocolExtensionID ::= INTEGER (0..maxProtocolExtensions) + +ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs) + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome} + +END +-- ASN1STOP +-- ASN1START +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + + +E1AP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + + ProcedureCode, + ProtocolIE-ID + +FROM E1AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-reset ProcedureCode ::= 0 +id-errorIndication ProcedureCode ::= 1 +id-privateMessage ProcedureCode ::= 2 +id-gNB-CU-UP-E1Setup ProcedureCode ::= 3 +id-gNB-CU-CP-E1Setup ProcedureCode ::= 4 +id-gNB-CU-UP-ConfigurationUpdate ProcedureCode ::= 5 +id-gNB-CU-CP-ConfigurationUpdate ProcedureCode ::= 6 +id-e1Release ProcedureCode ::= 7 +id-bearerContextSetup ProcedureCode ::= 8 +id-bearerContextModification ProcedureCode ::= 9 +id-bearerContextModificationRequired ProcedureCode ::= 10 +id-bearerContextRelease ProcedureCode ::= 11 +id-bearerContextReleaseRequest ProcedureCode ::= 12 +id-bearerContextInactivityNotification ProcedureCode ::= 13 +id-dLDataNotification ProcedureCode ::= 14 +id-dataUsageReport ProcedureCode ::= 15 +id-gNB-CU-UP-CounterCheck ProcedureCode ::= 16 +id-gNB-CU-UP-StatusIndication ProcedureCode ::= 17 +id-uLDataNotification ProcedureCode ::= 18 +id-mRDC-DataUsageReport ProcedureCode ::= 19 +id-TraceStart ProcedureCode ::= 20 +id-DeactivateTrace ProcedureCode ::= 21 +id-resourceStatusReportingInitiation ProcedureCode ::= 22 +id-resourceStatusReporting ProcedureCode ::= 23 +id-iAB-UPTNLAddressUpdate ProcedureCode ::= 24 +id-CellTrafficTrace ProcedureCode ::= 25 +id-earlyForwardingSNTransfer ProcedureCode ::= 26 +id-gNB-CU-CPMeasurementResultsInformation ProcedureCode ::= 27 + + +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + +maxnoofErrors INTEGER ::= 256 +maxnoofSPLMNs INTEGER ::= 12 +maxnoofSliceItems INTEGER ::= 1024 +maxnoofIndividualE1ConnectionsToReset INTEGER ::= 65536 +maxnoofEUTRANQOSParameters INTEGER ::= 256 +maxnoofNGRANQOSParameters INTEGER ::= 256 +maxnoofDRBs INTEGER ::= 32 +maxnoofNRCGI INTEGER ::= 512 +maxnoofPDUSessionResource INTEGER ::= 256 +maxnoofQoSFlows INTEGER ::= 64 +maxnoofUPParameters INTEGER ::= 8 +maxnoofCellGroups INTEGER ::= 4 +maxnooftimeperiods INTEGER ::= 2 +maxnoofTNLAssociations INTEGER ::= 32 +maxnoofTLAs INTEGER ::= 16 +maxnoofGTPTLAs INTEGER ::= 16 +maxnoofTNLAddresses INTEGER ::= 8 +maxnoofMDTPLMNs INTEGER ::= 16 +maxnoofQoSParaSets INTEGER ::= 8 +maxnoofExtSliceItems INTEGER ::= 65535 +maxnoofDataForwardingTunneltoE-UTRAN INTEGER ::= 256 +maxnoofExtNRCGI INTEGER ::= 16384 + + +-- ************************************************************** +-- +-- IEs +-- +-- ************************************************************** + +id-Cause ProtocolIE-ID ::= 0 +id-CriticalityDiagnostics ProtocolIE-ID ::= 1 +id-gNB-CU-CP-UE-E1AP-ID ProtocolIE-ID ::= 2 +id-gNB-CU-UP-UE-E1AP-ID ProtocolIE-ID ::= 3 +id-ResetType ProtocolIE-ID ::= 4 +id-UE-associatedLogicalE1-ConnectionItem ProtocolIE-ID ::= 5 +id-UE-associatedLogicalE1-ConnectionListResAck ProtocolIE-ID ::= 6 +id-gNB-CU-UP-ID ProtocolIE-ID ::= 7 +id-gNB-CU-UP-Name ProtocolIE-ID ::= 8 +id-gNB-CU-CP-Name ProtocolIE-ID ::= 9 +id-CNSupport ProtocolIE-ID ::= 10 +id-SupportedPLMNs ProtocolIE-ID ::= 11 +id-TimeToWait ProtocolIE-ID ::= 12 +id-SecurityInformation ProtocolIE-ID ::= 13 +id-UEDLAggregateMaximumBitRate ProtocolIE-ID ::= 14 +id-System-BearerContextSetupRequest ProtocolIE-ID ::= 15 +id-System-BearerContextSetupResponse ProtocolIE-ID ::= 16 +id-BearerContextStatusChange ProtocolIE-ID ::= 17 +id-System-BearerContextModificationRequest ProtocolIE-ID ::= 18 +id-System-BearerContextModificationResponse ProtocolIE-ID ::= 19 +id-System-BearerContextModificationConfirm ProtocolIE-ID ::= 20 +id-System-BearerContextModificationRequired ProtocolIE-ID ::= 21 +id-DRB-Status-List ProtocolIE-ID ::= 22 +id-ActivityNotificationLevel ProtocolIE-ID ::= 23 +id-ActivityInformation ProtocolIE-ID ::= 24 +id-Data-Usage-Report-List ProtocolIE-ID ::= 25 +id-New-UL-TNL-Information-Required ProtocolIE-ID ::= 26 +id-GNB-CU-CP-TNLA-To-Add-List ProtocolIE-ID ::= 27 +id-GNB-CU-CP-TNLA-To-Remove-List ProtocolIE-ID ::= 28 +id-GNB-CU-CP-TNLA-To-Update-List ProtocolIE-ID ::= 29 +id-GNB-CU-CP-TNLA-Setup-List ProtocolIE-ID ::= 30 +id-GNB-CU-CP-TNLA-Failed-To-Setup-List ProtocolIE-ID ::= 31 +id-DRB-To-Setup-List-EUTRAN ProtocolIE-ID ::= 32 +id-DRB-To-Modify-List-EUTRAN ProtocolIE-ID ::= 33 +id-DRB-To-Remove-List-EUTRAN ProtocolIE-ID ::= 34 +id-DRB-Required-To-Modify-List-EUTRAN ProtocolIE-ID ::= 35 +id-DRB-Required-To-Remove-List-EUTRAN ProtocolIE-ID ::= 36 +id-DRB-Setup-List-EUTRAN ProtocolIE-ID ::= 37 +id-DRB-Failed-List-EUTRAN ProtocolIE-ID ::= 38 +id-DRB-Modified-List-EUTRAN ProtocolIE-ID ::= 39 +id-DRB-Failed-To-Modify-List-EUTRAN ProtocolIE-ID ::= 40 +id-DRB-Confirm-Modified-List-EUTRAN ProtocolIE-ID ::= 41 +id-PDU-Session-Resource-To-Setup-List ProtocolIE-ID ::= 42 +id-PDU-Session-Resource-To-Modify-List ProtocolIE-ID ::= 43 +id-PDU-Session-Resource-To-Remove-List ProtocolIE-ID ::= 44 +id-PDU-Session-Resource-Required-To-Modify-List ProtocolIE-ID ::= 45 +id-PDU-Session-Resource-Setup-List ProtocolIE-ID ::= 46 +id-PDU-Session-Resource-Failed-List ProtocolIE-ID ::= 47 +id-PDU-Session-Resource-Modified-List ProtocolIE-ID ::= 48 +id-PDU-Session-Resource-Failed-To-Modify-List ProtocolIE-ID ::= 49 +id-PDU-Session-Resource-Confirm-Modified-List ProtocolIE-ID ::= 50 +id-DRB-To-Setup-Mod-List-EUTRAN ProtocolIE-ID ::= 51 +id-DRB-Setup-Mod-List-EUTRAN ProtocolIE-ID ::= 52 +id-DRB-Failed-Mod-List-EUTRAN ProtocolIE-ID ::= 53 +id-PDU-Session-Resource-Setup-Mod-List ProtocolIE-ID ::= 54 +id-PDU-Session-Resource-Failed-Mod-List ProtocolIE-ID ::= 55 +id-PDU-Session-Resource-To-Setup-Mod-List ProtocolIE-ID ::= 56 +id-TransactionID ProtocolIE-ID ::= 57 +id-Serving-PLMN ProtocolIE-ID ::= 58 +id-UE-Inactivity-Timer ProtocolIE-ID ::= 59 +id-System-GNB-CU-UP-CounterCheckRequest ProtocolIE-ID ::= 60 +id-DRBs-Subject-To-Counter-Check-List-EUTRAN ProtocolIE-ID ::= 61 +id-DRBs-Subject-To-Counter-Check-List-NG-RAN ProtocolIE-ID ::= 62 +id-PPI ProtocolIE-ID ::= 63 +id-gNB-CU-UP-Capacity ProtocolIE-ID ::= 64 +id-GNB-CU-UP-OverloadInformation ProtocolIE-ID ::= 65 +id-UEDLMaximumIntegrityProtectedDataRate ProtocolIE-ID ::= 66 +id-PDU-Session-To-Notify-List ProtocolIE-ID ::= 67 +id-PDU-Session-Resource-Data-Usage-List ProtocolIE-ID ::= 68 +id-SNSSAI ProtocolIE-ID ::= 69 +id-DataDiscardRequired ProtocolIE-ID ::= 70 +id-OldQoSFlowMap-ULendmarkerexpected ProtocolIE-ID ::= 71 +id-DRB-QoS ProtocolIE-ID ::= 72 +id-GNB-CU-UP-TNLA-To-Remove-List ProtocolIE-ID ::= 73 +id-endpoint-IP-Address-and-Port ProtocolIE-ID ::= 74 +id-TNLAssociationTransportLayerAddressgNBCUUP ProtocolIE-ID ::= 75 +id-RANUEID ProtocolIE-ID ::= 76 +id-GNB-DU-ID ProtocolIE-ID ::= 77 +id-CommonNetworkInstance ProtocolIE-ID ::= 78 +id-NetworkInstance ProtocolIE-ID ::= 79 +id-QoSFlowMappingIndication ProtocolIE-ID ::= 80 +id-TraceActivation ProtocolIE-ID ::= 81 +id-TraceID ProtocolIE-ID ::= 82 +id-SubscriberProfileIDforRFP ProtocolIE-ID ::= 83 +id-AdditionalRRMPriorityIndex ProtocolIE-ID ::= 84 +id-RetainabilityMeasurementsInfo ProtocolIE-ID ::= 85 +id-Transport-Layer-Address-Info ProtocolIE-ID ::= 86 +id-QoSMonitoringRequest ProtocolIE-ID ::= 87 +id-PDCP-StatusReportIndication ProtocolIE-ID ::= 88 +id-gNB-CU-CP-Measurement-ID ProtocolIE-ID ::= 89 +id-gNB-CU-UP-Measurement-ID ProtocolIE-ID ::= 90 +id-RegistrationRequest ProtocolIE-ID ::= 91 +id-ReportCharacteristics ProtocolIE-ID ::= 92 +id-ReportingPeriodicity ProtocolIE-ID ::= 93 +id-TNL-AvailableCapacityIndicator ProtocolIE-ID ::= 94 +id-HW-CapacityIndicator ProtocolIE-ID ::= 95 +id-RedundantCommonNetworkInstance ProtocolIE-ID ::= 96 +id-redundant-nG-UL-UP-TNL-Information ProtocolIE-ID ::= 97 +id-redundant-nG-DL-UP-TNL-Information ProtocolIE-ID ::= 98 +id-RedundantQosFlowIndicator ProtocolIE-ID ::= 99 +id-TSCTrafficCharacteristics ProtocolIE-ID ::= 100 +id-CNPacketDelayBudgetDownlink ProtocolIE-ID ::= 101 +id-CNPacketDelayBudgetUplink ProtocolIE-ID ::= 102 +id-ExtendedPacketDelayBudget ProtocolIE-ID ::= 103 +id-AdditionalPDCPduplicationInformation ProtocolIE-ID ::= 104 +id-RedundantPDUSessionInformation ProtocolIE-ID ::= 105 +id-RedundantPDUSessionInformation-used ProtocolIE-ID ::= 106 +id-QoS-Mapping-Information ProtocolIE-ID ::= 107 +id-DLUPTNLAddressToUpdateList ProtocolIE-ID ::= 108 +id-ULUPTNLAddressToUpdateList ProtocolIE-ID ::= 109 +id-NPNSupportInfo ProtocolIE-ID ::= 110 +id-NPNContextInfo ProtocolIE-ID ::= 111 +id-MDTConfiguration ProtocolIE-ID ::= 112 +id-ManagementBasedMDTPLMNList ProtocolIE-ID ::= 113 +id-TraceCollectionEntityIPAddress ProtocolIE-ID ::= 114 +id-PrivacyIndicator ProtocolIE-ID ::= 115 +id-TraceCollectionEntityURI ProtocolIE-ID ::= 116 +id-URIaddress ProtocolIE-ID ::= 117 +id-EHC-Parameters ProtocolIE-ID ::= 118 +id-DRBs-Subject-To-Early-Forwarding-List ProtocolIE-ID ::= 119 +id-DAPSRequestInfo ProtocolIE-ID ::= 120 +id-CHOInitiation ProtocolIE-ID ::= 121 +id-EarlyForwardingCOUNTReq ProtocolIE-ID ::= 122 +id-EarlyForwardingCOUNTInfo ProtocolIE-ID ::= 123 +id-AlternativeQoSParaSetList ProtocolIE-ID ::= 124 + id-ExtendedSliceSupportList ProtocolIE-ID ::= 125 +id-MCG-OfferedGBRQoSFlowInfo ProtocolIE-ID ::= 126 +id-Number-of-tunnels ProtocolIE-ID ::= 127 +id-DRB-Measurement-Results-Information-List ProtocolIE-ID ::= 128 +id-Extended-GNB-CU-CP-Name ProtocolIE-ID ::= 129 +id-Extended-GNB-CU-UP-Name ProtocolIE-ID ::= 130 +id-DataForwardingtoE-UTRANInformationList ProtocolIE-ID ::= 131 +id-QosMonitoringReportingFrequency ProtocolIE-ID ::= 132 +id-QoSMonitoringDisabled ProtocolIE-ID ::= 133 +id-AdditionalHandoverInfo ProtocolIE-ID ::= 134 +id-Extended-NR-CGI-Support-List ProtocolIE-ID ::= 135 +id-DataForwardingtoNG-RANQoSFlowInformationList ProtocolIE-ID ::= 136 +id-MaxCIDEHCDL ProtocolIE-ID ::= 137 +id-ignoreMappingRuleIndication ProtocolIE-ID ::= 138 +id-DirectForwardingPathAvailability ProtocolIE-ID ::= 139 +id-EarlyDataForwardingIndicator ProtocolIE-ID ::= 140 +id-QoSFlowsDRBRemapping ProtocolIE-ID ::= 141 + + +END +-- ASN1STOP +-- ASN1START +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +E1AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) e1ap (5) version1 (1) e1ap-Containers (5) } + + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs, + Criticality, + Presence, + PrivateIE-ID, + ProtocolIE-ID + +FROM E1AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +E1AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +E1AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +E1AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container { E1AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-SingleContainer { E1AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field { E1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id E1AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality E1AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value E1AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container Lists for Protocol IE Containers +-- +-- ************************************************************** + +ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, E1AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-Container {{IEsSetParam}} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer { E1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField { E1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id E1AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality E1AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue E1AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container { E1AP-PRIVATE-IES : IEsSetParam} ::= + SEQUENCE (SIZE (1..maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field { E1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id E1AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality E1AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value E1AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END +-- ASN1STOP diff --git a/openair2/E1AP/MESSAGES/ASN.1/38463-g80.R16.78.0.cmake b/openair2/E1AP/MESSAGES/ASN.1/38463-g80.R16.78.0.cmake new file mode 100644 index 0000000000..5638ba50d6 --- /dev/null +++ b/openair2/E1AP/MESSAGES/ASN.1/38463-g80.R16.78.0.cmake @@ -0,0 +1,941 @@ +set(E1AP_GRAMMAR ASN.1/38463-g80.R16.78.0.asn) + +set(e1ap_source + ANY.c + asn_application.c + asn_bit_data.c + asn_codecs_prim.c + asn_internal.c + asn_random_fill.c + asn_SEQUENCE_OF.c + asn_SET_OF.c + ber_decoder.c + ber_tlv_length.c + ber_tlv_tag.c + BIT_STRING.c + constraints.c + constr_CHOICE.c + constr_SEQUENCE.c + constr_SEQUENCE_OF.c + constr_SET_OF.c + constr_TYPE.c + der_encoder.c + E1AP_ActivityInformation.c + E1AP_ActivityNotificationLevel.c + E1AP_AdditionalHandoverInfo.c + E1AP_AdditionalPDCPduplicationInformation.c + E1AP_AdditionalRRMPriorityIndex.c + E1AP_AlternativeQoSParaSetItem.c + E1AP_AlternativeQoSParaSetList.c + E1AP_AveragingWindow.c + E1AP_BearerContextInactivityNotification.c + E1AP_BearerContextModificationConfirm.c + E1AP_BearerContextModificationFailure.c + E1AP_BearerContextModificationRequest.c + E1AP_BearerContextModificationRequired.c + E1AP_BearerContextModificationResponse.c + E1AP_BearerContextReleaseCommand.c + E1AP_BearerContextReleaseComplete.c + E1AP_BearerContextReleaseRequest.c + E1AP_BearerContextSetupFailure.c + E1AP_BearerContextSetupRequest.c + E1AP_BearerContextSetupResponse.c + E1AP_BearerContextStatusChange.c + E1AP_BitRate.c + E1AP_BurstArrivalTime.c + E1AP_Cause.c + E1AP_CauseMisc.c + E1AP_CauseProtocol.c + E1AP_CauseRadioNetwork.c + E1AP_CauseTransport.c + E1AP_Cell-Group-ID.c + E1AP_Cell-Group-Information.c + E1AP_Cell-Group-Information-Item.c + E1AP_CellTrafficTrace.c + E1AP_CHOInitiation.c + E1AP_CipheringAlgorithm.c + E1AP_CNSupport.c + E1AP_CommonNetworkInstance.c + E1AP_ConfidentialityProtectionIndication.c + E1AP_ConfidentialityProtectionResult.c + E1AP_CP-TNL-Information.c + E1AP_Criticality.c + E1AP_CriticalityDiagnostics.c + E1AP_CriticalityDiagnostics-IE-List.c + E1AP_DAPSRequestInfo.c + E1AP_DataDiscardRequired.c + E1AP_Data-Forwarding-Information.c + E1AP_Data-Forwarding-Information-Request.c + E1AP_Data-Forwarding-Request.c + E1AP_DataForwardingtoE-UTRANInformationList.c + E1AP_DataForwardingtoE-UTRANInformationListItem.c + E1AP_DataForwardingtoNG-RANQoSFlowInformationList.c + E1AP_DataForwardingtoNG-RANQoSFlowInformationList-Item.c + E1AP_Data-Usage-per-PDU-Session-Report.c + E1AP_Data-Usage-per-QoS-Flow-Item.c + E1AP_Data-Usage-per-QoS-Flow-List.c + E1AP_DataUsageReport.c + E1AP_Data-Usage-Report-Item.c + E1AP_Data-Usage-Report-List.c + E1AP_DeactivateTrace.c + E1AP_DefaultDRB.c + E1AP_DirectForwardingPathAvailability.c + E1AP_DiscardTimer.c + E1AP_DLDataNotification.c + E1AP_DLDiscarding.c + E1AP_DL-TX-Stop.c + E1AP_DLUPTNLAddressToUpdateItem.c + E1AP_DLUPTNLAddressToUpdateList.c + E1AP_DRB-Activity.c + E1AP_DRB-Activity-Item.c + E1AP_DRB-Activity-List.c + E1AP_DRBBStatusTransfer.c + E1AP_DRB-Confirm-Modified-Item-EUTRAN.c + E1AP_DRB-Confirm-Modified-Item-NG-RAN.c + E1AP_DRB-Confirm-Modified-List-EUTRAN.c + E1AP_DRB-Confirm-Modified-List-NG-RAN.c + E1AP_DRB-Failed-Item-EUTRAN.c + E1AP_DRB-Failed-Item-NG-RAN.c + E1AP_DRB-Failed-List-EUTRAN.c + E1AP_DRB-Failed-List-NG-RAN.c + E1AP_DRB-Failed-Mod-Item-EUTRAN.c + E1AP_DRB-Failed-Mod-Item-NG-RAN.c + E1AP_DRB-Failed-Mod-List-EUTRAN.c + E1AP_DRB-Failed-Mod-List-NG-RAN.c + E1AP_DRB-Failed-To-Modify-Item-EUTRAN.c + E1AP_DRB-Failed-To-Modify-Item-NG-RAN.c + E1AP_DRB-Failed-To-Modify-List-EUTRAN.c + E1AP_DRB-Failed-To-Modify-List-NG-RAN.c + E1AP_DRB-ID.c + E1AP_DRB-Measurement-Results-Information-Item.c + E1AP_DRB-Measurement-Results-Information-List.c + E1AP_DRB-Modified-Item-EUTRAN.c + E1AP_DRB-Modified-Item-NG-RAN.c + E1AP_DRB-Modified-List-EUTRAN.c + E1AP_DRB-Modified-List-NG-RAN.c + E1AP_DRB-Removed-Item.c + E1AP_DRB-Required-To-Modify-Item-EUTRAN.c + E1AP_DRB-Required-To-Modify-Item-NG-RAN.c + E1AP_DRB-Required-To-Modify-List-EUTRAN.c + E1AP_DRB-Required-To-Modify-List-NG-RAN.c + E1AP_DRB-Required-To-Remove-Item-EUTRAN.c + E1AP_DRB-Required-To-Remove-Item-NG-RAN.c + E1AP_DRB-Required-To-Remove-List-EUTRAN.c + E1AP_DRB-Required-To-Remove-List-NG-RAN.c + E1AP_DRB-Setup-Item-EUTRAN.c + E1AP_DRB-Setup-Item-NG-RAN.c + E1AP_DRB-Setup-List-EUTRAN.c + E1AP_DRB-Setup-List-NG-RAN.c + E1AP_DRB-Setup-Mod-Item-EUTRAN.c + E1AP_DRB-Setup-Mod-Item-NG-RAN.c + E1AP_DRB-Setup-Mod-List-EUTRAN.c + E1AP_DRB-Setup-Mod-List-NG-RAN.c + E1AP_DRBs-Subject-To-Counter-Check-Item-EUTRAN.c + E1AP_DRBs-Subject-To-Counter-Check-Item-NG-RAN.c + E1AP_DRBs-Subject-To-Counter-Check-List-EUTRAN.c + E1AP_DRBs-Subject-To-Counter-Check-List-NG-RAN.c + E1AP_DRBs-Subject-To-Early-Forwarding-Item.c + E1AP_DRBs-Subject-To-Early-Forwarding-List.c + E1AP_DRB-Status-Item.c + E1AP_DRB-Status-List.c + E1AP_DRB-To-Modify-Item-EUTRAN.c + E1AP_DRB-To-Modify-Item-NG-RAN.c + E1AP_DRB-To-Modify-List-EUTRAN.c + E1AP_DRB-To-Modify-List-NG-RAN.c + E1AP_DRB-To-Remove-Item-EUTRAN.c + E1AP_DRB-To-Remove-Item-NG-RAN.c + E1AP_DRB-To-Remove-List-EUTRAN.c + E1AP_DRB-To-Remove-List-NG-RAN.c + E1AP_DRB-To-Setup-Item-EUTRAN.c + E1AP_DRB-To-Setup-Item-NG-RAN.c + E1AP_DRB-To-Setup-List-EUTRAN.c + E1AP_DRB-To-Setup-List-NG-RAN.c + E1AP_DRB-To-Setup-Mod-Item-EUTRAN.c + E1AP_DRB-To-Setup-Mod-Item-NG-RAN.c + E1AP_DRB-To-Setup-Mod-List-EUTRAN.c + E1AP_DRB-To-Setup-Mod-List-NG-RAN.c + E1AP_DRB-Usage-Report-Item.c + E1AP_DRB-Usage-Report-List.c + E1AP_Duplication-Activation.c + E1AP_Dynamic5QIDescriptor.c + E1AP_E1AP-PDU.c + E1AP_E1ReleaseRequest.c + E1AP_E1ReleaseResponse.c + E1AP_EarlyDataForwardingIndicator.c + E1AP_EarlyForwardingCOUNTInfo.c + E1AP_EarlyForwardingCOUNTReq.c + E1AP_EarlyForwardingSNTransfer.c + E1AP_EHC-Common-Parameters.c + E1AP_EHC-Downlink-Parameters.c + E1AP_EHC-Parameters.c + E1AP_EHC-Uplink-Parameters.c + E1AP_EncryptionKey.c + E1AP_Endpoint-IP-address-and-port.c + E1AP_ErrorIndication.c + E1AP_EUTRANAllocationAndRetentionPriority.c + E1AP_EUTRAN-QoS.c + E1AP_EUTRAN-QoS-Support-Item.c + E1AP_EUTRAN-QoS-Support-List.c + E1AP_Extended-GNB-CU-CP-Name.c + E1AP_Extended-GNB-CU-UP-Name.c + E1AP_Extended-NR-CGI-Support-Item.c + E1AP_Extended-NR-CGI-Support-List.c + E1AP_ExtendedPacketDelayBudget.c + E1AP_ExtendedSliceSupportList.c + E1AP_FirstDLCount.c + E1AP_GBR-QoSFlowInformation.c + E1AP_GBR-QosInformation.c + E1AP_GNB-CU-CP-ConfigurationUpdateAcknowledge.c + E1AP_GNB-CU-CP-ConfigurationUpdate.c + E1AP_GNB-CU-CP-ConfigurationUpdateFailure.c + E1AP_GNB-CU-CP-E1SetupFailure.c + E1AP_GNB-CU-CP-E1SetupRequest.c + E1AP_GNB-CU-CP-E1SetupResponse.c + E1AP_GNB-CU-CPMeasurementResultsInformation.c + E1AP_GNB-CU-CP-Name.c + E1AP_GNB-CU-CP-NameUTF8String.c + E1AP_GNB-CU-CP-NameVisibleString.c + E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-Item.c + E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-List.c + E1AP_GNB-CU-CP-TNLA-Setup-Item.c + E1AP_GNB-CU-CP-TNLA-Setup-List.c + E1AP_GNB-CU-CP-TNLA-To-Add-Item.c + E1AP_GNB-CU-CP-TNLA-To-Add-List.c + E1AP_GNB-CU-CP-TNLA-To-Remove-Item.c + E1AP_GNB-CU-CP-TNLA-To-Remove-List.c + E1AP_GNB-CU-CP-TNLA-To-Update-Item.c + E1AP_GNB-CU-CP-TNLA-To-Update-List.c + E1AP_GNB-CU-CP-UE-E1AP-ID.c + E1AP_GNB-CU-UP-Capacity.c + E1AP_GNB-CU-UP-CellGroupRelatedConfiguration.c + E1AP_GNB-CU-UP-CellGroupRelatedConfiguration-Item.c + E1AP_GNB-CU-UP-ConfigurationUpdateAcknowledge.c + E1AP_GNB-CU-UP-ConfigurationUpdate.c + E1AP_GNB-CU-UP-ConfigurationUpdateFailure.c + E1AP_GNB-CU-UP-CounterCheckRequest.c + E1AP_GNB-CU-UP-E1SetupFailure.c + E1AP_GNB-CU-UP-E1SetupRequest.c + E1AP_GNB-CU-UP-E1SetupResponse.c + E1AP_GNB-CU-UP-ID.c + E1AP_GNB-CU-UP-Name.c + E1AP_GNB-CU-UP-NameUTF8String.c + E1AP_GNB-CU-UP-NameVisibleString.c + E1AP_GNB-CU-UP-OverloadInformation.c + E1AP_GNB-CU-UP-StatusIndication.c + E1AP_GNB-CU-UP-TNLA-To-Remove-Item.c + E1AP_GNB-CU-UP-TNLA-To-Remove-List.c + E1AP_GNB-CU-UP-UE-E1AP-ID.c + E1AP_GNB-DU-ID.c + E1AP_GTP-TEID.c + E1AP_GTPTLA-Item.c + E1AP_GTPTLAs.c + E1AP_GTPTunnel.c + E1AP_HFN.c + E1AP_HW-CapacityIndicator.c + E1AP_IAB-UPTNLAddressUpdateAcknowledge.c + E1AP_IAB-UPTNLAddressUpdate.c + E1AP_IAB-UPTNLAddressUpdateFailure.c + E1AP_IgnoreMappingRuleIndication.c + E1AP_ImmediateMDT.c + E1AP_Inactivity-Timer.c + E1AP_InitiatingMessage.c + E1AP_IntegrityProtectionAlgorithm.c + E1AP_IntegrityProtectionIndication.c + E1AP_IntegrityProtectionKey.c + E1AP_IntegrityProtectionResult.c + E1AP_InterfacesToTrace.c + E1AP_Links-to-log.c + E1AP_M4Configuration.c + E1AP_M4period.c + E1AP_M6Configuration.c + E1AP_M6report-Interval.c + E1AP_M7Configuration.c + E1AP_M7period.c + E1AP_MaxCIDEHCDL.c + E1AP_MaxDataBurstVolume.c + E1AP_MaximumIPdatarate.c + E1AP_MaxIPrate.c + E1AP_MaxPacketLossRate.c + E1AP_MDT-Activation.c + E1AP_MDT-Configuration.c + E1AP_MDTMode.c + E1AP_MDTPLMNList.c + E1AP_MeasurementsToActivate.c + E1AP_MRDC-DataUsageReport.c + E1AP_MRDC-Data-Usage-Report-Item.c + E1AP_MRDC-Usage-Information.c + E1AP_NetworkInstance.c + E1AP_New-UL-TNL-Information-Required.c + E1AP_NGRANAllocationAndRetentionPriority.c + E1AP_NG-RAN-QoS-Support-Item.c + E1AP_NG-RAN-QoS-Support-List.c + E1AP_NID.c + E1AP_Non-Dynamic5QIDescriptor.c + E1AP_NPNContextInfo.c + E1AP_NPNContextInfo-SNPN.c + E1AP_NPNSupportInfo.c + E1AP_NPNSupportInfo-SNPN.c + E1AP_NR-Cell-Identity.c + E1AP_NR-CGI.c + E1AP_NR-CGI-Support-Item.c + E1AP_NR-CGI-Support-List.c + E1AP_Number-of-tunnels.c + E1AP_OutOfOrderDelivery.c + E1AP_PacketDelayBudget.c + E1AP_PacketErrorRate.c + E1AP_PDCP-Configuration.c + E1AP_PDCP-Count.c + E1AP_PDCP-DataRecovery.c + E1AP_PDCP-Duplication.c + E1AP_PDCP-Reestablishment.c + E1AP_PDCP-SN.c + E1AP_PDCP-SN-Size.c + E1AP_PDCP-SN-Status-Information.c + E1AP_PDCP-SN-Status-Request.c + E1AP_PDCP-StatusReportIndication.c + E1AP_PDU-Session-ID.c + E1AP_PDU-Session-Resource-Activity.c + E1AP_PDU-Session-Resource-Activity-Item.c + E1AP_PDU-Session-Resource-Activity-List.c + E1AP_PDU-Session-Resource-Confirm-Modified-Item.c + E1AP_PDU-Session-Resource-Confirm-Modified-List.c + E1AP_PDU-Session-Resource-Data-Usage-Item.c + E1AP_PDU-Session-Resource-Data-Usage-List.c + E1AP_PDU-Session-Resource-Failed-Item.c + E1AP_PDU-Session-Resource-Failed-List.c + E1AP_PDU-Session-Resource-Failed-Mod-Item.c + E1AP_PDU-Session-Resource-Failed-Mod-List.c + E1AP_PDU-Session-Resource-Failed-To-Modify-Item.c + E1AP_PDU-Session-Resource-Failed-To-Modify-List.c + E1AP_PDU-Session-Resource-Modified-Item.c + E1AP_PDU-Session-Resource-Modified-List.c + E1AP_PDU-Session-Resource-Required-To-Modify-Item.c + E1AP_PDU-Session-Resource-Required-To-Modify-List.c + E1AP_PDU-Session-Resource-Setup-Item.c + E1AP_PDU-Session-Resource-Setup-List.c + E1AP_PDU-Session-Resource-Setup-Mod-Item.c + E1AP_PDU-Session-Resource-Setup-Mod-List.c + E1AP_PDU-Session-Resource-To-Modify-Item.c + E1AP_PDU-Session-Resource-To-Modify-List.c + E1AP_PDU-Session-Resource-To-Remove-Item.c + E1AP_PDU-Session-Resource-To-Remove-List.c + E1AP_PDU-Session-Resource-To-Setup-Item.c + E1AP_PDU-Session-Resource-To-Setup-List.c + E1AP_PDU-Session-Resource-To-Setup-Mod-Item.c + E1AP_PDU-Session-Resource-To-Setup-Mod-List.c + E1AP_PDU-Session-To-Notify-Item.c + E1AP_PDU-Session-To-Notify-List.c + E1AP_PDU-Session-Type.c + E1AP_PER-Exponent.c + E1AP_Periodicity.c + E1AP_PER-Scalar.c + E1AP_PLMN-Identity.c + E1AP_PortNumber.c + E1AP_PPI.c + E1AP_Pre-emptionCapability.c + E1AP_Pre-emptionVulnerability.c + E1AP_Presence.c + E1AP_PriorityLevel.c + E1AP_PrivacyIndicator.c + E1AP_PrivateIE-Container.c + E1AP_PrivateIE-Field.c + E1AP_PrivateIE-ID.c + E1AP_PrivateMessage.c + E1AP_ProcedureCode.c + E1AP_ProtocolExtensionContainer.c + E1AP_ProtocolExtensionField.c + E1AP_ProtocolExtensionID.c + E1AP_ProtocolIE-Container.c + E1AP_ProtocolIE-ContainerList.c + E1AP_ProtocolIE-Field.c + E1AP_ProtocolIE-ID.c + E1AP_ProtocolIE-SingleContainer.c + E1AP_QCI.c + E1AP_QoS-Characteristics.c + E1AP_QoS-Flow-Failed-Item.c + E1AP_QoS-Flow-Failed-List.c + E1AP_QoS-Flow-Identifier.c + E1AP_QoS-Flow-Item.c + E1AP_QoSFlowLevelQoSParameters.c + E1AP_QoS-Flow-List.c + E1AP_QoS-Flow-Mapping-Indication.c + E1AP_QoS-Flow-Mapping-Item.c + E1AP_QoS-Flow-Mapping-List.c + E1AP_QoS-Flow-QoS-Parameter-Item.c + E1AP_QoS-Flow-QoS-Parameter-List.c + E1AP_QoS-Flow-Removed-Item.c + E1AP_QoS-Flows-DRB-Remapping.c + E1AP_QoS-Flows-to-be-forwarded-Item.c + E1AP_QoS-Flows-to-be-forwarded-List.c + E1AP_QoS-Mapping-Information.c + E1AP_QosMonitoringDisabled.c + E1AP_QosMonitoringReportingFrequency.c + E1AP_QosMonitoringRequest.c + E1AP_QoS-Parameters-Support-List.c + E1AP_QoSPriorityLevel.c + E1AP_RANUEID.c + E1AP_RAT-Type.c + E1AP_RedundantPDUSessionInformation.c + E1AP_RedundantQoSFlowIndicator.c + E1AP_RegistrationRequest.c + E1AP_ReportCharacteristics.c + E1AP_ReportingPeriodicity.c + E1AP_ResetAcknowledge.c + E1AP_ResetAll.c + E1AP_Reset.c + E1AP_ResetType.c + E1AP_ResourceStatusFailure.c + E1AP_ResourceStatusRequest.c + E1AP_ResourceStatusResponse.c + E1AP_ResourceStatusUpdate.c + E1AP_RetainabilityMeasurementsInfo.c + E1AP_RLC-Mode.c + E1AP_ROHC.c + E1AP_ROHC-Parameters.c + E1AP_RSN.c + E1AP_SDAP-Configuration.c + E1AP_SDAP-Header-DL.c + E1AP_SDAP-Header-UL.c + E1AP_SecurityAlgorithm.c + E1AP_SecurityIndication.c + E1AP_SecurityInformation.c + E1AP_SecurityResult.c + E1AP_Slice-Support-Item.c + E1AP_Slice-Support-List.c + E1AP_SNSSAI.c + E1AP_SubscriberProfileIDforRFP.c + E1AP_SuccessfulOutcome.c + E1AP_SupportedPLMNs-Item.c + E1AP_SupportedPLMNs-List.c + E1AP_System-BearerContextModificationConfirm.c + E1AP_System-BearerContextModificationRequest.c + E1AP_System-BearerContextModificationRequired.c + E1AP_System-BearerContextModificationResponse.c + E1AP_System-BearerContextSetupRequest.c + E1AP_System-BearerContextSetupResponse.c + E1AP_System-GNB-CU-UP-CounterCheckRequest.c + E1AP_TimeToWait.c + E1AP_TNLAssociationUsage.c + E1AP_TNL-AvailableCapacityIndicator.c + E1AP_TraceActivation.c + E1AP_TraceDepth.c + E1AP_TraceID.c + E1AP_TraceStart.c + E1AP_TransactionID.c + E1AP_TransportLayerAddress.c + E1AP_Transport-Layer-Address-Info.c + E1AP_Transport-UP-Layer-Addresses-Info-To-Add-Item.c + E1AP_Transport-UP-Layer-Addresses-Info-To-Add-List.c + E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-Item.c + E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-List.c + E1AP_T-Reordering.c + E1AP_T-ReorderingTimer.c + E1AP_TriggeringMessage.c + E1AP_TSCTrafficCharacteristics.c + E1AP_TSCTrafficInformation.c + E1AP_TypeOfError.c + E1AP_UE-Activity.c + E1AP_UE-associatedLogicalE1-ConnectionItem.c + E1AP_UE-associatedLogicalE1-ConnectionListResAck.c + E1AP_UE-associatedLogicalE1-ConnectionListRes.c + E1AP_UL-Configuration.c + E1AP_ULDataNotification.c + E1AP_ULDataSplitThreshold.c + E1AP_ULUPTNLAddressToUpdateItem.c + E1AP_ULUPTNLAddressToUpdateList.c + E1AP_UnsuccessfulOutcome.c + E1AP_UplinkOnlyROHC.c + E1AP_UP-Parameters.c + E1AP_UP-Parameters-Item.c + E1AP_UPSecuritykey.c + E1AP_UP-TNL-Information.c + E1AP_URIaddress.c + INTEGER.c + NativeEnumerated.c + NativeInteger.c + OBJECT_IDENTIFIER.c + OCTET_STRING.c + OPEN_TYPE.c + per_decoder.c + per_encoder.c + per_opentype.c + per_support.c + PrintableString.c + UTF8String.c + VisibleString.c + xer_decoder.c + xer_encoder.c + xer_support.c +) + +set(e1ap_headers + ANY.h + asn_application.h + asn_bit_data.h + asn_codecs.h + asn_codecs_prim.h + asn_internal.h + asn_ioc.h + asn_random_fill.h + asn_SEQUENCE_OF.h + asn_SET_OF.h + asn_system.h + ber_decoder.h + ber_tlv_length.h + ber_tlv_tag.h + BIT_STRING.h + constraints.h + constr_CHOICE.h + constr_SEQUENCE.h + constr_SEQUENCE_OF.h + constr_SET_OF.h + constr_TYPE.h + der_encoder.h + E1AP_ActivityInformation.h + E1AP_ActivityNotificationLevel.h + E1AP_AdditionalHandoverInfo.h + E1AP_AdditionalPDCPduplicationInformation.h + E1AP_AdditionalRRMPriorityIndex.h + E1AP_AlternativeQoSParaSetItem.h + E1AP_AlternativeQoSParaSetList.h + E1AP_asn_constant.h + E1AP_AveragingWindow.h + E1AP_BearerContextInactivityNotification.h + E1AP_BearerContextModificationConfirm.h + E1AP_BearerContextModificationFailure.h + E1AP_BearerContextModificationRequest.h + E1AP_BearerContextModificationRequired.h + E1AP_BearerContextModificationResponse.h + E1AP_BearerContextReleaseCommand.h + E1AP_BearerContextReleaseComplete.h + E1AP_BearerContextReleaseRequest.h + E1AP_BearerContextSetupFailure.h + E1AP_BearerContextSetupRequest.h + E1AP_BearerContextSetupResponse.h + E1AP_BearerContextStatusChange.h + E1AP_BitRate.h + E1AP_BurstArrivalTime.h + E1AP_Cause.h + E1AP_CauseMisc.h + E1AP_CauseProtocol.h + E1AP_CauseRadioNetwork.h + E1AP_CauseTransport.h + E1AP_Cell-Group-ID.h + E1AP_Cell-Group-Information.h + E1AP_Cell-Group-Information-Item.h + E1AP_CellTrafficTrace.h + E1AP_CHOInitiation.h + E1AP_CipheringAlgorithm.h + E1AP_CNSupport.h + E1AP_CommonNetworkInstance.h + E1AP_ConfidentialityProtectionIndication.h + E1AP_ConfidentialityProtectionResult.h + E1AP_CP-TNL-Information.h + E1AP_CriticalityDiagnostics.h + E1AP_CriticalityDiagnostics-IE-List.h + E1AP_Criticality.h + E1AP_DAPSRequestInfo.h + E1AP_DataDiscardRequired.h + E1AP_Data-Forwarding-Information.h + E1AP_Data-Forwarding-Information-Request.h + E1AP_Data-Forwarding-Request.h + E1AP_DataForwardingtoE-UTRANInformationList.h + E1AP_DataForwardingtoE-UTRANInformationListItem.h + E1AP_DataForwardingtoNG-RANQoSFlowInformationList.h + E1AP_DataForwardingtoNG-RANQoSFlowInformationList-Item.h + E1AP_Data-Usage-per-PDU-Session-Report.h + E1AP_Data-Usage-per-QoS-Flow-Item.h + E1AP_Data-Usage-per-QoS-Flow-List.h + E1AP_DataUsageReport.h + E1AP_Data-Usage-Report-Item.h + E1AP_Data-Usage-Report-List.h + E1AP_DeactivateTrace.h + E1AP_DefaultDRB.h + E1AP_DirectForwardingPathAvailability.h + E1AP_DiscardTimer.h + E1AP_DLDataNotification.h + E1AP_DLDiscarding.h + E1AP_DL-TX-Stop.h + E1AP_DLUPTNLAddressToUpdateItem.h + E1AP_DLUPTNLAddressToUpdateList.h + E1AP_DRB-Activity.h + E1AP_DRB-Activity-Item.h + E1AP_DRB-Activity-List.h + E1AP_DRBBStatusTransfer.h + E1AP_DRB-Confirm-Modified-Item-EUTRAN.h + E1AP_DRB-Confirm-Modified-Item-NG-RAN.h + E1AP_DRB-Confirm-Modified-List-EUTRAN.h + E1AP_DRB-Confirm-Modified-List-NG-RAN.h + E1AP_DRB-Failed-Item-EUTRAN.h + E1AP_DRB-Failed-Item-NG-RAN.h + E1AP_DRB-Failed-List-EUTRAN.h + E1AP_DRB-Failed-List-NG-RAN.h + E1AP_DRB-Failed-Mod-Item-EUTRAN.h + E1AP_DRB-Failed-Mod-Item-NG-RAN.h + E1AP_DRB-Failed-Mod-List-EUTRAN.h + E1AP_DRB-Failed-Mod-List-NG-RAN.h + E1AP_DRB-Failed-To-Modify-Item-EUTRAN.h + E1AP_DRB-Failed-To-Modify-Item-NG-RAN.h + E1AP_DRB-Failed-To-Modify-List-EUTRAN.h + E1AP_DRB-Failed-To-Modify-List-NG-RAN.h + E1AP_DRB-ID.h + E1AP_DRB-Measurement-Results-Information-Item.h + E1AP_DRB-Measurement-Results-Information-List.h + E1AP_DRB-Modified-Item-EUTRAN.h + E1AP_DRB-Modified-Item-NG-RAN.h + E1AP_DRB-Modified-List-EUTRAN.h + E1AP_DRB-Modified-List-NG-RAN.h + E1AP_DRB-Removed-Item.h + E1AP_DRB-Required-To-Modify-Item-EUTRAN.h + E1AP_DRB-Required-To-Modify-Item-NG-RAN.h + E1AP_DRB-Required-To-Modify-List-EUTRAN.h + E1AP_DRB-Required-To-Modify-List-NG-RAN.h + E1AP_DRB-Required-To-Remove-Item-EUTRAN.h + E1AP_DRB-Required-To-Remove-Item-NG-RAN.h + E1AP_DRB-Required-To-Remove-List-EUTRAN.h + E1AP_DRB-Required-To-Remove-List-NG-RAN.h + E1AP_DRB-Setup-Item-EUTRAN.h + E1AP_DRB-Setup-Item-NG-RAN.h + E1AP_DRB-Setup-List-EUTRAN.h + E1AP_DRB-Setup-List-NG-RAN.h + E1AP_DRB-Setup-Mod-Item-EUTRAN.h + E1AP_DRB-Setup-Mod-Item-NG-RAN.h + E1AP_DRB-Setup-Mod-List-EUTRAN.h + E1AP_DRB-Setup-Mod-List-NG-RAN.h + E1AP_DRBs-Subject-To-Counter-Check-Item-EUTRAN.h + E1AP_DRBs-Subject-To-Counter-Check-Item-NG-RAN.h + E1AP_DRBs-Subject-To-Counter-Check-List-EUTRAN.h + E1AP_DRBs-Subject-To-Counter-Check-List-NG-RAN.h + E1AP_DRBs-Subject-To-Early-Forwarding-Item.h + E1AP_DRBs-Subject-To-Early-Forwarding-List.h + E1AP_DRB-Status-Item.h + E1AP_DRB-Status-List.h + E1AP_DRB-To-Modify-Item-EUTRAN.h + E1AP_DRB-To-Modify-Item-NG-RAN.h + E1AP_DRB-To-Modify-List-EUTRAN.h + E1AP_DRB-To-Modify-List-NG-RAN.h + E1AP_DRB-To-Remove-Item-EUTRAN.h + E1AP_DRB-To-Remove-Item-NG-RAN.h + E1AP_DRB-To-Remove-List-EUTRAN.h + E1AP_DRB-To-Remove-List-NG-RAN.h + E1AP_DRB-To-Setup-Item-EUTRAN.h + E1AP_DRB-To-Setup-Item-NG-RAN.h + E1AP_DRB-To-Setup-List-EUTRAN.h + E1AP_DRB-To-Setup-List-NG-RAN.h + E1AP_DRB-To-Setup-Mod-Item-EUTRAN.h + E1AP_DRB-To-Setup-Mod-Item-NG-RAN.h + E1AP_DRB-To-Setup-Mod-List-EUTRAN.h + E1AP_DRB-To-Setup-Mod-List-NG-RAN.h + E1AP_DRB-Usage-Report-Item.h + E1AP_DRB-Usage-Report-List.h + E1AP_Duplication-Activation.h + E1AP_Dynamic5QIDescriptor.h + E1AP_E1AP-PDU.h + E1AP_E1ReleaseRequest.h + E1AP_E1ReleaseResponse.h + E1AP_EarlyDataForwardingIndicator.h + E1AP_EarlyForwardingCOUNTInfo.h + E1AP_EarlyForwardingCOUNTReq.h + E1AP_EarlyForwardingSNTransfer.h + E1AP_EHC-Common-Parameters.h + E1AP_EHC-Downlink-Parameters.h + E1AP_EHC-Parameters.h + E1AP_EHC-Uplink-Parameters.h + E1AP_EncryptionKey.h + E1AP_Endpoint-IP-address-and-port.h + E1AP_ErrorIndication.h + E1AP_EUTRANAllocationAndRetentionPriority.h + E1AP_EUTRAN-QoS.h + E1AP_EUTRAN-QoS-Support-Item.h + E1AP_EUTRAN-QoS-Support-List.h + E1AP_Extended-GNB-CU-CP-Name.h + E1AP_Extended-GNB-CU-UP-Name.h + E1AP_Extended-NR-CGI-Support-Item.h + E1AP_Extended-NR-CGI-Support-List.h + E1AP_ExtendedPacketDelayBudget.h + E1AP_ExtendedSliceSupportList.h + E1AP_FirstDLCount.h + E1AP_GBR-QoSFlowInformation.h + E1AP_GBR-QosInformation.h + E1AP_GNB-CU-CP-ConfigurationUpdateAcknowledge.h + E1AP_GNB-CU-CP-ConfigurationUpdateFailure.h + E1AP_GNB-CU-CP-ConfigurationUpdate.h + E1AP_GNB-CU-CP-E1SetupFailure.h + E1AP_GNB-CU-CP-E1SetupRequest.h + E1AP_GNB-CU-CP-E1SetupResponse.h + E1AP_GNB-CU-CPMeasurementResultsInformation.h + E1AP_GNB-CU-CP-Name.h + E1AP_GNB-CU-CP-NameUTF8String.h + E1AP_GNB-CU-CP-NameVisibleString.h + E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-Item.h + E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-List.h + E1AP_GNB-CU-CP-TNLA-Setup-Item.h + E1AP_GNB-CU-CP-TNLA-Setup-List.h + E1AP_GNB-CU-CP-TNLA-To-Add-Item.h + E1AP_GNB-CU-CP-TNLA-To-Add-List.h + E1AP_GNB-CU-CP-TNLA-To-Remove-Item.h + E1AP_GNB-CU-CP-TNLA-To-Remove-List.h + E1AP_GNB-CU-CP-TNLA-To-Update-Item.h + E1AP_GNB-CU-CP-TNLA-To-Update-List.h + E1AP_GNB-CU-CP-UE-E1AP-ID.h + E1AP_GNB-CU-UP-Capacity.h + E1AP_GNB-CU-UP-CellGroupRelatedConfiguration.h + E1AP_GNB-CU-UP-CellGroupRelatedConfiguration-Item.h + E1AP_GNB-CU-UP-ConfigurationUpdateAcknowledge.h + E1AP_GNB-CU-UP-ConfigurationUpdateFailure.h + E1AP_GNB-CU-UP-ConfigurationUpdate.h + E1AP_GNB-CU-UP-CounterCheckRequest.h + E1AP_GNB-CU-UP-E1SetupFailure.h + E1AP_GNB-CU-UP-E1SetupRequest.h + E1AP_GNB-CU-UP-E1SetupResponse.h + E1AP_GNB-CU-UP-ID.h + E1AP_GNB-CU-UP-Name.h + E1AP_GNB-CU-UP-NameUTF8String.h + E1AP_GNB-CU-UP-NameVisibleString.h + E1AP_GNB-CU-UP-OverloadInformation.h + E1AP_GNB-CU-UP-StatusIndication.h + E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h + E1AP_GNB-CU-UP-TNLA-To-Remove-List.h + E1AP_GNB-CU-UP-UE-E1AP-ID.h + E1AP_GNB-DU-ID.h + E1AP_GTP-TEID.h + E1AP_GTPTLA-Item.h + E1AP_GTPTLAs.h + E1AP_GTPTunnel.h + E1AP_HFN.h + E1AP_HW-CapacityIndicator.h + E1AP_IAB-UPTNLAddressUpdateAcknowledge.h + E1AP_IAB-UPTNLAddressUpdateFailure.h + E1AP_IAB-UPTNLAddressUpdate.h + E1AP_IgnoreMappingRuleIndication.h + E1AP_ImmediateMDT.h + E1AP_Inactivity-Timer.h + E1AP_InitiatingMessage.h + E1AP_IntegrityProtectionAlgorithm.h + E1AP_IntegrityProtectionIndication.h + E1AP_IntegrityProtectionKey.h + E1AP_IntegrityProtectionResult.h + E1AP_InterfacesToTrace.h + E1AP_Links-to-log.h + E1AP_M4Configuration.h + E1AP_M4period.h + E1AP_M6Configuration.h + E1AP_M6report-Interval.h + E1AP_M7Configuration.h + E1AP_M7period.h + E1AP_MaxCIDEHCDL.h + E1AP_MaxDataBurstVolume.h + E1AP_MaximumIPdatarate.h + E1AP_MaxIPrate.h + E1AP_MaxPacketLossRate.h + E1AP_MDT-Activation.h + E1AP_MDT-Configuration.h + E1AP_MDTMode.h + E1AP_MDTPLMNList.h + E1AP_MeasurementsToActivate.h + E1AP_MRDC-DataUsageReport.h + E1AP_MRDC-Data-Usage-Report-Item.h + E1AP_MRDC-Usage-Information.h + E1AP_NetworkInstance.h + E1AP_New-UL-TNL-Information-Required.h + E1AP_NGRANAllocationAndRetentionPriority.h + E1AP_NG-RAN-QoS-Support-Item.h + E1AP_NG-RAN-QoS-Support-List.h + E1AP_NID.h + E1AP_Non-Dynamic5QIDescriptor.h + E1AP_NPNContextInfo.h + E1AP_NPNContextInfo-SNPN.h + E1AP_NPNSupportInfo.h + E1AP_NPNSupportInfo-SNPN.h + E1AP_NR-Cell-Identity.h + E1AP_NR-CGI.h + E1AP_NR-CGI-Support-Item.h + E1AP_NR-CGI-Support-List.h + E1AP_Number-of-tunnels.h + E1AP_OutOfOrderDelivery.h + E1AP_PacketDelayBudget.h + E1AP_PacketErrorRate.h + E1AP_PDCP-Configuration.h + E1AP_PDCP-Count.h + E1AP_PDCP-DataRecovery.h + E1AP_PDCP-Duplication.h + E1AP_PDCP-Reestablishment.h + E1AP_PDCP-SN.h + E1AP_PDCP-SN-Size.h + E1AP_PDCP-SN-Status-Information.h + E1AP_PDCP-SN-Status-Request.h + E1AP_PDCP-StatusReportIndication.h + E1AP_PDU-Session-ID.h + E1AP_PDU-Session-Resource-Activity.h + E1AP_PDU-Session-Resource-Activity-Item.h + E1AP_PDU-Session-Resource-Activity-List.h + E1AP_PDU-Session-Resource-Confirm-Modified-Item.h + E1AP_PDU-Session-Resource-Confirm-Modified-List.h + E1AP_PDU-Session-Resource-Data-Usage-Item.h + E1AP_PDU-Session-Resource-Data-Usage-List.h + E1AP_PDU-Session-Resource-Failed-Item.h + E1AP_PDU-Session-Resource-Failed-List.h + E1AP_PDU-Session-Resource-Failed-Mod-Item.h + E1AP_PDU-Session-Resource-Failed-Mod-List.h + E1AP_PDU-Session-Resource-Failed-To-Modify-Item.h + E1AP_PDU-Session-Resource-Failed-To-Modify-List.h + E1AP_PDU-Session-Resource-Modified-Item.h + E1AP_PDU-Session-Resource-Modified-List.h + E1AP_PDU-Session-Resource-Required-To-Modify-Item.h + E1AP_PDU-Session-Resource-Required-To-Modify-List.h + E1AP_PDU-Session-Resource-Setup-Item.h + E1AP_PDU-Session-Resource-Setup-List.h + E1AP_PDU-Session-Resource-Setup-Mod-Item.h + E1AP_PDU-Session-Resource-Setup-Mod-List.h + E1AP_PDU-Session-Resource-To-Modify-Item.h + E1AP_PDU-Session-Resource-To-Modify-List.h + E1AP_PDU-Session-Resource-To-Remove-Item.h + E1AP_PDU-Session-Resource-To-Remove-List.h + E1AP_PDU-Session-Resource-To-Setup-Item.h + E1AP_PDU-Session-Resource-To-Setup-List.h + E1AP_PDU-Session-Resource-To-Setup-Mod-Item.h + E1AP_PDU-Session-Resource-To-Setup-Mod-List.h + E1AP_PDU-Session-To-Notify-Item.h + E1AP_PDU-Session-To-Notify-List.h + E1AP_PDU-Session-Type.h + E1AP_PER-Exponent.h + E1AP_Periodicity.h + E1AP_PER-Scalar.h + E1AP_PLMN-Identity.h + E1AP_PortNumber.h + E1AP_PPI.h + E1AP_Pre-emptionCapability.h + E1AP_Pre-emptionVulnerability.h + E1AP_Presence.h + E1AP_PriorityLevel.h + E1AP_PrivacyIndicator.h + E1AP_PrivateIE-Container.h + E1AP_PrivateIE-Field.h + E1AP_PrivateIE-ID.h + E1AP_PrivateMessage.h + E1AP_ProcedureCode.h + E1AP_ProtocolExtensionContainer.h + E1AP_ProtocolExtensionField.h + E1AP_ProtocolExtensionID.h + E1AP_ProtocolIE-Container.h + E1AP_ProtocolIE-ContainerList.h + E1AP_ProtocolIE-Field.h + E1AP_ProtocolIE-ID.h + E1AP_ProtocolIE-SingleContainer.h + E1AP_QCI.h + E1AP_QoS-Characteristics.h + E1AP_QoS-Flow-Failed-Item.h + E1AP_QoS-Flow-Failed-List.h + E1AP_QoS-Flow-Identifier.h + E1AP_QoS-Flow-Item.h + E1AP_QoSFlowLevelQoSParameters.h + E1AP_QoS-Flow-List.h + E1AP_QoS-Flow-Mapping-Indication.h + E1AP_QoS-Flow-Mapping-Item.h + E1AP_QoS-Flow-Mapping-List.h + E1AP_QoS-Flow-QoS-Parameter-Item.h + E1AP_QoS-Flow-QoS-Parameter-List.h + E1AP_QoS-Flow-Removed-Item.h + E1AP_QoS-Flows-DRB-Remapping.h + E1AP_QoS-Flows-to-be-forwarded-Item.h + E1AP_QoS-Flows-to-be-forwarded-List.h + E1AP_QoS-Mapping-Information.h + E1AP_QosMonitoringDisabled.h + E1AP_QosMonitoringReportingFrequency.h + E1AP_QosMonitoringRequest.h + E1AP_QoS-Parameters-Support-List.h + E1AP_QoSPriorityLevel.h + E1AP_RANUEID.h + E1AP_RAT-Type.h + E1AP_RedundantPDUSessionInformation.h + E1AP_RedundantQoSFlowIndicator.h + E1AP_RegistrationRequest.h + E1AP_ReportCharacteristics.h + E1AP_ReportingPeriodicity.h + E1AP_ResetAcknowledge.h + E1AP_ResetAll.h + E1AP_Reset.h + E1AP_ResetType.h + E1AP_ResourceStatusFailure.h + E1AP_ResourceStatusRequest.h + E1AP_ResourceStatusResponse.h + E1AP_ResourceStatusUpdate.h + E1AP_RetainabilityMeasurementsInfo.h + E1AP_RLC-Mode.h + E1AP_ROHC.h + E1AP_ROHC-Parameters.h + E1AP_RSN.h + E1AP_SDAP-Configuration.h + E1AP_SDAP-Header-DL.h + E1AP_SDAP-Header-UL.h + E1AP_SecurityAlgorithm.h + E1AP_SecurityIndication.h + E1AP_SecurityInformation.h + E1AP_SecurityResult.h + E1AP_Slice-Support-Item.h + E1AP_Slice-Support-List.h + E1AP_SNSSAI.h + E1AP_SubscriberProfileIDforRFP.h + E1AP_SuccessfulOutcome.h + E1AP_SupportedPLMNs-Item.h + E1AP_SupportedPLMNs-List.h + E1AP_System-BearerContextModificationConfirm.h + E1AP_System-BearerContextModificationRequest.h + E1AP_System-BearerContextModificationRequired.h + E1AP_System-BearerContextModificationResponse.h + E1AP_System-BearerContextSetupRequest.h + E1AP_System-BearerContextSetupResponse.h + E1AP_System-GNB-CU-UP-CounterCheckRequest.h + E1AP_TimeToWait.h + E1AP_TNLAssociationUsage.h + E1AP_TNL-AvailableCapacityIndicator.h + E1AP_TraceActivation.h + E1AP_TraceDepth.h + E1AP_TraceID.h + E1AP_TraceStart.h + E1AP_TransactionID.h + E1AP_TransportLayerAddress.h + E1AP_Transport-Layer-Address-Info.h + E1AP_Transport-UP-Layer-Addresses-Info-To-Add-Item.h + E1AP_Transport-UP-Layer-Addresses-Info-To-Add-List.h + E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-Item.h + E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-List.h + E1AP_T-Reordering.h + E1AP_T-ReorderingTimer.h + E1AP_TriggeringMessage.h + E1AP_TSCTrafficCharacteristics.h + E1AP_TSCTrafficInformation.h + E1AP_TypeOfError.h + E1AP_UE-Activity.h + E1AP_UE-associatedLogicalE1-ConnectionItem.h + E1AP_UE-associatedLogicalE1-ConnectionListResAck.h + E1AP_UE-associatedLogicalE1-ConnectionListRes.h + E1AP_UL-Configuration.h + E1AP_ULDataNotification.h + E1AP_ULDataSplitThreshold.h + E1AP_ULUPTNLAddressToUpdateItem.h + E1AP_ULUPTNLAddressToUpdateList.h + E1AP_UnsuccessfulOutcome.h + E1AP_UplinkOnlyROHC.h + E1AP_UP-Parameters.h + E1AP_UP-Parameters-Item.h + E1AP_UPSecuritykey.h + E1AP_UP-TNL-Information.h + E1AP_URIaddress.h + INTEGER.h + NativeEnumerated.h + NativeInteger.h + OBJECT_IDENTIFIER.h + OCTET_STRING.h + OPEN_TYPE.h + per_decoder.h + per_encoder.h + per_opentype.h + per_support.h + PrintableString.h + UTF8String.h + VisibleString.h + xer_decoder.h + xer_encoder.h + xer_support.h +) diff --git a/openair2/E1AP/MESSAGES/CMakeLists.txt b/openair2/E1AP/MESSAGES/CMakeLists.txt new file mode 100644 index 0000000000..a69e703c80 --- /dev/null +++ b/openair2/E1AP/MESSAGES/CMakeLists.txt @@ -0,0 +1,20 @@ +set(E1AP_VERSION 16 78 0) +make_version(E1AP_cc ${E1AP_VERSION}) +#add_definitions(-DE1AP_VERSION=${E1AP_cc}) +string(REPLACE ";" "." E1AP_RELEASE "${E1AP_VERSION}") + +if(E1AP_RELEASE VERSION_EQUAL "16.78.0") + include(ASN.1/38463-g80.R16.78.0.cmake) +else() + message(FATAL_ERROR "unknown E1AP_RELEASE ${E1AP_RELEASE}") +endif() + +add_custom_command(OUTPUT ${e1ap_source} ${e1ap_headers} + COMMAND ASN1C_PREFIX=E1AP_ asn1c -gen-PER -no-gen-OER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${E1AP_GRAMMAR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${E1AP_GRAMMAR} + COMMENT "Generating E1AP source files from ${CMAKE_CURRENT_SOURCE_DIR}/${E1AP_GRAMMAR}" +) + +add_library(asn1_e1ap ${e1ap_source}) +target_include_directories(asn1_e1ap PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") +target_compile_options(asn1_e1ap PRIVATE -DASN_DISABLE_OER_SUPPORT -w) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c new file mode 100644 index 0000000000..b49f4d4ca1 --- /dev/null +++ b/openair2/E1AP/e1ap.c @@ -0,0 +1,385 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "e1ap.h" + +int asn1_encoder_xer_print = 1; + +int e1ap_assoc_id(bool isCu, instance_t instance) { + return 0; +} + +int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) { + DevAssert(pdu != NULL); + + if (asn1_encoder_xer_print) { + LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n"); + xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu); + LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n"); + } + + char errbuf[2048]; /* Buffer for error message */ + size_t errlen = sizeof(errbuf); /* Size of the buffer */ + int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, pdu, errbuf, &errlen); + + if(ret) { + fprintf(stderr, "%s: Constraint validation failed: %s\n", func, errbuf); + } + + void *buffer = NULL; + ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, buffer); + + if (encoded < 0) { + LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func); + return -1; + } else { + MessageDef *message = itti_alloc_new_message(isCu?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ); + sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; + s->assoc_id = e1ap_assoc_id(isCu,instance); + s->buffer = buffer; + s->buffer_length = encoded; + s->stream = stream; + LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func); + itti_send_msg_to_task(TASK_SCTP, instance, message); + } + + return encoded; +} + +void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) { + MessageDef *message = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_t *sctp_close_association = &message->ittiMsg.sctp_close_association; + sctp_close_association->assoc_id = e1ap_assoc_id(isCu,instance); + itti_send_msg_to_task(TASK_SCTP, instance, message); +} + +int e1ap_send_RESET(bool isCu, instance_t instance, E1AP_Reset_t *Reset) { + AssertFatal(false,"Not implemented yet\n"); + E1AP_E1AP_PDU_t pdu= {0}; + return e1ap_encode_send(isCu, instance, &pdu,0, __func__); +} + +int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1ap_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +/* + Error Indication +*/ +int e1ap_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) { + AssertFatal(false,"Not implemented yet\n"); +} + + +/* + E1 Setup: can be sent on both ways, to be refined +*/ + +int e1apCUUP_send_SETUP_REQUEST(instance_t instance, E1AP_Reset_t *Reset) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_send_SETUP_RESPONSE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_send_SETUP_FAILURE() { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +/* + E1 configuration update: can be sent in both ways, to be refined +*/ + +int e1apCUUP_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +/* + E1 release +*/ + +int e1ap_send_RELEASE_REQUEST(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1ap_handle_RELEASE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +/* + BEARER CONTEXT SETUP REQUEST +*/ + +int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +/* + BEARER CONTEXT MODIFICATION REQUEST +*/ + +int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} +/* + BEARER CONTEXT RELEASE +*/ + +int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +/* +BEARER CONTEXT INACTIVITY NOTIFICATION + */ + +int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} +/* + DL DATA +*/ + +int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} + +int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + E1AP_E1AP_PDU_t *pdu) { + AssertFatal(false,"Not implemented yet\n"); +} diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.h b/openair2/E1AP/e1ap.h similarity index 53% rename from openair1/PHY/LTE_TRANSPORT/if5_tools.h rename to openair2/E1AP/e1ap.h index 6c75b20bd9..c7b2c24e8b 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.h +++ b/openair2/E1AP/e1ap.h @@ -9,6 +9,8 @@ * * http://www.openairinterface.org/?page_id=698 * + * Author and copyright: Laurent Thomas, open-cells.com + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,52 +21,14 @@ * contact@openairinterface.org */ -/*! \file PHY/LTE_TRANSPORT/if5_tools.h -* \brief -* \author S. Sandeep Kumar, Raymond Knopp -* \date 2016 -* \version 0.1 -* \company Eurecom -* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr -* \note -* \warning -*/ +#ifndef __E1AP_H_ +#define __E1AP_H_ -#ifndef __IF5_TOOLS_H__ -#define __IF5_TOOLS_H__ - -#include -#include "PHY/defs_eNB.h" - -#define IF5_RRH_GW_DL 0x0022 -#define IF5_RRH_GW_UL 0x0023 -#define IF5_MOBIPASS 0xbffe - -struct IF5_mobipass_header { - /// - uint16_t flags; - /// - uint16_t fifo_status; - /// - uint8_t seqno; - /// - uint8_t ack; - /// - uint32_t word0; - /// - uint32_t time_stamp; - -} __attribute__ ((__packed__)); - -typedef struct IF5_mobipass_header IF5_mobipass_header_t; -#define sizeof_IF5_mobipass_header_t 14 - -void send_IF5(RU_t *, openair0_timestamp, int, uint8_t*, uint16_t); - -void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type); - - -void malloc_IF5_buffer(RU_t *ru); +#include +#include "openairinterface5g_limits.h" +#include +#include +#include +#include #endif - diff --git a/openair2/ENB_APP/NB_IoT_config.c b/openair2/ENB_APP/NB_IoT_config.c index 26ba8989e1..617954bf3a 100644 --- a/openair2/ENB_APP/NB_IoT_config.c +++ b/openair2/ENB_APP/NB_IoT_config.c @@ -39,7 +39,7 @@ #include "SystemInformationBlockType2.h" #include "PHY/phy_extern.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "common/config/config_userapi.h" #include "RRC_config_tools.h" #include "RRC_paramsvalues.h" diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index bce15f9050..5e2ce872db 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -46,7 +46,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "PHY/phy_extern.h" #include "PHY/INIT/phy_init.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "nfapi_vnf.h" #include "nfapi_pnf.h" #include "targets/RT/USER/lte-softmodem.h" diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 50ee4341ee..8cde58a7a8 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -105,11 +105,23 @@ typedef enum { #define CONFIG_STRING_RU_NR_SCS_FOR_RASTER "nr_scs_for_raster" #define CONFIG_STRING_RU_TX_SUBDEV "tx_subdev" #define CONFIG_STRING_RU_RX_SUBDEV "rx_subdev" +#define CONFIG_STRING_RU_RXFH_CORE_ID "rxfh_core_id" +#define CONFIG_STRING_RU_TXFH_CORE_ID "txfh_core_id" +#define CONFIG_STRING_RU_TP_CORES "tp_cores" +#define CONFIG_STRING_RU_NUM_TP_CORES "num_tp_cores" +#define CONFIG_STRING_RU_NUM_INTERFACES "num_interfaces" +#define CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION "half_slot_parallelization" #define HLP_RU_SF_AHEAD "LTE TX processing advance" #define HLP_RU_SL_AHEAD "NR TX processing advance" #define HLP_RU_NR_FLAG "Use NR numerology (for AW2SORI)" #define HLP_RU_NR_SCS_FOR_RASTER "NR SCS for raster (for AW2SORI)" +#define HLP_RU_RXFH_CORE_ID "Core ID for RX Fronthaul thread (ECPRI IF5)" +#define HLP_RU_TXFH_CORE_ID "Core ID for TX Fronthaul thread (ECPRI IF5)" +#define HLP_RU_TP_CORES "List of cores for RU ThreadPool" +#define HLP_RU_NUM_TP_CORES "Number of cores for RU ThreadPool" +#define HLP_RU_NUM_INTERFACES "Number of network interfaces for RU" +#define HLP_RU_HALF_SLOT_PARALLELIZATION "run half slots in parallel in RU FEP" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -146,6 +158,12 @@ typedef enum { #define RU_NR_SCS_FOR_RASTER 32 #define RU_TX_SUBDEV 33 #define RU_RX_SUBDEV 34 +#define RU_RXFH_CORE_ID 33 +#define RU_TXFH_CORE_ID 34 +#define RU_TP_CORES 35 +#define RU_NUM_TP_CORES 36 +#define RU_NUM_INTERFACES 37 +#define RU_HALF_SLOT_PARALLELIZATION 38 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -186,6 +204,12 @@ typedef enum { {CONFIG_STRING_RU_NR_SCS_FOR_RASTER, HLP_RU_NR_SCS_FOR_RASTER, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ {CONFIG_STRING_RU_TX_SUBDEV, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_RX_SUBDEV, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_RXFH_CORE_ID, HLP_RU_RXFH_CORE_ID, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_TXFH_CORE_ID, HLP_RU_TXFH_CORE_ID, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_TP_CORES, HLP_RU_TP_CORES, 0, uptr:NULL, defintarrayval:DEFRUTPCORES, TYPE_INTARRAY, 8}, \ + {CONFIG_STRING_RU_NUM_TP_CORES, HLP_RU_NUM_TP_CORES, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_NUM_INTERFACES, HLP_RU_NUM_INTERFACES, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION, HLP_RU_HALF_SLOT_PARALLELIZATION, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index 5fab0f6dfb..62f2f43926 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -51,6 +51,7 @@ #define CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD "pucch0_dtx_threshold" #define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD "prach_dtx_threshold" #define CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD "pusch_dtx_threshold" +#define CONFIG_STRING_L1_SRS_DTX_THRESHOLD "srs_dtx_threshold" #define CONFIG_STRING_L1_MAX_LDPC_ITERATIONS "max_ldpc_iterations" /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* L1 configuration parameters */ @@ -71,6 +72,7 @@ {CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_SRS_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_MAX_LDPC_ITERATIONS, NULL, 0, uptr:NULL, defintval:5, TYPE_UINT, 0}, \ } #define L1_CC_IDX 0 @@ -87,7 +89,8 @@ #define L1_PUCCH0_DTX_THRESHOLD 11 #define L1_PRACH_DTX_THRESHOLD 12 #define L1_PUSCH_DTX_THRESHOLD 13 -#define L1_MAX_LDPC_ITERATIONS 14 +#define L1_SRS_DTX_THRESHOLD 14 +#define L1_MAX_LDPC_ITERATIONS 15 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index fe8071ad66..9263525b31 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -88,7 +88,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { { - if(NGAP_CONF_MODE){ + if(get_softmodem_params()->sa){ ngap_register_gnb_req_t *ngap_register_gNB; //Type Temporarily reuse // note: there is an implicit relationship between the data structure and the message name @@ -188,7 +188,7 @@ void *gNB_app_task(void *args_p) /* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info * can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/ - if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) { + if ((get_softmodem_params()->sa || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) { /* Try to register each gNB */ //registered_gnb = 0; __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 978331a312..ed73855373 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -34,6 +34,7 @@ #include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log_extern.h" #include "assertions.h" +#include "executables/softmodem-common.h" #include "gnb_config.h" #include "gnb_paramdef.h" #include "enb_paramdef.h" @@ -49,7 +50,7 @@ // #include "LAYER2/MAC/extern.h" // #include "LAYER2/MAC/proto.h" #include "PHY/INIT/phy_init.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "nfapi_vnf.h" #include "nfapi_pnf.h" @@ -640,7 +641,7 @@ void RCconfig_nr_flexran() /* gNB ID from configuration, as read in by RCconfig_RRC() */ if (!GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr) { // Calculate a default gNB ID - if (AMF_MODE_ENABLED) + if (get_softmodem_params()->sa) gnb_id = i + (ngap_generate_gNB_id () & 0xFFFFFF8); else gnb_id = i; @@ -826,6 +827,7 @@ void RCconfig_NR_L1(void) { RC.gNB[j]->pucch0_thres = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr); RC.gNB[j]->prach_thres = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr); RC.gNB[j]->pusch_thres = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr); + RC.gNB[j]->srs_thres = *(L1_ParamList.paramarray[j][L1_SRS_DTX_THRESHOLD].uptr); RC.gNB[j]->max_ldpc_iterations = *(L1_ParamList.paramarray[j][L1_MAX_LDPC_ITERATIONS].uptr); RC.gNB[j]->num_ulprbbl = num_prbbl; RC.gNB[j]->ap_N1 = N1; @@ -1159,24 +1161,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; AssertFatal (i0) { // Output a list of all gNBs. ////////// Identification parameters @@ -1184,7 +1168,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { if (GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr == NULL) { // Calculate a default gNB ID - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { uint32_t hash; hash = ngap_generate_gNB_id (); gnb_id = i + (hash & 0xFFFFFF8); @@ -1444,26 +1428,8 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { /* get global parameters, defined outside any section in the config file */ config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); - - /* - if (AMF_MODE_ENABLED) { - if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { - asn_debug = 0; - asn1_xer_print = 0; - } else if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) { - asn_debug = 1; - asn1_xer_print = 1; - } else if (strcasecmp(*(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr) , GNB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) { - asn_debug = 1; - asn1_xer_print = 2; - } else { - asn_debug = 0; - asn1_xer_print = 0; - } - } - */ - AssertFatal (isa) { uint32_t hash; hash = ngap_generate_gNB_id (); @@ -1631,7 +1597,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { // SCTP SETTING NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG); config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); @@ -1755,7 +1721,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { for (k = 0; k < GNBParamList.numelt; k++) { if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { // Calculate a default eNB ID - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { uint32_t hash; hash = ngap_generate_gNB_id (); gnb_id = k + (hash & 0xFFFFFF8); @@ -1898,7 +1864,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG); config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 1272b16ec0..6567500ac5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -708,12 +708,12 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint16_t msi_control_element[29], *msi_ptr; // MSI buffer pointer char *buffer_pointer=NULL; - if (msi_flag == 1) { - // Create MSI here - msi_ptr = &msi_control_element[0]; + if (msi_flag == 1 && cc->mbms_SessionList) { + // Create MSI here + msi_ptr = &msi_control_element[0]; - //Header for MTCHs - num_mtch = cc->mbms_SessionList[mbms_mch_i]->list.count; + // Header for MTCHs + num_mtch = cc->mbms_SessionList[mbms_mch_i]->list.count; TBS = get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); @@ -867,52 +867,63 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { // there is MTCHs, loop if there are more than 1 - if (mtch_flag == 1 ) { - // Calculate TBS - // get MTCH data from RLC (like for DTCH) - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", - module_idP, CC_id, frameP, subframeP, i, j); + // BAd race condition: all this struct is filled by another thread, no mutex or any code to make it coherent + if (mtch_flag == 1 && cc->mbms_SessionList && cc->mbms_SessionList[0] && cc->mbms_SessionList[0]->list.array[0]) { + // Calculate TBS + // get MTCH data from RLC (like for DTCH) + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", module_idP, CC_id, frameP, subframeP, i, j); - header_len_mtch = 3; - LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", - module_idP, CC_id, frameP, MTCH, TBS, - TBS - header_len_mcch - header_len_msi - sdu_length_total - - header_len_mtch); + header_len_mtch = 3; + LOG_D(MAC, + "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + module_idP, + CC_id, + frameP, + MTCH, + TBS, + TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch); - //TODO - mbms_rab_id = cc->mbms_SessionList[0/*mbms_mch_i*/]->list.array[0]->logicalChannelIdentity_r9; + // TODO + mbms_rab_id = cc->mbms_SessionList[0 /*mbms_mch_i*/]->list.array[0]->logicalChannelIdentity_r9; - rlc_status = - mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP, - module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, - cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9, - //MTCH, - 0, 0 - ); + rlc_status = mac_rlc_status_ind(module_idP, + 0xfffd, + frameP, + subframeP, + module_idP, + ENB_FLAG_YES, + MBMS_FLAG_YES, + cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9, + // MTCH, + 0, + 0); - bytes_in_buffer = rlc_status.bytes_in_buffer; + bytes_in_buffer = rlc_status.bytes_in_buffer; - //TOCHECK is this really neede? - if( !(mcch_flag==1 || msi_flag==1) ) - msi_sfs = rlc_status.bytes_in_buffer/(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)+(rlc_status.bytes_in_buffer%(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)?1:0); + // TOCHECK is this really neede? + if (!(mcch_flag == 1 || msi_flag == 1)) + msi_sfs = rlc_status.bytes_in_buffer / (TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch) + + (rlc_status.bytes_in_buffer % (TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch) ? 1 : 0); - uint16_t TBS_MTCH = - get_TBS_DL(cc->pmch_Config[mbms_mch_i]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth)); + uint16_t TBS_MTCH = get_TBS_DL(cc->pmch_Config[mbms_mch_i]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth)); - if(msi_flag==1 && buffer_pointer!=NULL){ - // msi_ptr = &msi_control_element[0]; + if (msi_flag == 1 && buffer_pointer != NULL) { + // msi_ptr = &msi_control_element[0]; - msi_pmch_stop = (rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0); + msi_pmch_stop = + (rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch) / (TBS_MTCH /*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch) + + ((rlc_status.bytes_in_buffer - TBS - header_len_mcch - header_len_msi - sdu_length_total) % (TBS_MTCH /*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch) ? 0 + : 0); - for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment - msi_ptr = &msi_control_element[k]; + for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment + msi_ptr = &msi_control_element[k]; - ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; + ((MSI_ELEMENT *)msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; // mtch_lcid; - if( msi_pmch_stop > cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) - LOG_E(MAC,"e-MBMS Buffer Overflow\n"); + if (msi_pmch_stop > cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) + LOG_E(MAC, "e-MBMS Buffer Overflow\n"); - if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { + if (msi_pmch_stop >= num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = (((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) >> 8) & 0x7f); ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = ((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) & 0xff); msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9); diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 1fd7182c6f..12ffaf4a5b 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -74,7 +74,7 @@ #include "PHY/defs_common.h" // for PRACH_RESOURCES_t #include "PHY/LTE_TRANSPORT/transport_common.h" -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" /** @defgroup _mac MAC * @ingroup _oai2 diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 9f1e0099a6..7275a0a4e5 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1962,7 +1962,7 @@ void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){ uint32_t delta_arfcn = nrarfcn - N_OFFs; if(delta_arfcn%(nr_bandtable[i].step_size)!=0) - AssertFatal(1 == 0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size); + AssertFatal(1==0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size); } @@ -1982,10 +1982,10 @@ uint32_t to_nrarfcn(int nr_bandP, "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n", nr_bandP, bw, (long long unsigned int)dl_CarrierFreq_by_1k, (long long unsigned int)nr_bandtable[i].dl_min); - AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz), + AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz/2), "Band %d, dl_CarrierFreq %llu bw %u: DL carrier frequency %llu kHz > %llu\n", nr_bandP, (long long unsigned int)dl_CarrierFreq,bw, (long long unsigned int)dl_CarrierFreq_by_1k, - (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz)); + (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz/2)); int deltaFglobal = 60; uint32_t N_REF_Offs = 2016667; @@ -2005,7 +2005,7 @@ uint32_t to_nrarfcn(int nr_bandP, // This is equation before Table 5.4.2.1-1 in 38101-1-f30 // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs) nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs); - get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); + //get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); return nrarfcn; } @@ -3155,26 +3155,28 @@ int is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, sl else return(slot_in_period >= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); } -int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols, int startSymbol, int mappingtype_fromDCI, int length) { +int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols, int startSymbol, mappingType_t mappingtype, int length) { - int l0;int dmrs_AdditionalPosition = 0; + int dmrs_AdditionalPosition = 0; NR_DMRS_DownlinkConfig_t *dmrs_config = NULL; - LOG_D(MAC, "NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d\n", NrOfSymbols, startSymbol, mappingtype_fromDCI, dmrs_TypeA_Position); - - if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2; - else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3; - else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position); + LOG_D(MAC, "NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d\n", NrOfSymbols, startSymbol, mappingtype, dmrs_TypeA_Position); + int l0 = 0; // type B + if (mappingtype == typeA) { + if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2; + else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3; + else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position); + } // in case of DCI FORMAT 1_0 or dedicated pdsch config not received additionposition = pos2, len1 should be used // referred to section 5.1.6.2 in 38.214 dmrs_AdditionalPosition = 2; if (pdsch_Config != NULL) { - if (mappingtype_fromDCI == typeA) { // Type A + if (mappingtype == typeA) { // Type A if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; - } else if (mappingtype_fromDCI == typeB) { + } else if (mappingtype == typeB) { if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup; } else { @@ -3191,17 +3193,17 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i int32_t l_prime = -1; // columns 0-3 for TypeA, 4-7 for TypeB - column = (mappingtype_fromDCI == typeA) ? dmrs_AdditionalPosition : (dmrs_AdditionalPosition + 4); + column = (mappingtype == typeA) ? dmrs_AdditionalPosition : (dmrs_AdditionalPosition + 4); // Section 7.4.1.1.2 in Spec 38.211 // For PDSCH Mapping TypeA, ld is duration between first OFDM of the slot and last OFDM symbol of the scheduled PDSCH resources // For TypeB, ld is the duration of the scheduled PDSCH resources - ld = (mappingtype_fromDCI == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols; + ld = (mappingtype == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols; AssertFatal(ld > 2 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld); AssertFatal((NrOfSymbols + startSymbol) < 15,"Illegal S+L according to Table 5.1.2.1-1 Spec 38.214 S:%d L:%d\n",startSymbol, NrOfSymbols); - if (mappingtype_fromDCI == typeA) { + if (mappingtype == typeA) { // Section 7.4.1.1.2 in Spec 38.211 AssertFatal((l0 == 2) || (l0 == 3 && dmrs_AdditionalPosition != 3),"Wrong config, If dmrs_TypeA_Position POS3, ADD POS cannot be POS3 \n"); @@ -3229,7 +3231,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i LOG_D(MAC, "l0:%d, ld:%d,row:%d, column:%d, addpos:%d, maxlen:%d\n", l0, ld, row, column, dmrs_AdditionalPosition, length); AssertFatal(l_prime>=0,"ERROR in configuration.Check Time Domain allocation of this Grant. l_prime < 1. row:%d, column:%d\n", row, column); - l_prime = (mappingtype_fromDCI == typeA) ? (l_prime | l0) : (l_prime << startSymbol); + l_prime = (mappingtype == typeA) ? (l_prime | l0) : (l_prime << startSymbol); LOG_D(MAC, " PDSCH DMRS MASK in HEX:%x\n", l_prime); return l_prime; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index d45c01b4b0..a55bbee74d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -38,6 +38,18 @@ #include "openair1/PHY/impl_defs_nr.h" #include "common/utils/nr/nr_common.h" +typedef enum { + pusch_dmrs_pos0 = 0, + pusch_dmrs_pos1 = 1, + pusch_dmrs_pos2 = 2, + pusch_dmrs_pos3 = 3, +} pusch_dmrs_AdditionalPosition_t; + +typedef enum { + typeA = 0, + typeB = 1 +} mappingType_t; + uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti); uint8_t get_BG(uint32_t A, uint16_t R); @@ -46,7 +58,7 @@ uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); -int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol,int mappingtype_fromDCI,int length); +int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol,mappingType_t mappingtype,int length); int is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,slot_t slotP); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 4adee2bced..f8b313efd8 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -32,7 +32,7 @@ //#include "defs.h" #include "mac_proto.h" -#include "../../ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" //#undef MALLOC #include "assertions.h" #include "PHY/types.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 770bae5b5d..85badb7e0a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -512,6 +512,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int nr_dl_slots = n; int nr_ulstart_slot = 0; if (tdd) { + nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0); nr_dl_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0); nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0); nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index a368ba4e32..5cf4bc295c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -181,8 +181,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if ((slot == 0) && (frame & 127) == 0) { - char stats_output[16384]; - stats_output[0] = '\0'; + char stats_output[16000] = {0}; dump_mac_stats(RC.nrmac[module_idP], stats_output, sizeof(stats_output), true); LOG_I(NR_MAC, "Frame.Slot %d.%d\n%s\n", frame, slot, stats_output); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 2d8dd574e3..72b7f2a565 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1145,8 +1145,6 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_SearchSpace_t *ss = ra->ra_ss; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = dl_bwp->tdaList; - long BWPStart = 0; long BWPSize = 0; NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; @@ -1161,10 +1159,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // Calculate number of symbols int time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); - int startSymbolIndex, nrOfSymbols; - const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n"); + NR_tda_info_t tda_info = nr_get_pdsch_tda_info(dl_bwp, + time_domain_assignment); NR_ControlResourceSet_t *coreset = ra->coreset; @@ -1172,7 +1168,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra uint16_t *vrb_map = cc[CC_id].vrb_map; for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { - if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(startSymbolIndex, nrOfSymbols)) { + if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) { rbStart += i; i = 0; } @@ -1212,9 +1208,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra return; } - LOG_D(NR_MAC,"Msg2 startSymbolIndex.nrOfSymbols %d.%d\n",startSymbolIndex,nrOfSymbols); - - int mappingtype = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType; + LOG_D(NR_MAC,"Msg2 startSymbolIndex.nrOfSymbols %d.%d\n",tda_info.startSymbolIndex,tda_info.nrOfSymbols); // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them @@ -1244,16 +1238,12 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control // information to data and is reset every slot. const int pduindex = nr_mac->pdu_index[CC_id]++; - - NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; - int dmrsConfigType=0; - if (pdsch_Config && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type) - dmrsConfigType = 1; + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, + dl_bwp, + &tda_info, + 1); pdsch_pdu_rel15->pduBitmap = 0; pdsch_pdu_rel15->rnti = ra->RA_rnti; @@ -1269,37 +1259,22 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType; + pdsch_pdu_rel15->dmrsConfigType = dmrs_parms.dmrsConfigType; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = nrOfSymbols <= 2 ? 1 : 2; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = dmrs_parms.numDmrsCdmGrpsNoData; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; pdsch_pdu_rel15->rbStart = rbStart; pdsch_pdu_rel15->rbSize = rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; - pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(pdsch_Config, - nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, - nrOfSymbols, - startSymbolIndex, - mappingtype, - 1); + pdsch_pdu_rel15->StartSymbolIndex = tda_info.startSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = tda_info.nrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = dmrs_parms.dl_dmrs_symb_pos; uint8_t tb_scaling = 0; int R, Qm; - uint8_t N_PRB_DMRS; uint32_t TBS=0; - if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { - // if no data in dmrs cdm group is 1 only even REs have no data - // if no data in dmrs cdm group is 2 both odd and even REs have no data - N_PRB_DMRS = pdsch_pdu_rel15->numDmrsCdmGrpsNoData*6; - } - else { - N_PRB_DMRS = pdsch_pdu_rel15->numDmrsCdmGrpsNoData*4; - } - uint16_t dmrs_length = get_num_dmrs(pdsch_pdu_rel15->dlDmrsSymbPos); while(TBS<9) { // min TBS for RAR is 9 bytes mcsIndex++; @@ -1308,8 +1283,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra TBS = nr_compute_tbs(Qm, R, rbSize, - nrOfSymbols, - N_PRB_DMRS*dmrs_length, + tda_info.nrOfSymbols, + dmrs_parms.N_PRB_DMRS*dmrs_parms.N_DMRS_SLOT, 0, // overhead tb_scaling, // tb scaling 1)>>3; // layers @@ -1414,7 +1389,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra CCEIndex, aggregation_level); for (int rb = 0; rb < rbSize; rb++) { - vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(startSymbolIndex, nrOfSymbols); + vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); } ra->state = WAIT_Msg3; @@ -1437,8 +1412,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra NR_SearchSpace_t *ss = ra->ra_ss; NR_ControlResourceSet_t *coreset = ra->coreset; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = dl_bwp->tdaList; - AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n"); rnti_t tc_rnti = ra->rnti; @@ -1554,48 +1527,12 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } } - // Calculate number of symbols - int startSymbolIndex, nrOfSymbols; - const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n"); + NR_tda_info_t msg4_tda = nr_get_pdsch_tda_info(dl_bwp, time_domain_assignment); - int mappingtype = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType; - - uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, - scc->dmrs_TypeA_Position, - nrOfSymbols, - startSymbolIndex, - mappingtype, - 1); - - uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos); - - NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; - int dmrsConfigType=0; - if (pdsch_Config && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type) - dmrsConfigType = 1; - - nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2; - if (nrOfSymbols == 2) { - nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1; - } - - AssertFatal(nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData == 1 - || nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData == 2, - "nr_mac->schedCtrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData %d is not possible", - nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData); - - uint8_t N_PRB_DMRS = 0; - if (dmrsConfigType==NFAPI_NR_DMRS_TYPE1) { - N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6; - } - else { - N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 4; - } + NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, + dl_bwp, + &msg4_tda, + 1); uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; @@ -1609,17 +1546,17 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra rbSize++; else mcsIndex++; - LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",N_PRB_DMRS,N_DMRS_SLOT); + LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT); harq->tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), nr_get_code_rate_dl(mcsIndex, mcsTableIdx), - rbSize, nrOfSymbols, N_PRB_DMRS * N_DMRS_SLOT, 0, tb_scaling,1) >> 3; + rbSize, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3; } while (harq->tb_size < ra->mac_pdu_length && mcsIndex<=28); AssertFatal(harq->tb_size >= ra->mac_pdu_length,"Cannot allocate Msg4\n"); int i = 0; while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { - if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(startSymbolIndex, nrOfSymbols)) { + if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols)) { rbStart += i+1; i = 0; } else { @@ -1687,18 +1624,18 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType; + pdsch_pdu_rel15->dmrsConfigType = dmrs_info.dmrsConfigType; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = nrOfSymbols <= 2 ? 1 : 2; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = dmrs_info.numDmrsCdmGrpsNoData; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; pdsch_pdu_rel15->rbStart = rbStart; pdsch_pdu_rel15->rbSize = rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; - pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos; + pdsch_pdu_rel15->StartSymbolIndex = msg4_tda.startSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = msg4_tda.nrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = dmrs_info.dl_dmrs_symb_pos; int x_Overhead = 0; nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); @@ -1811,7 +1748,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra CCEIndex, aggregation_level); for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) { - vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] |= SL_to_bitmap(startSymbolIndex, nrOfSymbols); + vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 3895ffe42c..0438070da3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -281,9 +281,8 @@ uint32_t schedule_control_sib1(module_id_t module_id, int CC_id, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, int time_domain_allocation, - int startSymbolIndex, - int nrOfSymbols, - uint16_t dlDmrsSymbPos, + NR_pdsch_dmrs_t *dmrs_parms, + NR_tda_info_t *tda_info, uint8_t candidate_idx, uint16_t num_total_bytes) { @@ -309,8 +308,11 @@ uint32_t schedule_control_sib1(module_id_t module_id, type0_PDCCH_CSS_config); } - gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation; - gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = 0; // starting from mcs 0 + NR_sched_pdsch_t *pdsch = &gNB_mac->sched_ctrlCommon->sched_pdsch; + pdsch->time_domain_allocation = time_domain_allocation; + pdsch->dmrs_parms = *dmrs_parms; + pdsch->tda_info = *tda_info; + pdsch->mcs = 0; // starting from mcs 0 gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes; uint8_t nr_of_candidates; @@ -333,58 +335,49 @@ uint32_t schedule_control_sib1(module_id_t module_id, const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs; int rbStart = type0_PDCCH_CSS_config->cset_start_rb; - // TODO: There are exceptions to this in table 5.1.2.1.1-4,5 (Default time domain allocation tables B, C) - int mappingtype = (startSymbolIndex <= 3)? typeA: typeB; - - if (nrOfSymbols == 2) { - gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1; - } else { - gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2; - } - // Calculate number of PRB_DMRS - uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6; - uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); - LOG_D(MAC,"dlDmrsSymbPos %x\n",dlDmrsSymbPos); + uint8_t N_PRB_DMRS = pdsch->dmrs_parms.N_PRB_DMRS; + uint16_t dmrs_length = pdsch->dmrs_parms.N_DMRS_SLOT; + LOG_D(MAC,"dlDmrsSymbPos %x\n",pdsch->dmrs_parms.dl_dmrs_symb_pos); int mcsTableIdx = 0; int rbSize = 0; uint32_t TBS = 0; do { - if(rbSize < bwpSize && !(vrb_map[rbStart + rbSize]&SL_to_bitmap(startSymbolIndex, nrOfSymbols))) + if(rbSize < bwpSize && !(vrb_map[rbStart + rbSize]&SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols))) rbSize++; else{ - if (gNB_mac->sched_ctrlCommon->sched_pdsch.mcs<10) - gNB_mac->sched_ctrlCommon->sched_pdsch.mcs++; + if (pdsch->mcs<10) + pdsch->mcs++; else break; } - TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, mcsTableIdx), - nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, mcsTableIdx), - rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3; + TBS = nr_compute_tbs(nr_get_Qm_dl(pdsch->mcs, mcsTableIdx), + nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx), + rbSize, tda_info->nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3; } while (TBS < gNB_mac->sched_ctrlCommon->num_total_bytes); AssertFatal(TBS>=gNB_mac->sched_ctrlCommon->num_total_bytes,"Couldn't allocate enough resources for %d bytes in SIB1 PDSCH\n", gNB_mac->sched_ctrlCommon->num_total_bytes); - gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize = rbSize; - gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart = 0; + pdsch->rbSize = rbSize; + pdsch->rbStart = 0; - LOG_D(NR_MAC,"mcs = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.mcs); - LOG_D(NR_MAC,"startSymbolIndex = %i\n", startSymbolIndex); - LOG_D(NR_MAC,"nrOfSymbols = %i\n", nrOfSymbols); - LOG_D(NR_MAC, "rbSize = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize); + LOG_D(NR_MAC,"mcs = %i\n", pdsch->mcs); + LOG_D(NR_MAC,"startSymbolIndex = %i\n", tda_info->startSymbolIndex); + LOG_D(NR_MAC,"nrOfSymbols = %i\n", tda_info->nrOfSymbols); + LOG_D(NR_MAC, "rbSize = %i\n", pdsch->rbSize); LOG_D(NR_MAC,"TBS = %i\n", TBS); LOG_D(NR_MAC,"dmrs_length %d\n",dmrs_length); LOG_D(NR_MAC,"N_PRB_DMRS = %d\n",N_PRB_DMRS); - LOG_D(NR_MAC,"mappingtype = %d\n", mappingtype); + LOG_D(NR_MAC,"mappingtype = %d\n", tda_info->mapping_type); // Mark the corresponding RBs as used fill_pdcch_vrb_map(gNB_mac, CC_id, &gNB_mac->sched_ctrlCommon->sched_pdcch, gNB_mac->sched_ctrlCommon->cce_index, gNB_mac->sched_ctrlCommon->aggregation_level); - for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; rb++) { - vrb_map[rb + rbStart] |= SL_to_bitmap(startSymbolIndex, nrOfSymbols); + for (int rb = 0; rb < pdsch->rbSize; rb++) { + vrb_map[rb + rbStart] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); } return TBS; } @@ -395,13 +388,13 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, uint32_t TBS, int StartSymbolIndex, - int NrOfSymbols, - uint16_t dlDmrsSymbPos) { + int NrOfSymbols) { gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = gNB_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int mcsTableIdx = 0; + NR_sched_pdsch_t *pdsch = &gNB_mac->sched_ctrlCommon->sched_pdsch; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; @@ -433,11 +426,11 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; - pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, mcsTableIdx); - pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, mcsTableIdx); - pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx); + pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx); + pdsch_pdu_rel15->mcsIndex[0] = pdsch->mcs; pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; - pdsch_pdu_rel15->rvIndex[0] = 0; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0]; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; @@ -445,16 +438,16 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->dmrsConfigType = 0; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = pdsch->dmrs_parms.numDmrsCdmGrpsNoData; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart; - pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; + pdsch_pdu_rel15->rbStart = pdsch->rbStart; + pdsch_pdu_rel15->rbSize = pdsch->rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; pdsch_pdu_rel15->TBSize[0] = TBS; pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos; + pdsch_pdu_rel15->dlDmrsSymbPos = pdsch->dmrs_parms.dl_dmrs_symb_pos; LOG_D(NR_MAC,"sib1:bwpStart %d, bwpSize %d\n",pdsch_pdu_rel15->BWPStart,pdsch_pdu_rel15->BWPSize); LOG_D(NR_MAC,"sib1:rbStart %d, rbSize %d\n",pdsch_pdu_rel15->rbStart,pdsch_pdu_rel15->rbSize); LOG_D(NR_MAC,"sib1:dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos); @@ -485,8 +478,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0( pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs); - dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation; - dci_payload.mcs = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs; + dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->sched_pdsch.time_domain_allocation; + dci_payload.mcs = pdsch->mcs; dci_payload.rv = pdsch_pdu_rel15->rvIndex[0]; dci_payload.harq_pid = 0; dci_payload.ndi = 0; @@ -587,22 +580,29 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) AssertFatal((startSymbolIndex+nrOfSymbols)<14,"SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n",time_domain_allocation); - int mappingtype = is_typeA? typeA: typeB; - uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, mappingtype, 1); + NR_tda_info_t tda_info = { + .mapping_type = is_typeA ? typeA : typeB, + .startSymbolIndex = startSymbolIndex, + .nrOfSymbols = nrOfSymbols + }; + + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, + NULL, + &tda_info, + 1); // Configure sched_ctrlCommon for SIB1 uint32_t TBS = schedule_control_sib1(module_idP, CC_id, type0_PDCCH_CSS_config, time_domain_allocation, - startSymbolIndex, - nrOfSymbols, - dlDmrsSymbPos, + &dmrs_parms, + &tda_info, candidate_idx, sib1_sdu_length); nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; - nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols, dlDmrsSymbPos); + nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols); const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 597477c3d3..6dfd73a297 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -391,17 +391,13 @@ bool allocate_dl_retransmission(module_id_t module_id, NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + NR_sched_pdsch_t *curInfo = &sched_ctrl->sched_pdsch; - //TODO remove this and handle retransmission with old nrOfLayers - // once ps structure is removed - if(ps->nrOfLayers < retInfo->nrOfLayers) { - LOG_W(NR_MAC,"Cannot schedule retransmission. RI changed from %d to %d\n", - retInfo->nrOfLayers, ps->nrOfLayers); - abort_nr_dl_harq(UE, current_harq_pid); - remove_front_nr_list(&sched_ctrl->retrans_dl_harq); - return false; - } + // If the RI changed between current rtx and a previous transmission + // we need to verify if it is not decreased + // othwise it wouldn't be possible to transmit the same TBS + int layers = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->nrOfLayers : retInfo->nrOfLayers; + int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index; const int coresetid = sched_ctrl->coreset->controlResourceSetId; const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : dl_bwp->BWPSize; @@ -411,13 +407,16 @@ bool allocate_dl_retransmission(module_id_t module_id, const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n"); - if (tda == retInfo->time_domain_allocation) { + if (tda == retInfo->time_domain_allocation && + layers == retInfo->nrOfLayers) { + + NR_tda_info_t *tda_info = &retInfo->tda_info; /* Check that there are enough resources for retransmission */ while (rbSize < retInfo->rbSize) { rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ rbSize = 0; - const int slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + const int slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; @@ -431,30 +430,16 @@ bool allocate_dl_retransmission(module_id_t module_id, rbSize < retInfo->rbSize) rbSize++; } - - /* check whether we need to switch the TDA allocation since the last - * (re-)transmission */ - if (ps->time_domain_allocation != tda) { - nr_set_pdsch_semi_static(dl_bwp, - scc, - tda, - ps->nrOfLayers, - sched_ctrl, - ps); - } } else { /* the retransmission will use a different time domain allocation, check * that we have enough resources */ - NR_pdsch_semi_static_t temp_ps = *ps; + NR_tda_info_t temp_tda = nr_get_pdsch_tda_info(dl_bwp, tda); + NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, + dl_bwp, + &temp_tda, + layers); - nr_set_pdsch_semi_static(dl_bwp, - scc, - tda, - ps->nrOfLayers, - sched_ctrl, - &temp_ps); - - const uint16_t slbitmap = SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; @@ -465,9 +450,9 @@ bool allocate_dl_retransmission(module_id_t module_id, uint16_t new_rbSize; bool success = nr_find_nb_rb(retInfo->Qm, retInfo->R, - temp_ps.nrOfLayers, - temp_ps.nrOfSymbols, - temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT, + layers, + temp_tda.nrOfSymbols, + temp_dmrs.N_PRB_DMRS * temp_dmrs.N_DMRS_SLOT, retInfo->tb_size, 1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */ rbSize, @@ -484,7 +469,10 @@ bool allocate_dl_retransmission(module_id_t module_id, retInfo->tb_size = new_tbs; retInfo->rbSize = new_rbSize; retInfo->time_domain_allocation = tda; - sched_ctrl->pdsch_semi_static = temp_ps; + retInfo->nrOfLayers = layers; + retInfo->pm_index = pm_index; + retInfo->dmrs_parms = temp_dmrs; + retInfo->tda_info = temp_tda; } /* Find a free CCE */ @@ -544,7 +532,7 @@ bool allocate_dl_retransmission(module_id_t module_id, *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); return true; } @@ -585,10 +573,8 @@ void pf_dl(module_id_t module_id, const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; - UE->layers = ps->nrOfLayers; // initialization of layers to the previous value in the structure /* Calculate Throughput */ const float a = 0.0005f; // corresponds to 200ms window const uint32_t b = UE->mac_stats.dl.current_bytes; @@ -633,7 +619,10 @@ void pf_dl(module_id_t module_id, sched_pdsch->mcs = max_mcs; else sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); - UE->layers = set_dl_nrOfLayers(sched_ctrl); + sched_pdsch->nrOfLayers = get_dl_nrOfLayers(sched_ctrl, current_BWP->dci_format); + sched_pdsch->pm_index = get_pm_index(UE, + sched_pdsch->nrOfLayers, + mac->xp_pdsch_antenna_ports); const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); uint32_t tbs = nr_compute_tbs(Qm, @@ -643,7 +632,7 @@ void pf_dl(module_id_t module_id, 0, /* N_PRB_DMRS * N_DMRS_SLOT */ 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - UE->layers) >> 3; + sched_pdsch->nrOfLayers) >> 3; float coeff_ue = (float) tbs / UE->dl_thr_ue; LOG_D(NR_MAC,"UE %04x b %d, thr_ue %f, tbs %d, coeff_ue %f\n", UE->rnti, b, UE->dl_thr_ue, tbs, coeff_ue); @@ -732,21 +721,14 @@ void pf_dl(module_id_t module_id, sched_ctrl->aggregation_level); /* MCS has been set above */ - const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); - AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n"); NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], scc, slot); + AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); - if (ps->nrOfLayers != iterator->UE->layers || ps->time_domain_allocation != tda ) { - nr_set_pdsch_semi_static(dl_bwp, - scc, - tda, - iterator->UE->layers, - sched_ctrl, - ps); - } + sched_pdsch->tda_info = nr_get_pdsch_tda_info(dl_bwp, sched_pdsch->time_domain_allocation); + NR_tda_info_t *tda_info = &sched_pdsch->tda_info; - const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); // Freq-demain allocation while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) @@ -757,6 +739,10 @@ void pf_dl(module_id_t module_id, while (rbStart + max_rbSize < bwpSize && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == slbitmap) max_rbSize++; + sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, + dl_bwp, + tda_info, + sched_pdsch->nrOfLayers); sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->pucch_allocation = alloc; @@ -770,9 +756,9 @@ void pf_dl(module_id_t module_id, //const int oh = 3 * sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024); nr_find_nb_rb(sched_pdsch->Qm, sched_pdsch->R, - ps->nrOfLayers, - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->N_DMRS_SLOT, + sched_pdsch->nrOfLayers, + tda_info->nrOfSymbols, + sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT, sched_ctrl->num_total_bytes + oh, min_rbSize, max_rbSize, @@ -912,12 +898,9 @@ void nr_schedule_ue_spec(module_id_t module_id, continue; const rnti_t rnti = UE->rnti; - /* pre-computed PDSCH values that only change if time domain - * allocation/DMRS parameters change. Updated in the preprocessor through - * nr_set_pdsch_semi_static() */ - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; + /* POST processing */ - const uint8_t nrOfLayers = ps->nrOfLayers; + const uint8_t nrOfLayers = sched_pdsch->nrOfLayers; const uint16_t R = sched_pdsch->R; const uint8_t Qm = sched_pdsch->Qm; const uint32_t TBS = sched_pdsch->tb_size; @@ -941,6 +924,8 @@ void nr_schedule_ue_spec(module_id_t module_id, remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); } + NR_tda_info_t *tda_info = &sched_pdsch->tda_info; + NR_pdsch_dmrs_t *dmrs_parms = &sched_pdsch->dmrs_parms; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; DevAssert(!harq->is_waiting); add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); @@ -957,9 +942,9 @@ void nr_schedule_ue_spec(module_id_t module_id, sched_ctrl->aggregation_level, sched_pdsch->rbStart, sched_pdsch->rbSize, - ps->startSymbolIndex, - ps->nrOfSymbols, - ps->dl_dmrs_symb_pos, + tda_info->startSymbolIndex, + tda_info->nrOfSymbols, + dmrs_parms->dl_dmrs_symb_pos, sched_pdsch->mcs, nrOfLayers, TBS, @@ -1033,11 +1018,11 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->transmissionScheme = 0; pdsch_pdu->refPoint = 0; // Point A // DMRS - pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos; - pdsch_pdu->dmrsConfigType = ps->dmrsConfigType; + pdsch_pdu->dlDmrsSymbPos = dmrs_parms->dl_dmrs_symb_pos; + pdsch_pdu->dmrsConfigType = dmrs_parms->dmrsConfigType; pdsch_pdu->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu->SCID = 0; - pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData; + pdsch_pdu->numDmrsCdmGrpsNoData = dmrs_parms->numDmrsCdmGrpsNoData; pdsch_pdu->dmrsPorts = (1<resourceAlloc = 1; @@ -1045,20 +1030,11 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->rbSize = sched_pdsch->rbSize; pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP // Resource Allocation in time domain - pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex; - pdsch_pdu->NrOfSymbols = ps->nrOfSymbols; + pdsch_pdu->StartSymbolIndex = tda_info->startSymbolIndex; + pdsch_pdu->NrOfSymbols = tda_info->nrOfSymbols; // Precoding - if (sched_ctrl->set_pmi) { - const int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id; - nr_csi_report_t *csi_report = &UE->csi_report_template[report_id]; - pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; - pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = set_pm_index(sched_ctrl, - nrOfLayers, - csi_report->N1, - csi_report->N2, - gNB_mac->xp_pdsch_antenna_ports, - csi_report->codebook_mode); - } + pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; + pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index; // TBS_LBRM according to section 5.4.2.1 of 38.212 // TODO: verify the case where pdsch_servingcellconfig is NULL, in which case // in principle maxMIMO_layers should be given by the maximum number of layers @@ -1130,7 +1106,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->rbStart, pdsch_pdu->BWPSize); dci_payload.format_indicator = 1; - dci_payload.time_domain_assignment.val = ps->time_domain_allocation; + dci_payload.time_domain_assignment.val = sched_pdsch->time_domain_allocation; dci_payload.mcs = sched_pdsch->mcs; dci_payload.rv = pdsch_pdu->rvIndex[0]; dci_payload.harq_pid = current_harq_pid; @@ -1139,7 +1115,7 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213 dci_payload.pucch_resource_indicator = pucch->resource_indicator; dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; // PDSCH to HARQ TI - dci_payload.antenna_ports.val = ps->dmrs_ports_id; + dci_payload.antenna_ports.val = dmrs_parms->dmrs_ports_id; dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; LOG_D(NR_MAC, "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " @@ -1319,9 +1295,7 @@ void nr_schedule_ue_spec(module_id_t module_id, harq->sched_pdsch = *sched_pdsch; /* save which time allocation has been used, to be used on * retransmissions */ - harq->sched_pdsch.time_domain_allocation = ps->time_domain_allocation; - /* save nr of layers for retransmissions */ - harq->sched_pdsch.nrOfLayers = ps->nrOfLayers; + harq->sched_pdsch.time_domain_allocation = sched_pdsch->time_domain_allocation; // ta command is sent, values are reset if (sched_ctrl->ta_apply) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index e474315de7..5136c7fc53 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -179,8 +179,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } -extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda); -extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData); uint32_t target_dl_mcs = 9; uint32_t target_dl_Nl = 1; uint32_t target_dl_bw = 50; @@ -199,10 +197,9 @@ void nr_preprocessor_phytest(module_id_t module_id, const int CC_id = 0; const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - ps->nrOfLayers = target_dl_Nl; - if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl) - nr_set_pdsch_semi_static(dl_bwp, scc, tda, target_dl_Nl,sched_ctrl , ps); + NR_tda_info_t tda_info = nr_get_pdsch_tda_info(dl_bwp, tda); + sched_ctrl->sched_pdsch.tda_info = tda_info; + sched_ctrl->sched_pdsch.time_domain_allocation = tda; /* find largest unallocated chunk */ const int bwpSize = dl_bwp->BWPSize; @@ -217,12 +214,12 @@ void nr_preprocessor_phytest(module_id_t module_id, while (true) { /* advance to first free RB */ while (rbStart < bwpSize && - (vrb_map[rbStart + BWPStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols))) + (vrb_map[rbStart + BWPStart]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols))) rbStart++; rbSize = 1; /* iterate until we are at target_dl_bw or no available RBs */ while (rbStart + rbSize < bwpSize && - !(vrb_map[rbStart + rbSize + BWPStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) && + !(vrb_map[rbStart + rbSize + BWPStart]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) && rbSize < target_dl_bw) rbSize++; /* found target_dl_bw? */ @@ -308,18 +305,24 @@ void nr_preprocessor_phytest(module_id_t module_id, sched_pdsch->rbStart = rbStart; sched_pdsch->rbSize = rbSize; + sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, + dl_bwp, + &tda_info, + target_dl_Nl); + sched_pdsch->mcs = target_dl_mcs; + sched_pdsch->nrOfLayers = target_dl_Nl; sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_ctrl->dl_bler_stats.mcs = target_dl_mcs; /* for logging output */ sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, sched_pdsch->R, sched_pdsch->rbSize, - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->N_DMRS_SLOT, + tda_info.nrOfSymbols, + sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - ps->nrOfLayers) + sched_pdsch->nrOfLayers) >> 3; /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */ @@ -327,7 +330,7 @@ void nr_preprocessor_phytest(module_id_t module_id, /* mark the corresponding RBs as used */ for (int rb = 0; rb < sched_pdsch->rbSize; rb++) - vrb_map[rb + sched_pdsch->rbStart + BWPStart] = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + vrb_map[rb + sched_pdsch->rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize); } @@ -378,14 +381,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot)) return false; - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ - NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; - if (ps->time_domain_allocation != tda - || ps->nrOfLayers != target_ul_Nl) - nr_set_pusch_semi_static(ul_bwp, scc, tda, target_ul_Nl,ps); - uint16_t rbStart = 0; uint16_t rbSize; @@ -397,10 +392,13 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ else rbSize = target_ul_bw; + NR_tda_info_t tda_info = nr_get_pusch_tda_info(ul_bwp, tda); + sched_ctrl->sched_pusch.tda_info = tda_info; + uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; for (int i = rbStart; i < rbStart + rbSize; ++i) { - if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) != 0) { + if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) != 0) { LOG_E(MAC, "%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n", __func__, @@ -452,7 +450,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; /* Calculate TBS from MCS */ - ps->nrOfLayers = target_ul_Nl; + sched_pusch->nrOfLayers = target_ul_Nl; sched_pusch->R = nr_get_code_rate_ul(mcs, ul_bwp->mcs_table); sched_pusch->Qm = nr_get_Qm_ul(mcs, ul_bwp->mcs_table); if (ul_bwp->pusch_Config->tp_pi2BPSK @@ -460,14 +458,21 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_pusch->R >>= 1; sched_pusch->Qm <<= 1; } + + NR_pusch_dmrs_t dmrs = get_ul_dmrs_params(scc, + ul_bwp, + &tda_info, + sched_pusch->nrOfLayers); + sched_ctrl->sched_pusch.dmrs_info = dmrs; + sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, sched_pusch->R, sched_pusch->rbSize, - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->num_dmrs_symb, + tda_info.nrOfSymbols, + dmrs.N_PRB_DMRS * dmrs.num_dmrs_symb, 0, // nb_rb_oh 0, - ps->nrOfLayers /* NrOfLayers */) + sched_pusch->nrOfLayers /* NrOfLayers */) >> 3; /* mark the corresponding RBs as used */ @@ -478,6 +483,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_ctrl->aggregation_level); for (int rb = rbStart; rb < rbStart + rbSize; rb++) - vrb_map_UL[rb+BWPStart] |= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + vrb_map_UL[rb+BWPStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); return true; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e991c2450a..5a7f5f973f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -142,31 +142,39 @@ static inline uint8_t get_max_cces(uint8_t scs) { return (nr_max_number_of_cces_per_slot[scs]); } -uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl) { +uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, + const nr_dci_format_t dci_format) { // TODO check this but it should be enough for now - // if there is not csi report RI is 0 from initialization - return (sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri + 1); + // if there is not csi report activated RI is 0 from initialization + if(dci_format == NR_DL_DCI_FORMAT_1_0) + return 1; + else + return (sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri + 1); } -uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl, +uint16_t get_pm_index(const NR_UE_info_t *UE, int layers, - int N1, int N2, - int xp_pdsch_antenna_ports, - int codebook_mode) { + int xp_pdsch_antenna_ports) { + + if (layers == 1) return 0; + + const NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + const int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id; + const nr_csi_report_t *csi_report = &UE->csi_report_template[report_id]; + const int N1 = csi_report->N1; + const int N2 = csi_report->N2; + const int antenna_ports = (N1*N2)<<1; - int antenna_ports = (N1*N2)<<1; if (xp_pdsch_antenna_ports == 1 && antenna_ports>1) return 0; //identity matrix (basic 5G configuration handled by PMI report is with XP antennas) - int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1; - int x2 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2; + const int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1; + const int x2 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2; LOG_D(NR_MAC,"PMI report: x1 %d x2 %d\n",x1,x2); - sched_ctrl->set_pmi = false; - if (antenna_ports == 2) return x2; else @@ -214,41 +222,68 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx) return 9; } +NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc, + const NR_UE_DL_BWP_t *dl_bwp, + const NR_tda_info_t *tda_info, + const int Layers) { -void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) { - - //TODO first basic implementation of dmrs port selection - // only vaild for a single codeword - // for now it assumes a selection of Nl consecutive dmrs ports - // and a single front loaded symbol - // dmrs_ports_id is the index of Tables 7.3.1.2.2-1/2/3/4 - // number of front loaded symbols need to be consistent with maxLength - // when a more complete implementation is done - - switch (ps->nrOfLayers) { - case 1: - ps->dmrs_ports_id = 0; - ps->numDmrsCdmGrpsNoData = 1; - ps->frontloaded_symb = 1; - break; - case 2: - ps->dmrs_ports_id = 2; - ps->numDmrsCdmGrpsNoData = 1; - ps->frontloaded_symb = 1; - break; - case 3: - ps->dmrs_ports_id = 9; - ps->numDmrsCdmGrpsNoData = 2; - ps->frontloaded_symb = 1; - break; - case 4: - ps->dmrs_ports_id = 10; - ps->numDmrsCdmGrpsNoData = 2; - ps->frontloaded_symb = 1; - break; - default: - AssertFatal(1==0,"Number of layers %d\n not supported or not valid\n",ps->nrOfLayers); + NR_pdsch_dmrs_t dmrs = {0}; + int frontloaded_symb = 1; // default value + nr_dci_format_t dci_format = dl_bwp ? dl_bwp->dci_format : NR_DL_DCI_FORMAT_1_0; + if (dci_format == NR_DL_DCI_FORMAT_1_0) { + dmrs.numDmrsCdmGrpsNoData = tda_info->nrOfSymbols == 2 ? 1 : 2; + dmrs.dmrs_ports_id = 0; } + else { + //TODO first basic implementation of dmrs port selection + // only vaild for a single codeword + // for now it assumes a selection of Nl consecutive dmrs ports + // and a single front loaded symbol + // dmrs_ports_id is the index of Tables 7.3.1.2.2-1/2/3/4 + // number of front loaded symbols need to be consistent with maxLength + // when a more complete implementation is done + + switch (Layers) { + case 1: + dmrs.dmrs_ports_id = 0; + dmrs.numDmrsCdmGrpsNoData = 1; + frontloaded_symb = 1; + break; + case 2: + dmrs.dmrs_ports_id = 2; + dmrs.numDmrsCdmGrpsNoData = 1; + frontloaded_symb = 1; + break; + case 3: + dmrs.dmrs_ports_id = 9; + dmrs.numDmrsCdmGrpsNoData = 2; + frontloaded_symb = 1; + break; + case 4: + dmrs.dmrs_ports_id = 10; + dmrs.numDmrsCdmGrpsNoData = 2; + frontloaded_symb = 1; + break; + default: + AssertFatal(1==0,"Number of layers %d\n not supported or not valid\n",Layers); + } + } + + NR_PDSCH_Config_t *pdsch_Config = dl_bwp ? dl_bwp->pdsch_Config : NULL; + if (pdsch_Config) { + if (tda_info->mapping_type == typeB) + dmrs.dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type != NULL; + else + dmrs.dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type != NULL; + } + else + dmrs.dmrsConfigType = NFAPI_NR_DMRS_TYPE1; + + dmrs.N_PRB_DMRS = dmrs.numDmrsCdmGrpsNoData * (dmrs.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); + dmrs.dl_dmrs_symb_pos = fill_dmrs_mask(pdsch_Config, scc->dmrs_TypeA_Position, tda_info->nrOfSymbols, tda_info->startSymbolIndex, tda_info->mapping_type, frontloaded_symb); + dmrs.N_DMRS_SLOT = get_num_dmrs(dmrs.dl_dmrs_symb_pos); + LOG_D(NR_MAC,"Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",dmrs.N_PRB_DMRS,dmrs.dl_dmrs_symb_pos,dmrs.N_DMRS_SLOT); + return dmrs; } NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, @@ -514,109 +549,70 @@ bool nr_find_nb_rb(uint16_t Qm, return *tbs >= bytes && *nb_rb <= nb_rb_max; } -void nr_set_pdsch_semi_static(const NR_UE_DL_BWP_t *dl_bwp, - const NR_ServingCellConfigCommon_t *scc, - int tda, - uint8_t layers, - NR_UE_sched_ctrl_t *sched_ctrl, - NR_pdsch_semi_static_t *ps) -{ - bool reset_dmrs = false; +NR_tda_info_t nr_get_pdsch_tda_info(const NR_UE_DL_BWP_t *dl_bwp, + const int tda) { - NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; - LOG_D(NR_MAC,"tda %d, ps->time_domain_allocation %d,layers %d, ps->nrOfLayers %d, pdsch_config %p\n",tda,ps->time_domain_allocation,layers,ps->nrOfLayers,pdsch_Config); - reset_dmrs = true; - ps->time_domain_allocation = tda; + NR_tda_info_t tda_info = {0}; NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = dl_bwp->tdaList; AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); - ps->mapping_type = tdaList->list.array[tda]->mappingType; - if (pdsch_Config) { - if (ps->mapping_type == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB) - ps->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type != NULL; - else - ps->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type != NULL; - } - else - ps->dmrsConfigType = NFAPI_NR_DMRS_TYPE1; + tda_info.mapping_type = tdaList->list.array[tda]->mappingType; const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols); - - if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) { - if (ps->nrOfSymbols == 2) - ps->numDmrsCdmGrpsNoData = 1; - else - ps->numDmrsCdmGrpsNoData = 2; - ps->dmrs_ports_id = 0; - ps->frontloaded_symb = 1; - ps->nrOfLayers = 1; - } - else { - LOG_D(NR_MAC,"checking layers\n"); - if (ps->nrOfLayers != layers || ps->numDmrsCdmGrpsNoData == 0) { - reset_dmrs = true; - ps->nrOfLayers = layers; - set_dl_dmrs_ports(ps); - } - } - - ps->N_PRB_DMRS = ps->numDmrsCdmGrpsNoData * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); - - if (reset_dmrs) { - ps->dl_dmrs_symb_pos = fill_dmrs_mask(pdsch_Config, scc ? scc->dmrs_TypeA_Position : 0, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb); - ps->N_DMRS_SLOT = get_num_dmrs(ps->dl_dmrs_symb_pos); - } - LOG_D(NR_MAC,"Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",ps->N_PRB_DMRS,ps->dl_dmrs_symb_pos,ps->N_DMRS_SLOT); + SLIV2SL(startSymbolAndLength, &tda_info.startSymbolIndex, &tda_info.nrOfSymbols); + return tda_info; } -void nr_set_pusch_semi_static(const NR_UE_UL_BWP_t *ul_bwp, - const NR_ServingCellConfigCommon_t *scc, - int tda, - uint8_t nrOfLayers, - NR_pusch_semi_static_t *ps) { +NR_tda_info_t nr_get_pusch_tda_info(const NR_UE_UL_BWP_t *ul_bwp, + const int tda) { - ps->time_domain_allocation = tda; + NR_tda_info_t tda_info = {0}; + NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = ul_bwp->tdaList; + AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); + tda_info.mapping_type = tdaList->list.array[tda]->mappingType; + const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &tda_info.startSymbolIndex, &tda_info.nrOfSymbols); + return tda_info; +} - const int startSymbolAndLength = ul_bwp->tdaList->list.array[tda]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength, - &ps->startSymbolIndex, - &ps->nrOfSymbols); +NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc, + const NR_UE_UL_BWP_t *ul_bwp, + const NR_tda_info_t *tda_info, + const int Layers) { - ps->nrOfLayers = nrOfLayers; + NR_pusch_dmrs_t dmrs = {0}; // TODO setting of cdm groups with no data to be redone for MIMO - if (ul_bwp->transform_precoding || nrOfLayers<3) - ps->num_dmrs_cdm_grps_no_data = (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1) ? 1 : (ps->nrOfSymbols == 2 ? 1 : 2); + if (ul_bwp->transform_precoding || Layers<3) + dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2; else - ps->num_dmrs_cdm_grps_no_data = 2; + dmrs.num_dmrs_cdm_grps_no_data = 2; + + NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ? + (tda_info->mapping_type == typeA ? + ul_bwp->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : + ul_bwp->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) : NULL; + + dmrs.dmrs_config_type = NR_DMRS_UplinkConfig && NR_DMRS_UplinkConfig->dmrs_Type ? 1 : 0; + + const pusch_dmrs_AdditionalPosition_t additional_pos = (NR_DMRS_UplinkConfig && NR_DMRS_UplinkConfig->dmrs_AdditionalPosition) ? + (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == + NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3 ? + 3 : *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition) : 2; + + const pusch_maxLength_t pusch_maxLength = NR_DMRS_UplinkConfig ? (NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2) : 1; + dmrs.ul_dmrs_symb_pos = get_l_prime(tda_info->nrOfSymbols, + tda_info->mapping_type, + additional_pos, + pusch_maxLength, + tda_info->startSymbolIndex, + scc->dmrs_TypeA_Position); - /* DMRS calculations */ - ps->mapping_type = ul_bwp->tdaList->list.array[tda]->mappingType; - ps->NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ? - (ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA ? - ul_bwp->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : - ul_bwp->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) : NULL; - ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig ? ((ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1)) : 0; - const pusch_dmrs_AdditionalPosition_t additional_pos = - ps->NR_DMRS_UplinkConfig ? (ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL - ? 2 - : (*ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == - NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3 - ? 3 - : *ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition)):2; - const pusch_maxLength_t pusch_maxLength = - ps->NR_DMRS_UplinkConfig ? (ps->NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2) : 1; - ps->ul_dmrs_symb_pos = get_l_prime(ps->nrOfSymbols, - ps->mapping_type, - additional_pos, - pusch_maxLength, - ps->startSymbolIndex, - scc->dmrs_TypeA_Position); uint8_t num_dmrs_symb = 0; - for(int i = ps->startSymbolIndex; i < ps->startSymbolIndex + ps->nrOfSymbols; i++) - num_dmrs_symb += (ps->ul_dmrs_symb_pos >> i) & 1; - ps->num_dmrs_symb = num_dmrs_symb; - ps->N_PRB_DMRS = ps->dmrs_config_type == 0 - ? ps->num_dmrs_cdm_grps_no_data * 6 - : ps->num_dmrs_cdm_grps_no_data * 4; + for(int i = tda_info->startSymbolIndex; i < tda_info->startSymbolIndex + tda_info->nrOfSymbols; i++) + num_dmrs_symb += (dmrs.ul_dmrs_symb_pos >> i) & 1; + dmrs.num_dmrs_symb = num_dmrs_symb; + dmrs.N_PRB_DMRS = dmrs.num_dmrs_cdm_grps_no_data * (dmrs.dmrs_config_type == 0 ? 6 : 4); + + dmrs.NR_DMRS_UplinkConfig = NR_DMRS_UplinkConfig; + return dmrs; } #define BLER_UPDATE_FRAME 10 @@ -2501,8 +2497,8 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE); /* set illegal time domain allocation to force recomputation of all fields */ - sched_ctrl->pdsch_semi_static.time_domain_allocation = -1; - sched_ctrl->pusch_semi_static.time_domain_allocation = -1; + sched_ctrl->sched_pdsch.time_domain_allocation = -1; + sched_ctrl->sched_pusch.time_domain_allocation = -1; /* Set default BWPs */ sched_ctrl->next_dl_bwp_id = -1; @@ -2957,28 +2953,6 @@ void nr_mac_update_timers(module_id_t module_id, // add all available DL HARQ processes for this UE in SA create_dl_harq_list(sched_ctrl, UE->current_DL_BWP.pdsch_servingcellconfig); } - - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - const uint8_t layers = set_dl_nrOfLayers(sched_ctrl); - const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); - - nr_set_pdsch_semi_static(&UE->current_DL_BWP, - scc, - tda, - layers, - sched_ctrl, - ps); - - - NR_pusch_semi_static_t *ups = &sched_ctrl->pusch_semi_static; - const uint8_t nrOfLayers = 1; - const int utda = get_ul_tda(RC.nrmac[module_id], scc, slot); - - nr_set_pusch_semi_static(&UE->current_UL_BWP, - scc, - utda, - nrOfLayers, - ups); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 0a57c47b42..c347ea5bea 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -707,7 +707,6 @@ uint8_t evaluate_pmi_report(uint8_t *payload, sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); - sched_ctrl->set_pmi = true; return tot_bitlen; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 74b4291ef6..032b83ca5d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -53,30 +53,28 @@ const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon return 0; // if FDD or not mixed slot in TDD, for now use default TDA (TODO handle CSI-RS slots) } -int compute_bw_factor(int mu, int rb) { - // 38.213 7.1.1 - return (10 * log10(rb << mu)); -} - -int compute_delta_tf(int tbs_bits, - int rb, - int n_layers, - int n_symbols, - int n_dmrs, - long *deltaMCS) { +int compute_ph_factor(int mu, + int tbs_bits, + int rb, + int n_layers, + int n_symbols, + int n_dmrs, + long *deltaMCS) { // 38.213 7.1.1 // if the PUSCH transmission is over more than one layer delta_tf = 0 - if(deltaMCS == NULL || n_layers>1) - return 0; - else - AssertFatal(1==0,"Compute DeltaTF not yet fully supported\n"); + int delta_tf = 0; + if(deltaMCS != NULL && n_layers == 1) { + const int n_re = (NR_NB_SC_PER_RB * n_symbols - n_dmrs) * rb; + const int BPRE = tbs_bits/n_re; //TODO change for PUSCH with CSI + const float f = pow(2, (float) BPRE * 1.25); + const float beta = 1.0f; //TODO change for PUSCH with CSI + delta_tf = (10 * log10((f - 1) * beta)); + } - const int n_re = (NR_NB_SC_PER_RB * n_symbols - n_dmrs) * rb; - const int BPRE = tbs_bits/n_re; //TODO change for PUSCH with CSI - const float f = pow(2, (float) BPRE * 1.25); - const float beta = 1.0f; //TODO change for PUSCH with CSI - return(10 * log10((f - 1) * beta)); + const int bw_factor = 10 * log10(rb << mu); + + return (delta_tf + bw_factor); } // For both UL-SCH except: @@ -114,7 +112,6 @@ int nr_process_mac_pdu(instance_t module_idP, { uint8_t done = 0; - int sdus = 0; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -247,13 +244,13 @@ int nr_process_mac_pdu(instance_t module_idP, // in sched_ctrl we set normalized PH wrt MCS and PRBs long *deltaMCS = ul_bwp->pusch_Config ? ul_bwp->pusch_Config->pusch_PowerControl->deltaMCS : NULL; sched_ctrl->ph = PH + - compute_bw_factor(sched_pusch->mu, sched_pusch->rbSize) + - compute_delta_tf(sched_pusch->tb_size<<3, - sched_pusch->rbSize, - 0, //n_layers - 0, //n_symbols - 0, //n_dmrs - deltaMCS); + compute_ph_factor(sched_pusch->mu, + sched_pusch->tb_size<<3, + sched_pusch->rbSize, + sched_pusch->nrOfLayers, + sched_pusch->tda_info.nrOfSymbols, //n_symbols + sched_pusch->dmrs_info.num_dmrs_symb*sched_pusch->dmrs_info.N_PRB_DMRS, //n_dmrs + deltaMCS); /* 38.133 Table10.1.18.1-1 */ sched_ctrl->pcmax = PCMAX - 29; LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n", @@ -263,6 +260,7 @@ int nr_process_mac_pdu(instance_t module_idP, case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: //38.321 section 6.1.3.9 // varialbe length + AssertFatal(1==0,"Multi entry PHR not supported\n"); if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) return 0; /* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */ @@ -271,6 +269,7 @@ int nr_process_mac_pdu(instance_t module_idP, case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT: //38.321 section 6.1.3.9 // varialbe length + AssertFatal(1==0,"Multi entry PHR not supported\n"); if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) return 0; /* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */ @@ -795,8 +794,8 @@ void handle_nr_srs_measurements(const module_id_t module_id, const uint8_t num_symbols, const uint8_t wide_band_snr, const uint8_t num_reported_symbols, - nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list) { - + nfapi_nr_srs_indication_reported_symbol_t *reported_symbol_list) +{ LOG_D(NR_MAC, "(%d.%d) Received SRS indication for rnti: 0x%04x\n", frame, slot, rnti); #ifdef SRS_IND_DEBUG @@ -805,32 +804,39 @@ void handle_nr_srs_measurements(const module_id_t module_id, LOG_I(NR_MAC, "rnti = 0x%04x\n", rnti); LOG_I(NR_MAC, "timing_advance = %i\n", timing_advance); LOG_I(NR_MAC, "num_symbols = %i\n", num_symbols); - LOG_I(NR_MAC, "wide_band_snr = %i (%i dB)\n", wide_band_snr, (wide_band_snr>>1)-64); + LOG_I(NR_MAC, "wide_band_snr = %i (%i dB)\n", wide_band_snr, (wide_band_snr >> 1) - 64); LOG_I(NR_MAC, "num_reported_symbols = %i\n", num_reported_symbols); LOG_I(NR_MAC, "reported_symbol_list[0].num_rbs = %i\n", reported_symbol_list[0].num_rbs); - for(int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { - LOG_I(NR_MAC, "reported_symbol_list[0].rb_list[%3i].rb_snr = %i (%i dB)\n", - rb, reported_symbol_list[0].rb_list[rb].rb_snr, (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64); + for (int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { + LOG_I(NR_MAC, "reported_symbol_list[0].rb_list[%3i].rb_snr = %i (%i dB)\n", rb, reported_symbol_list[0].rb_list[rb].rb_snr, (reported_symbol_list[0].rb_list[rb].rb_snr >> 1) - 64); } #endif NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, rnti); if (!UE) { - LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti); + LOG_E(NR_MAC, "Could not find UE for RNTI %04x\n", rnti); return; } + if (wide_band_snr == 0xFF) { + LOG_W(NR_MAC, "Invalid wide_band_snr for RNTI %04x\n", rnti); + return; + } + + int wide_band_snr_dB = (wide_band_snr >> 1) - 64; + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_mac_stats_t *stats = &UE->mac_stats; - stats->srs_wide_band_snr = (wide_band_snr>>1)-64; + stats->srs_wide_band_snr = wide_band_snr_dB; const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; uint16_t *ulprbbl = nr_mac->ulprbbl; - memset(ulprbbl, 0, reported_symbol_list[0].num_rbs*sizeof(uint16_t)); + memset(ulprbbl, 0, reported_symbol_list[0].num_rbs * sizeof(uint16_t)); + for (int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { - int snr = (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64; - if (snr < ul_prbblack_SNR_threshold) { + int snr = (reported_symbol_list[0].rb_list[rb].rb_snr >> 1) - 64; + if (snr < wide_band_snr_dB - ul_prbblack_SNR_threshold) { ulprbbl[rb] = 0x3FFF; // all symbols taken } LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]); @@ -903,8 +909,7 @@ void update_ul_ue_R_Qm(int mcs, int mcs_table, const NR_PUSCH_Config_t *pusch_Co } } - -void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_pusch_semi_static_t *ps, NR_UE_UL_BWP_t *ul_bwp, uint16_t minRb, uint32_t tbs, uint16_t *Rb, uint8_t *mcs) +void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_sched_pusch_t *sched_pusch, NR_UE_UL_BWP_t *ul_bwp, uint16_t minRb, uint32_t tbs, uint16_t *Rb, uint8_t *mcs) { AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb); AssertFatal(*mcs >= 0 && *mcs <= 28, "illegal MCS %d\n", *mcs); @@ -915,35 +920,35 @@ void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_pusch_semi_static_t *ps, NR_U update_ul_ue_R_Qm(*mcs, ul_bwp->mcs_table, ul_bwp->pusch_Config, &R, &Qm); long *deltaMCS = ul_bwp->pusch_Config ? ul_bwp->pusch_Config->pusch_PowerControl->deltaMCS : NULL; - int tx_power = compute_bw_factor(mu, *Rb) + - compute_delta_tf(tbs_bits, - *Rb, - ps->nrOfLayers, - ps->nrOfSymbols, - ps->N_PRB_DMRS*ps->num_dmrs_symb, - deltaMCS); + int tx_power = compute_ph_factor(mu, + tbs_bits, + *Rb, + sched_pusch->nrOfLayers, + sched_pusch->tda_info.nrOfSymbols, + sched_pusch->dmrs_info.N_PRB_DMRS*sched_pusch->dmrs_info.num_dmrs_symb, + deltaMCS); while (ph_limit < tx_power && *Rb >= minRb) { (*Rb)--; - tx_power = compute_bw_factor(mu, *Rb) + - compute_delta_tf(tbs_bits, - *Rb, - ps->nrOfLayers, - ps->nrOfSymbols, - ps->N_PRB_DMRS*ps->num_dmrs_symb, - deltaMCS); + tx_power = compute_ph_factor(mu, + tbs_bits, + *Rb, + sched_pusch->nrOfLayers, + sched_pusch->tda_info.nrOfSymbols, + sched_pusch->dmrs_info.N_PRB_DMRS*sched_pusch->dmrs_info.num_dmrs_symb, + deltaMCS); } while (ph_limit < tx_power && *mcs > 6) { (*mcs)--; update_ul_ue_R_Qm(*mcs, ul_bwp->mcs_table, ul_bwp->pusch_Config, &R, &Qm); - tx_power = compute_bw_factor(mu, *Rb) + - compute_delta_tf(tbs_bits, - *Rb, - ps->nrOfLayers, - ps->nrOfSymbols, - ps->N_PRB_DMRS*ps->num_dmrs_symb, - deltaMCS); + tx_power = compute_ph_factor(mu, + tbs_bits, + *Rb, + sched_pusch->nrOfLayers, + sched_pusch->tda_info.nrOfSymbols, + sched_pusch->dmrs_info.N_PRB_DMRS*sched_pusch->dmrs_info.num_dmrs_symb, + deltaMCS); } if (ph_limit < tx_power) @@ -971,22 +976,11 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, const uint8_t nrOfLayers = 1; LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); LOG_D(NR_MAC,"tbs %d\n",retInfo->tb_size); - if (tda == retInfo->time_domain_allocation) { - /* check whether we need to switch the TDA allocation since tha last - * (re-)transmission */ - NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; - - if (ps->time_domain_allocation != tda - || ps->nrOfLayers != nrOfLayers) { - nr_set_pusch_semi_static(&UE->current_UL_BWP, - scc, - tda, - nrOfLayers, - ps); - } + if (tda == retInfo->time_domain_allocation && + nrOfLayers == retInfo->nrOfLayers) { /* Check the resource is enough for retransmission */ - const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; if (rbStart + retInfo->rbSize > bwpSize) { @@ -995,15 +989,15 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, } LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); } else { - NR_pusch_semi_static_t temp_ps; - nr_set_pusch_semi_static(&UE->current_UL_BWP, - scc, - tda, - nrOfLayers, - &temp_ps); + + NR_tda_info_t tda_info = nr_get_pusch_tda_info(&UE->current_UL_BWP, tda); + NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, + &UE->current_UL_BWP, + &tda_info, + nrOfLayers); /* the retransmission will use a different time domain allocation, check * that we have enough resources */ - const uint16_t slbitmap = SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; int rbSize = 0; @@ -1014,8 +1008,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, bool success = nr_find_nb_rb(retInfo->Qm, retInfo->R, 1, // layers - temp_ps.nrOfSymbols, - temp_ps.N_PRB_DMRS * temp_ps.num_dmrs_symb, + tda_info.nrOfSymbols, + dmrs_info.N_PRB_DMRS * dmrs_info.num_dmrs_symb, retInfo->tb_size, 1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */ rbSize, @@ -1031,7 +1025,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, retInfo->tb_size = new_tbs; retInfo->rbSize = new_rbSize; retInfo->time_domain_allocation = tda; - sched_ctrl->pusch_semi_static = temp_ps; + retInfo->dmrs_info = dmrs_info; + retInfo->tda_info = tda_info; } /* Find a free CCE */ @@ -1089,7 +1084,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, /* Mark the corresponding RBs as used */ n_rb_sched -= sched_pusch->rbSize; for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= SL_to_bitmap(sched_ctrl->pusch_semi_static.startSymbolIndex, sched_ctrl->pusch_semi_static.nrOfSymbols); + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); return true; } @@ -1136,7 +1131,6 @@ void pf_ul(module_id_t module_id, const uint16_t bwpSize = current_BWP->BWPSize; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul; /* Calculate throughput */ @@ -1228,24 +1222,17 @@ void pf_ul(module_id_t module_id, if (remainUEs == 0) return; - /* Save PUSCH field */ - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ - const uint8_t nrOfLayers = 1; - const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); - if (ps->time_domain_allocation != tda - || ps->nrOfLayers != nrOfLayers) { - nr_set_pusch_semi_static(current_BWP, - scc, - tda, - nrOfLayers, - ps); - } + sched_pusch->nrOfLayers = 1; + sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_pusch->slot); + sched_pusch->tda_info = nr_get_pusch_tda_info(current_BWP, sched_pusch->time_domain_allocation); + sched_pusch->dmrs_info = get_ul_dmrs_params(scc, + current_BWP, + &sched_pusch->tda_info, + sched_pusch->nrOfLayers); LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d num_dmrs_cdm_grps_no_data %d\n", - min_rb, rbStart, ps->num_dmrs_cdm_grps_no_data); - const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + min_rb, rbStart, sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data); + const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; if (rbStart + min_rb >= bwpSize) { @@ -1269,11 +1256,11 @@ void pf_ul(module_id_t module_id, sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, sched_pusch->R, sched_pusch->rbSize, - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->num_dmrs_symb, + sched_pusch->tda_info.nrOfSymbols, + sched_pusch->dmrs_info.N_PRB_DMRS * sched_pusch->dmrs_info.num_dmrs_symb, 0, // nb_rb_oh 0, - ps->nrOfLayers) + sched_pusch->nrOfLayers) >> 3; /* Mark the corresponding RBs as used */ @@ -1333,26 +1320,19 @@ void pf_ul(module_id_t module_id, const uint16_t bwpSize = current_BWP->BWPSize; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; - /* Save PUSCH field */ - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether TDA, or - * num_dmrs_cdm_grps_no_data has changed and only then recompute */ - const uint8_t nrOfLayers = 1; - const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); - if (ps->time_domain_allocation != tda - || ps->nrOfLayers != nrOfLayers) { - nr_set_pusch_semi_static(current_BWP, - scc, - tda, - nrOfLayers, - ps); - } + sched_pusch->nrOfLayers = 1; + sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_pusch->slot); + sched_pusch->tda_info = nr_get_pusch_tda_info(current_BWP, sched_pusch->time_domain_allocation); + sched_pusch->dmrs_info = get_ul_dmrs_params(scc, + current_BWP, + &sched_pusch->tda_info, + sched_pusch->nrOfLayers); + update_ul_ue_R_Qm(sched_pusch->mcs, current_BWP->mcs_table, current_BWP->pusch_Config, &sched_pusch->R, &sched_pusch->Qm); int rbStart = 0; - const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; sched_pusch->rbStart = rbStart; @@ -1374,7 +1354,7 @@ void pf_ul(module_id_t module_id, sched_pusch->mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; if(sched_ctrl->pcmax!=0 || sched_ctrl->ph!=0) // verify if the PHR related parameter have been initialized - nr_ue_max_mcs_min_rb(sched_pusch->mu, sched_ctrl->ph, ps, current_BWP, min_rbSize, B, &max_rbSize, &sched_pusch->mcs); + nr_ue_max_mcs_min_rb(current_BWP->scs, sched_ctrl->ph, sched_pusch, current_BWP, min_rbSize, B, &max_rbSize, &sched_pusch->mcs); if (sched_pusch->mcs < sched_ctrl->ul_bler_stats.mcs) sched_ctrl->ul_bler_stats.mcs = sched_pusch->mcs; /* force estimated MCS down */ @@ -1385,8 +1365,8 @@ void pf_ul(module_id_t module_id, nr_find_nb_rb(sched_pusch->Qm, sched_pusch->R, 1, // layers - ps->nrOfSymbols, - ps->N_PRB_DMRS * ps->num_dmrs_symb, + sched_pusch->tda_info.nrOfSymbols, + sched_pusch->dmrs_info.N_PRB_DMRS * sched_pusch->dmrs_info.num_dmrs_symb, B, min_rbSize, max_rbSize, @@ -1396,7 +1376,8 @@ void pf_ul(module_id_t module_id, sched_pusch->rbSize = rbSize; sched_pusch->tb_size = TBS; LOG_D(NR_MAC,"rbSize %d (max_rbSize %d), TBS %d, est buf %d, sched_ul %d, B %d, CCE %d, num_dmrs_symb %d, N_PRB_DMRS %d\n", - rbSize, max_rbSize,sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B,sched_ctrl->cce_index,ps->num_dmrs_symb,ps->N_PRB_DMRS); + rbSize, max_rbSize,sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B, + sched_ctrl->cce_index,sched_pusch->dmrs_info.num_dmrs_symb,sched_pusch->dmrs_info.N_PRB_DMRS); /* Mark the corresponding RBs as used */ @@ -1621,11 +1602,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) int rnti_types[2] = { NR_RNTI_C, 0 }; - /* pre-computed PUSCH values that only change if time domain allocation, - * DCI format, or DMRS parameters change. Updated in the preprocessor - * through nr_set_pusch_semi_static() */ - NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; - /* Statistics */ AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); UE->mac_stats.ul.rounds[cur_harq->round]++; @@ -1636,7 +1612,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) cur_harq->sched_pusch = *sched_pusch; /* save which time allocation has been used, to be used on * retransmissions */ - cur_harq->sched_pusch.time_domain_allocation = ps->time_domain_allocation; + cur_harq->sched_pusch.time_domain_allocation = sched_pusch->time_domain_allocation; sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; UE->mac_stats.ul.total_rbs += sched_pusch->rbSize; @@ -1668,12 +1644,12 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) sched_ctrl->aggregation_level, sched_pusch->rbStart, sched_pusch->rbSize, - ps->startSymbolIndex, - ps->nrOfSymbols, - ps->ul_dmrs_symb_pos, + sched_pusch->tda_info.startSymbolIndex, + sched_pusch->tda_info.nrOfSymbols, + sched_pusch->dmrs_info.ul_dmrs_symb_pos, sched_pusch->mcs, - ps->nrOfLayers, - ps->num_dmrs_cdm_grps_no_data, + sched_pusch->nrOfLayers, + sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data, sched_pusch->tb_size, harq_id, cur_harq->round, @@ -1728,18 +1704,19 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->data_scrambling_id = *current_BWP->pusch_Config->dataScramblingIdentityPUSCH; else pusch_pdu->data_scrambling_id = *scc->physCellId; - pusch_pdu->nrOfLayers = ps->nrOfLayers; - pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; + pusch_pdu->nrOfLayers = sched_pusch->nrOfLayers; + pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data; /* FAPI: DMRS */ - pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos; - pusch_pdu->dmrs_config_type = ps->dmrs_config_type; + pusch_pdu->ul_dmrs_symb_pos = sched_pusch->dmrs_info.ul_dmrs_symb_pos; + pusch_pdu->dmrs_config_type = sched_pusch->dmrs_info.dmrs_config_type; + const NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = sched_pusch->dmrs_info.NR_DMRS_UplinkConfig; if (pusch_pdu->transform_precoding) { // transform precoding disabled long *scramblingid=NULL; - if (ps->NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) - scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; - else if (ps->NR_DMRS_UplinkConfig) - scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1; + if (NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) + scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; + else if (NR_DMRS_UplinkConfig) + scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1; if (scramblingid == NULL) pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; else @@ -1747,14 +1724,14 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) } else { pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; - if (ps->NR_DMRS_UplinkConfig && ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) - pusch_pdu->pusch_identity = *ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity; - else if (ps->NR_DMRS_UplinkConfig) + if (NR_DMRS_UplinkConfig && NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) + pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity; + else if (NR_DMRS_UplinkConfig) pusch_pdu->pusch_identity = *scc->physCellId; } pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] - pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; - pusch_pdu->dmrs_ports = ((1<nrOfLayers) - 1); + pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data; + pusch_pdu->dmrs_ports = ((1<nrOfLayers) - 1); /* FAPI: Pusch Allocation in frequency domain */ pusch_pdu->resource_alloc = 1; //type 1 @@ -1767,8 +1744,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->frequency_hopping = 1; /* FAPI: Resource Allocation in time domain */ - pusch_pdu->start_symbol_index = ps->startSymbolIndex; - pusch_pdu->nr_of_symbols = ps->nrOfSymbols; + pusch_pdu->start_symbol_index = sched_pusch->tda_info.startSymbolIndex; + pusch_pdu->nr_of_symbols = sched_pusch->tda_info.nrOfSymbols; /* PUSCH PDU */ AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round%4); @@ -1804,8 +1781,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30; // V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled - if ((ps->NR_DMRS_UplinkConfig==NULL) || ((ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) && - (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping == NULL))) + if ((NR_DMRS_UplinkConfig==NULL) || ((NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) && + (NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping == NULL))) pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; else AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); @@ -1816,10 +1793,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) /*-----------------------------------------------------------------------------*/ /* PUSCH PTRS */ - if (ps->NR_DMRS_UplinkConfig && ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) { + if (NR_DMRS_UplinkConfig && NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) { bool valid_ptrs_setup = false; pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); - valid_ptrs_setup = set_ul_ptrs_values(ps->NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup, + valid_ptrs_setup = set_ul_ptrs_values(NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup, pusch_pdu->rb_size, pusch_pdu->mcs_index, pusch_pdu->mcs_table, &pusch_pdu->pusch_ptrs.ptrs_freq_density,&pusch_pdu->pusch_ptrs.ptrs_time_density, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset,&pusch_pdu->pusch_ptrs.num_ptrs_ports, @@ -1875,7 +1852,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) scc, pusch_pdu, &uldci_payload, - ps->time_domain_allocation, + sched_pusch->time_domain_allocation, UE->UE_sched_ctrl.tpc0, current_BWP); fill_dci_pdu_rel15(scc, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 6a3f778af9..20e3865387 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -87,9 +87,8 @@ uint32_t schedule_control_sib1(module_id_t module_id, int CC_id, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, int time_domain_allocation, - int startSymbolIndex, - int nrOfSymbols, - uint16_t dlDmrsSymbPos, + NR_pdsch_dmrs_t *dmrs_parms, + NR_tda_info_t *tda_info, uint8_t candidate_idx, uint16_t num_total_bytes); @@ -325,18 +324,16 @@ long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, int mu); -void nr_set_pdsch_semi_static(const NR_UE_DL_BWP_t *dl_bwp, - const NR_ServingCellConfigCommon_t *scc, - int tda, - uint8_t layers, - NR_UE_sched_ctrl_t *sched_ctrl, - NR_pdsch_semi_static_t *ps); +NR_tda_info_t nr_get_pdsch_tda_info(const NR_UE_DL_BWP_t *dl_bwp, + const int tda); -void nr_set_pusch_semi_static(const NR_UE_UL_BWP_t *ul_bwp, - const NR_ServingCellConfigCommon_t *scc, - int tda, - uint8_t nrOfLayers, - NR_pusch_semi_static_t *ps); +NR_tda_info_t nr_get_pusch_tda_info(const NR_UE_UL_BWP_t *ul_bwp, + const int tda); + +NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc, + const NR_UE_UL_BWP_t *ul_bwp, + const NR_tda_info_t *tda_info, + const int Layers); uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); @@ -460,16 +457,18 @@ int16_t ssb_index_from_prach(module_id_t module_idP, void find_SSB_and_RO_available(module_id_t module_idP); -void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps); +NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc, + const NR_UE_DL_BWP_t *BWP, + const NR_tda_info_t *tda_info, + const int Layers); -uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl, +uint16_t get_pm_index(const NR_UE_info_t *UE, int layers, - int N1, int N2, - int xp_pdsch_antenna_ports, - int codebook_mode); + int xp_pdsch_antenna_ports); uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx); -uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl); + +uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format); const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index b272561a2d..b103182a67 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -45,7 +45,7 @@ extern RAN_CONTEXT_t RC; -#define MACSTATSSTRLEN 65536 +#define MACSTATSSTRLEN 16000 void *nrmac_stats_thread(void *arg) { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 346f1f8516..44d5ff6e34 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -43,7 +43,7 @@ #include /* Commmon */ -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" #include "COMMON/platform_constants.h" #include "common/ran_context.h" #include "collection/linear_alloc.h" @@ -373,23 +373,20 @@ typedef struct NR_sched_pucch { int start_symb; } NR_sched_pucch_t; -/* PUSCH semi-static configuration: as long as the TDA and DCI format remain - * the same over the same uBWP and search space, there is no need to - * recalculate all S/L, MCS table, or DMRS-related parameters over and over - * again. Hence, we store them in this struct for easy reference. */ -typedef struct NR_pusch_semi_static_t { - int time_domain_allocation; - uint8_t nrOfLayers; - uint8_t num_dmrs_cdm_grps_no_data; +typedef struct NR_tda_info { + mappingType_t mapping_type; int startSymbolIndex; int nrOfSymbols; - long mapping_type; - NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; - uint16_t dmrs_config_type; - uint16_t ul_dmrs_symb_pos; - uint8_t num_dmrs_symb; +} NR_tda_info_t; + +typedef struct NR_pusch_dmrs { uint8_t N_PRB_DMRS; -} NR_pusch_semi_static_t; + uint8_t num_dmrs_symb; + uint16_t ul_dmrs_symb_pos; + uint8_t num_dmrs_cdm_grps_no_data; + nfapi_nr_dmrs_type_e dmrs_config_type; + NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; +} NR_pusch_dmrs_t; typedef struct NR_sched_pusch { int frame; @@ -411,10 +408,11 @@ typedef struct NR_sched_pusch { /// UL HARQ PID to use for this UE, or -1 for "any new" int8_t ul_harq_pid; - /// the Time Domain Allocation used for this transmission. Note that this is - /// only important for retransmissions; otherwise, the TDA in - /// NR_pusch_semi_static_t has precedence + uint8_t nrOfLayers; + // time_domain_allocation is the index of a list of tda int time_domain_allocation; + NR_tda_info_t tda_info; + NR_pusch_dmrs_t dmrs_info; } NR_sched_pusch_t; typedef struct NR_sched_srs { @@ -423,24 +421,14 @@ typedef struct NR_sched_srs { bool srs_scheduled; } NR_sched_srs_t; -/* PDSCH semi-static configuratio: as long as the TDA/DMRS/mcsTable remains the - * same, there is no need to recalculate all S/L or DMRS-related parameters - * over and over again. Hence, we store them in this struct for easy - * reference. */ -typedef struct NR_pdsch_semi_static { - int time_domain_allocation; - uint8_t numDmrsCdmGrpsNoData; - uint8_t frontloaded_symb; - int mapping_type; - int startSymbolIndex; - int nrOfSymbols; - uint8_t nrOfLayers; +typedef struct NR_pdsch_dmrs { uint8_t dmrs_ports_id; uint8_t N_PRB_DMRS; uint8_t N_DMRS_SLOT; uint16_t dl_dmrs_symb_pos; + uint8_t numDmrsCdmGrpsNoData; nfapi_nr_dmrs_type_e dmrsConfigType; -} NR_pdsch_semi_static_t; +} NR_pdsch_dmrs_t; typedef struct NR_sched_pdsch { /// RB allocation within active BWP @@ -461,11 +449,13 @@ typedef struct NR_sched_pdsch { // pucch format allocation uint8_t pucch_allocation; - /// the Time Domain Allocation used for this transmission. Note that this is - /// only important for retransmissions; otherwise, the TDA in - /// NR_pdsch_semi_static_t has precedence - int time_domain_allocation; + uint16_t pm_index; uint8_t nrOfLayers; + + NR_pdsch_dmrs_t dmrs_parms; + // time_domain_allocation is the index of a list of tda + int time_domain_allocation; + NR_tda_info_t tda_info; } NR_sched_pdsch_t; typedef struct NR_UE_harq { @@ -578,8 +568,6 @@ typedef struct { /// CSI in second. This order is important for nr_acknack_scheduling()! NR_sched_pucch_t sched_pucch[2]; - /// PUSCH semi-static configuration: is not cleared across TTIs - NR_pusch_semi_static_t pusch_semi_static; /// Sched PUSCH: scheduling decisions, copied into HARQ and cleared every TTI NR_sched_pusch_t sched_pusch; @@ -596,8 +584,6 @@ typedef struct { /// PHR info: nominal UE transmit power levels (dBm) int pcmax; - /// PDSCH semi-static configuration: is not cleared across TTIs - NR_pdsch_semi_static_t pdsch_semi_static; /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI NR_sched_pdsch_t sched_pdsch; /// UE-estimated maximum MCS (from CSI-RS) @@ -632,7 +618,6 @@ typedef struct { int ul_failure; struct CSI_Report CSI_report; bool SR; - bool set_pmi; /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; /// HARQ processes that are free @@ -720,7 +705,6 @@ typedef struct { NR_gNB_UCI_STATS_t uci_statS; float ul_thr_ue; float dl_thr_ue; - int layers; } NR_UE_info_t; typedef struct { diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index ec90817500..1e2266adb1 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -590,7 +590,7 @@ void rlc_data_ind ( T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); #endif const ngran_node_t type = RC.rrc[ctxt_pP->module_id]->node_type; - AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU, + AssertFatal(!NODE_IS_CU(type), "Can't be CU, bad node type %d\n", type); if (NODE_IS_DU(type) && srb_flagP == 1) { diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 30d1d13baa..71b7c3b3c4 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -514,7 +514,7 @@ rb_found: T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); const ngran_node_t type = RC.nrrrc[0 /*ctxt_pP->module_id*/]->node_type; - AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU, + AssertFatal(!NODE_IS_CU(type), "Can't be CU, bad node type %d\n", type); // if (NODE_IS_DU(type) && is_srb == 0) { @@ -1102,7 +1102,7 @@ void nr_rlc_tick(int frame, int subframe) } /* This is a hack, to compile the gNB. - * TODO: remove it. The solution is to cleanup cmake_targets/CMakeLists.txt + * TODO: remove it. The solution is to cleanup CMakeLists.txt */ void rlc_tick(int a, int b) { diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c index 11ae770e3e..914484c1b6 100644 --- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c +++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c @@ -415,7 +415,7 @@ rb_found: T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); const ngran_node_t type = RC.rrc[0 /*ctxt_pP->module_id*/]->node_type; - AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU, + AssertFatal(!NODE_IS_CU(type), "Can't be CU, bad node type %d\n", type); if (NODE_IS_DU(type)) { diff --git a/openair2/MCE_APP/mce_config.c b/openair2/MCE_APP/mce_config.c index 9d9d9028e5..dfbea5c652 100644 --- a/openair2/MCE_APP/mce_config.c +++ b/openair2/MCE_APP/mce_config.c @@ -45,7 +45,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "PHY/phy_extern.h" #include "PHY/INIT/phy_init.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "nfapi_vnf.h" #include "nfapi_pnf.h" diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index cefafcba80..f74f213cf0 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -45,7 +45,7 @@ #include "openair2/RRC/NR_UE/rrc_vars.h" #include "openair2/GNB_APP/L1_nr_paramdef.h" #include "openair2/GNB_APP/gnb_paramdef.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" #include #define MAX_IF_MODULES 100 diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index b1123dce5f..d446c23938 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -1,5 +1,4 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + /* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under @@ -39,6 +38,8 @@ #include "nfapi_interface.h" #include "platform_types.h" #include +#include + #define MAX_NUM_DL_PDU 100 #define MAX_NUM_UL_PDU 100 @@ -135,7 +136,6 @@ typedef struct { int CC_id; nfapi_config_request_t *cfg; } PHY_Config_t; -#include typedef struct IF_Module_s{ //define the function pointer diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index cd57ea9ff1..28aeac880a 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -27,7 +27,7 @@ #include "openair2/PHY_INTERFACE/phy_stub_UE.h" #include "openair2/ENB_APP/L1_paramdef.h" #include "openair2/ENB_APP/enb_paramdef.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" #include "common/config/config_load_configmodule.h" #include "common/config/config_userapi.h" #include diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index aefbc01831..7154b34962 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1004,9 +1004,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char } - if ((RC.rrc[ctxt.module_id]->node_type == ngran_eNB_CU) || - (RC.rrc[ctxt.module_id]->node_type == ngran_ng_eNB_CU) || - (RC.rrc[ctxt.module_id]->node_type == ngran_gNB_CU) ){ + if (NODE_IS_CU(RC.rrc[ctxt.module_id]->node_type)) { struct eNB_RRC_INST_s *rrc= RC.rrc[0]; MessageDef *message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_SETUP_REQ); f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 47b6e38402..af7bdcfbc7 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -983,7 +983,6 @@ uint8_t do_RRCReject(uint8_t Mod_id, return((enc_rval.encoded+7)/8); } - void fill_initial_SpCellConfig(int uid, NR_SpCellConfig_t *SpCellConfig, const NR_ServingCellConfigCommon_t *scc, @@ -1061,7 +1060,8 @@ void fill_initial_SpCellConfig(int uid, ASN_SEQUENCE_ADD(&pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList->list,plrefRS); pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL; pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL; - pusch_Config->pusch_PowerControl->deltaMCS = NULL; + pusch_Config->pusch_PowerControl->deltaMCS = calloc(1, sizeof(*pusch_Config->pusch_PowerControl->deltaMCS)); + *pusch_Config->pusch_PowerControl->deltaMCS = NR_PUSCH_PowerControl__deltaMCS_enabled; pusch_Config->pusch_PowerControl->sri_PUSCH_MappingToAddModList = calloc(1,sizeof(*pusch_Config->pusch_PowerControl->sri_PUSCH_MappingToAddModList)); NR_SRI_PUSCH_PowerControl_t *sriPUSCHPC=calloc(1,sizeof(*sriPUSCHPC)); sriPUSCHPC->sri_PUSCH_PowerControlId=0; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index deb2c4965e..d53288fd61 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -1112,7 +1112,8 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp, pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList = NULL; pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL; pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL; - pusch_Config->pusch_PowerControl->deltaMCS = NULL; + pusch_Config->pusch_PowerControl->deltaMCS = calloc(1, sizeof(*pusch_Config->pusch_PowerControl->deltaMCS)); + *pusch_Config->pusch_PowerControl->deltaMCS = NR_PUSCH_PowerControl__deltaMCS_enabled; pusch_Config->pusch_PowerControl->sri_PUSCH_MappingToAddModList = NULL; pusch_Config->pusch_PowerControl->sri_PUSCH_MappingToReleaseList = NULL; pusch_Config->frequencyHopping=NULL; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 8be829f51f..7361c56658 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -524,7 +524,7 @@ rrc_gNB_process_RRCSetupComplete( ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1; ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); } else { rrc_gNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP); @@ -868,11 +868,12 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( DRB_config->pdcp_Config->drb->integrityProtection = NULL; DRB_config->pdcp_Config->drb->statusReportRequired = NULL; - DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL; + DRB_config->pdcp_Config->drb->outOfOrderDelivery = calloc(1,sizeof(*DRB_config->pdcp_Config->drb->outOfOrderDelivery)); + *DRB_config->pdcp_Config->drb->outOfOrderDelivery = NR_PDCP_Config__drb__outOfOrderDelivery_true; DRB_config->pdcp_Config->moreThanOneRLC = NULL; DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering)); - *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; + *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms20; DRB_config->pdcp_Config->ext1 = NULL; if (rrc->security.do_drb_integrity) { @@ -1616,7 +1617,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.Srb1.Active = 1; //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { hashtable_rc_t h_rc; int j; rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; @@ -1693,13 +1694,13 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.ul_failure_timer = 0; return; } - } /* AMF_MODE_ENABLED */ + } /* Update RNTI in ue_context */ ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else ue_context_pP->ue_context.rnti = ctxt_pP->rnti; - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { uint8_t send_security_mode_command = false; nr_rrc_pdcp_config_security( ctxt_pP, @@ -2342,7 +2343,7 @@ rrc_gNB_decode_dcch( ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); } - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { if(ue_context_p->ue_context.pdu_session_release_command_flag == 1) { xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier; ue_context_p->ue_context.pdu_session_release_command_flag = 0; @@ -2475,7 +2476,7 @@ rrc_gNB_decode_dcch( LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, "[MSG] RRC UL Information Transfer \n"); - if (AMF_MODE_ENABLED == 1) { + if (get_softmodem_params()->sa) { rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg); @@ -2623,7 +2624,7 @@ rrc_gNB_decode_dcch( if(eutra_index == -1) break; } - if (AMF_MODE_ENABLED == 1) { + if (get_softmodem_params()->sa) { rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ul_dcch_msg); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 1dca25b618..3c61ec8dc2 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -424,7 +424,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList = NULL; pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL; pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL; - pusch_Config->pusch_PowerControl->deltaMCS = NULL; + pusch_Config->pusch_PowerControl->deltaMCS = calloc(1, sizeof(*pusch_Config->pusch_PowerControl->deltaMCS)); + *pusch_Config->pusch_PowerControl->deltaMCS = NR_PUSCH_PowerControl__deltaMCS_enabled; pusch_Config->pusch_PowerControl->sri_PUSCH_MappingToAddModList = NULL; pusch_Config->pusch_PowerControl->sri_PUSCH_MappingToReleaseList = NULL; pusch_Config->frequencyHopping=NULL; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bf4f053ba6..a1a5665a01 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -152,7 +152,7 @@ static int nr_rrc_set_state (module_id_t ue_mod_idP, Rrc_State_NR_t state) { } static int nr_rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_NR_t subState ) { - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { switch (NR_UE_rrc_inst[ue_mod_idP].nrRrcState) { case RRC_STATE_INACTIVE_NR: AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST_NR), @@ -835,7 +835,7 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index // After SI is received, prepare RRCConnectionRequest if (NR_UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option - if (AMF_MODE_ENABLED) { + if (get_softmodem_params()->sa) { nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index ); } @@ -1341,20 +1341,16 @@ static void rrc_ue_generate_RRCSetupComplete( const char *nas_msg; int nas_msg_length; - if (AMF_MODE_ENABLED) { - if (get_softmodem_params()->sa) { - as_nas_info_t initialNasMsg; - generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); - nas_msg = (char*)initialNasMsg.data; - nas_msg_length = initialNasMsg.length; - } else { - nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; - nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; - } + if (get_softmodem_params()->sa) { + as_nas_info_t initialNasMsg; + generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); + nas_msg = (char*)initialNasMsg.data; + nas_msg_length = initialNasMsg.length; } else { nas_msg = nr_nas_attach_req_imsi; nas_msg_length = sizeof(nr_nas_attach_req_imsi); } + size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer), Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", @@ -1708,9 +1704,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) { uint8_t i=0,rv[6]; - if(get_softmodem_params()->sa) { - AMF_MODE_ENABLED = 1; - } if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { // Get RRCConnectionRequest, fill random for now // Generate random byte stream for contention resolution @@ -1802,7 +1795,7 @@ nr_rrc_ue_establish_srb2( LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n", ue_mod_idP, frameP, DRB_config->drb_Identity); - if(!AMF_MODE_ENABLED) { + if(!get_softmodem_params()->sa) { ip_addr_offset3 = 0; ip_addr_offset4 = 1; LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, diff --git a/openair3/MME_APP/mme_config.c b/openair3/MME_APP/mme_config.c index 8005b85fd4..d51795a91a 100644 --- a/openair3/MME_APP/mme_config.c +++ b/openair3/MME_APP/mme_config.c @@ -45,7 +45,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "PHY/phy_extern.h" #include "PHY/INIT/phy_init.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "nfapi_vnf.h" #include "nfapi_pnf.h" diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 59e275ad53..bce973354b 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -64,8 +64,6 @@ #include "oaisim_amf_test_s1c.h" #endif -ngap_gNB_config_t ngap_config; - static int ngap_gNB_generate_ng_setup_request( ngap_gNB_instance_t *instance_p, ngap_gNB_amf_data_t *ngap_amf_data_p); diff --git a/openair3/NGAP/ngap_gNB.h b/openair3/NGAP/ngap_gNB.h index e6a24acdb4..2aa0080cd1 100644 --- a/openair3/NGAP/ngap_gNB.h +++ b/openair3/NGAP/ngap_gNB.h @@ -39,18 +39,6 @@ #ifndef NGAP_GNB_H_ #define NGAP_GNB_H_ -typedef struct ngap_gNB_config_s { - // MME related params - unsigned char amf_enabled; ///< AMF enabled ? - unsigned char ngap_enabled; ///< NGAP enabled ? -} ngap_gNB_config_t; - -extern ngap_gNB_config_t ngap_config; - -#define AMF_MODE_ENABLED ngap_config.amf_enabled -#define NGAP_CONF_MODE ngap_config.ngap_enabled - - void *ngap_gNB_process_itti_msg(void*); void ngap_gNB_init(void); void *ngap_gNB_task(void *arg); diff --git a/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_QuickStart.readme b/sdr/ADRV9371_ZC706/SYRTEM_IQ_QuickStart.readme similarity index 98% rename from targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_QuickStart.readme rename to sdr/ADRV9371_ZC706/SYRTEM_IQ_QuickStart.readme index cd74fdb397..82814a1d58 100755 --- a/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_QuickStart.readme +++ b/sdr/ADRV9371_ZC706/SYRTEM_IQ_QuickStart.readme @@ -22,7 +22,7 @@ git checkout 375-syrtem-sdr-platform or git checkout develop-nr (after merge request accepted) -./targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh +./sdr/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh -> Reading package lists... Done -> Building dependency tree -> Reading state information... Done diff --git a/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh b/sdr/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh similarity index 100% rename from targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh rename to sdr/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh diff --git a/targets/ARCH/AW2SORI/oaiori.c b/sdr/AW2SORI/oaiori.c similarity index 96% rename from targets/ARCH/AW2SORI/oaiori.c rename to sdr/AW2SORI/oaiori.c index 3c424086dd..07a90a2129 100644 --- a/targets/ARCH/AW2SORI/oaiori.c +++ b/sdr/AW2SORI/oaiori.c @@ -16,19 +16,21 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include "common_lib.h" #include "ethernet_lib.h" - +#include "common/utils/system.h" #include "ori.h" -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" typedef struct eutra_bandentry_s { int16_t band; @@ -250,7 +252,6 @@ int aw2s_startstreaming(openair0_device *device) { } ORI_Object_s *link= ORI_FindObject(ori, ORI_ObjectType_ORILink, 0, NULL); - if (tx0 == NULL || (tx1 == NULL && openair0_cfg->tx_num_channels > 1) || (tx2 == NULL && openair0_cfg->tx_num_channels > 2) || @@ -335,7 +336,7 @@ int aw2s_startstreaming(openair0_device *device) { printf("\n\n\n========================================================\n"); /* Put Tx3 into service */ - result = ORI_ObjectStateModification(ori, tx1, ORI_AST_Unlocked, &RE_result); + result = ORI_ObjectStateModification(ori, tx3, ORI_AST_Unlocked, &RE_result); if(result != ORI_Result_SUCCESS) { printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result)); @@ -402,7 +403,7 @@ int aw2s_startstreaming(openair0_device *device) { if (rx3) { printf("\n\n\n========================================================\n"); - /* Put Rx1 into service */ + /* Put Rx3 into service */ result = ORI_ObjectStateModification(ori, rx3, ORI_AST_Unlocked, &RE_result); if(result != ORI_Result_SUCCESS) { @@ -412,37 +413,8 @@ int aw2s_startstreaming(openair0_device *device) { } printf("ORI_ObjectStateModify: %s\n", ORI_Result_Print(RE_result)); } - /* - while (rx0->fst != ORI_FST_Operational || - (openair0_cfg->rx_num_channels > 1 && rx1->fst != ORI_FST_Operational) || - tx0->fst != ORI_FST_Operational || - (openair0_cfg->tx_num_channels > 1 && tx1->fst != ORI_FST_Operational)) - {}*/ - // test RX interface - uint64_t TS; - char temp_rx[2048] __attribute__((aligned(32))); - int aid,r0=0,r1=(openair0_cfg->rx_num_channels > 1) ? 0 : 1; - int r2=(openair0_cfg->rx_num_channels > 2) ? 0 : 1; - int r3=(openair0_cfg->rx_num_channels > 3) ? 0 : 1; - int i; - int Npackets=1024000; - for (i=0;itrx_read_func2(device, - (openair0_timestamp*)&TS, - (void*)temp_rx, - 256, - &aid); - if (aid == 0) r0=1; - if (aid == 1) r1=1; - if (aid == 2) r2=1; - if (aid == 3) r3=1; - } - if (r0==1 && r1==1 && r2==1 && r3==1) printf("Streaming started, returning to OAI\n"); - else { - printf("Didn't get anything from one antenna port after %d packets %d,%d,%d,%d\n",Npackets,r0,r1,r2,r3); - return(-1); - } + device->fhstate.active=1; return(0); } @@ -924,7 +896,7 @@ int aw2s_oriinit(openair0_device *device) { int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) { - + printf("Initializing AW2S (%p,%p,%p)\n",aw2s_oriinit,aw2s_oricleanup,aw2s_startstreaming); device->thirdparty_init = aw2s_oriinit; device->thirdparty_cleanup = aw2s_oricleanup; device->thirdparty_startstreaming = aw2s_startstreaming; diff --git a/targets/ARCH/AW2SORI/ori.h b/sdr/AW2SORI/ori.h similarity index 100% rename from targets/ARCH/AW2SORI/ori.h rename to sdr/AW2SORI/ori.h diff --git a/targets/ARCH/BLADERF/README b/sdr/BLADERF/README similarity index 100% rename from targets/ARCH/BLADERF/README rename to sdr/BLADERF/README diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/sdr/BLADERF/USERSPACE/LIB/bladerf_lib.c similarity index 100% rename from targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c rename to sdr/BLADERF/USERSPACE/LIB/bladerf_lib.c diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h b/sdr/BLADERF/USERSPACE/LIB/bladerf_lib.h similarity index 100% rename from targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h rename to sdr/BLADERF/USERSPACE/LIB/bladerf_lib.h diff --git a/targets/ARCH/COMMON/common_lib.c b/sdr/COMMON/common_lib.c similarity index 100% rename from targets/ARCH/COMMON/common_lib.c rename to sdr/COMMON/common_lib.c diff --git a/targets/ARCH/COMMON/common_lib.h b/sdr/COMMON/common_lib.h similarity index 92% rename from targets/ARCH/COMMON/common_lib.h rename to sdr/COMMON/common_lib.h index 07fea1aa5c..71607cb27f 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/sdr/COMMON/common_lib.h @@ -37,6 +37,7 @@ #include #include #include "record_player.h" +#include /* default name of shared library implementing the radio front end */ #define OAI_RF_LIBNAME "oai_device" @@ -153,6 +154,14 @@ typedef enum { gpsdo=2 } clock_source_t; +/*! \brief Structure used for initializing UDP read threads */ +typedef struct { + openair0_device *device; + int thread_id; + pthread_t pthread; + notifiedFIFO_t *resp; +} udp_ctx_t; + /*! \brief RF frontend parameters set by application */ typedef struct { @@ -184,7 +193,9 @@ typedef struct { char* tx_subdev; //! \brief RX base addresses for mmapped_dma int32_t *rxbase[4]; - //! \brief TX base addresses for mmapped_dma + //! \brief RX buffer size for direct access + int rxsize; + //! \brief TX base addresses for mmapped_dma or direct access int32_t *txbase[4]; //! \brief Center frequency in Hz for RX. //! index: [0..rx_num_channels[ @@ -250,6 +261,10 @@ typedef struct { int nr_band; //! NR scs for raster int nr_scs_for_raster; + //! Core IDs for RX FH + int rxfh_cores[4]; + //! Core IDs for TX FH + int txfh_cores[4]; } openair0_config_t; /*! \brief RF mapping */ @@ -318,6 +333,19 @@ typedef struct { bool write_thread_exit; } openair0_thread_t; +typedef struct fhstate_s { + openair0_timestamp TS[8]; + openair0_timestamp TS0; + openair0_timestamp olddeltaTS[8]; + openair0_timestamp oldTS[8]; + openair0_timestamp TS_read; + int first_read; + uint32_t *buff[8]; + uint32_t buff_size; + int r[8]; + int active; +} fhstate_t; + /*!\brief structure holds the parameters to configure USRP devices */ struct openair0_device_t { /*!tx write thread*/ @@ -352,6 +380,24 @@ struct openair0_device_t { /*!brief Can be used by driver to hold internal structure*/ void *priv; + /*!brief pointer to FH state, used in ECPRI split 8*/ + fhstate_t fhstate; + + /*!brief message response for notification fifo*/ + notifiedFIFO_t *respudpTX; + + /*!brief UDP TX thread context*/ + udp_ctx_t **utx; + + /*!brief Used in ECPRI split 8 to indicate numerator of sampling rate ratio*/ + int sampling_rate_ratio_n; + + /*!brief Used in ECPRI split 8 to indicate denominator of sampling rate ratio*/ + int sampling_rate_ratio_d; + + /*!brief Used in ECPRI split 8 to indicate the TX/RX timing offset*/ + int txrx_offset; + /* Functions API, which are called by the application*/ /*! \brief Called to start the transceiver. Return 0 if OK, < 0 if error @@ -398,7 +444,7 @@ struct openair0_device_t { @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to true if timestamp parameter needs to be applied */ - int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int antenna_id, int flags); + int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void **buff, int fd_ind,int nsamps, int flags,int nant); /*! \brief Receive samples from hardware. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for @@ -420,12 +466,13 @@ struct openair0_device_t { * was received. * \param device the hardware to use * \param[out] ptimestamp the time at which the first sample was received. - * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps. + * \param[out] buff A pointer to a buffer[ant_id][] for received samples. The buffer[ant_id] must be large enough to hold the number of samples \ref nsamps * the number of packets. * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param packet_idx offset into * \param antenna_id Index of antenna from which samples were received * \returns the number of sample read */ - int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, void *buff, int nsamps,int *antenna_id); + int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, uint32_t **buff, int nsamps); /*! \brief print the device statistics * \param device the hardware to use @@ -474,6 +521,7 @@ struct openair0_device_t { /*! \brief Pointer to generic RRU private information */ + void *thirdparty_priv; /*! \brief Callback for Third-party RRU Initialization routine @@ -500,6 +548,9 @@ struct openair0_device_t { * \return a pointer to the parameter */ void *(*get_internal_parameter)(char *id); + /* \brief timing statistics for TX fronthaul (ethernet) + */ + time_stats_t tx_fhaul; }; /* type of device init function, implemented in shared lib */ diff --git a/targets/ARCH/COMMON/record_player.c b/sdr/COMMON/record_player.c similarity index 100% rename from targets/ARCH/COMMON/record_player.c rename to sdr/COMMON/record_player.c diff --git a/targets/ARCH/COMMON/record_player.h b/sdr/COMMON/record_player.h similarity index 99% rename from targets/ARCH/COMMON/record_player.h rename to sdr/COMMON/record_player.h index f4f17c6ee6..cd715eecf1 100644 --- a/targets/ARCH/COMMON/record_player.h +++ b/sdr/COMMON/record_player.h @@ -21,7 +21,7 @@ * contact@openairinterface.org */ -/** targets/ARCH/COMMON/record-player.h +/** sdr/COMMON/record-player.h * * \author: bruno.mongazon-cazavet@nokia-bell-labs.com */ diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/sdr/ETHERNET/USERSPACE/LIB/eth_raw.c similarity index 95% rename from targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c rename to sdr/ETHERNET/USERSPACE/LIB/eth_raw.c index 9c0a9e3f65..89d6c97c3f 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/sdr/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -80,10 +80,11 @@ int eth_socket_init_raw(openair0_device *device) { perror("ETHERNET: Error opening RAW socket (control)"); exit(0); } - if ((eth->sockfdd = socket(sock_dom, sock_type, sock_proto)) == -1) { - perror("ETHERNET: Error opening RAW socket (user)"); - exit(0); - } + for (int i=0;inum_fd;i++) + if ((eth->sockfdd[i] = socket(sock_dom, sock_type, sock_proto)) == -1) { + perror("ETHERNET: Error opening RAW socket (user)"); + exit(0); + } /* initialize destination address */ bzero((void *)&(eth->local_addrc_ll), sizeof(struct sockaddr_ll)); @@ -94,8 +95,9 @@ int eth_socket_init_raw(openair0_device *device) { strcpy(eth->if_index.ifr_name,eth->if_name); if (ioctl(eth->sockfdc, SIOCGIFINDEX, &(eth->if_index)) < 0) perror("SIOCGIFINDEX"); - if (ioctl(eth->sockfdd, SIOCGIFINDEX, &(eth->if_index)) < 0) - perror("SIOCGIFINDEX"); + for (int i=0;inum_fd;i++) + if (ioctl(eth->sockfdd[i], SIOCGIFINDEX, &(eth->if_index)) < 0) + perror("SIOCGIFINDEX"); eth->local_addrc_ll.sll_family = AF_PACKET; eth->local_addrc_ll.sll_ifindex = eth->if_index.ifr_ifindex; @@ -111,10 +113,11 @@ int eth_socket_init_raw(openair0_device *device) { eth->local_addrd_ll.sll_pkttype = PACKET_OTHERHOST; eth->addr_len = sizeof(struct sockaddr_ll); - if (bind(eth->sockfdd,(struct sockaddr *)ð->local_addrd_ll,eth->addr_len)<0) { - perror("ETHERNET: Cannot bind to socket (user)"); - exit(0); - } + for (int i=0;inum_fd;i++) + if (bind(eth->sockfdd[i],(struct sockaddr *)ð->local_addrd_ll,eth->addr_len)<0) { + perror("ETHERNET: Cannot bind to socket (user)"); + exit(0); + } /* Construct the Ethernet header */ ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost))); @@ -165,7 +168,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi /* Send packet */ - bytes_sent += send(eth->sockfdd, + bytes_sent += send(eth->sockfdd[cc % eth->num_fd], buff2, pktsize, sendto_flag); @@ -214,7 +217,7 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam memcpy(buff[0], (void*)ð->ehd, MAC_HEADER_SIZE_BYTES); - bytes_sent = send(eth->sockfdd, + bytes_sent = send(eth->sockfdd[cc % eth->num_fd], buff[0], packet_size, 0); @@ -266,7 +269,7 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi while(bytes_received < receive_bytes) { again: - ret = recv(eth->sockfdd, + ret = recv(eth->sockfdd[cc % eth->num_fd], buff2, receive_bytes, rcvfrom_flag); @@ -345,7 +348,7 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam while (bytes_received < packet_size) { again: - ret = recv(eth->sockfdd, + ret = recv(eth->sockfdd[cc % eth->num_fd], buff[0], packet_size, MSG_PEEK); @@ -397,7 +400,7 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam } while(bytes_received < packet_size) { - ret = recv(eth->sockfdd, + ret = recv(eth->sockfdd[cc % eth->num_fd], buff[0], packet_size, 0); diff --git a/sdr/ETHERNET/USERSPACE/LIB/eth_udp.c b/sdr/ETHERNET/USERSPACE/LIB/eth_udp.c new file mode 100644 index 0000000000..dd9414a44c --- /dev/null +++ b/sdr/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -0,0 +1,547 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file ethernet_lib.c + * \brief API to stream I/Q samples over standard ethernet + * \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp + * \date 2015 + * \version 0.2 + * \company Eurecom + * \maintainer: navid.nikaein@eurecom.fr + * \note + * \warning + */ + +// _GNU_SOURCE needed to have sched_getcpu() from sched.h +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/utils/LOG/vcd_signal_dumper.h" +#include + +#include "common_lib.h" +#include "ethernet_lib.h" +#include "common/utils/threadPool/thread-pool.h" + +//#define DEBUG 1 + +// These are for IF5 and must be put into the device structure if multiple RUs in the same RAU !!!!!!!!!!!!!!!!! +uint16_t pck_seq_num = 1; +uint16_t pck_seq_num_cur=0; +uint16_t pck_seq_num_prev=0; + +int eth_socket_init_udp(openair0_device *device) { + + eth_state_t *eth = (eth_state_t*)device->priv; + eth_params_t *eth_params = device->eth_params; + + char str_local[INET_ADDRSTRLEN]; + char str_remote[INET_ADDRSTRLEN]; + + const char *local_ip, *remote_ipc,*remote_ipd; + int local_portc=0,local_portd=0, remote_portc=0,remote_portd=0; + int sock_dom=0; + int sock_type=0; + int sock_proto=0; + int enable=1; + const char str[2][4] = {"RRU\0","RAU\0"}; + int hostind = 0; + + local_ip = eth_params->my_addr; + local_portc = eth_params->my_portc; + local_portd = eth_params->my_portd; + + + if (device->host_type == RRU_HOST ) { + + remote_ipc = "0.0.0.0"; + remote_ipd = eth_params->remote_addr; + remote_portc = 0; + remote_portd = eth_params->remote_portd;; + printf("[%s] local ip addr %s portc %d portd %d\n", "RRU", local_ip, local_portc, local_portd); + } else { + remote_ipc = eth_params->remote_addr; + remote_ipd = "0.0.0.0"; + remote_portc = eth_params->remote_portc; + remote_portd = 0; + hostind = 1; + printf("[%s] local ip addr %s portc %d portd %d\n","RAU", local_ip, local_portc, local_portd); + } + + /* Open socket to send on */ + sock_dom=AF_INET; + sock_type=SOCK_DGRAM; + sock_proto=IPPROTO_UDP; + + if ((eth->sockfdc = socket(sock_dom, sock_type, sock_proto)) == -1) { + perror("ETHERNET: Error opening socket (control)"); + exit(0); + } + + for (int i = 0;inum_fd;i++) + if ((eth->sockfdd[i] = socket(sock_dom, sock_type, sock_proto)) == -1) { + printf("ETHERNET: Error opening socket (user %d)",i); + exit(0); + } + + /* initialize addresses */ + bzero((void *)&(eth->dest_addrc), sizeof(eth->dest_addrc)); + bzero((void *)&(eth->local_addrc), sizeof(eth->local_addrc)); + bzero((void *)&(eth->dest_addrd), sizeof(eth->dest_addrd)); + bzero((void *)&(eth->local_addrd), sizeof(eth->local_addrd)); + + + eth->addr_len = sizeof(struct sockaddr_in); + + eth->dest_addrc.sin_family = AF_INET; + inet_pton(AF_INET,remote_ipc,&(eth->dest_addrc.sin_addr.s_addr)); + eth->dest_addrc.sin_port=htons(remote_portc); + inet_ntop(AF_INET, &(eth->dest_addrc.sin_addr), str_remote, INET_ADDRSTRLEN); + + eth->dest_addrd.sin_family = AF_INET; + inet_pton(AF_INET,remote_ipd,&(eth->dest_addrd.sin_addr.s_addr)); + eth->dest_addrd.sin_port=htons(remote_portd); + + eth->local_addrc.sin_family = AF_INET; + inet_pton(AF_INET,local_ip,&(eth->local_addrc.sin_addr.s_addr)); + eth->local_addrc.sin_port=htons(local_portc); + inet_ntop(AF_INET, &(eth->local_addrc.sin_addr), str_local, INET_ADDRSTRLEN); + + eth->local_addrd.sin_family = AF_INET; + inet_pton(AF_INET,local_ip,&(eth->local_addrd.sin_addr.s_addr)); + eth->local_addrd.sin_port=htons(local_portd); + + + + + /* set reuse address flag */ + if (setsockopt(eth->sockfdc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { + perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (control)"); + exit(0); + } + for (int i=0;inum_fd;i++) { + if (setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) { + printf("ETHERNET: Cannot set SO_NO_CHECK option on socket (user %d)",i); + exit(0); + } +#if 0 /*def SO_ATTACH_REUSEPORT_EBPF*/ + if (setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int))) { + printf("ETHERNET: Cannot set SO_REUSEPORT option on socket (user %d)",i); + exit(0); + } + struct sock_filter code[]={ + { BPF_LD | BPF_W | BPF_ABS, 0, 0, SKF_AD_OFF + SKF_AD_CPU }, // A = #cpu + { BPF_RET | BPF_A, 0, 0, 0 }, // return A + }; + struct sock_fprog bpf = { + .len = sizeof(code)/sizeof(struct sock_filter), + .filter = code, + }; + if (i==0 && setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &bpf, sizeof(bpf))) { + printf("ETHERNET: Cannot set SO_ATTACH_REUSEPORT_EBPF option on socket (user %d)",i); + exit(0); + } + else printf("ETHERNET: set SO_ATTACH_REUSEPORT_EBPF option on socket (user %d)\n",i); +#endif + + } + + /* want to receive -> so bind */ + if (bind(eth->sockfdc,(struct sockaddr *)ð->local_addrc,eth->addr_len)<0) { + perror("ETHERNET: Cannot bind to socket (control)"); + exit(0); + } else { + printf("[%s] binding to %s:%d (control)\n",str[hostind],str_local,ntohs(eth->local_addrc.sin_port)); + } + for (int i=0;inum_fd;i++) + if (bind(eth->sockfdd[i],(struct sockaddr *)ð->local_addrd,eth->addr_len)<0) { + printf("ETHERNET: Cannot bind to socket (user %d)",i); + exit(0); + } else { + printf("[%s] binding to %s:%d (user %d)\n",str[hostind],str_local,ntohs(eth->local_addrd.sin_port),i); + } + + return 0; +} + +int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { + + // Read nblocks info from packet itself + int nblocks = nsamps; + int bytes_received=-1; + eth_state_t *eth = (eth_state_t*)device->priv; + + ssize_t packet_size = sizeof_IF4p5_header_t; + IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0]); + + int block_cnt=0; + + // *2 because of 2 antennas PUL/DLFFT are controlled by nsamps, PRACH is not + packet_size = max(UDP_IF4p5_PRACH_SIZE_BYTES*2, max(UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks), UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks))); + + while(bytes_received == -1) { + again: + bytes_received = recvfrom(eth->sockfdd[0/*cc%eth->num_fd*/], + buff[0], + packet_size, + 0, + (struct sockaddr *)ð->dest_addrd, + (socklen_t *)ð->addr_len); + if (bytes_received ==-1) { + eth->num_rx_errors++; + if (errno == EAGAIN) { + printf("Lost IF4p5 connection with %s\n", inet_ntoa(eth->dest_addrd.sin_addr)); + return -1; + } else if (errno == EWOULDBLOCK) { + block_cnt++; + usleep(10); + if (block_cnt == 1000) { + perror("ETHERNET IF4p5 READ (EWOULDBLOCK): "); + } else { + printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); + goto again; + } + } else { + return(-1); + //perror("ETHERNET IF4p5 READ"); + //printf("(%s):\n", strerror(errno)); + } + } else { + *timestamp = test_header->sub_type; + eth->rx_actual_nsamps = bytes_received>>1; + eth->rx_count++; + } + } + eth->rx_nsamps = nsamps; + return(bytes_received); +} + +int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + + int nblocks = nsamps; + int bytes_sent = 0; + + + eth_state_t *eth = (eth_state_t*)device->priv; + + ssize_t packet_size; + + char str[INET_ADDRSTRLEN]; + + inet_ntop(AF_INET, &(eth->dest_addrd.sin_addr), str, INET_ADDRSTRLEN); + + if (flags == IF4p5_PDLFFT) { + packet_size = UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks); + } else if (flags == IF4p5_PULFFT) { + packet_size = UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks); + } else if (flags == IF4p5_PULTICK) { + packet_size = UDP_IF4p5_PULTICK_SIZE_BYTES; + } else if ((flags >= IF4p5_PRACH)&& + (flags <= (IF4p5_PRACH+4))) { + packet_size = UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + (nsamps<<1); + } else { + printf("trx_eth_write_udp_IF4p5: unknown flags %d\n",flags); + return(-1); + } + + eth->tx_nsamps = nblocks; + + bytes_sent = sendto(eth->sockfdd[0/*cc%eth->num_fd*/], + buff[0], + packet_size, + 0, + (struct sockaddr*)ð->dest_addrd, + eth->addr_len); + + if (bytes_sent == -1) { + eth->num_tx_errors++; + perror("error writing to remote unit (user) : "); + exit(-1); + } else { + eth->tx_actual_nsamps = bytes_sent>>1; + eth->tx_count++; + } + return (bytes_sent); +} + + + +void *trx_eth_write_udp_cmd(udpTXelem_t *udpTXelem) { + + openair0_device *device=udpTXelem->device; + openair0_timestamp timestamp = udpTXelem->timestamp; + void **buff = udpTXelem->buff; + int nsamps = udpTXelem->nsamps; + int nant = udpTXelem->nant; + int bytes_sent=0; + eth_state_t *eth = (eth_state_t*)device->priv; + int sendto_flag =0; + fhstate_t *fhstate = &device->fhstate; + + //sendto_flag|=flags; + eth->tx_nsamps=nsamps; + + uint64_t last_rxTS = fhstate->TS[0]-fhstate->TS0; + uint64_t TS_advance=0; + if (timestamp > last_rxTS) TS_advance = timestamp - last_rxTS; + + if (TS_advance < (nsamps/2)) LOG_W(PHY,"Starting TX FH for TS %llu absslot %llu(%llu) last_rxTS %llu TS_advance %llu samples\n",(unsigned long long)timestamp,(unsigned long long)timestamp/nsamps,((unsigned long long)timestamp/nsamps)%20,(unsigned long long)last_rxTS,(unsigned long long)TS_advance); + void *buff2; +#if defined(__x86_64) || defined(__i386__) +#ifdef __AVX2__ + int nsamps2 = 256>>3; + __m256i buff_tx[nsamps2+1]; + buff2=(void*)&buff_tx[1] - APP_HEADER_SIZE_BYTES; +#else + int nsamps2 = 256>>2; + __m128i buff_tx[nsamps2+2]; + buff2=(void*)&buff_tx[2] - APP_HEADER_SIZE_BYTES; +#endif +#elif defined(__arm__) || defined(__aarch64__) + int nsamps2 = 256>>2; + int16x8_t buff_tx[nsamps2+2]; + buff2=(void*)&buff_tx[2] - APP_HEADER_SIZE_BYTES; +#else +#error Unsupported CPU architecture, ethernet device cannot be built +#endif + + /* construct application header */ + // ECPRI Protocol revision + reserved bits (1 byte) + *(uint8_t *)buff2 = ECPRIREV; + // ECPRI Message type (1 byte) + *(uint8_t *)(buff2 + 1) = 64; + + openair0_timestamp TS = timestamp + fhstate->TS0; + TS = (6*device->sampling_rate_ratio_d*TS)/device->sampling_rate_ratio_n; + TS -= device->txrx_offset; + int TSinc = (6*256*device->sampling_rate_ratio_d)/device->sampling_rate_ratio_n; + int len=256; + LOG_D(PHY,"TS %llu (%llu),txrx_offset %d,d %d, n %d, buff[0] %p buff[1] %p\n", + (unsigned long long)TS,(unsigned long long)timestamp,device->txrx_offset,device->sampling_rate_ratio_d,device->sampling_rate_ratio_n, + buff[0],buff[1]); + for (int offset=0;offset>8; + *(uint8_t *)(buff2 + 3) = len&0xff; + for (int aid = 0; aidTS0,aid,offset,len); + // ECPRI PC_ID (2 bytes) + *(uint16_t *)(buff2 + 4) = aid; + // bring TX data into 12 MSBs +#if defined(__x86_64__) || defined(__i386__) +#ifdef __AVX2__ + __m256i *buff256 = (__m256i *)&(((int32_t*)buff[aid])[offset]); + for (int j=0; j<32; j+=8) { + buff_tx[1+j] = _mm256_slli_epi16(buff256[j],4); + buff_tx[2+j] = _mm256_slli_epi16(buff256[j+1],4); + buff_tx[3+j] = _mm256_slli_epi16(buff256[j+2],4); + buff_tx[4+j] = _mm256_slli_epi16(buff256[j+3],4); + buff_tx[5+j] = _mm256_slli_epi16(buff256[j+4],4); + buff_tx[6+j] = _mm256_slli_epi16(buff256[j+5],4); + buff_tx[7+j] = _mm256_slli_epi16(buff256[j+6],4); + buff_tx[8+j] = _mm256_slli_epi16(buff256[j+7],4); + } +#else + __m128i *buff128 = (__m128i *)&buff[aid][offset]; + for (int j=0; j<64; j++) buff_tx[2+j] = _mm_slli_epi16(buff128[j],4); +#endif +#elif defined(__arm__) + int16x8_t *buff128 = (__int16x8_t*)&buff[aid][offset]; + for (int j=0; j<64; j++) buff_tx[2+j] = vshlq_n_s16(((int16x8_t *)buff128)[j],4); +#endif + + /* Send packet */ + bytes_sent = sendto(eth->sockfdd[0], + buff2, + UDP_PACKET_SIZE_BYTES(len>>2), + sendto_flag, + (struct sockaddr*)ð->dest_addrd, + eth->addr_len); + if ( bytes_sent == -1) { + eth->num_tx_errors++; + perror("ETHERNET WRITE: "); + exit(-1); + } else { + eth->tx_actual_nsamps=bytes_sent>>2; + eth->tx_count++; + } + } // aid + } // offset + free(buff); + return(NULL); +} + +int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int fd_ind, int nsamps, int flags, int nant) { + + union udpTXReqUnion id = {.s={(uint64_t)timestamp,nsamps,0}}; + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(udpTXelem_t), id.p, device->utx[fd_ind]->resp,NULL); + udpTXelem_t * udptxelem=(udpTXelem_t *) NotifiedFifoData(req); + udptxelem->device = device; + udptxelem->timestamp = timestamp; + udptxelem->buff = calloc(nant,sizeof(void*)); + memcpy(udptxelem->buff,buff,nant*sizeof(void*)); + udptxelem->fd_ind = fd_ind; + udptxelem->nsamps = nsamps; + udptxelem->flags = flags; + udptxelem->nant = nant; + pushNotifiedFIFO(device->utx[fd_ind]->resp, req); + LOG_D(PHY,"Pushed to TX FH FIFO, TS %llu, nsamps %d, nant %d buffs[0] %p buffs[1] %p\n", + (unsigned long long)timestamp,nsamps,nant,udptxelem->buff[0],udptxelem->buff[1]); + return(0); +} +extern int oai_exit; + +void *udp_write_thread(void *arg) { + + udp_ctx_t *utx = (udp_ctx_t *)arg; + utx->resp = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_elt_t)); + initNotifiedFIFO(utx->resp); + LOG_D(PHY,"UDP write thread started on core %d\n",sched_getcpu()); + reset_meas(&utx->device->tx_fhaul); + while (oai_exit == 0) { + notifiedFIFO_elt_t *res = pullNotifiedFIFO(utx->resp); + udpTXelem_t *udptxelem = (udpTXelem_t *)NotifiedFifoData(res); + LOG_D(PHY,"Pulled from TX FH FIFO, TS %llu, nsamps %d, nant %d\n",(unsigned long long)udptxelem->timestamp,udptxelem->nsamps,udptxelem->nant); + start_meas(&utx->device->tx_fhaul); + trx_eth_write_udp_cmd(udptxelem); + stop_meas(&utx->device->tx_fhaul); + // send data to RU + delNotifiedFIFO_elt(res); + } + free(utx->resp); + return(NULL); +} + +void *udp_read_thread(void *arg) { + openair0_timestamp TS; + + int aid; + udp_ctx_t *u = (udp_ctx_t *)arg; + openair0_device *device=u->device; + fhstate_t *fhstate = &device->fhstate; + char buffer[UDP_PACKET_SIZE_BYTES(256)]; + int first_read=0; + while (oai_exit == 0) { + LOG_I(PHY,"UDP read thread %d, waiting for start sampling_rate_d %d, sampling_rate_n %d\n",u->thread_id,device->sampling_rate_ratio_n,device->sampling_rate_ratio_d); + while (fhstate->active > 0) { + size_t count = recvfrom(((eth_state_t*)device->priv)->sockfdd[0], + buffer,sizeof(buffer),0, + (struct sockaddr *)&((eth_state_t*)device->priv)->dest_addrd, + (socklen_t *)&((eth_state_t*)device->priv)->addr_len); + aid = *(uint16_t*)(&buffer[ECPRICOMMON_BYTES]); + TS = *(openair0_timestamp *)(&buffer[ECPRICOMMON_BYTES+ECPRIPCID_BYTES]); + // convert TS to samples, /6 for AW2S @ 30.72 Ms/s, this is converted for other sample rates in OAI application + TS = (device->sampling_rate_ratio_n*TS)/(device->sampling_rate_ratio_d*6); + if ((int)count <= 0) continue; + AssertFatal(aid < 8,"Cannot handle more than 8 antennas, got aid %d\n",aid); + fhstate->r[aid]=1; + if (aid==0 && first_read == 0) fhstate->TS0 = TS; + first_read = 1; + /* store the timestamp value from packet's header */ + fhstate->TS[aid] = TS; + int64_t offset = TS - fhstate->TS0; + if (offset > 0) offset = offset % device->openair0_cfg->rxsize; + else offset = TS % device->openair0_cfg->rxsize + ((((uint64_t)1)<<63)-(fhstate->TS0-1)) % device->openair0_cfg->rxsize; + // need to do memcpy since there is no guarantee that aid is the same each time, otherwise we could have used + // zero-copy and corrected the header component. + + memcpy((void*)(device->openair0_cfg->rxbase[aid]+offset), + (void*)&buffer[APP_HEADER_SIZE_BYTES], + count-APP_HEADER_SIZE_BYTES); + LOG_D(PHY,"UDP read thread_id %d (%d), aid %d, TS %llu, TS0 %llu, offset %ld\n",(int)u->thread_id,(int)sched_getcpu(),aid,(unsigned long long)TS,(unsigned long long)fhstate->TS0,offset); + } + sleep(1); + } + return(0); +} + +int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, uint32_t **buff, int nsamps) { + + fhstate_t *fhstate = &device->fhstate; + openair0_timestamp prev_read_TS= fhstate->TS_read, min_TS; + // block until FH is ready + while (fhstate->r[0] == 0 || fhstate->r[1] == 0 || fhstate->r[2] == 0 || fhstate->r[3] == 0 || + fhstate->r[4] == 0 || fhstate->r[5] == 0 || fhstate->r[6] == 0 || fhstate->r[7] == 0) usleep(100); + + // get minimum TS over all antennas + min_TS = fhstate->TS[0]; + for (int i=1;iopenair0_cfg->rx_num_channels;i++) min_TS = min(min_TS,fhstate->TS[i]); + // poll/sleep until we accumulated enough samples on each antenna port + int count=0; + while (fhstate->first_read == 1 && min_TS < (fhstate->TS0+prev_read_TS + nsamps)) { + usleep(50); + min_TS = fhstate->TS[0]; + for (int i=1;iopenair0_cfg->rx_num_channels;i++) min_TS = min(min_TS,fhstate->TS[i]); + count++; + } + + if (fhstate->first_read == 0) { + *timestamp = 0; + fhstate->TS_read = *timestamp+nsamps; + LOG_D(PHY,"first read : TS_read %llu, TS %llu state (%d,%d,%d,%d,%d,%d,%d,%d)\n",(unsigned long long)fhstate->TS_read,(unsigned long long)*timestamp, + fhstate->r[0],fhstate->r[1],fhstate->r[2],fhstate->r[3],fhstate->r[4],fhstate->r[5],fhstate->r[6],fhstate->r[7]); + } + else { + *timestamp = fhstate->TS_read; + fhstate->TS_read = prev_read_TS + nsamps; + LOG_D(PHY,"TS_read %llu (%llu, %llu), min_TS %llu, prev_read_TS %llu, nsamps %d, fhstate->TS0+prev_TS+nsamps %llu, wait count %d x 100us\n",(unsigned long long)fhstate->TS_read,(unsigned long long)*timestamp/nsamps,((unsigned long long)*timestamp/nsamps)%20,(unsigned long long)min_TS,(unsigned long long)prev_read_TS,nsamps,(unsigned long long)(fhstate->TS0+prev_read_TS+nsamps),count); + } + fhstate->first_read = 1; + return (nsamps); +} + + + +int trx_eth_ctlsend_udp(openair0_device *device, void *msg, ssize_t msg_len) { + + return(sendto(((eth_state_t*)device->priv)->sockfdc, + msg, + msg_len, + 0, + (struct sockaddr *)&((eth_state_t*)device->priv)->dest_addrc, + ((eth_state_t*)device->priv)->addr_len)); +} + + +int trx_eth_ctlrecv_udp(openair0_device *device, void *msg, ssize_t msg_len) { + + return (recvfrom(((eth_state_t*)device->priv)->sockfdc, + msg, + msg_len, + 0, + (struct sockaddr *)&((eth_state_t*)device->priv)->dest_addrc, + (socklen_t *)&((eth_state_t*)device->priv)->addr_len)); +} diff --git a/sdr/ETHERNET/USERSPACE/LIB/ethernet.md b/sdr/ETHERNET/USERSPACE/LIB/ethernet.md new file mode 100644 index 0000000000..78058e9324 --- /dev/null +++ b/sdr/ETHERNET/USERSPACE/LIB/ethernet.md @@ -0,0 +1,51 @@ +# Ethernet drivers + +This directory contains ethernet-based drivers for fronthaul. The only functional versions today are ECPRI time-domain (split 8) over UDP for AW2S and IF4.5 (split 7) for OAI RU over UDP. The RAW ethernet implementation is currently not tested and quite possibly obsolete. + + +## license + Author: + Raymond Knopp, EURECOM + OAI License V1.1 +# Top-level + +The files implement the OAI IF device interface which provides the transmit/receive (trx) functions for generic ethernet-based devices. Some minimal control-plane socket handling for IF4p5 is also provided. It comprises the following top-level functions (ethernet_lib.c) which are mapped to the OAI device structure: + +* trx_eth_start : create sockets and threads to handle I/O +* trx_eth_end : close sockets +* trx_eth_stop : stops 3rd party (AW2S) device +* trx_eth_set_freq : empty +* trx_eth_set_gains : empty +* trx_eth_get_stats : empty +* trx_eth_reset_stats : empty +* trx_eth_write_init : empty +* ethernet_tune : write certain performance-related parameters to ethernet device +* transport_init : entry routine to fill device data structure with function pointers + + +# IF4p5 U-plane implementation + +It is contained in the eth_udp.c and eth_raw.c files. The two basic routines are + +* trx_eth_read_udp_IF4p5() : implements a blocking read for three particular IF4p5 packets, IF4p5_PULFFT (for OAI RCC/DU), IF4p5_PRACH and IF4p5_PDLFFT (for OAI RU). The packets are parsed and mapped to the appropriate physical channels by the OAI physical layer +* trx_eth_write_udp_IF4p5 : implements a write for the three IF4p5 packets. + +* trx_eth_ctlsend_udp : implements the sending component for the control socket + +* trx_eth_ctlrecv_udp : implements the receive component for the control socket (blocking read) + +# ECPRI U-plane implementation + +It is contained in the eth_udp.c file and only implements ECPRI/UDP. The implementation has 2 top-level functions: + +* trx_eth_write_udp : This sends a stream of packets containing 16-bit I/ 16-bit Q samples to the ECPRI RU. It uses the proprietary AW2S format (user-defined). Each packet carries 256 samples and some header information (timestamp, antenna index) and fits inslightly more than 1024 bytes. Each packet with Ethernet, IP and UDP headers fits into a regular Ethernet frame. The transmit function does not block and pushes the data to a worker thread (udp_write_thread) which runs in the background. The worker thread scales the IQ samples to fit in 16-bit units and forms the ECPRI packets for each antenna. The signals are split into 256-sample chunks and antennas are handled in sequence for each chunk. This ensures that all antennas receive their signals more or less at the same time. + +* trx_eth_read_udp : This is a blocking read which waits for a worker thread (udp_read_thread) listening on the U-plane socket to have acquired enough samples satisfying the request (nsamps). The requests are usually a slot (NR) or subframe (LTE) worth of samples. The worker thread identifies the antenna index (aid) and timestamp of each packet and copies the received chunk into the destination memory location according to the timestamp modulo the length of the receive buffer. The memory location for read is identifited during initialization of the interface and is written circularly. Typically the buffer would contain a frame's worth of samples, but this is not a requirement. There is only one memcpy in the driver and the end OAI application can use the data in its normal local buffer (RU.common.rxdata[aid]). The memcpy is needed since the destination address depends on the antenna index which is carried in the received packet itself. Kernel filtering and redirection (C/EBPF,XDP) doesn't seem to be possible with the AW2S packet format. + +The two threads should be pinned to isolated CPUs to maximize performance. Their CPU id's can be passed to the driver from the OAI application. tx_fh_core and rx_fh_core in the RU section of the OAI .conf file. + +# Obsolete code + +Non ECPRI split 8 and IF4p5 with RAW sockets is not functional anymore (eth_raw.c). split-8 will be resusitated if an RU implementing ECPRI is integrated with OAI. IF4p5 with raw sockets is replaced with the FHI Split 7.2 interface. + + diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.c similarity index 74% rename from targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c rename to sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.c index c15bdc37cb..dfb136749b 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -64,8 +64,78 @@ int trx_eth_start(openair0_device *device) AssertFatal(device->thirdparty_init != NULL, "device->thirdparty_init is null\n"); AssertFatal(device->thirdparty_init(device) == 0, "third-party init failed\n"); device->openair0_cfg->samples_per_packet = 256; - } - /* initialize socket */ + eth->num_fd = 1; //max(device->openair0_cfg->rx_num_channels,device->openair0_cfg->tx_num_channels); + udp_ctx_t *u[1+eth->num_fd]; + device->utx = (udp_ctx_t**)malloc(sizeof(device->utx)); + for (int i=0;inum_fd;i++) { + u[i] = malloc(sizeof(udp_ctx_t)); + u[i]->thread_id=i; + u[i]->device = device; + printf("UDP Read Thread %d on core %d\n",i,device->openair0_cfg->rxfh_cores[i]); + threadCreate(&u[i]->pthread,udp_read_thread,u[i],"udp read thread",device->openair0_cfg->rxfh_cores[i],OAI_PRIORITY_RT_MAX); + device->utx[i] = malloc(sizeof(udp_ctx_t)); + device->utx[i]->thread_id=i; + device->utx[i]->device = device; + printf("UDP Write Thread %d on core %d\n",i,device->openair0_cfg->txfh_cores[i]); + threadCreate(&device->utx[i]->pthread,udp_write_thread,device->utx[i],"udp write thread",device->openair0_cfg->txfh_cores[i],OAI_PRIORITY_RT_MAX); + } + device->sampling_rate_ratio_n=1; + device->sampling_rate_ratio_d=1; + if (device->openair0_cfg->nr_flag==1) { // This check if RRU knows about NR numerologies + if (device->openair0_cfg->num_rb_dl <= 162 && device->openair0_cfg->num_rb_dl > 106) { + device->sampling_rate_ratio_n = 2; + device->txrx_offset=5500; + } + else if (device->openair0_cfg->num_rb_dl <= 106 && device->openair0_cfg->num_rb_dl > 51) { + device->sampling_rate_ratio_d=3; + device->sampling_rate_ratio_n=4; + device->txrx_offset=3750; + } + else if (device->openair0_cfg->num_rb_dl == 51) { + device->sampling_rate_ratio_n=1; + device->sampling_rate_ratio_d=1; + device->txrx_offset=7500; + } + else AssertFatal(1==0,"num_rb_dl %d not ok with ECPRI\n",device->openair0_cfg->num_rb_dl); + } + else { + if (device->openair0_cfg->num_rb_dl == 100 || device->openair0_cfg->num_rb_dl == 51) { + device->sampling_rate_ratio_d = 1; + device->txrx_offset=7500; + } + else if (device->openair0_cfg->num_rb_dl == 75) { + device->sampling_rate_ratio_d = 4; + device->sampling_rate_ratio_n=3; + device->txrx_offset=7500; + } + else if (device->openair0_cfg->num_rb_dl == 50) { + device->sampling_rate_ratio_d = 2; + device->txrx_offset=7500; + } + else if (device->openair0_cfg->num_rb_dl == 25) { + device->sampling_rate_ratio_d = 4; + device->txrx_offset=7500; + } + else AssertFatal(1==0,"num_rb_dl %d not ok with ECPRI\n",device->openair0_cfg->num_rb_dl); + } +#ifdef USE_TX_TPOOL + int threadCnt = device->openair0_cfg->tx_num_channels; + if (threadCnt < 2) LOG_E(PHY,"Number of threads for gNB should be more than 1. Allocated only %d\n",threadCnt); + char pool[80]; + sprintf(pool,"-1"); + int s_offset = 0; + for (int icpu=1; icputhreadPool = (tpool_t*)malloc(sizeof(tpool_t)); + initTpool(pool, device->threadPool, cpumeas(CPUMEAS_GETSTATE)); + // ULSCH decoder result FIFO + device->respudpTX = (notifiedFIFO_elt_t*) malloc(sizeof(notifiedFIFO_elt_t)); + initNotifiedFIFO(device->respudpTX); +#endif + } + /* initialize socket */ if (eth->flags == ETH_RAW_MODE) { printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); if (eth_socket_init_raw(device)!=0) return -1; @@ -145,10 +215,11 @@ int trx_eth_start(openair0_device *device) if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; } /* apply additional configuration */ - if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1; - if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1; - if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1; - if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1; + if(ethernet_tune (device, SND_BUF_SIZE,67108864)!=0) return -1; + if(ethernet_tune (device, RCV_BUF_SIZE,67108864)!=0) return -1; + if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 67108864)!=0) return -1; + if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 67108864)!=0) return -1; + if(ethernet_tune (device, TX_Q_LEN, 10000)!=0) return -1; return 0; @@ -159,12 +230,13 @@ void trx_eth_end(openair0_device *device) { eth_state_t *eth = (eth_state_t*)device->priv; /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ - if ( close(eth->sockfdd) <0 ) { - perror("ETHERNET: Failed to close socket"); - exit(0); - } else { - printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU"); - } + for (int i=0;inum_fd;i++) + if ( close(eth->sockfdd[i]) <0 ) { + perror("ETHERNET: Failed to close socket"); + exit(0); + } else { + printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU"); + } } @@ -224,7 +296,8 @@ int ethernet_tune(openair0_device *device, /****************** socket level options ************************/ switch(option) { case SND_BUF_SIZE: /* transmit socket buffer size */ - if (setsockopt(eth->sockfdd, + for (int i=0;inum_fd;i++) + if (setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_SNDBUF, &value,sizeof(value))) { @@ -232,10 +305,11 @@ int ethernet_tune(openair0_device *device, } else { printf("send buffer size= %d bytes\n",value); } - break; + break; case RCV_BUF_SIZE: /* receive socket buffer size */ - if (setsockopt(eth->sockfdd, + for (int i=0;inum_fd;i++) { + if (setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_RCVBUF, &value,sizeof(value))) { @@ -243,26 +317,29 @@ int ethernet_tune(openair0_device *device, } else { printf("receive bufffer size= %d bytes\n",value); } - break; + } + break; case RCV_TIMEOUT: timeout.tv_sec = value/1000000; timeout.tv_usec = value%1000000;//less than rt_period? if (setsockopt(eth->sockfdc, - SOL_SOCKET, - SO_RCVTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); + SOL_SOCKET, + SO_RCVTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); } else { - printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); + printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); } - if (setsockopt(eth->sockfdd, - SOL_SOCKET, - SO_RCVTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); + for (int i=0;inum_fd;i++) { + if (setsockopt(eth->sockfdd[i], + SOL_SOCKET, + SO_RCVTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); + } } break; @@ -277,13 +354,15 @@ int ethernet_tune(openair0_device *device, } else { printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); } - if (setsockopt(eth->sockfdd, - SOL_SOCKET, - SO_SNDTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); + for (int i=0;inum_fd;i++) { + if (setsockopt(eth->sockfdd[i], + SOL_SOCKET, + SO_SNDTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); + } } break; @@ -293,20 +372,24 @@ int ethernet_tune(openair0_device *device, ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)-1); ifr.ifr_mtu =value; - if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 ) - perror ("[ETHERNET] Can't set the MTU"); - else - printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu); + for (int i=0;inum_fd;i++) { + if (ioctl(eth->sockfdd[i],SIOCSIFMTU,(caddr_t)&ifr) < 0 ) + perror ("[ETHERNET] Can't set the MTU"); + else + printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu); + } break; case TX_Q_LEN: /* change TX queue length of eth interface */ ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)-1); ifr.ifr_qlen =value; - if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) - perror ("[ETHERNET] Can't set the txqueuelen"); - else - printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen); + for (int i=0;inum_fd;i++) { + if (ioctl(eth->sockfdd[i],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) + perror ("[ETHERNET] Can't set the txqueuelen"); + else + printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen); + } break; /******************* device level options *************************/ @@ -357,7 +440,7 @@ int ethernet_tune(openair0_device *device, } break; case KERNEL_RCV_BUF_MAX_SIZE: - ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.rmem_max=%d",value); + ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.rmem_max=%d;sysctl -w net.core.rmem_default=%d",value,value); if (ret > 0) { ret=system(system_cmd); if (ret == -1) { @@ -371,7 +454,7 @@ int ethernet_tune(openair0_device *device, } break; case KERNEL_SND_BUF_MAX_SIZE: - ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.wmem_max=%d",value); + ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.wmem_max=%d;sysctl -w net.core.wmem_default=%d;sysctl -w net.core.netdev_max_backlog=5000;sysctl -w net.core.optmem_max=524288;",value,value); if (ret > 0) { ret=system(system_cmd); if (ret == -1) { @@ -413,7 +496,10 @@ int transport_init(openair0_device *device, eth->compression = ALAW_COMPRESS; } + eth->num_fd = 1; + printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == RAU_HOST) ? "RAU": "RRU")); + printf("[ETHERNET]: num_fd %d\n",eth->num_fd); device->Mod_id = 0;//num_devices_eth++; device->transp_type = ETHERNET_TP; device->trx_start_func = trx_eth_start; @@ -438,6 +524,9 @@ int transport_init(openair0_device *device, device->trx_read_func2 = trx_eth_read_udp; device->trx_ctlsend_func = trx_eth_ctlsend_udp; device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; + memset((void*)&device->fhstate,0,sizeof(device->fhstate)); + printf("Setting %d RX channels to waiting\n",openair0_cfg->rx_num_channels); + for (int i=openair0_cfg->rx_num_channels;i<8;i++) device->fhstate.r[i] = 1; } else if (eth->flags == ETH_RAW_IF4p5_MODE) { device->trx_write_func = trx_eth_write_raw_IF4p5; device->trx_read_func = trx_eth_read_raw_IF4p5; @@ -454,6 +543,7 @@ int transport_init(openair0_device *device, eth->if_name = eth_params->local_if_name; device->priv = eth; + /* device specific */ // openair0_cfg[0].iq_rxrescale = 15;//rescale iqs // openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h similarity index 92% rename from targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h rename to sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h index ad64ac1a8a..edb093e525 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h +++ b/sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h @@ -41,6 +41,7 @@ #include #include #include +#include #define MAX_INST 4 #define DEFAULT_IF "lo" @@ -59,12 +60,16 @@ typedef struct { /*!\brief socket file desc (control)*/ int sockfdc; + /*!\brief number of sockets for user-plane*/ + int num_fd; /*!\brief socket file desc (user)*/ - int sockfdd; + int sockfdd[8]; /*!\brief interface name */ char *if_name; /*!\brief buffer size */ unsigned int buffer_size; + /*!\brief Fronthaul state */ + fhstate_t *fhstate; /*!\brief destination address (control) for UDP socket*/ struct sockaddr_in dest_addrc; /*!\brief local address (control) for UDP socket*/ @@ -205,6 +210,28 @@ typedef struct { short q; } iqoai_t ; +typedef struct udpTXelem_s { + openair0_device *device; + openair0_timestamp timestamp; + void **buff; + int fd_ind; + int nant; + int nsamps; + int flags; +} udpTXelem_t; + +struct udpTXReqId { + uint64_t TS; + int aid; + int length; + uint16_t spare; +} __attribute__((packed)); + +union udpTXReqUnion { + struct udpTXReqId s; + uint64_t p; +}; + void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag); unsigned short calc_csum (unsigned short *buf, int nwords); void dump_dev(openair0_device *device); @@ -214,7 +241,8 @@ void inline dump_txcounters(openair0_device *device); */ void dump_iqs(char * buff, int iq_cnt); - +void *udp_read_thread(void *arg); +void *udp_write_thread(void *arg); /*! \fn int ethernet_tune (openair0_device *device, unsigned int option, int value); * \brief this function allows you to configure certain ethernet parameters in socket or device level @@ -237,8 +265,8 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value); * @ingroup _oai */ int eth_socket_init_udp(openair0_device *device); -int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags); -int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc); +int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buf, int fd_ind, int nsamps, int flags,int nant); +int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, uint32_t **buff, int nsamps); int eth_socket_init_raw(openair0_device *device); diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/sdr/ETHERNET/USERSPACE/LIB/if_defs.h similarity index 97% rename from targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h rename to sdr/ETHERNET/USERSPACE/LIB/if_defs.h index 47205cf8b8..0df47e2205 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h +++ b/sdr/ETHERNET/USERSPACE/LIB/if_defs.h @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h +/*! \file sdr/ETHERNET/USERSPACE/LIB/if_defs.h * \brief * \author S. Sandeep Kumar, Raymond Knopp * \date 2016 @@ -38,7 +38,6 @@ #ifndef LITE_COMPILATION #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #endif // ETH transport preference modes diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/sdr/ETHERNET/benetel/4g/benetel.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/benetel.c rename to sdr/ETHERNET/benetel/4g/benetel.c diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/sdr/ETHERNET/benetel/4g/dpdk_driver.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c rename to sdr/ETHERNET/benetel/4g/dpdk_driver.c diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/sdr/ETHERNET/benetel/4g/low.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/low.c rename to sdr/ETHERNET/benetel/4g/low.c diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/sdr/ETHERNET/benetel/4g/low.h similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/low.h rename to sdr/ETHERNET/benetel/4g/low.h diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/sdr/ETHERNET/benetel/4g/low_dpdk.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c rename to sdr/ETHERNET/benetel/4g/low_dpdk.c diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/sdr/ETHERNET/benetel/4g/shared_buffers.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c rename to sdr/ETHERNET/benetel/4g/shared_buffers.c diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/sdr/ETHERNET/benetel/4g/shared_buffers.h similarity index 100% rename from targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h rename to sdr/ETHERNET/benetel/4g/shared_buffers.h diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/sdr/ETHERNET/benetel/5g/benetel.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/benetel.c rename to sdr/ETHERNET/benetel/5g/benetel.c diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/sdr/ETHERNET/benetel/5g/dpdk_driver.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c rename to sdr/ETHERNET/benetel/5g/dpdk_driver.c diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/sdr/ETHERNET/benetel/5g/low.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/low.c rename to sdr/ETHERNET/benetel/5g/low.c diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/sdr/ETHERNET/benetel/5g/low.h similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/low.h rename to sdr/ETHERNET/benetel/5g/low.h diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/sdr/ETHERNET/benetel/5g/low_dpdk.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c rename to sdr/ETHERNET/benetel/5g/low_dpdk.c diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/sdr/ETHERNET/benetel/5g/shared_buffers.c similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c rename to sdr/ETHERNET/benetel/5g/shared_buffers.c diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/sdr/ETHERNET/benetel/5g/shared_buffers.h similarity index 100% rename from targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h rename to sdr/ETHERNET/benetel/5g/shared_buffers.h diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/sdr/IRIS/USERSPACE/LIB/iris_lib.cpp similarity index 100% rename from targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp rename to sdr/IRIS/USERSPACE/LIB/iris_lib.cpp diff --git a/targets/ARCH/LMSSDR/LimeSDR.ini b/sdr/LMSSDR/LimeSDR.ini similarity index 100% rename from targets/ARCH/LMSSDR/LimeSDR.ini rename to sdr/LMSSDR/LimeSDR.ini diff --git a/targets/ARCH/LMSSDR/LimeSDR_above_1p8GHz.ini b/sdr/LMSSDR/LimeSDR_above_1p8GHz.ini similarity index 100% rename from targets/ARCH/LMSSDR/LimeSDR_above_1p8GHz.ini rename to sdr/LMSSDR/LimeSDR_above_1p8GHz.ini diff --git a/targets/ARCH/LMSSDR/LimeSDR_above_1p8GHz_1v4.ini b/sdr/LMSSDR/LimeSDR_above_1p8GHz_1v4.ini similarity index 100% rename from targets/ARCH/LMSSDR/LimeSDR_above_1p8GHz_1v4.ini rename to sdr/LMSSDR/LimeSDR_above_1p8GHz_1v4.ini diff --git a/targets/ARCH/LMSSDR/LimeSDR_below_1p8GHz.ini b/sdr/LMSSDR/LimeSDR_below_1p8GHz.ini similarity index 100% rename from targets/ARCH/LMSSDR/LimeSDR_below_1p8GHz.ini rename to sdr/LMSSDR/LimeSDR_below_1p8GHz.ini diff --git a/targets/ARCH/LMSSDR/LimeSDR_below_1p8GHz_1v4.ini b/sdr/LMSSDR/LimeSDR_below_1p8GHz_1v4.ini similarity index 100% rename from targets/ARCH/LMSSDR/LimeSDR_below_1p8GHz_1v4.ini rename to sdr/LMSSDR/LimeSDR_below_1p8GHz_1v4.ini diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/sdr/LMSSDR/USERSPACE/LIB/lms_lib.cpp similarity index 100% rename from targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp rename to sdr/LMSSDR/USERSPACE/LIB/lms_lib.cpp diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp b/sdr/LMSSDR/USERSPACE/LIB/sodera_lib.cpp similarity index 100% rename from targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp rename to sdr/LMSSDR/USERSPACE/LIB/sodera_lib.cpp diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/sdr/USRP/USERSPACE/LIB/usrp_lib.cpp similarity index 100% rename from targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp rename to sdr/USRP/USERSPACE/LIB/usrp_lib.cpp diff --git a/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md b/sdr/iqplayer/DOC/iqrecordplayer_usage.md similarity index 98% rename from targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md rename to sdr/iqplayer/DOC/iqrecordplayer_usage.md index 6ccdca3bfa..d2507c3291 100644 --- a/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md +++ b/sdr/iqplayer/DOC/iqrecordplayer_usage.md @@ -134,7 +134,7 @@ options for replay mode are: [PHY]I lte-softmodem prach_I0 = 0.0 dB [PHY]I ru thread max_I0 18, min_I0 12 [HW]W ru thread iqplayer device terminating subframes replay after 5 iteration -/usr/local/oai/develop/openairinterface5g/targets/ARCH/iqplayer/iqplayer_lib.c:222 trx_iqplayer_read() Exiting OAI softmodem: replay ended, triggering process termination +/usr/local/oai/develop/openairinterface5g/sdr/iqplayer/iqplayer_lib.c:222 trx_iqplayer_read() Exiting OAI softmodem: replay ended, triggering process termination ``` ## iq recorder and iq player implementation overview diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/sdr/iqplayer/iqplayer_lib.c similarity index 100% rename from targets/ARCH/iqplayer/iqplayer_lib.c rename to sdr/iqplayer/iqplayer_lib.c diff --git a/targets/ARCH/rfsimulator/README.md b/sdr/rfsimulator/README.md similarity index 100% rename from targets/ARCH/rfsimulator/README.md rename to sdr/rfsimulator/README.md diff --git a/targets/ARCH/rfsimulator/apply_channelmod.c b/sdr/rfsimulator/apply_channelmod.c similarity index 99% rename from targets/ARCH/rfsimulator/apply_channelmod.c rename to sdr/rfsimulator/apply_channelmod.c index 4ff5321e4d..5cb16803bb 100644 --- a/targets/ARCH/rfsimulator/apply_channelmod.c +++ b/sdr/rfsimulator/apply_channelmod.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include /* Legacy study: diff --git a/targets/ARCH/rfsimulator/new_channel_sim.c b/sdr/rfsimulator/new_channel_sim.c similarity index 98% rename from targets/ARCH/rfsimulator/new_channel_sim.c rename to sdr/rfsimulator/new_channel_sim.c index 0501babd20..b5a10bc61c 100644 --- a/targets/ARCH/rfsimulator/new_channel_sim.c +++ b/sdr/rfsimulator/new_channel_sim.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include // Ziggurat static double wn[128],fn[128]; diff --git a/targets/ARCH/rfsimulator/rfsimulator.h b/sdr/rfsimulator/rfsimulator.h similarity index 100% rename from targets/ARCH/rfsimulator/rfsimulator.h rename to sdr/rfsimulator/rfsimulator.h diff --git a/targets/ARCH/rfsimulator/simulator.c b/sdr/rfsimulator/simulator.c similarity index 99% rename from targets/ARCH/rfsimulator/simulator.c rename to sdr/rfsimulator/simulator.c index fb16796cab..a395f3ca85 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/sdr/rfsimulator/simulator.c @@ -51,7 +51,7 @@ #include "openair1/PHY/defs_UE.h" #define CHANNELMOD_DYNAMICLOAD #include -#include +#include #define PORT 4043 //default TCP port for this simulator #define CirSize 6144000 // 100ms is enough diff --git a/targets/ARCH/rfsimulator/stored_node.c b/sdr/rfsimulator/stored_node.c similarity index 100% rename from targets/ARCH/rfsimulator/stored_node.c rename to sdr/rfsimulator/stored_node.c diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/Makefile.inc b/targets/ARCH/ETHERNET/USERSPACE/LIB/Makefile.inc deleted file mode 100644 index 6e58738c4f..0000000000 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ -ETHERNET_OBJ += $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.o -ETHERNET_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c -ETHERNET_CFLAGS += -O2 -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON - diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c deleted file mode 100644 index ee0dce48f0..0000000000 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file ethernet_lib.c - * \brief API to stream I/Q samples over standard ethernet - * \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp - * \date 2015 - * \version 0.2 - * \company Eurecom - * \maintainer: navid.nikaein@eurecom.fr - * \note - * \warning - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common/utils/LOG/vcd_signal_dumper.h" - -#include "common_lib.h" -#include "ethernet_lib.h" - -//#define DEBUG 1 - -// These are for IF5 and must be put into the device structure if multiple RUs in the same RAU !!!!!!!!!!!!!!!!! -uint16_t pck_seq_num = 1; -uint16_t pck_seq_num_cur=0; -uint16_t pck_seq_num_prev=0; - -int eth_socket_init_udp(openair0_device *device) { - - eth_state_t *eth = (eth_state_t*)device->priv; - eth_params_t *eth_params = device->eth_params; - - char str_local[INET_ADDRSTRLEN]; - char str_remote[INET_ADDRSTRLEN]; - - const char *local_ip, *remote_ipc,*remote_ipd; - int local_portc=0,local_portd=0, remote_portc=0,remote_portd=0; - int sock_dom=0; - int sock_type=0; - int sock_proto=0; - int enable=1; - const char str[2][4] = {"RRU\0","RAU\0"}; - int hostind = 0; - - local_ip = eth_params->my_addr; - local_portc = eth_params->my_portc; - local_portd = eth_params->my_portd; - - - if (device->host_type == RRU_HOST ) { - - remote_ipc = "0.0.0.0"; - remote_ipd = eth_params->remote_addr; - remote_portc = 0; - remote_portd = eth_params->remote_portd;; - printf("[%s] local ip addr %s portc %d portd %d\n", "RRU", local_ip, local_portc, local_portd); - } else { - remote_ipc = eth_params->remote_addr; - remote_ipd = "0.0.0.0"; - remote_portc = eth_params->remote_portc; - remote_portd = 0; - hostind = 1; - printf("[%s] local ip addr %s portc %d portd %d\n","RAU", local_ip, local_portc, local_portd); - } - - /* Open socket to send on */ - sock_dom=AF_INET; - sock_type=SOCK_DGRAM; - sock_proto=IPPROTO_UDP; - - if ((eth->sockfdc = socket(sock_dom, sock_type, sock_proto)) == -1) { - perror("ETHERNET: Error opening socket (control)"); - exit(0); - } - - if ((eth->sockfdd = socket(sock_dom, sock_type, sock_proto)) == -1) { - perror("ETHERNET: Error opening socket (user)"); - exit(0); - } - - /* initialize addresses */ - bzero((void *)&(eth->dest_addrc), sizeof(eth->dest_addrc)); - bzero((void *)&(eth->local_addrc), sizeof(eth->local_addrc)); - bzero((void *)&(eth->dest_addrd), sizeof(eth->dest_addrd)); - bzero((void *)&(eth->local_addrd), sizeof(eth->local_addrd)); - - - eth->addr_len = sizeof(struct sockaddr_in); - - eth->dest_addrc.sin_family = AF_INET; - inet_pton(AF_INET,remote_ipc,&(eth->dest_addrc.sin_addr.s_addr)); - eth->dest_addrc.sin_port=htons(remote_portc); - inet_ntop(AF_INET, &(eth->dest_addrc.sin_addr), str_remote, INET_ADDRSTRLEN); - - eth->dest_addrd.sin_family = AF_INET; - inet_pton(AF_INET,remote_ipd,&(eth->dest_addrd.sin_addr.s_addr)); - eth->dest_addrd.sin_port=htons(remote_portd); - - eth->local_addrc.sin_family = AF_INET; - inet_pton(AF_INET,local_ip,&(eth->local_addrc.sin_addr.s_addr)); - eth->local_addrc.sin_port=htons(local_portc); - inet_ntop(AF_INET, &(eth->local_addrc.sin_addr), str_local, INET_ADDRSTRLEN); - - eth->local_addrd.sin_family = AF_INET; - inet_pton(AF_INET,local_ip,&(eth->local_addrd.sin_addr.s_addr)); - eth->local_addrd.sin_port=htons(local_portd); - - - - - /* set reuse address flag */ - if (setsockopt(eth->sockfdc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { - perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (control)"); - exit(0); - } - if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) { - perror("ETHERNET: Cannot set SO_NO_CHECK option on socket (user)"); - exit(0); - } - - /* want to receive -> so bind */ - if (bind(eth->sockfdc,(struct sockaddr *)ð->local_addrc,eth->addr_len)<0) { - perror("ETHERNET: Cannot bind to socket (control)"); - exit(0); - } else { - printf("[%s] binding to %s:%d (control)\n",str[hostind],str_local,ntohs(eth->local_addrc.sin_port)); - } - if (bind(eth->sockfdd,(struct sockaddr *)ð->local_addrd,eth->addr_len)<0) { - perror("ETHERNET: Cannot bind to socket (user)"); - exit(0); - } else { - printf("[%s] binding to %s:%d (user)\n",str[hostind],str_local,ntohs(eth->local_addrd.sin_port)); - } - - return 0; -} - -int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { - - // Read nblocks info from packet itself - int nblocks = nsamps; - int bytes_received=-1; - eth_state_t *eth = (eth_state_t*)device->priv; - - ssize_t packet_size = sizeof_IF4p5_header_t; - IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0]); - - int block_cnt=0; - - // *2 because of 2 antennas PUL/DLFFT are controlled by nsamps, PRACH is not - packet_size = max(UDP_IF4p5_PRACH_SIZE_BYTES*2, max(UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks), UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks))); - - while(bytes_received == -1) { - again: - bytes_received = recvfrom(eth->sockfdd, - buff[0], - packet_size, - 0, - (struct sockaddr *)ð->dest_addrd, - (socklen_t *)ð->addr_len); - if (bytes_received ==-1) { - eth->num_rx_errors++; - if (errno == EAGAIN) { - printf("Lost IF4p5 connection with %s\n", inet_ntoa(eth->dest_addrd.sin_addr)); - return -1; - } else if (errno == EWOULDBLOCK) { - block_cnt++; - usleep(10); - if (block_cnt == 1000) { - perror("ETHERNET IF4p5 READ (EWOULDBLOCK): "); - } else { - printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); - goto again; - } - } else { - return(-1); - //perror("ETHERNET IF4p5 READ"); - //printf("(%s):\n", strerror(errno)); - } - } else { - *timestamp = test_header->sub_type; - eth->rx_actual_nsamps = bytes_received>>1; - eth->rx_count++; - } - } - - eth->rx_nsamps = nsamps; - return(bytes_received); -} - -int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { - - int nblocks = nsamps; - int bytes_sent = 0; - - - eth_state_t *eth = (eth_state_t*)device->priv; - - ssize_t packet_size; - - char str[INET_ADDRSTRLEN]; - - inet_ntop(AF_INET, &(eth->dest_addrd.sin_addr), str, INET_ADDRSTRLEN); - - if (flags == IF4p5_PDLFFT) { - packet_size = UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks); - } else if (flags == IF4p5_PULFFT) { - packet_size = UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks); - } else if (flags == IF4p5_PULTICK) { - packet_size = UDP_IF4p5_PULTICK_SIZE_BYTES; - } else if ((flags >= IF4p5_PRACH)&& - (flags <= (IF4p5_PRACH+4))) { - packet_size = UDP_HEADER_SIZE_BYTES + IPV4_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + (nsamps<<1); - } else { - printf("trx_eth_write_udp_IF4p5: unknown flags %d\n",flags); - return(-1); - } - - eth->tx_nsamps = nblocks; - - bytes_sent = sendto(eth->sockfdd, - buff[0], - packet_size, - 0, - (struct sockaddr*)ð->dest_addrd, - eth->addr_len); - - if (bytes_sent == -1) { - eth->num_tx_errors++; - perror("error writing to remote unit (user) : "); - exit(-1); - } else { - eth->tx_actual_nsamps = bytes_sent>>1; - eth->tx_count++; - } - return (bytes_sent); -} - -int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags) { - - int bytes_sent=0; - eth_state_t *eth = (eth_state_t*)device->priv; - int sendto_flag =0; - - //sendto_flag|=flags; - eth->tx_nsamps=nsamps; - - - - - int nsamps2; // aligned to upper 32 or 16 byte boundary - -#if defined(__x86_64) || defined(__i386__) -#ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[nsamps2+1]; - __m256i *buff_tx2=buff_tx+1; -#else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[nsamps2+2]; - __m128i *buff_tx2=buff_tx+2; -#endif -#elif defined(__arm__) || defined(__aarch64__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[nsamps2+2]; - int16x8_t *buff_tx2=buff_tx+2; -#else -#error Unsupported CPU architecture, ethernet device cannot be built -#endif - - - // bring TX data into 12 LSBs for softmodem RX - for (int j=0; j 16381\n"); - *(uint8_t *)(buff2 + 2) = (nsamps<<2)>>8; - *(uint8_t *)(buff2 + 3) = (nsamps<<2)&0xff; - // ECPRI PC_ID (2 bytes) - *(uint16_t *)(buff2 + 4) = cc; - // OAI modified SEQ_ID (4 bytes) - *(uint64_t *)(buff2 + 6) = ((uint64_t )timestamp)*6; - - /* - printf("ECPRI TX (REV %x, MessType %d, Payload size %d, PC_ID %d, TS %llu\n", - *(uint8_t *)buff2, - *(uint8_t *)(buff2+1), - *(uint16_t *)(buff2+2), - *(uint16_t *)(buff2+4), - *(uint64_t *)(buff2+6)); - */ - - int sent_byte; - if (eth->compression == ALAW_COMPRESS) { - sent_byte = UDP_PACKET_SIZE_BYTES_ALAW(nsamps); - } else { - sent_byte = UDP_PACKET_SIZE_BYTES(nsamps); - } - - //while(bytes_sent < sent_byte) { - //printf("eth->pck_seq_num: %d\n", eth->pck_seq_num); -#if DEBUG - printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n", - (void *)(buff2+bytes_sent), - sent_byte - bytes_sent, - bytes_sent); -#endif - /* Send packet */ - bytes_sent = sendto(eth->sockfdd, - buff2, - sent_byte, - sendto_flag, - (struct sockaddr*)ð->dest_addrd, - eth->addr_len); - - if ( bytes_sent == -1) { - eth->num_tx_errors++; - perror("ETHERNET WRITE: "); - exit(-1); - } else { -#if DEBUG - printf("------- TX ------: nu=%d an_id=%d ts%d bytes_send=%d\n", - *(int16_t *)buff2, - *(int16_t *)(buff2 + sizeof(int16_t)), - *(openair0_timestamp *)(buff2 + sizeof(int32_t)), - bytes_sent); - - dump_packet((device->host_type == RAU_HOST)? "RAU":"RAU", buff2, UDP_PACKET_SIZE_BYTES(nsamps), TX_FLAG); -#endif - eth->tx_actual_nsamps=bytes_sent>>2; - eth->tx_count++; - eth->pck_seq_num++; - if ( eth->pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame) ) eth->pck_seq_num = 1; - } - //} - - return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2; -} - - -#define NOSHIFT 1 - -int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc) { - - int bytes_received=0; - eth_state_t *eth = (eth_state_t*)device->priv; - // openair0_timestamp prev_timestamp = -1; - int rcvfrom_flag =0; - int block_cnt=0; - int again_cnt=0; - static int packet_cnt=0; - int payload_size = UDP_PACKET_SIZE_BYTES(nsamps); - -#if defined(__x86_64__) || defined(__i386__) -#ifdef __AVX2__ - int nsamps2 = (payload_size>>5)+1; - __m256i temp_rx[nsamps2]; - char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES; -#else - int nsamps2 = (payload_size>>4)+1; - __m128i temp_rx[nsamps2]; - char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES; -#endif -#elif defined(__arm__) || defined(__aarch64__) - int nsamps2 = (payload_size>>4)+1; - int16x8_t temp_rx[nsamps2]; - char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES; -#else -#error Unsupported CPU architecture device cannot be built - int nsamps2 = (payload_size>>2)+1; - int32_t temp_rx[payload_size>>2]; - char* *temp_rx0 = ((char *)&temp_rx[1]) - APP_HEADER_SIZE_BYTES; -#endif - - eth->rx_nsamps=nsamps; - - bytes_received=0; - block_cnt=0; - AssertFatal(eth->compression == NO_COMPRESS, "IF5 compression not supported for now\n"); - - while(bytes_received < payload_size) { - again: - bytes_received +=recvfrom(eth->sockfdd, - temp_rx0, - payload_size, - rcvfrom_flag, - (struct sockaddr *)ð->dest_addrd, - (socklen_t *)ð->addr_len); - packet_cnt++; - if (bytes_received ==-1) { - eth->num_rx_errors++; - if (errno == EAGAIN) { - again_cnt++; - usleep(10); - if (again_cnt == 1000) { - perror("ETHERNET READ: "); - exit(-1); - } else { - bytes_received=0; - goto again; - } - } else if (errno == EWOULDBLOCK) { - block_cnt++; - usleep(10); - if (block_cnt == 1000) { - perror("ETHERNET READ: "); - exit(-1); - } else { - printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); - goto again; - } - } - } else { - /* store the timestamp value from packet's header */ - *timestamp = *(openair0_timestamp *)(temp_rx0 + ECPRICOMMON_BYTES+ECPRIPCID_BYTES); - // convert TS to samples, /3 for 30.72 Ms/s, /6 for 15.36 Ms/s, /12 for 7.68 Ms/s, etc. - *timestamp = *timestamp/6; - // handle 1.4,3,5,10,15 MHz cases - *cc = *(uint16_t*)(temp_rx0 + ECPRICOMMON_BYTES); - } - eth->rx_actual_nsamps=payload_size>>2; - eth->rx_count++; - } - -#ifdef NOSHIFT - memcpy(buff,(void*)(temp_rx+1),payload_size); -#else - // populate receive buffer in lower 12-bits from 16-bit representation - for (int j=1; j>2); -} - - - -int trx_eth_ctlsend_udp(openair0_device *device, void *msg, ssize_t msg_len) { - - return(sendto(((eth_state_t*)device->priv)->sockfdc, - msg, - msg_len, - 0, - (struct sockaddr *)&((eth_state_t*)device->priv)->dest_addrc, - ((eth_state_t*)device->priv)->addr_len)); -} - - -int trx_eth_ctlrecv_udp(openair0_device *device, void *msg, ssize_t msg_len) { - - return (recvfrom(((eth_state_t*)device->priv)->sockfdc, - msg, - msg_len, - 0, - (struct sockaddr *)&((eth_state_t*)device->priv)->dest_addrc, - (socklen_t *)&((eth_state_t*)device->priv)->addr_len)); -} diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc deleted file mode 100644 index b79e3cec74..0000000000 --- a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o -IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp -IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON diff --git a/targets/DOCS/Doxyfile b/targets/DOCS/Doxyfile index 68c76f93fb..249afce0ff 100644 --- a/targets/DOCS/Doxyfile +++ b/targets/DOCS/Doxyfile @@ -792,11 +792,11 @@ INPUT = $(OPENAIR1_DIR)/PHY/defs.h \ $(OPENAIR2_DIR)/LAYER2/RLC/UM_v9.3.0/rlc_um.h \ $(OPENAIR2_DIR)/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h \ $(OPENAIR2_DIR)/NETWORK_DRIVER/MESH/proto_extern.h \ - $(OPENAIR_TARGETS)/ARCH/COMMON/common_lib.h \ - $(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp \ - $(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c \ - $(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h \ - $(OPENAIR_TARGETS)/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp + $(OPENAIR_DIR)/sdr/COMMON/common_lib.h \ + $(OPENAIR_DIR)/sdr/USRP/USERSPACE/LIB/usrp_lib.cpp \ + $(OPENAIR_DIR)/sdr/BLADERF/USERSPACE/LIB/bladerf_lib.c \ + $(OPENAIR_DIR)/sdr/BLADERF/USERSPACE/LIB/bladerf_lib.h \ + $(OPENAIR_DIR)/sdr/LMSSDR/USERSPACE/LIB/lms_lib.cpp # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf index f0f546208e..730b7e2832 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf @@ -7,7 +7,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf index be42f67d44..257f487aa5 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gNB_SA_40_2x2.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gNB_SA_40_2x2.conf index a050ed6035..490b2c4b88 100755 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gNB_SA_40_2x2.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gNB_SA_40_2x2.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf index 500f2be93e..e92f337dbe 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf index fa3960aec8..a69ec4ac31 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf @@ -6,7 +6,7 @@ gNBs = ( { ////////// Identification parameters: - gNB_CU_ID = 0xe00; + gNB_ID = 0xe00; # cell_type = "CELL_MACRO_GNB"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf index 98d901c35e..6ac50b6aa6 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf @@ -19,7 +19,7 @@ gNBs = ( pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; - do_SRS = 0; + do_SRS = 1; ul_prbblacklist = "135,136,137,138" pdcch_ConfigSIB1 = ({ diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf index f5f187a736..8bc681c67d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf @@ -17,7 +17,7 @@ gNBs = ////////// Physical parameters: - pdsch_AntennaPorts_N1 = 2; + pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; do_SRS = 1; @@ -254,7 +254,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; #pusch_TargetSNRx10 = 150; #pucch_TargetSNRx10 = 200; - ul_prbblack_SNR_threshold = 10; ulsch_max_frame_inactivity = 0; } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index b31569af11..7819bfe652 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -251,7 +251,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; - ul_prbblack_SNR_threshold = 10; ulsch_max_frame_inactivity = 0; } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf index 67797a0378..d7d6b9ca5a 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf @@ -20,6 +20,7 @@ gNBs = pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; + do_SRS = 1; pdcch_ConfigSIB1 = ( { diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index b99d97a180..5d01df15ef 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -62,12 +62,11 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "targets/ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "PHY/phy_extern.h" @@ -326,7 +325,6 @@ static void *L1_thread_tx(void *param) { //wait_sync("tx_thread"); - proc->respEncode = eNB->proc.L1_proc.respEncode; while (!oai_exit) { LOG_D(PHY,"Waiting for TX (IC %d)\n",proc->instance_cnt); @@ -835,14 +833,9 @@ static void *process_stats_thread(void *param) { print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL); print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL); print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL); print_meas(&eNB->dlsch_turbo_encoding_stats,"turbo_encoding",NULL,NULL); print_meas(&eNB->dlsch_interleaving_stats,"turbo_interleaving",NULL,NULL); print_meas(&eNB->dlsch_rate_matching_stats,"turbo_rate_matching",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL); } print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 859a5c40a2..10e1c177d0 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -54,18 +54,19 @@ #include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "SCHED/sched_common.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" -#include "targets/ARCH/COMMON/common_lib.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" /* these variables have to be defined before including ENB_APP/enb_paramdef.h */ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; static int DEFBFW[] = {0x00007fff}; +static int DEFRUTPCORES[] = {2,4,6,8}; + #include "ENB_APP/enb_paramdef.h" #include "common/config/config_userapi.h" @@ -134,8 +135,18 @@ static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t t if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); ru->south_out_cnt++; + int offset = subframe*ru->frame_parms->samples_per_tti; + void *buffs[ru->nb_tx]; + for (int aid=0;aidnb_tx;aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset]; + + ru->ifdevice.trx_write_func2(&ru->ifdevice, + timestamp, + buffs, + 0, + ru->frame_parms->samples_per_tti, + 0, + ru->nb_tx); - send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_RRH_GW_DL); } @@ -172,7 +183,7 @@ void fh_if5_south_in(RU_t *ru, int *subframe) { LTE_DL_FRAME_PARMS *fp = ru->frame_parms; RU_proc_t *proc = &ru->proc; - recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); + ru->ifdevice.trx_read_func2(&ru->ifdevice,&proc->timestamp_rx,NULL,fp->samples_per_tti); proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->tti_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; @@ -398,8 +409,8 @@ void fh_if5_north_asynch_in(RU_t *ru, LTE_DL_FRAME_PARMS *fp = ru->frame_parms; RU_proc_t *proc = &ru->proc; int tti_tx,frame_tx; - openair0_timestamp timestamp_tx; - recv_IF5(ru, ×tamp_tx, *subframe, IF5_RRH_GW_DL); + openair0_timestamp timestamp_tx=0; + //recv_IF5(ru, ×tamp_tx, *subframe, IF5_RRH_GW_DL); // LOG_I(PHY,"Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); tti_tx = (timestamp_tx/fp->samples_per_tti)%10; frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; @@ -492,11 +503,9 @@ void fh_if4p5_north_asynch_in(RU_t *ru, void fh_if5_north_out(RU_t *ru) { - RU_proc_t *proc=&ru->proc; - uint8_t seqno=0; /// **** send_IF5 of rxdata to BBU **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); - send_IF5(ru, proc->timestamp_rx, proc->tti_rx, &seqno, IF5_RRH_GW_UL); +// send_IF5(ru, proc->timestamp_rx, proc->tti_rx, &seqno, IF5_RRH_GW_UL); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index b1275e5dd5..82acba4f84 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -47,8 +47,8 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -645,18 +645,14 @@ int main ( int argc, char **argv ) for (int CC_id=0; CC_idproc.L1_proc; L1_rxtx_proc_t *L1proctx= &RC.eNB[x][CC_id]->proc.L1_proc_tx; - L1proc->threadPool=(tpool_t*)malloc(sizeof(tpool_t)); - L1proc->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + L1proc->threadPool = (tpool_t *)malloc(sizeof(tpool_t)); L1proc->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 ) initTpool(get_softmodem_params()->threadPoolConfig, L1proc->threadPool, true); else - initTpool("n", L1proc->threadPool, true); - initNotifiedFIFO(L1proc->respEncode); + initTpool("n", L1proc->threadPool, true); initNotifiedFIFO(L1proc->respDecode); - L1proctx->threadPool=L1proc->threadPool; - L1proctx->respEncode=L1proc->respEncode; - L1proctx->nbEncode=L1proc->nbEncode; + L1proctx->threadPool = L1proc->threadPool; } diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index e1fa279195..774561e268 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -20,7 +20,7 @@ #include #include #include "threads_t.h" -#include "../../ARCH/COMMON/common_lib.h" +#include "sdr/COMMON/common_lib.h" //#undef MALLOC #include "assertions.h" #include "PHY/types.h" @@ -29,7 +29,6 @@ #include "flexran_agent.h" #include "s1ap_eNB.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" -#include "targets/ARCH/COMMON/common_lib.h" #include "executables/softmodem-common.h" diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 963044a506..24d444751f 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -47,8 +47,8 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/if_defs.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all diff --git a/targets/RT/USER/ru_control.c b/targets/RT/USER/ru_control.c index 083b5f91ef..077ccdc771 100644 --- a/targets/RT/USER/ru_control.c +++ b/targets/RT/USER/ru_control.c @@ -53,11 +53,10 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "sdr/COMMON/common_lib.h" +#include "sdr/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "SCHED/sched_eNB.h" diff --git a/targets/TEST/PACKET_TRACER/pt.c b/targets/TEST/PACKET_TRACER/pt.c index 510865d33e..cc3b62728c 100644 --- a/targets/TEST/PACKET_TRACER/pt.c +++ b/targets/TEST/PACKET_TRACER/pt.c @@ -32,7 +32,6 @@ #include "PHY/vars.h" #include "MAC_INTERFACE/vars.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/defs.h"